upによるパラメータのオーバーライド
前回から調査しているChiselデザインのParameterization、site(), here(), up()
の調査の中で、今回はup()
の調査を行う。
up()
の使用方法は、とりあえずサンプルデザインを見るのがいいだろう。以下では、Adder()
とMul()
の2つのモジュールを定義している。p(BitWidth)
で入出力ビット数を定義している。Adder()
とMul()
のビット幅を全く別物で定義したい場合どうするかという問題を考える。
class Adder()(implicit p: Parameters) extends Module { val bitwidth = p(BitWidth) val io = IO(new Bundle{ val a = Input(SInt(bitwidth.W)) val b = Input(SInt(bitwidth.W)) val c = Output(SInt(bitwidth.W)) }) io.c := io.a + io.b } class Mul()(implicit p: Parameters) extends Module { val bitwidth = p(BitWidth) val io = IO(new Bundle{ val a = Input(SInt(bitwidth.W)) val b = Input(SInt(bitwidth.W)) val c = Output(SInt((bitwidth * 2).W)) }) io.c := io.a * io.b }
この時、Adder()
とMul()
のパラメータは以下のように定義している。Adder()
は64ビット、Mul()
は128ビットの入力ビット幅でインスタンス化するものとする。
case object AdderBitWidth extends Field[Int] case object MulBitWidth extends Field[Int] class DefaultConfig() extends Config((site, here, up) => { case AdderBitWidth => 64 case MulBitWidth => 128 })
Adder()
とMul()
をインスタンス時にそれぞれのパラメータをオーバライドするわけだが、adder_param
とmul_param
を新たに定義して渡すことになる。
val Adder_mod = Module(new Adder()(adder_params)) Adder_mod.io.a := io.a Adder_mod.io.b := io.b io.Adder_c := Adder_mod.io.c val mul_mod = Module(new Mul()(mul_params)) mul_mod.io.a := io.a mul_mod.io.b := io.b io.mul_c := mul_mod.io.c
ここで、adder_params
は上記のDefaultConfig
を引き継ぎつつ、BitWidth
パラメータを継承前のDefaultConfig
で使用しているパラメータで引き継ぐ。この時にup()
を使用する。これにより、`
val adder_params = p.alter((site, here, up) => { case BitWidth => up(AdderBitWidth) }) val mul_params = p.alter((site, here, up) => { case BitWidth => up(MulBitWidth) })
adder_params
のBitWidth
はDefaultConfig
のAdderBitWidth
を引き継ぎ、mul_params
のBitWidth
はDefaultConfig
のMulBitWidth
を引き継ぐことになる。これにより、同じBitWidth
パラメータでも別々のパラメータを引き継ぐことが可能になる。
結果は以下の通り、Adder
の入力ビット幅はAddrBitWidth
を引き継いで64ビットとなり、Mul
の入力ビット幅はMulBitWidth
を引き継いで128ビットとなった。
module Adder( input [63:0] io_a, input [63:0] io_b, output [63:0] io_c ); assign io_c = $signed(io_a) + $signed(io_b); // @[up_example.scala 48:8] endmodule module Mul( input [127:0] io_a, input [127:0] io_b, output [255:0] io_c ); assign io_c = $signed(io_a) * $signed(io_b); // @[up_example.scala 59:8] endmodule