簡體   English   中英

生成塊中的系統Verilog參數

[英]System Verilog parameters in generate block

我想基於實例化模塊時設置的參數來設置參數。 我有以下幾點。

module foo #(WORDS = 8);

parameter P00 = 33;
logic [7:0] tmp;

generate
  case (WORDS)
    4: begin : A
         assign tmp = 8'haa;
         parameter P00 = 4;
       end
    8: begin : B
         assign tmp = 8'hbb;
         parameter P00 = 8;
       end
   16: begin : C
         assign tmp = 8'hcc;
         parameter P00 = 16;
       end
   default: begin : D
              assign tmp = 8'hdd;
              parameter P00 = 8;
            end
  endcase
endgenerate

initial begin
  $display ("WORDS = %d", WORDS);
  $display ("tmp   = %h", tmp);
  $display ("P00   = %d", P00);
end

endmodule

我預期會因重新定義P00而出錯,但它編譯並運行並顯示以下內容。

WORDS =       8
tmp    = bb
P00    = 33

如果注釋“參數P00 = 33”分配,則會得到“尚未聲明標識符P00”。 錯誤。

似乎generate塊被忽略了。 怎么了

將參數定義放置在generate塊內會生成一個相對於generate塊內的分層范圍的新局部參數。 defparam通常是覆蓋參數值的方法。 但是, IEEE std 1800-2012在§23.10.1中明確聲明defparam不會影響其父范圍:

生成塊實例(請參見第27章)中或實例下的層次結構或實例數組(請參見28.3.5和23.3.2)中或之下的defparam語句不得在該層次結構之外更改參數值。

對於復雜的派生參數分配,可以使用函數。 例如:

parameter P01 = FUNC01(WORDS,P00);
function byte FUNC01(input byte w,p);
/* ... */
endfunction

這也是合法的: module foo #(parameter WORDS, P00=FUNC00(WORDS));

一個挑戰可能是每個參數可能需要自己的功能。 將參數與struct數據類型一起使用是將分配分組為單個函數的一種可能的解決方法。 該方法需要由模擬器,合成器和其他工具進行評估。 例:

typedef struct packed {
  int sub00;
  byte sub01;
  /* ... */
 bit [13:0] subNN
} param_t;
paramter param_t P = FUNC_P(/* inputs */);

function param_t FUNC_P(/* inputs */);
  param_t rtn;
  /* assign all rtn.sub* */
  return rtn;
endfunction

logic [P.sub01-1:0] tmpvar;

正如Morgan所言,您可以將大多數parameters定義為logic並使用組合塊。 但是,我強烈建議使用always_comb塊而不是always @*來保證值是計算值。 正如指出LRM §9.2.2.2.2:

always_comb在零時間自動執行一次,而always @ *等待直到推斷出的靈敏度列表中的信號發生變化。

最近在這里有很多關於使用生成和分配的問題,不確定是否分配了不正確地教授這些內容的新教程。

參數或Localparams不應定義超過一次,它們是常量,因此不能更改值。 我認為您也缺少模塊foo中的parameter關鍵字。

module foo #(
  parameter WORDS = 8
);

localparam P00 = WORD;

通常用作縮放因子:

module foo #(
  parameter WIDTH = 8
  parameter MAX_VALUE = 2**WIDTH
);

您定義的內容看起來應該只是在使用邏輯而非參數來保存值。

我將整個內容重寫為:

module foo #(WORDS = 8);

logic [31:0] P00 = 33;
logic [7:0]  tmp;

always @* begin
  case (WORDS)
    4: begin : A
         tmp = 8'haa;
         P00 = 4;
       end
    8: begin : B
         tmp = 8'hbb;
         P00 = 8;
       end
   16: begin : C
         tmp = 8'hcc;
         P00 = 16;
       end
   default: begin : D
            tmp = 8'hdd;
            P00 = 8;
      end
  endcase
end

對於您要在此處實現的目標,無需使用generate。

這有效(通常說您需要使所有4個生成塊的名稱都相同):

module foo #(WORDS = 8);

parameter P00 = 33;
logic [7:0] tmp;

generate
  case (WORDS)
    4: begin : B
         assign tmp = 8'haa;
         parameter P00 = 4;
       end
    8: begin : B
         assign tmp = 8'hbb;
         parameter P00 = 8;
       end
   16: begin : B
         assign tmp = 8'hcc;
         parameter P00 = 16;
       end
   default: begin : B
              assign tmp = 8'hdd;
              parameter P00 = 8;
            end
  endcase
endgenerate

initial begin
  $display ("WORDS = %d", WORDS);
  $display ("tmp   = %h", tmp);
  $display ("P00   = %d", B.P00);
end

endmodule

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM