如何在Chisel 3中向UInt复制一点?

时间:2019-06-04 07:53:05

标签: verilog bit 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}}一样?

1 个答案:

答案 0 :(得分:4)

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将使用多路复用器来填充宽度为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)作为输入,则后者的效率会低得多。