【发布时间】:2021-03-10 00:34:35
【问题描述】:
我正在使用 DSL (Chisel),其中库的一个特定部分要求我定义 Seq 的项目。我有几个伴随对象来创建一些中间逻辑并返回其中一项。我有一种情况,我想实际退回其中两件商品,但我很难弄清楚该怎么做。
假设这里的“项目”是Person。 (这里Person是什么并不重要)
DSL 希望你通过Seq 描述你所有的Persons。
val p1 = new Person(1)
val p2 = new Person(2)
Seq(p1,p2)
我有一个案例,我想将两个人联系在一起。例如,我知道有些人有朋友,他们到处拖,所以如果他们出现,他们的朋友也会出现(即使我不喜欢他们)。所以我希望能够做类似以下的事情。
object Group {
def apply(): Person, Person = { //return two of these
val pA = new Person(10)
val pAA = new Person(10+1)
}
}
这样,我可以轻松做到以下几点
Seq(p1, p2, Group)
//The Seq should have p1, p2, and the pA, pAA
由于这是 DSL,我无权更改内部结构。我可以创建 Seq 的每一部分,然后将它们组合在一起,但这并不理想,因为我会经常这样做,因此需要一个好的解决方案。出于同样的原因,我不能发回一个元组。
我尝试查看变量 args 是否可以在返回时起作用,但似乎不起作用。
任何帮助将不胜感激。谢谢
为我们的救世主杰克·科尼格更新
这是利用 RocketChip RegisterRotuer 节点来描述 RegFields
通常在我的设计中,我有来自某些逻辑的信号,我希望软件能够阻止上游逻辑并手动驱动信号(考虑一些使您希望软件能够驱动的功能) .为此,我构建了一个代表驱动值的 SW 寄存器,以及一个处理控制的“mux”SW 寄存器。我目前所做的是这个(目前返回一个Seq[RegField],但希望你看到我希望这是两个RegField 类型
/**
* Creates a muxed override register. This allows software to take control of a particular signal by setting the "_mux" register
* high. Once in this mode, the value of the signal is based on the software register defined here.
*
* This method makes the assumption that you want the two bitfields to be next to each other (reg then mux). If you do not want this
* or can't do this (because the signal you want to control is >=32bits) you will have to create two separate RWReg. One for the mux
* and one for the SW control value
*
*
* val rx_reset_reg = Wire(Bool())
* val rx_reset_mux = Wire(Bool())
* val rx_reset = WavClockMux (rx_reset_mux, rx_reset_reg, io.core.rx_reset)
* WavD2DRxRegs.CoreOverride -> Seq(WavRWReg(rx_reset_reg,0.U, "rx_reset", "RX Reset"),
* WavRWReg(rx_reset_mux,0.U, "rx_reset_mux", "Mux override for rx_reset")),
*
*
* This method also has the nuance that it returns a Seq[RegField]. So you must concatenate this companion object with the higher leve
* Seq[RegField] that we normally use for register generation
*
* WavRWMuxReg(in=io.core.tx_en, muxed=io.ana.tx_en, reg_reset=false.B, mux_reset=false.B, "tx_en", "Main TX enable") ++ Seq(<other regFields>)
*/
object WavRWMuxReg{
def apply[T <: Data](in: T, muxed : T, reg_reset: T, mux_reset: Bool, name: String, desc: String)(implicit p: Parameters): Seq[RegField] = {
//val reg = RegInit(reset)
val reg = RegInit(muxed.cloneType, reg_reset)
reg.suggestName("swi_" + name)
val mux = RegInit(mux_reset)
mux.suggestName("swi_" + name + "_mux")
muxed := Mux(mux, reg, in)
//litValue returns the Bigint value
val rf_reg = RegField(reg.getWidth, reg.asUInt, RegFieldDesc(name, desc, access=RegFieldAccessType.RW , reset=Some(reg_reset.litValue)))
val rf_mux = RegField(1 , mux.asUInt, RegFieldDesc(name+"_mux", "Mux control for corresponding register", access=RegFieldAccessType.RW , reset=Some(mux_reset.litValue)))
Seq(rf_reg, rf_mux)
}
}
-
in是输入逻辑 -
muxed将是混合后的信号(可以分配给Bundle之类的信号) -
*_reset是自动生成值/mux SW 寄存器的复位值
所以理想情况下,我会用它来创建两者,并且可以说
node.regmap(
0x0 -> Seq(WavRWReg(/*custom method that returns RegField*/),
WavRWMuxReg(/*returns two RegFields*/))
)
【问题讨论】:
-
您能否提供一个使用实际 Chisel API 的示例?这听起来有点像“HardwareTuple”的想法(见github.com/chipsalliance/chisel3/issues/864)。虽然这个问题有点老了,但我有一个想法 (
DataView),我希望在 Chisel 3.5 中实现它可以做你想做的事情 (gist.github.com/jackkoenig/20bffc2e9270386044aba9f00bc82fd5)。 -
嘿@JackKoenig,我已经更新了 Chisel/RocketChip 的细节。这似乎更像是 Scala 限制。 Dima 提出的解决方法还不错,它只是有点时髦,当你必须做几个时看起来有点难看。我认为不值得扩展 Chisel/RC 来弥补这一点。但很高兴听到你的想法。谢谢
-
嘿,史蒂夫,是的,我认为 Dima 的解决方案在这里是最好的。您也可以使用
Seq并执行.flatten,如果这对您来说更好,但除非火箭芯片提供RegFields(...)类型的构造,否则您会被稍微难看的东西卡住。 -
酷,我会坚持 Dima 的解决方案。