FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

Yosysの使い方を勉強する (10. parameterとgenerate)

RTLILでの階層構造の確認。もうちょっとパラメータ付きで確認する。 やってみたかったのは、パラメータの取り扱いとgenerate文の取り扱い。

module adder_sub
  #(parameter WIDTH = 8)
(
 input logic [WIDTH-1: 0]  in0,
 input logic [WIDTH-1: 0]  in1,
 output logic [WIDTH-1: 0] out
 );

generate for (genvar i = 0; i < WIDTH; i++) begin : loop
  if (i % 2 == 0) begin
    assign out[i] = in0[i] & in1[i];
  end else begin
    assign out[i] = in0[i] | in1[i];
  end
end
endgenerate

デフォルトでは、パラメータが8なので、Yosysでは8回分ループを回してその結果が出てくる。なんとなく想像したものと一緒になる。

Module Name = $paramod\adder_sub\WIDTH=s32'00000000000000000000000000001000
  Wires :
   Name = $or$adder4.sv:13$14_Y, width = 1, start_offset = 0
   Name = $and$adder4.sv:11$13_Y, width = 1, start_offset = 0
   Name = $or$adder4.sv:13$12_Y, width = 1, start_offset = 0
   Name = $and$adder4.sv:11$11_Y, width = 1, start_offset = 0
   Name = $or$adder4.sv:13$10_Y, width = 1, start_offset = 0
   Name = $and$adder4.sv:11$9_Y, width = 1, start_offset = 0
   Name = $or$adder4.sv:13$8_Y, width = 1, start_offset = 0
   Name = $and$adder4.sv:11$7_Y, width = 1, start_offset = 0
   Name = \out, width = 8, start_offset = 0
   Name = \in1, width = 8, start_offset = 0
   Name = \in0, width = 8, start_offset = 0
  Cells :
   Name = $or$adder4.sv:13$14
    SigSpec : \Y <-> chunk $or$adder4.sv:13$14_Y
    SigSpec : \B <-> chunk \in1
    SigSpec : \A <-> chunk \in0
   Name = $and$adder4.sv:11$13
    SigSpec : \Y <-> chunk $and$adder4.sv:11$13_Y
    SigSpec : \B <-> chunk \in1
    SigSpec : \A <-> chunk \in0
   Name = $or$adder4.sv:13$12
    SigSpec : \Y <-> chunk $or$adder4.sv:13$12_Y
    SigSpec : \B <-> chunk \in1
    SigSpec : \A <-> chunk \in0
   Name = $and$adder4.sv:11$11
    SigSpec : \Y <-> chunk $and$adder4.sv:11$11_Y
...
    SigSpec : \A <-> chunk \in0
  Connections :
   \out <- $and$adder4.sv:11$7_Y
   \out <- $or$adder4.sv:13$8_Y
   \out <- $and$adder4.sv:11$9_Y
   \out <- $or$adder4.sv:13$10_Y
   \out <- $and$adder4.sv:11$11_Y
   \out <- $or$adder4.sv:13$12_Y
   \out <- $and$adder4.sv:11$13_Y
   \out <- $or$adder4.sv:13$14_Y
  Process :

これを2つインスタンス化して上位階層を作ると、パラメータを付加されたモジュールが2つインスタンス化された。

module adder_top
  (
   input logic [7: 0]  in0,
   input logic [7: 0]  in1,
   output logic [7: 0] out
   );
logic [ 7: 0]          out_tmp0;
logic [ 3: 0]          out_tmp1;

adder_sub #(.WIDTH(8)) adder8 (.in0(in0[ 7: 0]), .in1(in1), .out(out_tmp0));
adder_sub #(.WIDTH(4)) adder1 (.in0(in0[ 3: 0]), .in1(in1), .out(out_tmp1));

assign out = out_tmp0 + out_tmp1;

endmodule // adder_top
Module Name = $paramod\adder_sub\WIDTH=s32'00000000000000000000000000000100
Module Name = $paramod\adder_sub\WIDTH=s32'00000000000000000000000000001000

おおむねparametergenerateの扱い方は想像通りだった。