xilinx原语详解及仿真之OSERDESE2

avatar
作者
猴君
阅读量:0

  Xlinx相关原语讲解导航页面,想要了解更过原语,可以点击该链接跳转。


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”(不包括引号)即可,工程中的代码为最初模式,其余模式按照文中描述修改即可。

  您的支持是我更新的最大动力!将持续更新工程,如果本文对您有帮助,还请多多点赞👍、评论💬和收藏⭐!

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!