LVDS高速接口测试

话不多说,直接测试

1. OUTPUT:LVDS_TX

2. SDR:代表着速率,测试选的SDR(单速率)

3. 8:串换因子,就是一对LVDS转化几bit的并行数据(和后面的clk,clk_div有关系)

4. 8:8对LVDS

5. LVDS都是差分电压,这个根据板卡上的电压选择

6. 类型肯定是差分的

1. 输出差分时钟

2. 时钟类型选择LVDS,和前面匹配

第三页是数据和时钟的延时,默认

下面说一下测试过程

发送端

1. 发送的数据(需要发送十几个周期的同步码,后面是递增数0~255)

2. 输出的差分时钟(频率和clk_in一致,500M)

3. 串行数据的时钟 (测试的500M)clk_in

4. 并行数据的时钟(测试125M)clk_div_in

clk_in和clk_div的关系就是就是图1中的串换因子以及SDR的关系: 8:1(DDR的话就是4:1)

1. LVDS_TX 核的输出时钟,连接在MMCM上

2. 输出500M和125M,用作LVDS_RX的CLK_IN和CLK_DIV_IN

接收端

LVDS接收需要考虑一个问题是:如何将数据和时钟对齐,这里的bitslip叫位移操作,用它来将同步码找出,进行数据的同步

1. 接收数据,先进行数据的同步

2. bitslip用来同步数据

3. clk_in和clk_div_in分别来自MMCM

4. 复位也来自MMCM

注意: bitslip是一个脉冲信号,产生一个脉冲,数据就移位一次,直到找出同步码为止

下面看下仿真的结果

1. 这是发送数据的同步码:EB90_01DC_EF18_EB90

2. 接收端经过bitslip的同步,最终得到的同步码

3.我用的8通道LVDS,所以bitslip是8bit,每个bit都需要移位,所以是FF

可以看到,发送的数据和接收的数据都是连续的,说明LVDS通信OK

附上代码

module lvds_module

#(
//    parameter     LVDS_DATA_HEAD = 64'hFF00_00FF_FF00_FFFF,          // 同步码
    parameter     LVDS_DATA_HEAD = 64'hEB90_01DC_EF18_EB90,          // 同步码    
    parameter     LVDS_DATA_HEAD_CNT = 8'h40,                                //  同步码的frame        
    parameter    BITSLIP_FRAME   = 4'h8                                           //  bitslip的参数
)

(

   input                          clk_div_in,
   input                          clk_in,

   input                          clk_reset,
   input                          io_reset
  
    );
    
    wire    [63:0]   data_out_from_device;  
    wire    [7:0]   data_out_to_pins_p;
    wire    [7:0]   data_out_to_pins_n;
    
    wire    [63:0]   data_in_to_device;  
    wire    [7:0]   data_in_from_pins_p;
    wire    [7:0]   data_in_from_pins_n;

    reg     [7:0]   bitslip;
        
    reg    [63:0]   data;
    reg     [7:0]   head_cnt; 
    reg     [7:0]   data_cnt;
    
    reg                 bitslip_head_flag;   
    reg     [3:0]     bitslip_cnt;
    
    wire    clk_to_pins_p;
    wire    clk_to_pins_n;
    wire    clk_rx;
    wire    clk_rx_div;    
    
    wire    locked;

  selectio_wiz_0 
  lvds_tx
 (
   .data_out_from_device(data_out_from_device), // input [63:0] data_out_from_device
   .data_out_to_pins_p(data_out_to_pins_p), // output [7:0] data_out_to_pins_p
   .data_out_to_pins_n(data_out_to_pins_n), // output [7:0] data_out_to_pins_n
   .clk_to_pins_p(clk_to_pins_p), // output clk_to_pins_p
   .clk_to_pins_n(clk_to_pins_n), // output clk_to_pins_n
   .clk_in(clk_in), // input clk_in                            
   .clk_div_in(clk_div_in), // input clk_div_in                        
   .clk_reset(clk_reset), // input clk_reset
   .io_reset(io_reset) // input io_reset
); 

  clk_wiz_1 clk_wiz_1
   (
    // Clock out ports
    .clk_out1(clk_rx),     // output clk_out1
    .clk_out2(clk_rx_div),     // output clk_out2
    // Status and control signals
    .locked(locked),       // output locked
   // Clock in ports
    .clk_in1_p(clk_to_pins_p),    // input clk_in1_p
    .clk_in1_n(clk_to_pins_n));    // input clk_in1_n
// INST_TAG_END ------ End INSTANTIATION Template ---------
  
    selectio_wiz_3 
    lvds_rx
   (
     .data_in_from_pins_p(data_in_from_pins_p), // input [0:0] data_in_from_pins_p
     .data_in_from_pins_n(data_in_from_pins_n), // input [0:0] data_in_from_pins_n
     .data_in_to_device(data_in_to_device), // output [7:0] data_in_to_device
     .bitslip(bitslip), // input bitslip                                                     
     .clk_in(clk_rx), // input clk_in                            
     .clk_div_in(clk_rx_div), // input clk_div_in   
     .io_reset(~locked) // input io_reset     
  );     
    
    assign data_out_from_device = data;
    assign data_in_from_pins_p = data_out_to_pins_p;
    assign data_in_from_pins_n = data_out_to_pins_n;               
            
    always @(posedge clk_div_in) begin
//        if (io_reset) begin
                if (~locked) begin
            head_cnt <= 0;
        end else if (head_cnt < LVDS_DATA_HEAD_CNT) begin
            head_cnt <= head_cnt + 1;
        end 
    end

    always @(posedge clk_div_in) begin
//        if (io_reset) begin
                if (~locked) begin
            data_cnt <= 0;
        end else if (head_cnt == LVDS_DATA_HEAD_CNT) begin
            data_cnt <= data_cnt + 1;
        end 
    end    
    
    always @(posedge clk_div_in) begin
//        if (io_reset) begin
                if (~locked) begin
            data <= 0;
        end else if (head_cnt == LVDS_DATA_HEAD_CNT) begin
            data <= data_cnt;
        end else begin
            data <= LVDS_DATA_HEAD;
        end          
    end    

    always @(posedge clk_div_in) begin
//        if (io_reset) begin
                if (~locked) begin
            bitslip_head_flag <= 0;
        end else if (data_in_to_device == LVDS_DATA_HEAD) begin
            bitslip_head_flag <= 1;
        end
    end    

    always @(posedge clk_div_in) begin
//        if (io_reset) begin
                if (~locked) begin
            bitslip_cnt <= 0;
        end else if (bitslip_cnt < BITSLIP_FRAME & ~bitslip_head_flag) begin
            bitslip_cnt <= bitslip_cnt + 1;
        end else begin
            bitslip_cnt <= 0;
        end
    end
    
    always @(posedge clk_div_in) begin
//        if (io_reset) begin
                if (~locked) begin
            bitslip <= 0;
        end else if (bitslip_cnt == BITSLIP_FRAME) begin    
            bitslip <= 8'hff;
        end else begin
            bitslip <= 0;
        end
    end         

endmodule

激励测试

module tb;

    reg clk_in;
    reg clk_div_in;
    reg clk_reset;     
    reg io_reset;   
    
lvds_module lvds_module(
//flash_spi flash_spi(

        .clk_in(clk_in),
        .clk_div_in(clk_div_in),
        .clk_reset(clk_reset),
        .io_reset(io_reset)        

    );
    
    initial begin
        clk_in <= 0;
        clk_div_in <= 1;
        clk_reset <= 1;
        io_reset <= 1;
        #500
        clk_reset <= 0;
        #500
        io_reset <= 0;  
        #1000_000 
        $stop;     
    end  
       
  //  500m
    always #2 clk_in = ~clk_in;   
    //  125M 
    always #8 clk_div_in = ~clk_div_in; 
    
endmodule

  • 7
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值