FPGA时序分析和时序约束案例

一、ODDR时序违例

1、7 Series ODDR

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

b1b0a8bb8b794f679ba682359719024c.png

3538861447d54e9aa442ff8f53747061.png

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

a0fb2c925bf54ca29fd2d8fda724ebec.png

ODDR2原语使用方法-优快云博客

9e831f8043da485c818a69dcee486e28.png

 

 由于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:

63f2bea4debf4616a62443b389df0e00.png

c6c6ab90c0cb4adb9c5970064ba7843c.png

 

2、OSERDESE2与OBUFDS原语

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

5c8f4b6d76954773bbf30d2665bd35a0.png

(1) OBUFDS

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

476565b72dae47b1aad24cfe2a7cef6f.png

 (2)OSERDESE2

OSERDESE2 是一种专用的并-串转换器,每个 OSERDESE2 模块都包括一个专用串行化程序用于数据和 3 状态控制。数据和 3 状态序列化程序都可以工作在 SDR 和 DDR 模式。数据串行化的位宽可以达到 8:1(如果使用原语模块级联,则可以到 10:1 和 14:1)。3 状态序列化最高可达 14:1,有一个专用的 DDR3 模式可用于支持高速内存应用程序。OSERESE2 框图如下图所示: fea39a86f24c47d489a028959697197d.png

最终更改设计以后的代码为:

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

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值