I'm looking for a Chisel way to do the following job:
wire [3:0] word;
wire bit;
assign word = {4{bit}};
I'm currently doing it like this:
val word = Wire(UInt(4.W))
val bit = Wire(Bool())
word := Cat(bit, bit, bit, bit)
However, this solution isn't very tidy when I need a bigger number:
val bigWord = Wire(UInt(32.W))
bigWord := Cat(bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit, bit)
io.out := summon_cthulhu()
Is there a better way to do this? Like Verilog assign bigWord = {32{bit}}
?
Qiu's comment is right. Using chisel3.util.Fill
is the right way to go.
To concretize this, the following Chisel:
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)
}
Produces the following Verilog:
module FooModule(
input clock,
input reset,
input a,
output [31:0] b
);
assign b = a ? 32'hffffffff : 32'h0;
endmodule
Note that Fill
will use a mux in the special case of filling by something with a width of one. Otherwise, this will do explicit concatenations in a tree.
As an aside, if you choose to do the concatenations explicitly, FIRRTL actually has a dedicated transform called CombineCats
that will try to clean this up for you. In the following, alternative example n - 1
temporaries are created where each bit is explicitly concatenated:
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(_ ## _)
}
You'll get the following 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
You will not, however, get the benefits of concatenation in a tree structure. If you were instead to use a UInt(32.W)
as the input, the latter would be much less efficient.