I am working with a DSL (Chisel) in which one particular part of the library requires me to define a Seq
of items. I have several companion objects to create some intermediate logic and return one of these items. I have a situation where I want to actually return two of these items, but I'm having a hard time figuring out how to do that.
Let's say the "items" here are Person
. (What Person
is here is not important)
The DSL wants you to describe all your Person
s through a Seq
.
val p1 = new Person(1)
val p2 = new Person(2)
Seq(p1,p2)
I have a case where I want to link two people together. For example, I know some people have friends that they drag everywhere, so if they are showing up so is their friend (even if I don't like them). So I want to be able to do something similar to the following.
object Group {
def apply(): Person, Person = { //return two of these
val pA = new Person(10)
val pAA = new Person(10+1)
}
}
this way, I can easily just do the following
Seq(p1, p2, Group)
//The Seq should have p1, p2, and the pA, pAA
Since this is a DSL, I do not have access to change the internals. I could create each piece of the Seq, then combine them all together, however this isn't ideal as this is something I'll do often enough that a good solution is desirable. I can't send back a tuple for the same reason.
I tried to see if the variable args would work on the return, but that did not seem to work.
Any help would be appreciated. Thanks
Update for our lord and savior Jack Koenig
This is utilizing the RocketChip RegisterRotuer
node to describe the RegFields
It is often in my designs where I have a signal coming from some logic and I want software to have the ability to block the upstream logic and drive a signal manually (think about some enable you want software to be able to drive). To do this I build a SW register that represents the driven value, and a "mux" SW register that handles the control. What I've currently done is this (currently returning a Seq[RegField]
but hopefully you see where I wanted this to be two RegField
types
/**
* 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
is the input logicmuxed
will be the post muxed signal (can be assigned to something like aBundle
signal)*_reset
are the reset value for the auto generated value/mux SW registers
So ideally I would use this to create both and would be able to just say
node.regmap(
0x0 -> Seq(WavRWReg(/*custom method that returns RegField*/),
WavRWMuxReg(/*returns two RegFields*/))
)
DataView
) that I'm hoping to implement in Chisel 3.5 that may do what you want (gist.github.com/jackkoenig/20bffc2e9270386044aba9f00bc82fd5). – Jack KoenigSeq
and do a.flatten
if that looks better for you, but unless rocket-chip were to supply aRegFields(...)
sort of construct, you're sort of stuck with the slightly ugly stuff. – Jack Koenig