quartus prime 16.0 報警告 inferring latch
阿新 • • 發佈:2017-09-07
gin nal def 解決 fault default 簡單 slaver ring
前言
當寫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
以上。
quartus prime 16.0 報警告 inferring latch