[verilog] generate (genvar) と for と always の順序に関する制約



generate → for → always の順に入れ子にしなければならないらしい。

正しいコード:

module main;
  reg[7:0] a = 0;
  reg clk;

  always
    #1 clk = ~($time & 1);

  always @(posedge clk)
    a[0] <= 1;

  genvar i;
  generate
    for (i=0; i<7; i=i+1) begin : my_block
      always @(posedge clk) begin
        a[i+1] <= a[i];
      end
    end
  endgenerate

  initial
    $monitor ("Time = %d a = %b",$time,a);

  initial
    #20 $finish;
endmodule

実行結果:

mint@ubuntu:~/Desktop/verilog$ iverilog -o genvar1 genvar1.v
mint@ubuntu:~/Desktop/verilog$ ./genvar1
Time =                    0 a = 00000000
Time =                    2 a = 00000001
Time =                    4 a = 00000011
Time =                    6 a = 00000111
Time =                    8 a = 00001111
Time =                   10 a = 00011111
Time =                   12 a = 00111111
Time =                   14 a = 01111111
Time =                   16 a = 11111111
Time =                   18 a = 11111111

正しくないコード1 (generate→always→forのパターン):

module main;
  reg[7:0] a = 0;
  reg clk;

  always
    #1 clk = ~($time & 1);

  always @(posedge clk)
    a[0] <= 1;

  genvar i;
  generate
    always @(posedge clk) begin
      for (i=0; i<7; i=i+1) begin : my_block
        a[i+1] <= a[i];
      end
    end
  endgenerate

  initial
    $monitor ("Time = %d a = %b",$time,a);

  initial
    #20 $finish;
endmodule

出力結果:

mint@ubuntu:~/Desktop/verilog$ iverilog -o genvar2 genvar2.v 
genvar2.v:14: register ``i'' unknown in main.
Elaboration failed
mint@ubuntu:~/Desktop/verilog$ 

正しくないコード2 (always→generate→forのパターン):

module main;
  reg[7:0] a = 0;
  reg clk;

  always
    #1 clk = ~($time & 1);

  always @(posedge clk)
    a[0] <= 1;

  always @(posedge clk) begin
    genvar i;
    generate
      for (i=0; i<7; i=i+1) begin : my_block
        a[i+1] <= a[i];
      end
    endgenerate
  end

  initial
    $monitor ("Time = %d a = %b",$time,a);

  initial
    #20 $finish;
endmodule

出力結果:

mint@ubuntu:~/Desktop/verilog$ iverilog -o genvar3 genvar3.v 
genvar3.v:12: syntax error
genvar3.v:12: error: malformed statement
genvar3.v:13: syntax error
genvar3.v:14: Syntax in assignment statement l-value.
genvar3.v:14: syntax error
genvar3.v:14: error: malformed statement
genvar3.v:14: syntax error
genvar3.v:15: Syntax in assignment statement l-value.
genvar3.v:17: syntax error
genvar3.v:21: error: invalid module item.
mint@ubuntu:~/Desktop/verilog$ 

エラーメッセージがわかりにくいんじゃーーーー!

とりあえず、初心を忘れないためにメモしておいた。