一、现象
最近使用赛灵思的FPGA设计项目时,出现时序约束失效问题。
点进去发现如下:
一个始终约束没有生效,有多处报错。
二、原因
出现这个问题的原因是,建立时间不满足。
时序违例的主要原因是建立时间和保持时间不满足要求,那么什么情况下会出现建立时间和保持时间不满足要求呢?
- 建立时间不满足要求通常是因为组合逻辑处理时间太长!
- 保持时间不满足要求通常是因为组合逻辑处理时间太短!
建立时间和保持时间都不满足往往出现在异步时钟域中!
三、解决办法
- 加强约束,重新进行综合,对违规的路径进行进一步的优化,但是一般效果可能不是很明显
- 降低时钟的频率,但是这个一般是在项目最初的时候决定的,这个时候很难再改变
- 拆分组合逻辑,插入寄存器,增加流水线,这个是常用的方法
- 优化布局布线,减小传输的延时
- 更改Place and Route Effort Level,overall,把Standard模式(通过最少的布局布线努力,给出最快的运行时间,适用于不太复杂的设计)更改为High模式(有最好的布局布线结果,运行实际也长,适用于复杂设计(默认设置))
四、实际项目更改
更改前:
reg [31:0]suma;wire [16:0]sumb;wire [15:0]sumc;
//将以太网报文数据部分长度参数寄存
always @(posedge clk or negedge rst_n) beginif(!rst_n) suma <= 32'd0;else if(cal_en)suma <= {IP_ver,IP_hdr_len,IP_tos}+IP_total_len+IP_id+{IP_rsv,IP_df,IP_mf,IP_frag_offset}+{IP_ttl,IP_protocol}+src_ip[31:16]+src_ip[15:0]+dst_ip[31:16]+dst_ip[15:0];elsesuma <= suma;
endassign sumb = suma[31:16]+suma[15:0];assign sumc = sumb[16]+sumb[15:0];assign checksum = ~sumc;
更改后:
reg [31:0]suma;
reg [31:0]suma_1;
wire [16:0]sumb;
wire [15:0]sumc;//将以太网报文数据部分长度参数寄存
always @(posedge clk or negedge rst_n) beginif(!rst_n) suma <= 32'd0;else if(cal_en)beginsuma_1<={IP_ver,IP_hdr_len,IP_tos}+IP_total_len+IP_id+{IP_rsv,IP_df,IP_mf,IP_frag_offset}+{IP_ttl,IP_protocol};suma <= /*{IP_ver,IP_hdr_len,IP_tos} 16'h4500+*//*IP_total_len+*//*IP_id 16'h0000+*//*{IP_rsv,IP_df,IP_mf,IP_frag_offset} 16'h0000+*//*{IP_ttl,IP_protocol} 16'h4011+*/suma_1+src_ip[31:16]+src_ip[15:0]+dst_ip[31:16]+dst_ip[15:0];endelsesuma <= suma;
endassign sumb = suma[31:16]+suma[15:0];
assign sumc = sumb[16]+sumb[15:0];
assign checksum = ~sumc;
分析:根据报错的路径,找到对于的代码,拆分组合逻辑,插入寄存器,增加流水线,这个是常用的方法。