一、ODDR时序违例
1、7 Series ODDR
在设计时遇到了如下的时序违例:这是调用ODDR2源语与寄存器之间的时序违例,属于是同步时钟违例。查了很久没有查到相应的约束思路。


由于这个设计为HDMI的视频差分信号输出,ODDR完成串并转换和差分信号输出,而这里使用了ODDR2,而ODDR2原语通为spartan6 selectio,不会出现在7 Series FPGAs:


由于7 Series没有ODDR2,所以代码应该改成如下所示:
ODDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" set/reset
) ODDR_1_p (
.Q (dataout_1_p), // 1-bit DDR output data
.C (clkx5), // 1-bit clock input
.CE (1'b1), // 1-bit clock enable input
.D1 (TMDS_shift_1h[0]), // 1-bit data input (associated with C0)
.D2 (TMDS_shift_1l[0]), // 1-bit data input (associated with C1)
.R (1'b0), // 1-bit reset input
.S (1'b0) // 1-bit set input
);
ODDR #(
.DDR_CLK_EDGE("OPPOSITE_EDGE"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" set/reset
) ODDR_1_n (
.Q (dataout_1_n), // 1-bit DDR output data
.C (~clkx5), // 1-bit clock input
.CE (1'b1), // 1-bit clock enable input
.D1 (~TMDS_shift_1h[0]), // 1-bit data input (associated with C0)
.D2 (~TMDS_shift_1l[0]), // 1-bit data input (associated with C1)
.R (1'b0), // 1-bit reset input
.S (1'b0) // 1-bit set input
);
经过修改以后的延迟如下所示:(只保留了ODDR_1),时序违例信号均出现在ODDR1_n:


2、OSERDESE2与OBUFDS原语
由于违例信号涉及HDMI差分信号输出,可以将原语改为OSERDESE2与OBUFDS,通过更改设计的方式的方式,去规避时序违例。具体内容可以参考:《达芬奇之 FPGA 开发指南V2.2》、《7 Series FPGAs SelectIO Resources(UG471)》

(1) OBUFDS
OBUFDS 是差分输出缓冲器,用于将来自 FPGA 内部逻辑的信号转换成差分信号输出,支持 TMDS 电平标准。OBUFDS 原语示意图如下所示:

(2)OSERDESE2
OSERDESE2 是一种专用的并-串转换器,每个 OSERDESE2 模块都包括一个专用串行化程序用于数据和 3 状态控制。数据和 3 状态序列化程序都可以工作在 SDR 和 DDR 模式。数据串行化的位宽可以达到 8:1(如果使用原语模块级联,则可以到 10:1 和 14:1)。3 状态序列化最高可达 14:1,有一个专用的 DDR3 模式可用于支持高速内存应用程序。OSERESE2 框图如下图所示: 
最终更改设计以后的代码为:
//-----------------------------------------------------
//wire define
wire reset;
wire cascade1; //用于两个OSERDESE2级联的信号
wire cascade2;
wire serial_data_out;
assign reset = 1;
//例化OSERDESE2原语,实现并串转换,Master模式
OSERDESE2 #(
.DATA_RATE_OQ ("DDR"), // 设置双倍数据速率
.DATA_RATE_TQ ("SDR"), // DDR, BUF, SDR
.DATA_WIDTH (10), // 输入的并行数据宽度为10bit
.SERDES_MODE ("MASTER"), // 设置为Master,用于10bit宽度扩展
.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_Master (
.CLK (clkx5), // 串行数据时钟,5倍时钟频率
.CLKDIV (clk), // 并行数据时钟
.RST (reset), // 1-bit input: Reset
.OCE (1'b1), // 1-bit input: Output data clock enable
.OQ (serial_data_out), // 串行输出数据
.D1 (datain_0[0]), // D1 - D8: 并行数据输入
.D2 (datain_0[1]),
.D3 (datain_0[2]),
.D4 (datain_0[3]),
.D5 (datain_0[4]),
.D6 (datain_0[5]),
.D7 (datain_0[6]),
.D8 (datain_0[7]),
.SHIFTIN1 (cascade1), // SHIFTIN1 用于位宽扩展
.SHIFTIN2 (cascade2), // SHIFTIN2
.SHIFTOUT1 (), // SHIFTOUT1: 用于位宽扩展
.SHIFTOUT2 (), // SHIFTOUT2
.OFB (), // 以下是未使用信号
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.TBYTEIN (1'b0),
.TCE (1'b0),
.TBYTEOUT (),
.TFB (),
.TQ ()
);
//例化OSERDESE2原语,实现并串转换,Slave模式
OSERDESE2 #(
.DATA_RATE_OQ ("DDR"), // 设置双倍数据速率
.DATA_RATE_TQ ("SDR"), // DDR, BUF, SDR
.DATA_WIDTH (10), // 输入的并行数据宽度为10bit
.SERDES_MODE ("SLAVE"), // 设置为Slave,用于10bit宽度扩展
.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_Slave (
.CLK (clkx5), // 串行数据时钟,5倍时钟频率
.CLKDIV (clk), // 并行数据时钟
.RST (reset), // 1-bit input: Reset
.OCE (1'b1), // 1-bit input: Output data clock enable
.OQ (), // 串行输出数据
.D1 (1'b0), // D1 - D8: 并行数据输入
.D2 (1'b0),
.D3 (datain_0[8]),
.D4 (datain_0[9]),
.D5 (1'b0),
.D6 (1'b0),
.D7 (1'b0),
.D8 (1'b0),
.SHIFTIN1 (), // SHIFTIN1 用于位宽扩展
.SHIFTIN2 (), // SHIFTIN2
.SHIFTOUT1 (cascade1), // SHIFTOUT1: 用于位宽扩展
.SHIFTOUT2 (cascade2), // SHIFTOUT2
.OFB (), // 以下是未使用信号
.T1 (1'b0),
.T2 (1'b0),
.T3 (1'b0),
.T4 (1'b0),
.TBYTEIN (1'b0),
.TCE (1'b0),
.TBYTEOUT (),
.TFB (),
.TQ ()
);
//转换差分信号
OBUFDS #(
.IOSTANDARD ("TMDS_33") // I/O电平标准为TMDS
) TMDS0 (
.I (serial_data_out),
.O (dataout_0_p),
.OB (dataout_0_n)
);
1575

被折叠的 条评论
为什么被折叠?



