Комментарий
Qiu правильный.Использование chisel3.util.Fill
- правильный путь.
Чтобы конкретизировать это, следующее Зубило:
import chisel3._
import chisel3.experimental.MultiIOModule
import chisel3.util.Fill
class FooModule(n: Int = 32) extends MultiIOModule {
val a: UInt = IO(Input(Bool()))
val b: UInt = IO(Output(UInt(n.W)))
b := Fill(n, a)
}
Создает следующий Verilog:
module FooModule(
input clock,
input reset,
input a,
output [31:0] b
);
assign b = a ? 32'hffffffff : 32'h0;
endmodule
Обратите внимание, что Fill
будет использовать мультиплексирование в особом случае заполнения чем-то шириной один.В противном случае это приведет к явным объединениям в дереве.
В качестве отступления, если вы решите делать сцепления явно, FIRRTL на самом деле имеет специальное преобразование под названием CombineCats
, которое попытается очистить это для вас.В следующем альтернативном примере n - 1
создаются временные данные, где каждый бит явно конкатенирован:
class BarModule(n: Int = 32) extends MultiIOModule {
val a: UInt = IO(Input(Bool()))
val b: UInt = IO(Output(UInt(n.W)))
b := Seq.fill(n)(a.asUInt).reduce(_ ## _)
}
Вы получите следующий Verilog:
module BarModule(
input clock,
input reset,
input a,
output [31:0] b
);
wire [9:0] _T_8;
wire [18:0] _T_17;
wire [27:0] _T_26;
wire [30:0] _T_29;
assign _T_8 = {a,a,a,a,a,a,a,a,a,a};
assign _T_17 = {_T_8,a,a,a,a,a,a,a,a,a};
assign _T_26 = {_T_17,a,a,a,a,a,a,a,a,a};
assign _T_29 = {_T_26,a,a,a};
assign b = {_T_29,a};
endmodule
Вы не будете, однакополучить преимущества конкатенации в древовидной структуре.Если вместо этого вы используете UInt(32.W)
в качестве входных данных, последний будет гораздо менее эффективным.