如何将单个位复制到 Chisel 3 中的 UInt?
How to duplicate a single bit to a UInt in Chisel 3?
我正在寻找一种 Chisel 方法来完成以下工作:
wire [3:0] word;
wire bit;
assign word = {4{bit}};
我目前是这样做的:
val word = Wire(UInt(4.W))
val bit = Wire(Bool())
word := Cat(bit, bit, bit, bit)
但是,当我需要更大的数字时,这个解决方案不是很整洁:
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()
有更好的方法吗?像 Verilog assign bigWord = {32{bit}}
?
Qiu's comment is right. Using 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
将在填充宽度为 1 的特殊情况下使用多路复用器。否则,这将在树中进行显式连接。
顺便说一句,如果您选择明确地进行连接,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)
作为输入,后者的效率会低得多。
我正在寻找一种 Chisel 方法来完成以下工作:
wire [3:0] word;
wire bit;
assign word = {4{bit}};
我目前是这样做的:
val word = Wire(UInt(4.W))
val bit = Wire(Bool())
word := Cat(bit, bit, bit, bit)
但是,当我需要更大的数字时,这个解决方案不是很整洁:
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()
有更好的方法吗?像 Verilog assign bigWord = {32{bit}}
?
Qiu's comment is right. Using 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
将在填充宽度为 1 的特殊情况下使用多路复用器。否则,这将在树中进行显式连接。
顺便说一句,如果您选择明确地进行连接,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)
作为输入,后者的效率会低得多。