SerDes介绍以及原语使用介绍(2)OSERDESE2原语仿真

文章目录

前言

上文通过xilinx ug471手册对OSERDESE有了简单的了解,接下来通过仿真进一步深化印象。

一、SDR模式

1.1、设计代码

以下代码表示在SDR模式下对输入的4位宽并行数据进行并串转换。

c 复制代码
module serdes_top(
   input          i_clk       ,
   input          i_div_clk   ,
   input          i_rst       ,
   input  [3 :0]  i_par_data  ,
   output         o_ser_data  
);
    
wire OFB;
    
   OSERDESE2 #(
      .DATA_RATE_OQ     ("SDR"         ), // DDR, SDR
      .DATA_RATE_TQ     ("DDR"         ), // DDR, BUF, SDR
      .DATA_WIDTH       (4             ), // Parallel data width (2-8,10,14)
      .INIT_OQ          (1'b0          ), // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ          (1'b0          ), // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE      ("MASTER"      ), // MASTER, SLAVE
      .SRVAL_OQ         (1'b0          ), // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ         (1'b0          ), // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL        ("FALSE"       ), // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC        ("FALSE"       ), // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH   (1             )  // 3-state converter width (1,4)
   )
   OSERDESE2_inst (
      .OFB              (OFB           ), // 1-bit output: Feedback path for data
      .OQ               (o_ser_data    ), // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1        (              ),
      .SHIFTOUT2        (              ),
      .TBYTEOUT         (              ), // 1-bit output: Byte group tristate
      .TFB              (              ), // 1-bit output: 3-state control
      .TQ               (              ), // 1-bit output: 3-state control
      .CLK              (i_clk         ), // 1-bit input: High speed clock
      .CLKDIV           (i_div_clk     ), // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1               (i_par_data[0] ),
      .D2               (i_par_data[1] ),
      .D3               (i_par_data[2] ),
      .D4               (i_par_data[3] ),
      .D5               (),
      .D6               (),
      .D7               (),
      .D8               (),
      // .D5               (i_par_data[4] ),
      // .D6               (i_par_data[5] ),
      // .D7               (i_par_data[6] ),
      // .D8               (i_par_data[7] ),
      .OCE              (1'b1          ), // 1-bit input: Output data clock enable
      .RST              (i_rst         ), // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1         (),
      .SHIFTIN2         (),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1               (1'b0          ),
      .T2               (1'b0          ),
      .T3               (1'b0          ),
      .T4               (1'b0          ),
      .TBYTEIN          (1'b0          ), // 1-bit input: Byte group tristate
      .TCE              (1'b0          )  // 1-bit input: 3-state clock enable
   );

1.2、testbench代码

以下为TB文件:

c 复制代码
module serdes_sim();

localparam P_CLK_PERIOD = 40;

reg clk, div_clk , rst;
reg [3 :0] r_din;

wire w_ser_dout;

always begin
    div_clk = 0;
    #(P_CLK_PERIOD); 
    div_clk = 1;
    #(P_CLK_PERIOD); 
end

always begin
    clk = 1;
    #(P_CLK_PERIOD/4); 
    clk = 0;
    #(P_CLK_PERIOD/4); 
end

initial begin
    rst = 1;
    #100;
    @(posedge clk);
    rst = 0;
    repeat(200) @(posedge clk);
    $stop;
end

initial begin
    r_din = 'd0;
    data_gen();
end

serdes_top serdes_top_u0(
   .i_clk           (clk        ),
   .i_div_clk       (div_clk    ),
   .i_rst           (rst        ),
   .i_par_data      (r_din      ),
   .o_ser_data      (w_ser_dout ) 
);

task data_gen();
begin
    r_din <= 'd0;
    wait(!rst);
    repeat(10) @(posedge div_clk);
    r_din <= ({$random} % 16);
    forever begin
        @(posedge div_clk);
        r_din <= ({$random} % 16);
    end
end
endtask

endmodule

1.3、仿真分析

第一个并行数据为4'b0100,在蓝色刻度线处被采样,黄色刻度线开始输出,但是按照表中输出时延应该是3个CLK后开始输出,这是因为CLK和CLKDIV相位对齐,输出时延可以变化一个CLK,仿真结果显示是4个CLK,相比于表中描述多了一个CLK.

二、DDR模式下

2.1、设计代码

只需要修改位宽,输入D5-D8、以及并串转换模式即可。

c 复制代码
module serdes_top(
   input          i_clk       ,
   input          i_div_clk   ,
   input          i_rst       ,
   input  [7 :0]  i_par_data  ,
   output         o_ser_data  
);
    
wire OFB;
    
   OSERDESE2 #(
      .DATA_RATE_OQ     ("DDR"         ), // DDR, SDR
      .DATA_RATE_TQ     ("DDR"         ), // DDR, BUF, SDR
      .DATA_WIDTH       (8             ), // Parallel data width (2-8,10,14)
      .INIT_OQ          (1'b0          ), // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ          (1'b0          ), // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE      ("MASTER"      ), // MASTER, SLAVE
      .SRVAL_OQ         (1'b0          ), // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ         (1'b0          ), // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL        ("FALSE"       ), // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC        ("FALSE"       ), // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH   (1             )  // 3-state converter width (1,4)
   )
   OSERDESE2_inst (
      .OFB              (OFB           ), // 1-bit output: Feedback path for data
      .OQ               (o_ser_data    ), // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1        (              ),
      .SHIFTOUT2        (              ),
      .TBYTEOUT         (              ), // 1-bit output: Byte group tristate
      .TFB              (              ), // 1-bit output: 3-state control
      .TQ               (              ), // 1-bit output: 3-state control
      .CLK              (i_clk         ), // 1-bit input: High speed clock
      .CLKDIV           (i_div_clk     ), // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1               (i_par_data[0] ),
      .D2               (i_par_data[1] ),
      .D3               (i_par_data[2] ),
      .D4               (i_par_data[3] ),
      // .D5               (),
      // .D6               (),
      // .D7               (),
      // .D8               (),
      .D5               (i_par_data[4] ),
      .D6               (i_par_data[5] ),
      .D7               (i_par_data[6] ),
      .D8               (i_par_data[7] ),
      .OCE              (1'b1          ), // 1-bit input: Output data clock enable
      .RST              (i_rst         ), // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1         (),
      .SHIFTIN2         (),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1               (1'b0          ),
      .T2               (1'b0          ),
      .T3               (1'b0          ),
      .T4               (1'b0          ),
      .TBYTEIN          (1'b0          ), // 1-bit input: Byte group tristate
      .TCE              (1'b0          )  // 1-bit input: 3-state clock enable
   );
   
endmodule

2.2、testbench代码

修改位宽以及产生随机数的大小即可。

c 复制代码
module serdes_sim();

localparam P_CLK_PERIOD = 40;

reg clk, div_clk , rst;
reg [7 :0] r_din;

wire w_ser_dout;

always begin
    div_clk = 0;
    #(P_CLK_PERIOD); 
    div_clk = 1;
    #(P_CLK_PERIOD); 
end

always begin
    clk = 1;
    #(P_CLK_PERIOD/4); 
    clk = 0;
    #(P_CLK_PERIOD/4); 
end

initial begin
    rst = 1;
    #100;
    @(posedge clk);
    rst = 0;
    repeat(200) @(posedge clk);
    $stop;
end

initial begin
    r_din = 'd0;
    data_gen();
end

serdes_top serdes_top_u0(
   .i_clk           (clk        ),
   .i_div_clk       (div_clk    ),
   .i_rst           (rst        ),
   .i_par_data      (r_din      ),
   .o_ser_data      (w_ser_dout ) 
);

task data_gen();
begin
    r_din <= 'd0;
    wait(!rst);
    repeat(10) @(posedge div_clk);
    r_din <= ({$random} % 256);
    forever begin
        @(posedge div_clk);
        r_din <= ({$random} % 256);
    end
end
endtask

endmodule

2.3、仿真分析

蓝色刻度线处采样到并行输入数据,黄色刻度线开始输出,延时为4个CLK,与表中描述是一致的。

三、OSERDES2级联

当我们需要对10位或14位并行数据进行并串转换时,需要对OSERDSES2进行级联。本实验以10位输入数据并串转换为例进行说明。

3.1、设计代码

俩个OSERDESE2级联,修改位宽,添加从OSERDESE2,连接SHIFT引脚,修改位宽即可。

c 复制代码
module serdes_top(
   input          i_clk       ,
   input          i_div_clk   ,
   input          i_rst       ,
   input  [9 :0]  i_par_data  ,
   output         o_ser_data  
);
    
wire OFB          ;
wire w_shiftout1  ;
wire w_shiftout2  ;
    
   OSERDESE2 #(
      .DATA_RATE_OQ     ("DDR"         ), // DDR, SDR
      .DATA_RATE_TQ     ("DDR"         ), // DDR, BUF, SDR
      .DATA_WIDTH       (10            ), // Parallel data width (2-8,10,14)
      .INIT_OQ          (1'b0          ), // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ          (1'b0          ), // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE      ("MASTER"      ), // MASTER, SLAVE
      .SRVAL_OQ         (1'b0          ), // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ         (1'b0          ), // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL        ("FALSE"       ), // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC        ("FALSE"       ), // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH   (1             )  // 3-state converter width (1,4)
   )
   OSERDESE2_inst (
      .OFB              (OFB           ), // 1-bit output: Feedback path for data
      .OQ               (o_ser_data    ), // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1        (              ),
      .SHIFTOUT2        (              ),
      .TBYTEOUT         (              ), // 1-bit output: Byte group tristate
      .TFB              (              ), // 1-bit output: 3-state control
      .TQ               (              ), // 1-bit output: 3-state control
      .CLK              (i_clk         ), // 1-bit input: High speed clock
      .CLKDIV           (i_div_clk     ), // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1               (i_par_data[0] ),
      .D2               (i_par_data[1] ),
      .D3               (i_par_data[2] ),
      .D4               (i_par_data[3] ),
      .D5               (i_par_data[4] ),
      .D6               (i_par_data[5] ),
      .D7               (i_par_data[6] ),
      .D8               (i_par_data[7] ),
      .OCE              (1'b1          ), // 1-bit input: Output data clock enable
      .RST              (i_rst         ), // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1         (w_shiftout1   ),
      .SHIFTIN2         (w_shiftout2   ),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1               (1'b0          ),
      .T2               (1'b0          ),
      .T3               (1'b0          ),
      .T4               (1'b0          ),
      .TBYTEIN          (1'b0          ), // 1-bit input: Byte group tristate
      .TCE              (1'b0          )  // 1-bit input: 3-state clock enable
   );

   OSERDESE2 #(
      .DATA_RATE_OQ     ("DDR"         ), // DDR, SDR
      .DATA_RATE_TQ     ("DDR"         ), // DDR, BUF, SDR
      .DATA_WIDTH       (10            ), // Parallel data width (2-8,10,14)
      .INIT_OQ          (1'b0          ), // Initial value of OQ output (1'b0,1'b1)
      .INIT_TQ          (1'b0          ), // Initial value of TQ output (1'b0,1'b1)
      .SERDES_MODE      ("SLAVE"      ), // MASTER, SLAVE
      .SRVAL_OQ         (1'b0          ), // OQ output value when SR is used (1'b0,1'b1)
      .SRVAL_TQ         (1'b0          ), // TQ output value when SR is used (1'b0,1'b1)
      .TBYTE_CTL        ("FALSE"       ), // Enable tristate byte operation (FALSE, TRUE)
      .TBYTE_SRC        ("FALSE"       ), // Tristate byte source (FALSE, TRUE)
      .TRISTATE_WIDTH   (1             )  // 3-state converter width (1,4)
   )
   OSERDESE2_inst1 (
      .OFB              (           ), // 1-bit output: Feedback path for data
      .OQ               (    ), // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1        (w_shiftout1   ),
      .SHIFTOUT2        (w_shiftout2   ),
      .TBYTEOUT         (              ), // 1-bit output: Byte group tristate
      .TFB              (              ), // 1-bit output: 3-state control
      .TQ               (              ), // 1-bit output: 3-state control
      .CLK              (i_clk         ), // 1-bit input: High speed clock
      .CLKDIV           (i_div_clk     ), // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1               (),
      .D2               (),
      .D3               (i_par_data[8] ),
      .D4               (i_par_data[9] ),
      // .D5               (),
      // .D6               (),
      // .D7               (),
      // .D8               (),
      .D5               (),
      .D6               (),
      .D7               (),
      .D8               (),
      .OCE              (1'b1          ), // 1-bit input: Output data clock enable
      .RST              (i_rst         ), // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1         (),
      .SHIFTIN2         (),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1               (1'b0          ),
      .T2               (1'b0          ),
      .T3               (1'b0          ),
      .T4               (1'b0          ),
      .TBYTEIN          (1'b0          ), // 1-bit input: Byte group tristate
      .TCE              (1'b0          )  // 1-bit input: 3-state clock enable
   );
   
endmodule

3.2、testbench代码

首先需要修改时钟信号,因为输入输出位宽10:1,在DDR模式下,时钟比为5:1,其次修改位宽以及随机数产生即可。

3.3、代码分析

蓝色刻度线处采样到并行输入数据,黄色刻度线开始输出,延时为4个CLK,表中描述延时应当为5个CLK,但此处CLK和DIVCLK是对齐的,所有导致了一个CLK的变化。

相关推荐
qq_392399908 分钟前
FPGA问题
fpga开发
乌恩大侠8 小时前
PXIe-7976【K410T】
fpga开发
作精本精12 小时前
Xilinx FPGA:vivado实现乒乓缓存
fpga开发
深圳信迈科技DSP+ARM+FPGA1 天前
基于X86+FPGA+AI的切割机控制、六轴机器人控制方案
人工智能·fpga开发·视觉检测
Anin蓝天(北京太速科技-陈)1 天前
116-基于5VLX110T FPGA FMC接口功能验证6U CPCI平台
图像处理·嵌入式硬件·fpga开发
作精本精1 天前
Xilinx FPGA:vivado关于真双端口的串口传输数据的实验
fpga开发
迪普微社区1 天前
双芯合璧,双FPGA赋能的软件无线电平台上线!
图像处理·fpga开发·fpga·开发板·通信·射频·雷达监测
程序员不想敲代码啊1 天前
【Emacs Verilog mode保姆级的使用指南】
fpga开发·编辑器·emacs
小达爱学习2 天前
verilog实现PID控制
fpga开发
FPGAmaster创新者2 天前
基于AGX ORIN与FPGA K7实现PCIE高速数据通信/Orin与FPGA高速数据传输/XDMA在linux系统使用教程
linux·嵌入式硬件·fpga开发