xilinx IBUFDS 使用和仿真


xilinx IBUFDS 使用和仿真

接收代碼:

以下代碼的功能為:接收16位的LVDS差分信號接收:

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

library ieee;

use ieee.std_logic_1164.all;

Library UNISIM;

use UNISIM.vcomponents.all;

 

entity LVDS_RX_TEST is

         port (

                   k7_rclkp                              :                in     std_logic;

                   k7_rclkn                              :                in     std_logic;

                   lvds_rx_dp                                    :                in     std_logic_vector(15 downto 0);

                   lvds_rx_dn                                    :                in     std_logic_vector(15 downto 0);

                   adc_clk                                          :                 out   std_logic;

                   adc_dat                                         :                 out   std_logic_vector(31 downto 0)

         );

end LVDS_RX_TEST;

 

architecture rtl of LVDS_RX_TEST is

 

signal        k7_rclk                        :                 std_logic;

signal        lvds_rx_dat               :                 std_logic_vector(15 downto 0);

signal        adc_dat_i                   :                 std_logic_vector(31 downto 0);

signal        adc_dat_r                  :                 std_logic_vector(31 downto 0);

signal        k7_rclk_bufds  :                 std_logic;

begin

adc_clk              <=              k7_rclk;

process (k7_rclk)

begin

         if (k7_rclk'event and k7_rclk = '1') then

                   adc_dat_r         <=              adc_dat_i;

                   adc_dat             <=              adc_dat_r;

         end if;

end process;

K7_RCLK_IBUFDS_INST : IBUFDS

   generic map (

      DIFF_TERM                            =>   TRUE,               -- Differential Termination

      IBUF_LOW_PWR                  =>   FALSE,               -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards

      IOSTANDARD                         =>   "LVDS_25")

   port map (

      O          =>   k7_rclk_bufds,       -- Buffer output

      I           =>   k7_rclkp,                  -- Diff_p buffer input (connect directly to top-level port)

      IB         =>   k7_rclkn                    -- Diff_n buffer input (connect directly to top-level port)

   );        

K7_RCLK_BUFG_INST : BUFG

   port map (

      O                                               =>   k7_rclk,            -- 1-bit output: Clock output

      I                                                 =>   k7_rclk_bufds         -- 1-bit input: Clock input

   );        

lvds_rx_gen:

for i in 0 to 15 generate

begin

         IBUFDS_inst : IBUFDS

                   generic map (

                            DIFF_TERM              =>   TRUE,      -- Differential Termination

                            IBUF_LOW_PWR    =>   FALSE,     -- Low power (TRUE) vs. performance (FALSE) setting for referenced I/O standards

                            IOSTANDARD           =>   "LVDS_25")

                   port map (

                            O =>lvds_rx_dat(i),        -- Buffer output

                            I =>          lvds_rx_dp(i),         -- Diff_p buffer input (connect directly to top-level port)

                            IB => lvds_rx_dn(i)           -- Diff_n buffer input (connect directly to top-level port)

                   );

         IDDR_inst : IDDR

                   generic map (

                   DDR_CLK_EDGE=>          "SAME_EDGE_PIPELINED",   --"OPPOSITE_EDGE", "SAME_EDGE"

                                                                                                                -- or "SAME_EDGE_PIPELINED"

                   INIT_Q1 =>   '0',                                                          -- Initial value of Q1: '0' or '1'

                   INIT_Q2 =>   '0',                                                          -- Initial value of Q2: '0' or '1'

                   SRTYPE   =>   "SYNC")                                                 -- Set/Reset type: "SYNC" or "ASYNC"

                   port map (

                            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

                            C     =>   k7_rclk,                                     -- 1-bit clock input

                            CE   =>   '1',                                                 -- 1-bit clock enable input

                            D     =>   lvds_rx_dat(i),                         -- 1-bit DDR data input

                            R     =>   '0',                                                        -- 1-bit reset

                            S      =>   '0'                                                        -- 1-bit set

                            );                        

end generate;

end rtl;

原始仿真代碼:

一開始的仿真代碼如下:

module TB;

         // Inputs

         reg k7_rclkp;

         reg k7_rclkn;

         reg [15:0] lvds_rx_dp;

         reg [15:0] lvds_rx_dn;

         // Outputs

         wire adc_clk;

         wire [31:0] adc_dat;

         LVDS_RX_TEST uut (

                   .k7_rclkp(k7_rclkp),

                   .k7_rclkn(k7_rclkn),

                   .lvds_rx_dp(lvds_rx_dp),

                   .lvds_rx_dn(lvds_rx_dn),

                   .adc_clk(adc_clk),

                   .adc_dat(adc_dat)

         );

         initial begin

                   k7_rclkp = 1;

                   k7_rclkn = 0;

                   lvds_rx_dp = 0;

                   lvds_rx_dn = 0;

                   // Wait 100 ns for global reset to finish

                   #100;

         end

always #100   k7_rclkp=~k7_rclkp;

always #100   k7_rclkn=~k7_rclkn;

always #100  lvds_rx_dp =lvds_rx_dp +2'b11;

always #100  lvds_rx_dn = lvds_rx_dn +2'b10;

endmodule

仿真結果有誤:

 

從圖中可以看出lvds_rx_dat一直為高阻態,接收到的信號均為錯誤信號!!

原因分析:

         分析發現是IBUFDS原語的輸出有問題!具體原因是自己對LVDS和IBUFDS的理解不到位,導致寫出always #10000  lvds_rx_dp =lvds_rx_dp +2'b11;

always #10000  lvds_rx_dn = lvds_rx_dn +2'b10;這樣錯誤的測試語句。

         事實上LVDS是差分信號,即lvds_rx_dp與lvds_rx_dn的每bit均是相反信號;IBUFDS原語的真值表如下:(其中“-*”表示輸出維持上一次的輸出值,保持不變)

         IBUFDS原語用於將差分輸入信號轉化成標准單端信號,且可加入可選延遲。在IBUFDS原語中,輸入信號為I、IB,一個為主,一個為從,二者相位相反。

修改后的仿真代碼:

module TB;

         // Inputs

         reg k7_rclkp;

         reg k7_rclkn;

         reg [15:0] lvds_rx_dp;

         reg [15:0] lvds_rx_dn;

         // Outputs

         wire adc_clk;

         wire [31:0] adc_dat;

         // Instantiate the Unit Under Test (UUT)

         LVDS_RX_TEST uut (

                   .k7_rclkp(k7_rclkp),

                   .k7_rclkn(k7_rclkn),

                   .lvds_rx_dp(lvds_rx_dp),

                   .lvds_rx_dn(lvds_rx_dn),

                   .adc_clk(adc_clk),

                   .adc_dat(adc_dat)

         );

         initial begin

                   // Initialize Inputs

                   k7_rclkp = 1;

                   k7_rclkn = 0;

                   lvds_rx_dp = 0;

                   lvds_rx_dn = 0;

                   #100;

         end

always #100   k7_rclkp=~k7_rclkp;

always #100   k7_rclkn=~k7_rclkn;

always #100  lvds_rx_dp =lvds_rx_dp +2'b11;

always #100  lvds_rx_dn = ~lvds_rx_dp; 

endmodule

修改后的仿真波形:

 

總結:

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)決定


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM