xilinx OBUFDS 使用和仿真
发送代码:
library ieee;
use ieee.std_logic_1164.all;
Library UNISIM;
use UNISIM.vcomponents.all;
entity LVDS_TX_TEST is
port (
xc7_clk : in std_logic;
k7_tclk : in std_logic;
k7_tclkp : out std_logic;
k7_tclkn : out std_logic;
lvds_tx_dp : out std_logic_vector(15 downto 0);
lvds_tx_dn : out std_logic_vector(15 downto 0);
dac_dat : in std_logic_vector(31 downto 0)
);
end LVDS_TX_TEST;
architecture rtl of LVDS_TX_TEST is
signal lvds_tx_dat : std_logic_vector(15 downto 0);
signal dac_dat_r1 : std_logic_vector(31 downto 0):= x"00000000";
signal dac_dat_r2 : std_logic_vector(31 downto 0):= x"0000" &x"0000";
begin
-- synchronize two cycles to achive better timing performance
process (xc7_clk)
begin
if (xc7_clk'event and xc7_clk = '1') then
dac_dat_r1 <= dac_dat;
dac_dat_r2 <= dac_dat_r1(31 downto 16) & dac_dat_r1(15 downto 0);
end if;
end process;
K7_TCLK_OBUFDS : OBUFDS
generic map (
IOSTANDARD => "LVDS_25", -- Specify the output I/O standard
SLEW => "FAST") -- Specify the output slew rate
port map (
O => k7_tclkp, -- Diff_p output (connect directly to top-level port)
OB => k7_tclkn, -- Diff_n output (connect directly to top-level port)
I => k7_tclk -- Buffer input
);
lvds_tx_gen:
for i in 0 to 15 generate
begin
ODDR_inst : ODDR
generic map(
DDR_CLK_EDGE => "SAME_EDGE", -- "OPPOSITE_EDGE" or "SAME_EDGE"
INIT => '0', -- Initial value for Q port ('1' or '0')
SRTYPE => "SYNC") -- Reset Type ("ASYNC" or "SYNC")
port map (
Q => lvds_tx_dat(i), -- 1-bit DDR output
C => xc7_clk, -- 1-bit clock input
CE => '1', -- 1-bit clock enable input
D1 => dac_dat_r2(i), -- 1-bit data input (positive edge)
D2 => dac_dat_r2(16+i), -- 1-bit data input (negative edge)
R => '0', -- 1-bit reset input
S => '0' -- 1-bit set input
);
OBUFDS_inst : OBUFDS
generic map (
IOSTANDARD => "LVDS_25", - Specify the output I/O standard
SLEW => "FAST") -- Specify the output slew rate
port map (
O => lvds_tx_dp(i), -- Diff_p output (connect directly to top-level port)
OB => lvds_tx_dn(i), -- Diff_n output (connect directly to top-level port)
I => lvds_tx_dat(i) -- Buffer input
);
end generate;
end rtl;
仿真代码:
module TB;
reg xc7_clk;
reg k7_tclk;
reg [31:0] dac_dat;
wire k7_tclkp;
wire k7_tclkn;
wire [15:0] lvds_tx_dp;
wire [15:0] lvds_tx_dn;
LVDS_TX_TEST uut (
.xc7_clk(xc7_clk),
.k7_tclk(k7_tclk),
.k7_tclkp(k7_tclkp),
.k7_tclkn(k7_tclkn),
.lvds_tx_dp(lvds_tx_dp),
.lvds_tx_dn(lvds_tx_dn),
.dac_dat(dac_dat)
);
initial begin
// Initialize Inputs
xc7_clk = 0;
k7_tclk = 0;
dac_dat = 32'hffffffff;
#100;
end
always #100 xc7_clk =~xc7_clk;
always #100 k7_tclk =~k7_tclk;
always #200 dac_dat =dac_dat + 32'h00010002;
endmodule
仿真波形:
总结:
xilinx IBUFDS发送时时钟高电平开始发低位数据!(高低位由语句:
D1 => dac_dat_r2(i), -- 1-bit data input (positive edge)
D2=> dac_dat_r2(17+i), -- 1-bit data input (negative edge))决定
xilinx IBUFDS接收时先接时钟高电平的数据,但将其置于输出信号的低位!(高低位由语句:
Q1 => adc_dat_i(i), -- 1-bit output for positive edge of clock
Q2 => adc_dat_i(16+i), -- 1-bit output for negative edge of clock)决定