2012-08-06 53 views
4

我想寫一個簡單的模塊來輸出一個14位數的基礎上,四個輸入信號的值。我的嘗試如下所示。「<signal>是不是一個常數」錯誤在if語句

module select_size(
    input a, 
    input b, 
    input c, 
    input d, 
    output [13:0] size 
); 

    if (a) begin 
     assign size = 14'h2222; 
    end 
    else begin 
     if (b) begin 
      assign size = 14'h1111; 
     end 
     else begin 
      if (c) begin 
       assign size = 14'h0777; 
      end 
      else begin 
       assign size = 14'h0333; 
      end 
     end 
    end 

endmodule 

在編譯時,我收到以下錯誤:

ERROR:HDLCompiler:44 - Line 67: c is not a constant

我不明白爲什麼那個特定的if語句不若其他兩個工作之前它是。我試圖改變的條件

if (c == 1) begin 

但無濟於事。

有誰知道如何解決這個錯誤?謝謝!

+0

編譯器認爲這些是條件生成項目,而不是條件語句。 – 2012-08-07 03:04:15

回答

6

兩個問題:

1)你需要把if報表always塊內。

如果您使用的Verilog-2001,您可以使用

always @* 
    if .... 
    end 
end 

否則指定的敏感性列表中的所有輸入:

always @(a or b or c or d) 
    if .... 
    end 
end 


2)恆定分配不會允許入內if語句。

if塊內的所有語句刪除assign關鍵字:

if (a) begin 
    size = 14'h2222; 
end 

您還必須聲明大小爲reg類型。

但是,我的首選是用條件操作符重寫整個模塊,我發現它更喜歡閱讀。這下面的模塊實現相同的結果:

module select_size(
    input a, 
    input b, 
    input c, 
    input d, 
    output [13:0] size 
); 

    assign size = a ? 14'h2222 : 
        b ? 14'h1111 : 
        c ? 14'h0777 : 
         14'h0333 ; 

endmodule 
+0

實現了(1)和(2),它似乎很好。 – 2012-08-06 22:06:18

+0

謝謝!我總是與@(*) – 2012-08-06 22:06:55

+0

一起去嵌套三元任務,非常有趣。我會試一試。謝謝一堆! – 2012-08-06 22:29:36

1

正如@Tim已經回答了,用reg類型裏面always塊或wireassign

@Tim也描述了嵌套三元賦值,而在這個例子中寫得很好,他們通常被認爲是不好的做法。它們意味着很長的組合路徑並且難以維護。組合路徑可以通過合成來優化,這應該暗示具有優化選擇邏輯的多路複用器。

更容易維護代碼將擁有較低的擁有成本,只要它不會導致更大的綜合設計,通常是首選。

我的實現是使用casez(?不關心)。我發現每個值的優先級更易於查看/調試。

module select_size(
    input a, 
    input b, 
    input c, 
    input d, 
    output logic [13:0] size //logic (SystemVerilog) or reg type 
); 

always @* begin 
    casez ({a,b,c}) 
    3'b1?? : size = 14'h2222 ; 
    3'b01? : size = 14'h1111 ; 
    3'b001 : size = 14'h0777 ; 
    3'b000 : size = 14'h0333 ; 
    default: size = 'bx  ; 
    endcase 
end 

endmodule 
+0

「他們通常被認爲是不好的做法」。你有這個說法的來源嗎?我不認爲它會產生比案例陳述更糟糕的路徑,因爲即使是微不足道的編譯器優化。 – Tim 2012-08-08 17:14:19

+0

另外,雖然我知道這是一個微不足道的模塊,有些設計偏好,但在一個更復雜的設計中,我相信你還應該添加一個將輸出分配給X的默認情況。這是我更喜歡三元賦值的另一個原因,如果您不小心,if/else和case語句可能會對驗證中的X-Propagation產生危險影響。如果你模擬這個,並且a/b/c/d是X,那麼三元賦值將把X傳播到輸出(理想),if/else將輸出14'h0333,並且casez語句將鎖定之前的值,因爲它沒有默認聲明。 – Tim 2012-08-09 01:16:12

+0

一般不好的做法,我已經/給出了每個代碼審查。公司編碼指南。我在使用大量嵌套三元運算符的舊代碼庫上進行維護的經驗。每一位爲我提供指導的人也都避免了這些問題,因爲如果不按預期工作,那麼在調試時會遇到麻煩。 – Morgan 2012-08-09 08:03:51