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的变化。

相关推荐
风_峰1 天前
AMD 自适应SoC产品系列讲解
fpga开发
FPGA小c鸡1 天前
AXI-Full突发传输完全攻略:从INCR/WRAP/FIXED到4KB边界、地址计算、响应机制(附实战案例)
fpga开发
集芯微电科技有限公司1 天前
DC-DC|40V/10A大电流高效率升压恒压控制器
c语言·数据结构·单片机·嵌入式硬件·fpga开发
minglie12 天前
Vitis HLS c转verilog
c语言·开发语言·fpga开发
江蘇的蘇2 天前
基于FPGA实现NVMe硬盘的读写功能
fpga开发
forgeda2 天前
国产FPGA故障注入测试-用户使用指南
fpga开发·国产fpga·故障注入测试·大容量芯片·7vx690t·复旦jmf fpga·高可用系统
扮作大侠2 天前
vitis板级支持包的.c文件位置
fpga开发
FPGA_小田老师2 天前
FPGA例程(2):LED流水灯--vivado FPGA程序固化下载
fpga开发·fpga程序固化·flash烧写·mcs文件生成
Hqst_xiangxuajun2 天前
万兆SFP光纤笼子交换机和PCIE网卡主板上起到什么作用
网络·fpga开发·oracle·sqlite·json·信息与通信
雨洛lhw2 天前
vivado码流压缩
fpga开发·码流压缩