当前位置: 代码迷 >> 综合 >> Xilinx LVDS Output——原语调用
  详细解决方案

Xilinx LVDS Output——原语调用

热度:19   发布时间:2024-01-28 06:02:35.0

Xilinx LVDS Output——原语调用

根据上一篇Xilinx LVDS Output——OSERDESE2说的内容,先例化出OSEREDSE2模块;

Primitive 调用

Vivado提供了相关的原语程序模板,可以直接调用,按照如下步骤:

先打开语言模板:

test

选择相应的原语文档:

在这里插入图片描述

完整文档如下(务必仔细阅读注释):

//  OSERDESE2  : In order to incorporate this function into the design,
//   Verilog   : the following instance declaration needs to be placed
//  instance   : in the body of the design code.  The instance name
// declaration : (OSERDESE2_inst) and/or the port declarations within the
//    code     : parenthesis may be changed to properly reference and
//             : connect this function to the design.  All inputs
//             : and outputs must be connected.//  <-----Cut code below this line---->// OSERDESE2: Output SERial/DESerializer with bitslip//            Kintex-7// Xilinx HDL Language Template, version 2018.3OSERDESE2 #(.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);// End of OSERDESE2_inst instantiation			

属性

如果使用的是DDR的方式,属性部分不用改动;如果使用SDR的方式,就将对应属性修改,其余默认:

  • 参数DATA_WIDTH修改为为需要使用的串解因子,这里修改为8
  • 参数DATA_RATE_OQ修改为SDR
  • 参数DATA_RATE_TQ修改为SDR
  • 参数TRISTATE_WIDTH修改为1

Port

端口部分需要根据使用进行修改:

  • OQ连接到输出数据;
  • CLK连接高频率的时钟;
  • CLKDIV连接低频率的时钟;
  • D1 ~ D7连接需要进行并转串的数据(1bit);
  • OCE, 1’b1 ,输出数据时钟使能,这里为常高;
  • RST~XRSTReset信号,这里系统时钟sys_rst_n为低有效,所以取反;
  • 其余SHIFTOUT12TBYTEOUTTFBTQ不连接;
  • SHIFTIN12T1 ~ T4TBYTEINTCE均连接1’b0;

OBUFDS

之前说的,都是将并行数据,串行输出的步骤;假设已经获串行的数据,还需要将其使用OBUFDS输出;

参考手册ug471_7Series_SelectIO.pdf Page45 ~ Page46

OBUFDS Primitive

在这里插入图片描述

观察为,输入Port I,输出Port OOB

同样在Language Templates中找到原语模版:

//   OBUFDS    : In order to incorporate this function into the design,
//   Verilog   : the following instance declaration needs to be placed
//  instance   : in the body of the design code.  The instance name
// declaration : (OBUFDS_inst) and/or the port declarations within the
//    code     : parenthesis may be changed to properly reference and
//             : connect this function to the design.  All inputs
//             : and outputs must be connected.//  <-----Cut code below this line---->// OBUFDS: Differential Output Buffer//         Kintex UltraScale// Xilinx HDL Language Template, version 2018.3OBUFDS OBUFDS_inst (.O(O),   // 1-bit output: Diff_p output (connect directly to top-level port).OB(OB), // 1-bit output: Diff_n output (connect directly to top-level port).I(I)    // 1-bit input: Buffer input);// End of OBUFDS_inst instantiation				

注意,看到OOB Port需要直接连接到顶层的输出引脚;

通用设计

OSERDES2OBUFDS联合起来,进行通用设计,这样移植和例化都比较方便;

需要定输出引脚个数,还需要加上CLK输出信号;

比如说输出引脚个数为16,串解因子为8

与低频时钟CLKDIV同步的数据tx_data位宽就是16 * 8 = 128bit

这时候需要将数据拆分,分别例化到16个引脚上;

如果是两个引脚,那就可以直接例化,如果有很多,那么就可以使用generate大法;

CLK

直接上code

parameter 					clk_pattern		=	8'b0101_0101;
wire						s_OSERDES_CLK				;	// tx io clk//---------------------------------------------------------------------
// Clock Output control
//---------------------------------------------------------------------
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)
)
U_OSERDESE2_CLK0 (.OFB				( 					),	// 1-bit output: Feedback path for data.OQ					( s_OSERDES_CLK		),	// 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					( clk_pattern[0]				),.D2					( clk_pattern[1]				),.D3					( clk_pattern[2]				),.D4					( clk_pattern[3]				),.D5					( clk_pattern[4]				),.D6					( clk_pattern[5]				),.D7					( clk_pattern[6]				),.D8					( clk_pattern[7]				),.OCE				( 1'b1				),	// 1-bit input: Output data clock enable.RST				( ~XRST				),	// 1-bit input: Reset// SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each).SHIFTIN1			( 1'b0				),.SHIFTIN2			( 1'b0				),// 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
);OBUFDS #(.SLEW				( "FAST"			)   // Specify the output slew rate
)
U_OBUFDS_CLK0 (.O					( OSERDES_CLK_P	),	// Diff_p output (connect directly to top-level port).OB					( OSERDES_CLK_N	),	// Diff_n output (connect directly to top-level port).I					( s_OSERDES_CLK	) 	// Buffer input
);

先通过OSERDES2clk_pattern输出,就有了clk的波形,接着连接到OBUFDS上,直接输出到差分引脚。

DATA

依然直接上code

parameter					DB_W 	= 16					// data bus width
wire		[DB_W-1  :0]	s_OSERDES_DAT				;	// tx io data//---------------------------------------------------------------------
// Data Output control
//---------------------------------------------------------------------
genvar i;
generatefor (i=0; i<DB_W; i=i+1) begin: data_txoutOSERDESE2 #(.DATA_RATE_OQ		( "SDR"							),	// DDR, SDR.DATA_RATE_TQ		( "SDR"							),	// 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))U_OSERDESE2_TLA0 (.OFB				( 								),	// 1-bit output: Feedback path for data.OQ					( s_OSERDES_DAT[i] 				),	// 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					( TX_DATA[i*8+7]				),.D2					( TX_DATA[i*8+6]				),.D3					( TX_DATA[i*8+5]				),.D4					( TX_DATA[i*8+4]				),.D5					( TX_DATA[i*8+3]				),.D6					( TX_DATA[i*8+2]				),.D7					( TX_DATA[i*8+1]				),.D8					( TX_DATA[i*8+0]				),.OCE				( 1'b1							),	// 1-bit input: Output data clock enable.RST				( ~XRST							),	// 1-bit input: Reset// SHIFTIN1 / SHIFTIN2: 1-bit (each) input: Data input expansion (1-bit each).SHIFTIN1			( 1'b0							),.SHIFTIN2			( 1'b0							),// 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);OBUFDS #(.SLEW			( "FAST"						)   // Specify the output slew rate)U_OBUFDS_TLA0 (.O				( OSERDES_DAT_P[i]				),	// Diff_p output (connect directly to top-level port).OB				( OSERDES_DAT_N[i]				),	// Diff_n output (connect directly to top-level port).I				( s_OSERDES_DAT[i]				) 	// Buffer input);end
endgenerate

使用generate语句,将16个引脚,全部一次例化,非常方便;下次使用的时候,直接修改参数DB_W即可;

至此,LVDS的输出RTL已经完成了。

One more thing

需要添加xdc文件,加入端口的约束和电平规格约束,举例如下:

# DATA
set_property PACKAGE_PIN L16 [get_ports {LVDS_OUTP[0]}]
set_property PACKAGE_PIN K16 [get_ports {LVDS_OUTN[0]}]set_property IOSTANDARD LVDS_25 [get_ports {LVDS_OUTP[0]}]
set_property IOSTANDARD LVDS_25 [get_ports {LVDS_OUTN[0]}]

所有LVDS输出的引脚进行引脚约束和电平规格约束之后,才算是大功告成。

  相关解决方案