zoukankan      html  css  js  c++  java
  • 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)决定

  • 相关阅读:
    mysql group_concat函数
    easyui textbox获取焦点事件
    jquery获取select下拉框的前一个,后一个,第一个,最后一个option对象
    easyui 只刷新当前页面的数据 datagrid reload 方法
    spring-data-jpa查询语句的书写实例小计
    jquery给input标签添加data-options属性
    正则表达式的常用方法
    正则表达式之 /^(d)$/
    jquery获取下拉列表的值和显示内容的方法
    一个 关于 case when的SQL
  • 原文地址:https://www.cnblogs.com/chuanchuan304/p/5893198.html
Copyright © 2011-2022 走看看