二、查看时序报告
1.ILA相关约束可以忽略
2.Report timing summary可以打印所有路径报告,方便查看哪些违例了。
三、解决跨时钟域违例
1、set false path
(1)复位信号,选择point到point,否则所有信号都 false了
(2)跨时钟域信号,可以选择clock到clock。
2、Set multicycle
两级寄存器之间有复杂的组合逻辑,导致延迟可能超过1个时钟周期。
(1)修改建立时间:set_multicycle_path -from $from_list -to $to_list <N>,建立时间采样沿在N处,建立时间OK了
(2)保持时间采样沿在N-1处,要求上一个数据的结束位置要在这,太难了,很可能报告时序违例,因此要把保持时间推回原先的采样沿0时刻位置:set_multicycle_path -from $from_list -to $to_list-hold <N-1>,还不行就<N-2>、<N-3>
四、解决同时钟域违例
1、synthesis策略
2、Implementation策略
3、布局布线物理优化(div_timing)
①扇出优化(设置post_place phy_opt)
和左侧相比,右边的白线被分割为多个起点扇出,减少了扇出延时。蓝线为优化前的效果。
②布局优化
如果一些较长的关键路径存在,布局工具会自动的进行从新规划布局方案使得路径变短,从而优化时序。
③布线优化
④HOLD FIX优化
⑤Retiming优化
4、插入流水线寄存器
(1)除法器IP核里增大latency,会给第一个计算结果带来延迟,但是增加了时序余量,改善了时序。
(2)组合逻辑带来延时,采用流水线打拍来改变代码,增大了latency,改善了时序。
`timescale 1ns / 1ps
//**************************************************************************
// *** 名称 : top_encode.v
// *** 作者 : xianyu_FPGA
// *** 博客 : https://www.cnblogs.com/xianyufpga/
// *** 日期 : 2020-04-12
// *** 描述 : 流水线案例,流水线优化后
//**************************************************************************
module top_encode
//========================< 端口 >==========================================
(
//input -----------------------------------------
input wire sysclk_in ,
input wire pkg_valid ,
input wire [15:0] in_data0 ,
input wire [15:0] in_data1 ,
input wire [15:0] in_data2 ,
input wire [15:0] in_data3 ,
input wire [15:0] in_data4 ,
input wire [15:0] in_data5 ,
input wire [15:0] in_data6 ,
input wire [15:0] in_data7 ,
//output ----------------------------------------
output reg o_encode_valid ,
output reg [31:0] o_encode
);
//========================< 信号 >==========================================
//reg -------------------------------------------
reg pkg_valid_r ;
reg [15:0] in_data0_r ;
reg [15:0] in_data1_r ;
reg [15:0] in_data2_r ;
reg [15:0] in_data3_r ;
reg [15:0] in_data4_r ;
reg [15:0] in_data5_r ;
reg [15:0] in_data6_r ;
reg [15:0] in_data7_r ;
//pll -------------------------------------------
wire sclk ;
wire clk150 ;
wire clk300 ;
//no pipelined ----------------------------------
wire [15:0] code_0 ;
wire [15:0] code_1 ;
wire [15:0] code_2 ;
wire [15:0] code_3 ;
wire [15:0] code_4 ;
wire [15:0] code_5 ;
wire [15:0] code_6 ;
wire [15:0] code_7 ;
wire [31:0] code_sum ;
//pipelined -------------------------------------
reg [15:0] code_0_r ;
reg [15:0] code_1_r ;
reg [15:0] code_2_r ;
reg [15:0] code_3_r ;
reg [15:0] code_4_r ;
reg [15:0] code_5_r ;
reg [15:0] code_6_r ;
reg [15:0] code_7_r ;
reg [31:0] code_sum_r ;
reg pkg_valid_rr ;
reg pkg_valid_rrr ;
//==========================================================================
//== pll
//==========================================================================
clk_gen clk_gen
(
.clk_out1 (clk150 ),
.clk_out2 (clk300 ),
.clk_in1 (sysclk_in )
);
assign sclk = clk150;
//==========================================================================
//== no pipelined
//==========================================================================
always @(posedge sclk) begin
pkg_valid_r <= pkg_valid;
in_data0_r <= in_data0;
in_data1_r <= in_data1;
in_data2_r <= in_data2;
in_data3_r <= in_data3;
in_data4_r <= in_data4;
in_data5_r <= in_data5;
in_data6_r <= in_data6;
in_data7_r <= in_data7;
end
assign code_0 = in_data0_r | in_data7_r;
assign code_1 = in_data1_r | in_data6_r;
assign code_2 = in_data2_r | in_data5_r;
assign code_3 = in_data3_r | in_data4_r;
assign code_4 = in_data0_r + in_data1_r + in_data2_r + in_data3_r;
assign code_5 = in_data1_r + in_data2_r + in_data3_r + in_data4_r;
assign code_6 = in_data2_r + in_data3_r + in_data4_r + in_data5_r;
assign code_7 = in_data3_r + in_data4_r + in_data5_r + in_data6_r;
assign code_sum = code_0 + code_1 + code_2 + code_3 + code_4 + code_5 + code_6 + code_7;
always @(posedge sclk) begin
o_encode_valid <= pkg_valid_r;
o_encode <= code_sum;
end
/*
//==========================================================================
//== pipelined
//==========================================================================
//一级寄存器
always @(posedge sclk) begin
code_0_r <= code_0;
code_1_r <= code_1;
code_2_r <= code_2;
code_3_r <= code_3;
code_4_r <= code_4;
code_5_r <= code_5;
code_6_r <= code_6;
code_7_r <= code_7;
end
//二级寄存器
always @(posedge sclk ) begin
code_sum_r <= code_0_r + code_1_r + code_2_r + code_3_r + code_4_r + code_5_r + code_6_r + code_7_r;
end
//==========================================================================
//== 信号对齐
//==========================================================================
always @(posedge sclk ) begin
pkg_valid_rr <= pkg_valid_r;
pkg_valid_rrr <= pkg_valid_rr;
end
//==========================================================================
//== 输出端口
//==========================================================================
always @(posedge sclk) begin
o_encode_valid <= pkg_valid_rrr;
o_encode <= code_sum_r;
end
*/
endmodule