quartus prime 16.0 報警告 inferring latch


前言

當寫always組合邏輯塊時,可能會寫出 poor code。綜合時軟件會推斷出鎖存器。例如下面代碼:

1 always @* begin
2   if (c == 1'b1) begin
3     w = (a & b) ^ c;
4   end
5 end

當c等於0的時候,w就會保持上一個值,所以就產生了鎖存器,quartus就會貼心的給你報一個警告。

 inferring latch(es) for signal or variable "ram", which holds its previous value in one or more paths through the process

流程:

解決方式一:

補全條件,如果用的if就補全else,用的case補全default;

解決方式二:

當你使用狀態機的時候,對於各種變量條件考慮可能不全面,查bug眼淚掉下來,還有你希望保持原值但不願看到警告(強迫症),最簡單的方式就是把always組合邏輯變成always時序邏輯,畢竟FPGA是一款偏時序的器件,能用時序邏輯最好用時序邏輯。

如spi的狀態機代碼:(舉個栗子,代碼風格和代碼可能都是錯的)

 1 always @(*) begin
 2     case (cstate)
 3         IDEL: begin
 4             //master_din_reg = 0;
 5             //master_dout = 0;
 6             cs = 1'b1;
 7             wr_done = 1'b0;
 8             rd_done = 1'b0;
 9             sck_en = 1'b0;
10         end 
11         LOAD: begin
12             cs = 1'b0;
13             master_din_reg = master_din;
14         end
15         SEND: begin
16             sck_en = 1'b1;
17         end
18         FINISH: begin
19             cs = 1'b1;
20             wr_done = 1'b1;
21             rd_done = 1'b1;
22             sck_en = 1'b0;
23             master_dout = master_dout_reg;
24         end
25         default: begin
26             master_din_reg = 0;
27             master_dout = 0;
28             cs = 1'b0;
29             wr_done = 1'b0;
30             rd_done = 1'b0;
31             sck_en = 1'b0;
32         end
33     endcase //case
34 end

組合改成時序邏輯(這是對的):

 1 always @(posedge clk or negedge rst_n) begin
 2     if (~rst_n) begin
 3         cs <= 1'b1;
 4         data_cnt_en <= 1'b0;
 5         sck_en <= 1'b0;
 6         master_din_reg <= 0;
 7         master_dout <= 0;
 8     end
 9     else begin
10         case (cstate)
11             IDEL: begin
12             data_cnt_en <= 1'b0;
13             master_din_reg <= (wr) ? master_din : master_din_reg; //load the data you want send to slaver;
14             end 
15             SEND: begin
16                 data_cnt_en <= 1'b1;
17                 cs <= 1'b0; 
18                 sck_en <= 1'b1;
19                 master_dout <= (send_over) ? master_dout_reg : master_dout; //master receiverd data;
20             end
21             FINISH: begin                  //send and load ok;
22                 sck_en <= 1'b0;
23                 cs <= 1'b1;
24                 data_cnt_en <= 1'b0;
25             end
26             default: begin
27                 cs <= 1'b1;
28                 sck_en <= 1'b0;
29                 data_cnt_en <= 1'b0;
30             end
31         endcase //case
32     end
33 end

 

以上。


免責聲明!

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



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