先抛出几个问题:
1.什么是 OSERDES? OSERDES 的作用是什么?使用场景?
2.OSERDES 结构是什么样?都有哪些端口?端口属性都是什么?
3.OSERDES 参数属性说明?
4.OSERDES 位扩展如何使用?
5.OSERDES 时序是什么样,延迟 latency,3-state 控制 ?
6.时序仿真怎么做?先上仿真结果图,后面会贴上代码
理解上面几个问题,也就清楚 OSERDES 如何使用了,接下来会按照上面问题的顺序对 OSERDES 进行说明。
注意本次使用的是OSERDES,单个 OSERDES 只有 6 个并行数据输入端口,现在已经有OSERDESE2,单个 OSERDESE2 达到 8 个并行数据输入端口.。
1.什么是OSERDES? OSERDES的作用是什么?使用场景?
OSERDES 全称是 output parallel-to-serial logic resources,用于将并行数据转换为串行数据输出,在传输视频信号 HDMI,LVDS 等常用此 IP。
2.OSERDES 结构是什么样?都有哪些端口?端口属性都是什么?
OSERDES 简要结构为图中红线左半部分,端口可按照类型分为三种:三态输出控制信号、时钟控制信号和并串转换信号。图中红线右半部分是 IOB,在本篇文章中添加链接描述提到,可以考古一下。
实际上,OSERDES 详细结构如下图,与上图不同的是增加了两组端口:SHIFTIN1/2,SHIFTOUT1/2,当在单个 OSERDES 的宽度无法满足同一组待并串转换的并行数据宽度时,就需要将两个 OSERDES 进行级联(cascade)。
端口说明;
CLKDIV:慢速时钟,并行数据端输入时钟
CLK:高速时钟,串行数据输出端时钟
D1-D6:并行数据输入
OQ:并转串数据输出
OCE:输出时钟使能
SR:复位信号,高有效
TI-T4:三态控制并行输入
TCE:三态时钟使能
TQ:三态控制输出
SHIFTOUT1/2:并行数据位宽超过 OSERDES 的 6 位转换能力时,从 OSERDES 输出信号
SHIFTIN1/2:并行数据位宽超过 OSERDES 的 6 位转换能力时,主 OSERDES 输入信号
REV:反像复位信号,使用时赋值为0
3.OSERDES参数属性说明?
OSERDES 在使用时,有9个参数需要赋值,主要定义OSERDES的工作模式及初始信号等。
参数说明:
DATE_RATE_OQ:“DDR”代表OQ在CLK的双沿输出,“SDR”代表OQ在CLK的上升沿沿输出,默认值为“DDR”;
DATA_RATE_TQ:“DDR”代表TQ在CLK的双沿输出,“SDR”代表TQ在CLK的上升沿沿输出,“BUF”代表三态控制为一个缓冲器,默认值为“DDR”;
DATA_WIDTH:并行输入数据位宽,DATE_RATE_OQ为“DDR”时,值可以是4、6、8、10;DATE_RATE_OQ为“SDR”时,值可以是2、3、4、5、6、7、8;默认值为4;
SERDES_MODE:并行数据位宽超过OSERDES的6位转换能力时使用,值可以是"MASTER"、“SLAVE”,默认值为"MASTER";
TRISTATE_WIDTH:三态控制位宽,DATE_RATE_TQ为“DDR”时,值可以是2、4;DATE_RATE_TQ为“SDR”或“BUF”时,值只能是1,默认值是4;
INIT_OQ:定义OQ的初始值;
INIT_TQ:定义TQ的初始值;
SRVAL_OQ:定义复位时OQ的值;
SRVAL_TQ:定义复位时OQ的值。
4.OSERDES位扩展如何使用
当使用 OSERDES 位扩展功能时,从(SLAVE)OSERDES 的 D1、D2 不能使用,因此 OQ 最多只能按照 10:1 进行并串转换,DATE_RATE_OQ 为 “DDR” 时,进行并串转换的并行数据位宽可以为 4、6、8、10;DATE_RATE_OQ 为 “SDR” 时,进行并串转换的并行数据位宽可以为 2、3、4、5、6、7、8。
同时要注意的是,最先传输出D1端的信号,依次传输 D2、D3……
5.OSERDES时序说明,延迟latency,3-state控制
OSERDES Latency 定义为 CLKDIV 时钟沿采集到 D1-D6 数据到在OQ端输出的第一个bit,这个延迟取决于参数 DATE_RATE_OQ 和 DATA_WIDTH,单位为 CLK 的时间,如下表
(1)在 2:1 的SDR模式下 OSERDES 传输的时序如下,可以看到从 Clock Event2 上升沿采集到D1、D2 数据 A 和 B,到 Clock Event3 开始输出 A,两个时钟事件相差 1 个 CLK
(2)看一下 8:1 的 DDR 模式,可以看到从 Clock Event2 上升沿采集到 D1、D2 的数据 A 和 B,Clock Event3 开始输出A,两个时钟事件相差 4 个 CLK
(3)4:1 的DDR 三态控制模式,T3 在 Clock Event2 置 1,导致 D3 端口的数据 G 没有输出,三态模式目前在视频信号输出这一块还不使用,因为只做输出。
6. 8:1 的 DDR 模式仿真
在 8:1 的 DDR 模式仿真,OSERDES 如何 cascade 进行并串转换,本次对 OQ 的输出不进行三态控制,所以 T1—T4 赋值为 0。
模块代码如下:
module oserdes( input clk_1x, input clk_4x, input clk_4x_phase_shift, input reset, input [7:0] par_data, output ser_data, ); wire shiftout1,shiftout2; OSERDES #( .DATA_RATE_OQ ("DDR"), // "DDR" or "SDR" .DATA_RATE_TQ ("DDR"), // "DDR", "SDR", or "BUF" .DATA_WIDTH (8), // DDR: 4,6,8, or 10 // SDR or BUF: 2,3,4,5,6,7, or 8 .INIT_OQ (1'b0), // INIT for Q1 register - '1' or '0' .INIT_TQ (1'b0), // INIT for Q2 register - '1' or '0' .SERDES_MODE ("MASTER"), //"MASTER" or "SLAVE" .SRVAL_OQ (1'b0), // Define Q1 output value upon SR assertion - '1' or '0' .SRVAL_TQ (1'b0), // Define Q1 output value upon SR assertion - '1' or '0' .TRISTATE_WIDTH(2) // Specify parallel to serial converter width // When DATA_RATE_TQ = DDR: 2 or 4 // When DATA_RATE_TQ = SDR or BUF: 1 ) U_OSERDES_MASTER ( .OQ(ser_data), .SHIFTOUT1(), .SHIFTOUT2(), .TQ(), .CLK(clk_4x), .CLKDIV(clk_1x), .D1(par_data[0]), .D2(par_data[1]), .D3(par_data[2]), .D4(par_data[3]), .D5(par_data[4]), .D6(par_data[5]), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(shiftout1), .SHIFTIN2(shiftout2), .SR(~reset), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0) ); OSERDES #( .DATA_RATE_OQ ("DDR"), // "DDR" or "SDR" .DATA_RATE_TQ ("DDR"), // "DDR", "SDR", or "BUF" .DATA_WIDTH (8), // DDR: 4,6,8, or 10 // SDR or BUF: 2,3,4,5,6,7, or 8 .INIT_OQ (1'b0), // INIT for Q1 register - '1' or '0' .INIT_TQ (1'b0), // INIT for Q2 register - '1' or '0' .SERDES_MODE ("SLAVE"), //"MASTER" or "SLAVE" .SRVAL_OQ (1'b0), // Define Q1 output value upon SR assertion - '1' or '0' .SRVAL_TQ (1'b0), // Define Q1 output value upon SR assertion - '1' or '0' .TRISTATE_WIDTH(2) // Specify parallel to serial converter width // When DATA_RATE_TQ = DDR: 2 or 4 // When DATA_RATE_TQ = SDR or BUF: 1 ) U_OSERDES_SLAVE ( .OQ(), .SHIFTOUT1(shiftout1), //MASTER OSERDES SHIFTIN1 .SHIFTOUT2(shiftout2), //MASTER OSERDES SHIFTIN2 .TQ(), .CLK(clk_4x), .CLKDIV(clk_1x), .D1(), .D2(), .D3(par_data[6]), .D4(par_data[7]), .D5(), .D6(), .OCE(1'b1), .REV(1'b0), .SHIFTIN1(), .SHIFTIN2(), .SR(~reset), .T1(1'b0), .T2(1'b0), .T3(1'b0), .T4(1'b0), .TCE(1'b0) ); endmodule
仿真测试代码如下:
module tb_oserdes; // Inputs reg clk_1x; reg clk_4x; reg clk_4x_phase_shift; reg reset; reg [7:0] par_data; // Outputs wire ser_data; wire ser_data_p; wire ser_data_n; reg clk_1x_phase_shift; // Instantiate the Unit Under Test (UUT) oserdes uut ( .clk_1x(clk_1x), .clk_4x(clk_4x), .clk_4x_phase_shift(clk_4x_phase_shift), .reset(reset), .par_data(par_data), .ser_data(ser_data), .ser_data_p(ser_data_p), .ser_data_n(ser_data_n) ); initial begin // Initialize Inputs clk_1x = 0; clk_4x = 1; clk_4x_phase_shift = 0; reset = 0; par_data = 0; clk_1x_phase_shift = 1; // Wait 100 ns for global reset to finish #100; reset =1; end // Add stimulus here always #12 clk_1x = ~clk_1x; always #3 clk_4x = ~clk_4x; always #12 clk_1x_phase_shift = ~clk_1x_phase_shift; always @(posedge clk_1x_phase_shift or negedge reset) begin if(!reset) par_data <=8'b0; else par_data <= par_data + 1'b1; end endmodule
仿真结果如图,可以看到延迟为 4 CLK,符合上述 延迟latency 的表格
7.几点思考延伸
(1)使用OSERDES一般都是高速信号,而高速信号通常会使用差分输出以保证信号的质量,而1个 I/O tile 只有两个OSERDES ,那么OSERDES 级联时候,MASTER 和 SLAVE 该如何分配 P/N 管脚。
(2)DIFF_HSTL、DIFF_SSTL能否使用未扩展功能,为什么?