xilinx原语详解及仿真——OSERDESE2

2023-12-13 19:11:50

1、概括OSERDESE2

??OSERDESE2(Output Parallel-to-Serial Logic Resources是7系列FPGA器件中的专用并串转换器,具有特定的时钟和逻辑资源。 图1是OSERDESE2的框图,每个OSERDESE2模块都包含一个用于数据和三态控制的专用串行器。数据和三态串行器输出都可以配置为SDR(在时钟的单沿传输数据)和DDR(在时钟的双沿传输数据)模式。数据序列化最高可达 8:1(如果使用OSERDESE2宽度扩展,则为10:1或14:1)。
在这里插入图片描述

图1 OSERDESE2框图

??OSERDESE2在FPGA中其实是和OLOGIC复用资源的,如图2所示,图中标注的是OLOGICE3,但是很多引脚都是OSERDESE2的,而OSERDESE2和OLOGICE3中的ODDR功能有相似的地方,都支持在时钟信号的双沿输出数据。所以这两个器件共用了资源,在使用时,同一个IO不能同时使用OLOGICE3和OSERDESE2的功能。

在这里插入图片描述

图2 OSERDESE2在FPGA中的分布

??OSERDESE2模块是将并行数据转换为串行数据进行输出,一般并行转串行的时序如图3所示。在第二个时钟上升沿采集到clk_div输入4bit并行数据,在一个clk_div时钟周期内需要将并行数据转换为串行数据输出,那么使用clk与clk_div相位对齐(同一锁相环输出两个相位相同的时钟即可),clk频率是clk_div四倍。然后在clk的上升沿从低位到高位依次输出din的数据。

在这里插入图片描述

图3 SDR模式下并行转串行时序图

??因此OSERDESE2也有两个时钟信号,一个与输出数据对齐CLK,一个与输入数据对齐的CLKDIV,CLK和CLKDIV的相位必须一致。此外OSERDESE2内部还有一个计数器,用来计数当前dout输出的是输入信号的第几位数据了,所以在使用OSERDESE2前,必须对OSERDESE2进行复位,复位信号可以是同步复位,也可以是异步复位,但是复位信号无效边沿必须与CLKDIV同步(即使用异步复位时,要考虑同步释放复位)。

??上述转换关系可知,时钟clk与clk_div的时钟频率之比与输入数据和输出数据的位宽之比一致。如果要将10bit并行输入数据转换为串行数据输出,那么clk频率为clk_div的10倍。HDMI传输1024*768,60Hz刷新率图像时,并行数据时钟clk_div为65MHz,那么clk的时钟频率为650MHz,这在FPGA内部还可以实现。但需要传输1920*1080分辨率,60Hz刷新率图像时,需要时钟clk_div频率达到148.5MHz,而clk需要1485MHz,这在7系列FPGA内部显然无法实现。

??如图4所示的DDR模式传输数据,在时钟clk上升沿和下降沿都输出数据,数据传输的速度提升一倍,传输同样的数据,相比SDR模式,DDR模式的时钟频率可以降低一半。

在这里插入图片描述

图4 DDR模式下并行转串行时序图

??在DDR模式下,两个时钟频率相差为输入数据位宽除以2。当然在DDR模式输入数据的位宽就不能是单数,时钟clk的频率不好处理。

??OSERDESE2模块还包含一个用于IOB的三态控制的并串转换器,最多只能把4位并行数据转换为串行数据且不能级联。

2、OSERDESE2原语信号及参数

2.1、OSERDESE2原语端口

??图5是OSERDESE2的原语框图,时钟CLK与输出串行数据对齐的高频时钟信号,而CLKDIV是与输入并行信号对齐的低频时钟信号。

在这里插入图片描述

图5 OSERDESE2原语框图

??D1~D8是并行输入数据端口,单个OSERDESE2最多配置8位输入并行输入数据,两个OSERDESE2模块级联可以配置10位或14位并行输入数据。注意D1最先转换为串行数据输出。

??OQ是串行输出信号,直接与IOB相连,该信号只能输出到FPGA管脚。 如果要将信号输出到ODELAYE2或者ISERDESE2,那么使用OFB端口,OFB和OQ两个端口的信号一模一样,只是数据走向不同。

??OSERDESE2原语还有三态控制输出的功能,那么T1~T4是三态控制信号,与D1~D4数据对应。使用三态功能时,TQ作为串行输出的管脚,用于判断OQ信号此时是作为输入引脚(TQ为高电平)还是输出引脚(TQ为低电平),而TFB与TQ原理类似。

??OCE就是数据转换的时钟使能信号,而TCE是三态转换的时钟使能信号,均是高电平有效。

??SHIFTIN1、SHIFTIN2、SHIFTOUT1、SHIFTOUT2用于OSERDESE2转换数据时的位扩展,单个OSERDESE2最多只能将8bit并行数据转换位串行数据输出,而两个OSERDESE2级联最多可以将14bit并行数据转换位串行数据输出。如图6所示,是两个OSERDESE2将10bit并行输入转换为串行输出的连接框图。从OSERDESE2的SHIFTOUT1、SHIFTOUT2连接到主OSERDESE2的SHIFTIN1、SHIFTIN2实现扩展。从模块的输入数据从D3开始连接,D1和D2不能使用。

在这里插入图片描述

图6 OSERDESE2 宽度扩展框图

??扩展OSERDESE2位宽时,如果是差分输出,主OSERDESE2必须位于差分输出对的正极(P 引脚)侧。表1列出了SDR和DDR模式的数据宽度可用取值。

表1 SDR和DDR模式的数据宽度可用取值
模式位宽(bit)
SDR2、3、4、5、6、7、8
DDR4、6、8、10、14

??RST是一个异步的高电平复位,RST拉高时,会将CLK和CLKDIV时钟域下的所有触发器清零输出低电平。当设计中存在多个OSERDESE2模块时,推荐所有OSERDESE2均使用同一个复位信号,并且RST拉高应该与CLKDIV信号同步,确保所有OSERDESE2模块能够同时退出复位状态。

2.2、OSERDESE2原语参数

??该原语总共存在11个参数,INIT_OQ用于表示OQ信号的初始状态,默认为1’b0。INIT_TQ用于表示TQ的初始状态,默认为1’b0。SRVAL_OQ用于表示OQ信号复位时的值,默认也为1’b0。SRVAL_TQ用于表示TQ信号复位时的值,默认也为1‘b0。在使用原语时,可以不对这四个参数进行修改,默认即可。

??参数SERDES_MODE定义使用宽度扩展时OSERDESE2模块是主模块还是从模块。可以为MASTER或SLAVE,默认为MASTER

??参数DATA_RATE_OQ定义数据是以单数据速率(SDR)还是双数据速率(DDR)进行串行化处理,默认值为DDR。

??参数DATA_WIDTH定义并串转换器的并行数据输入宽度。当 DATA_RATE_OQ设置为SDR时,DATA_WIDTH可能取值为2、3、4、5、6、7和8。当DATA_RATE_OQ设置为DDR时,DATA_WIDTH属性的可能值为 4、6、8 、10 和 14。

??参数DATA_RATE_TQ定义是否将三态控制作为单数据速率(SDR)还是双数据速率(DDR)进行处理。该属性允许的值为SDR、DDR或BUF,默认为DDR。在SDR和DDR模式下,使用T1~T4输入,并且可以使用TRISTATE_WIDTH配置三态输入宽度。在BUF模式下,SDR和DDR模式寄存器被旁路,使用T1输入。

??参数TRISTATE_WIDTH定义三态控制并串转换器的并行三态输入宽度。当DATA_RATE_TQ设置为SDR或BUF时,TRISTATE_WIDTH属性只能设置为1。当DATA_RATE_TQ设置为DDR时,TRISTATE_WIDTH属性的可能值为1和4。

图7显示了使用OSERDESE2的有效设置和组合。

在这里插入图片描述

图7 OSERDESE2属性组合

??OSERDESE2块的输入到输出延迟指的是当CLKDIV的上升沿把输入数据D1~D8端口的数据寄存到OSERDESE2内部时 到 OSERDESE2的OQ端口输出第一位数据的时间间隔。当CLK和CLKDIV的相位对齐时,延迟可能相差一个CLK周期,如果CLK和CLKDIV的相位没有对齐时,延迟的值取决于DATA_RATE和DATA_WIDTH的值,如图8所示。

在这里插入图片描述

图8 OSERDESE2 延迟

2.3、OSERDESE2模式时序

??如图9所示,OSERDESE2采用SDR模式将2位并行数据转换为串行数据输出,时钟CLK和CLKDIV的相位是对齐的,在CLKDIV第二个上升沿时,采集到两位并行输入数据2’bBA,经过一个CLK延迟后,在CLK的第一个上升沿输出A,第二CLK上升沿输出B,完成并行到串行数据的转换。

在这里插入图片描述

图9 2:1 SDR模式下OSERDESE2的时序图

??如图10所示,OSERDESE2采用DDR模式将8位并行数据转换为串行数据输出,在CLKDIV第二个上升沿时,OSERDESE2采样D1~D8的输入数据ABCDEFGH到内部,经过四个CLK周期后,在CLK的上升沿OQ输出第一个数据A,在CLK下降沿OQ输出第二个数据B,依次在双沿输出所有数据。

在这里插入图片描述

图10 8:1 DDR模式下OSERDESE2的时序图

??在CLKDIV第三个时钟周期内输出完第二个CLKDIV时钟采集的数据,在CLKDIV第四个时钟开始输出在CLKDIV第三个时钟采集到D1~D8的数据。

??如图11是使用三态传输时的时序图,此时最多将4位并行数据转为串行数据输出,在时钟CLKDIV第三个上升沿处,采集到D1D4的数据位EFGH,与此时T1T4的数据0010对应。

??经过一个CLK时钟周期后,OQ输出第一个串行数据E,而TQ开始输出对应三态数据0,当TQ数据为0时,才会将OQ的数据输出到IOB模块,当TQ为1时,FPGA管脚作为输入,此时不会把OQ的数据输出到IOB。因此图11中当TQ为低电平时,OBUFT.O才输出OQ对应的数据EFH,否则不输出OQ的数据。

在这里插入图片描述

图11 4:1 DDR模式下OSERDESE2三态传输的时序图

3、OSERDESE2原语仿真

??在Vivado中获取OSERDESE2原语模板,获取方式在讲解IDDR原语时已经详细讲过,不再赘述,获取原语模板如下所示:

   OSERDESE2 #(
      .DATA_RATE_OQ("DDR"),   // 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(4)      // 3-state converter width (1,4)
   )
   OSERDESE2_inst (
      .OFB(OFB),             // 1-bit output: Feedback path for data
      .OQ(OQ),               // 1-bit output: Data path output
      // SHIFTOUT1 / SHIFTOUT2: 1-bit (each) output: Data output expansion (1-bit each)
      .SHIFTOUT1(SHIFTOUT1),
      .SHIFTOUT2(SHIFTOUT2),
      .TBYTEOUT(TBYTEOUT),   // 1-bit output: Byte group tristate
      .TFB(TFB),             // 1-bit output: 3-state control
      .TQ(TQ),               // 1-bit output: 3-state control
      .CLK(CLK),             // 1-bit input: High speed clock
      .CLKDIV(CLKDIV),       // 1-bit input: Divided clock
      // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
      .D1(D1),
      .D2(D2),
      .D3(D3),
      .D4(D4),
      .D5(D5),
      .D6(D6),
      .D7(D7),
      .D8(D8),
      .OCE(OCE),             // 1-bit input: Output data clock enable
      .RST(RST),             // 1-bit input: Reset
      // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
      .SHIFTIN1(SHIFTIN1),
      .SHIFTIN2(SHIFTIN2),
      // T1 - T4: 1-bit (each) input: Parallel 3-state inputs
      .T1(T1),
      .T2(T2),
      .T3(T3),
      .T4(T4),
      .TBYTEIN(TBYTEIN),     // 1-bit input: Byte group tristate
      .TCE(TCE)              // 1-bit input: 3-state clock enable
   );

3.1 SDR模式并串转换

??首先来一个SDR模式的串并转换,输入5位并行数据,输出1位串行数据,高速时钟CLK的频率是输入数据时钟CLKDIV的5倍,对应的设计代码如下所示:

module oserdese2_ctrl(
    input           clk      ,//系统时钟信号;
    input           clk_div  ,
    input           rst      ,//系统复位信号,高电平有效;
    input [4 : 0]   din      ,//输入数据;

    output          oq       //输出数据
); 
    //例化主OSERDESE2原语
    OSERDESE2 #(
        .DATA_RATE_OQ   ( "SDR"     ),// DDR, SDR
        .DATA_RATE_TQ   ( "DDR"     ),// DDR, BUF, SDR
        .DATA_WIDTH     ( 5         ),// 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        (           ),// 1-bit output: Feedback path for data
        .OQ         (oq         ),// 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        (clk        ),// 1-bit input: High speed clock
        .CLKDIV     (clk_div    ),// 1-bit input: Divided clock
        // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
        .D1         (din[0]     ),
        .D2         (din[1]     ),
        .D3         (din[2]     ),
        .D4         (din[3]     ),
        .D5         (din[4]     ),
        .D6         (           ),
        .D7         (           ),
        .D8         (           ),
        .OCE        (1'b1       ),// 1-bit input: Output data clock enable
        .RST        (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

??对应的TestBench文件如下所示:

`timescale 1 ns/1 ns
module test();
    parameter	CYCLE		=   70      ;//系统时钟周期,单位ns,默认70ns;

    reg			                clk     ;//系统时钟,默认100MHz;
    reg			                rst     ;//系统复位,默认高电平有效;
    reg                         clk_div ;
    reg   [4 : 0]               din     ;

    wire                        oq      ;

    oserdese2_ctrl  u_oserdese2_ctrl (
        .clk        ( clk       ),
        .clk_div    ( clk_div   ),
        .rst        ( rst       ),
        .din        ( din       ),
        .oq         ( oq        )
    );

    //生成周期为CYCLE数值的系统时钟;
    initial begin
        clk_div = 1;
        forever #(CYCLE/2) clk_div = ~clk_div;
    end
    initial begin
        clk = 1;
        forever #(CYCLE/10) clk = ~clk;
    end

    //生成复位信号;
    initial begin
        rst = 0;
        #2;
        rst = 1;//开始时复位10个时钟;
        #(10*CYCLE);
        rst = 0;
        repeat(120) @(posedge clk);
        $stop;//停止仿真;
    end

    initial begin
        #1;
        din = 5'd0;
        forever begin
            #(CYCLE);
            din = ({$random} % 32);
        end
    end

endmodule

??运行仿真得到部分仿真截图,如图12所示,如果不注意分析,会以为仿真结果错误。复位信号rst复位完成(拉低)后,clk在760ns之后采集到第一个输入数据5’b01101,什么时候OQ才输出数据?通过查阅图8可知,在SDR模式,输入数据位宽:输出数据位宽之比等于5:1时,延迟4个clk时钟后OQ输出数据,所以在图12中820ns后的第一个时钟上升沿开始输出采集到的最低位数据1’b1,下个时钟上升沿输出1’b0,依次完成数据转换。注意OQ输出开始输出的clk时钟边沿并没有与clk_div的时钟边沿对齐。

在这里插入图片描述

图12 OSERDESE2在SDR模式下将5位并行数据串行化的仿真图

??特别注意:OQ输出数据与采集到数据的时间间隔要与图8表中的间隔一致,不然会错误分析

??然后把该工程的引脚进行分配,综合、实现工程,查看OQ信号在FPGA中的位置,如图13所示。

在这里插入图片描述

图13 OQ信号的分布

??把OQ信号前面的OSERDESE2放大,如图14所示,OSERDESE2占据OLOGICE3的位置,因此OLOGICE3与OSERDESE2是复用一些资源的。

在这里插入图片描述

图14 OSERDESE2布局布线

3.2 DDR模式并串转换

??图12中,clk频率是clk_div频率的5倍,同样的时钟关系,OSERDESE2使用DDR模式,可以把输入的10位并行数据转换为串行数据输出,单个OSERDESE2最多只能把8位并行数据转换位串行数据,因此需要两个OSERDESE2级联使用,对应的代码如下所示:

module oserdese2_ctrl(
    input           clk      ,//系统时钟信号;
    input           clk_div  ,
    input           rst      ,//系统复位信号,高电平有效;
    input [9 : 0]   din      ,//输入数据;

    output          oq       //输出数据
);
    wire            shiftou1;
    wire            shiftou2;
    //例化主OSERDESE2原语
    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)
    )
    u_OSERDESE2_M (
        .OFB        (           ),// 1-bit output: Feedback path for data
        .OQ         (oq         ),// 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        (clk        ),// 1-bit input: High speed clock
        .CLKDIV     (clk_div    ),// 1-bit input: Divided clock
        // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
        .D1         (din[0]     ),
        .D2         (din[1]     ),
        .D3         (din[2]     ),
        .D4         (din[3]     ),
        .D5         (din[4]     ),
        .D6         (din[5]     ),
        .D7         (din[6]     ),
        .D8         (din[7]     ),
        .OCE        (1'b1       ),// 1-bit input: Output data clock enable
        .RST        (rst        ),// 1-bit input: Reset
        // SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each)
        .SHIFTIN1   (shiftou1   ),
        .SHIFTIN2   (shiftou2   ),
        // 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原语
    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)
    )
    u_OSERDESE2_S (
        .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  (shiftou1   ),
        .SHIFTOUT2  (shiftou2   ),
        .TBYTEOUT   (           ),// 1-bit output: Byte group tristate
        .TFB        (           ),// 1-bit output: 3-state control
        .TQ         (           ),// 1-bit output: 3-state control
        .CLK        (clk        ),// 1-bit input: High speed clock
        .CLKDIV     (clk_div    ),// 1-bit input: Divided clock
        // D1 - D8: 1-bit (each) input: Parallel data inputs (1-bit each)
        .D1         (           ),
        .D2         (           ),
        .D3         (din[8]     ),
        .D4         (din[9]     ),
        .D5         (           ),
        .D6         (           ),
        .D7         (           ),
        .D8         (           ),
        .OCE        (1'b1       ),// 1-bit input: Output data clock enable
        .RST        (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

??TestBench只需要把第8行代码的输入数据位宽改为10位,第46行输入数据的赋值改成下面代码就行了。

din = ({$random} % 1024);

??仿真结果如图15所示,与SDR的区别在于DDR的oq信号在clk的上升沿和下降沿都会传输数据。clk_div采集到数据与oq输出数据的间隔由图8表中查得为4个clk周期,所以图15中clk_div采集到10’b0100001101,经过四个clk周期后,oq开始输出最低位数据,之后依次输出剩余数据。

在这里插入图片描述

图15 DDR模式下10位并行转串行仿真

??对新加入的几个管脚进行分配,对工程综合、实现,查看最后两个OSERDESE2的布局如图16所示,OQ的管脚直接与主OSERDESE2的输出连接,从OSERDESE2的SHIFTOUT1、SHIFTOUT2分别与主OSERDESE2的SHIFTIN1、SHIFTIN2连接。

在这里插入图片描述

图16 10位并行转串行数据的OSERDESE2布局图

??将主从OSERDESE2分别放大后如图17所示。

在这里插入图片描述

图17 放大后的主从OSERDESE2

??综上就是OSERDESE2原语的常用模式,DDR模式在HDMI接口中比ODDR更适用,效果也更好,在HDMI驱动模块设计时,将会使用OSERDESE2的DDR模式将10位数据转化为双沿传输的数据输出。

??需要本文所使用工程的在公众号后台回复” OSERDESE2”(不包括引号)即可,工程中的代码为最初模式,其余模式按照文中描述修改即可。

文章来源:https://blog.csdn.net/weixin_50810761/article/details/134818688
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。