Xilinx LVDS Output——原语调用

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.3

   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
   );

   // 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.3

   OBUFDS 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;
generate
	for (i=0; i<DB_W; i=i+1) begin: data_txout

		OSERDESE2 #(
			.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输出的引脚进行引脚约束和电平规格约束之后,才算是大功告成。

猜你喜欢

转载自blog.csdn.net/sinat_31206523/article/details/107346082