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

 

以上。

posted @ 2017-09-07 11:38  小翁同学  阅读(5082)  评论(0编辑  收藏  举报