Xilinx原语详解及仿真——OSERDESE2

作者:数字站

概括OSERDESE2

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

图1 OSERDESE2框图.JPG

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

图2 OSERDESE2在FPGA中的分布.JPG

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

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

因此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模式下并行转串行时序图.JPG

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

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

OSERDESE2原语信号及参数

OSERDESE2原语端口

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

图5 OSERDESE2原语框图.JPG

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 宽度扩展框图.JPG

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

表1 SDR和DDR模式的数据宽度可用取值.JPG


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

TBYTE_CTL和TBYTE_SRC信号是用于DDR3控制器使用的,直接关闭即可。

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属性组合.JPG

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

图8 OSERDESE2 延迟.JPG

OSERDESE2模式时序

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


图9 SDR模式下OSERDESE2的时序图.JPG

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

图10 DDR模式下OSERDESE2的时序图.JPG

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

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

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

图11 DDR模式下OSERDESE2三态传输的时序图.JPG

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

   );

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位并行数据串行化的仿真图.JPG

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

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

图13 OQ信号的分布.JPG

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

图14 OSERDESE2布局布线.JPG

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位并行转串行仿真.JPG

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

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

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

图17 放大后的主从OSERDESE2.JPG

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

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

文章来源:数字站

最新文章

最新文章