時序分析(6):時序分析違例和優化


  布局布線沒有滿足我們要求的時序情況下,該如何去解決呢?

一、時序分析的優化流程

 

二、查看時序報告

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策略

  點擊 SYNTHESIS --- Synthesis,在Options界面可以選擇不同的綜合策略,時序改善余地不大。

2、Implementation策略

  點擊 IMPLEMENTTION --- Synthesis,在Options界面可以選擇不同的綜合策略,進行時序改善。

3、布局布線物理優化(div_timing)

  例如乘法器除法器常常出現問題,可以用此方法解決。

(1)設置方法

(2)參考依據

(3)效果展示

①扇出優化(設置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

  多說一點,平常寫代碼時:case別寫太深、if else里不要嵌套 case、if 條件的條件位寬盡量窄(減少不同位之間的扇出差異)......

 

參考資料:V3學院FPGA教程

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM