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

前言

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

一、SDR模式

1.1、设计代码

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

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文件:

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、以及并串转换模式即可。

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代码

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

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引脚,修改位宽即可。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

顺子学不会FPGA

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值