Reputation: 668
I'm trying to implement a DMA like periphery to the rocket chip. Meaning a module that is hooked to the pbus, and controlled by registers. it also has a master hooked to the sbus.
I followed the sifive format to attach registers controlled peripheries without any problems. My question is how do I add the sbus master ?, the bellow is what I've tried before getting to dead end.
To the attach parameters class I've added the sbus:
case class dmaAttachParams(
dma : dmaParams,
controlBus: TLBusWrapper,
masterBus : TLBusWrapper, // <-- my addition
....
) (implicit val p: Parameters)
Then I modified the attach method in the factory object:
def attach(params: dmaAttachParams): TLdma = {
implicit val p = params.p
val name = s"dma_${nextId()}"
val cbus = params.controlBus
val mbus = params.masterBus // <- my addition
val dma = LazyModule(new TLdma(params.dma))
dma.suggestName(name)
cbus.coupleTo(s"slave_named_name") {
dma.controlXing(params.controlXType) := TLFragmenter(cbus.beatBytes, cbus.blockBytes) := _
}
InModuleBody { dma.module.clock := params.mclock.map(_.getWrappedValue).getOrElse(cbus.module.clock) }
InModuleBody { dma.module.reset := params.mreset.map(_.getWrappedValue).getOrElse(cbus.module.reset) }
// this section is my problem // <-- this section is my addition
mbus.from(s"master_named_name") {
mbus.inwardNode := TLBuffer() := dma.mnode // <- what should i do here ???
}
dma
}
The mndoe is a node I have add to the dma class like this:
val mnode = TLClientNode(Seq(TLClientPortParameters(Seq(TLClientParameters(name = "dmaSbusMaster")))))
what should be the body of the mbus.from() method that will do the work? trying to build this code gives this error:
Caused by: java.lang.IllegalArgumentException: requirement failed: buffer.node (A adapter node with parent buffer inside coupler_from_master_named_name) has 1 inputs and 0 outputs; they must match (Buffer.scala:69:28)
Any help will appreciated, in the rocket chip github issue forum, they no longer answer support questions. So if someone from there can answer here it will be great, as I am really stuck here.
P.S. just adding the way the attach method is invoked:
trait HasPeripheryDma { this: BaseSubsystem =>
val dmaNodes = p(PeripheryDmaKey).map { ps =>
dma.attach(dmaAttachParams(ps, pbus, sbus))
}
}
Implementing the body of the mbus.from() method as below:
mbus.from(s"master_named_name") {
mbus.inwardNode := TLBuffer(BufferParams.default) := dma.mnode
}
Does create a coupler from the dma on the SBUS , but it is not connected to the dma periphery. Any Ideas ?
Upvotes: 4
Views: 516
Reputation: 668
I have managed to attach the SBUS by reverse engineering of the way the slave is attached. If someone can/wants to elaborate more feel free to do so.
I have added a "TLOutwardCrossingHelper" field to the DMA periphery like this:
class TLdma(params : dmaParams) (implicit p: Parameters) extends dma(params) with HasTLControlRegMap {
val controlXingMaster : TLOutwardCrossingHelper = this.crossOut(mnode)
}
please note that equivalent "TLInwardCrossingHelper" is defined in the "HasTLControlRegMap " trait that we extending.
Then,In the attach method, the next line did the work:
_ := TLBuffer(BufferParams.default) := dma.controlXingMaster(params.controlXType)
In this way I was able to also hook the periphery to the coupler on the sbus. I assume the crossing object does something to the node , but I don't know what.
Upvotes: 1
Reputation: 31
I don't understand what is going wrong in your "Update", but this should work:
mbus.coupleFrom("master_named_dma") {
_ := TLBuffer(BufferParams.default) := dma.mnode
}
Upvotes: 3