3

How do you connect from Rocket-Chip to an external AHB slave port (i.e., the AHB port on a memory controller)? I have tried to pattern my code after several other examples that connected to an AXI4 slave device, and that works ok. However, when I try to implement the same approach, the := highlights in red squigglies in IntelliJ, which tells me it is not able to connect those two types of nodes, or that the classes are not compatible for a bind operation. I feel like I'm missing out on some important concept about these Node types that relates how to glue these devices together.

trait CanHaveDdr4Ahb extends LazyModule { this: BaseSubsystem =>

  import freechips.rocketchip.subsystem.ExtMem

  override val module: CanHaveDdr4AhbImp

  val ahb_mem = p(ExtMem).map {
    case MemoryPortParams(mpp, nChan) => {
    val portName = "my_ahb"
    val device = new MemoryDevice
    val memAHBNode = AHBSlaveSinkNode(Seq.tabulate(nChan) { channel =>
      val base = AddressSet.misaligned(mpp.base, mpp.size)
      val filter = AddressSet(channel * mbus.blockBytes, ~((nChan - 1) * mbus.blockBytes))

      AHBSlavePortParameters(
        slaves = Seq(AHBSlaveParameters(
          address = List(AddressSet(mpp.base, mpp.size - 1)),
          resources = device.reg,
          regionType = RegionType.UNCACHED,
          executable = true,
          supportsWrite = TransferSizes(1, mbus.blockBytes),
          supportsRead = TransferSizes(1, mbus.blockBytes))),
        beatBytes = mpp.beatBytes)
    })

// TODO: Why can't I assign DRAMController output to this AHBSlaveSinkNode?
// AHBSlaveSinkNode := OutwardNodeHandle[D,U,E,B] { body }
    memAHBNode := mbus.toDRAMController(Some(portName)) { TLToAHB() }
    memAHBNode
  }
}

Edit: Okay, after getting the code base worked back into Chipyard and using the solutions given, namely removing the assignment of nodePath and device in AHBSlaveParameters, and changing the := binding statement to:

memAHBNode := mbus.toDRAMController(Some(portName)) { TLToAHB() }

... the same type of error persists, something dealing with how the bind operation is trying to bind to something on the left-hand side with:

  OutwardNodeHandle[
    AHBMasterPortParameters, 
    AHBSlavePortParameters, 
    AHBEdgeParameters, 
    AHBMasterBundle] // <-- should be AHBSlaveBundle according to ahb/Nodes.scala

Note in the last line, it is trying to match an

OutwardNodeHandle[D,U,E,AHBSlaveBundle]

on the RHS with an inferred

OutwardNodeHandle[D,U,E,AHBMasterBundle]

on the LHS of the assignment. I don't know why the compiler is typing it that way. Below is the error output I'm getting. I updated the code above as well.

[error] /home/abryant/workspace/chipyard/generators/socta1_rtl/src/main/scala/devices/Ddr4Ahb.scala:62:16: overloaded method value := with alternatives:
[error]   [EY](h: freechips.rocketchip.diplomacy.OutwardNodeHandle[freechips.rocketchip.amba.ahb.AHBMasterPortParameters,freechips.rocketchip.amba.ahb.AHBSlavePortParameters,EY,freechips.rocketchip.amba.ahb.AHBSlaveBundle])(implicit p: freechips.rocketchip.config.Parameters, implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo)freechips.rocketchip.diplomacy.OutwardNodeHandle[freechips.rocketchip.amba.ahb.AHBMasterPortParameters,freechips.rocketchip.amba.ahb.AHBSlavePortParameters,freechips.rocketchip.amba.ahb.AHBEdgeParameters,freechips.rocketchip.amba.ahb.AHBSlaveBundle] <and>
[error]   [DX, UX, EX, BX <: Chisel.Data, EY](h: freechips.rocketchip.diplomacy.NodeHandle[DX,UX,EX,BX,freechips.rocketchip.amba.ahb.AHBMasterPortParameters,freechips.rocketchip.amba.ahb.AHBSlavePortParameters,EY,freechips.rocketchip.amba.ahb.AHBSlaveBundle])(implicit p: freechips.rocketchip.config.Parameters, implicit sourceInfo: chisel3.internal.sourceinfo.SourceInfo)freechips.rocketchip.diplomacy.NodeHandle[DX,UX,EX,BX,freechips.rocketchip.amba.ahb.AHBMasterPortParameters,freechips.rocketchip.amba.ahb.AHBSlavePortParameters,freechips.rocketchip.amba.ahb.AHBEdgeParameters,freechips.rocketchip.amba.ahb.AHBSlaveBundle]
[error]  cannot be applied to (freechips.rocketchip.diplomacy.OutwardNodeHandle[freechips.rocketchip.amba.ahb.AHBMasterPortParameters,freechips.rocketchip.amba.ahb.AHBSlavePortParameters,freechips.rocketchip.amba.ahb.AHBEdgeParameters,freechips.rocketchip.amba.ahb.AHBMasterBundle])
[error]     memAHBNode := mbus.toDRAMController(Some(portName)) {
[error]                ^

The OutwardNodeHandle that mbus.toDRAMController passes onto the := is inheritable from the AXI4Slave types, but not from the AHBSlave types.

  • 1
    Have you tried using the bulk connect operator <> here. Also there are times when IntelliJ gets it wrong and things will compile and run despite the red-squiggles. – Chick Markley Oct 29 '19 at 18:00
  • 1
    This is diplomatic land, so I don't think `<>` is relevant. – Jack Koenig Oct 29 '19 at 18:31
  • 1
    Have you tried compiling it? The Scala support in IntelliJ is pretty good, but sometimes gets things wrong. – Jack Koenig Oct 29 '19 at 18:32
  • Thank you. Yes, I moved the project to the Chipyard infrastructure and I'm still trying to get IntelliJ to play nice with that, so I don't have compilation output to share right yet. If I remember, it was something along the lines of what is in the comments above, that the type AHBSlaveIdentityNode was not compatible with OutwardNodeHandle[D, U, E, B] – Adam Bryant Oct 30 '19 at 16:04

2 Answers2

4

Try this:

          memAHBNode := mbus.toDRAMController(Some(portName)) { TLToAHB() }

You made it too complicated. :-)

You should also not set the nodePath or device fields in AHBSlavePortParamters. I'm frankly shocked that device exists and it should be removed ASAP.

  • Thank you! Where could I find out the intention behind each of these fields and the classes they belong to? – Adam Bryant Oct 30 '19 at 16:01
  • Unfortunately, rocket-chip is very much a RTFC repository with a side-order of word-of-mouth. You could look at the toDRAMController functions and notice that it effectively puts the contents of the `{}`s (TLToAHB in this case) on the left of a `:=` that ultimately gets driven by the mbus. – Wesley Terpstra Oct 31 '19 at 17:39
  • That makes sense ... but why is the TLToAHB adapter built to extend MixedAdapterNode(TLImp, AHBImpMaster), which uses the AHBMasterBundle, rather than MixedAdapterNode(TLImp, AHBImpSlave) which uses the AHBSlaveBundle? And conversely, why does ToTL in amba.ahb use the AHBSlaveBundle rather than the AHBMasterBundle? It seems backwards from the way the AXI4 interfaces are built. – Adam Bryant Nov 07 '19 at 16:27
  • Unfortunately, AHB is not symmetric. Slave and master devices have different signals when connected to the interconnect (as opposed to TileLink and AXI). Since TLToAHB converts TL requests into AHB requests, this conversion needs to use AHB master signals to frame requests. – Wesley Terpstra Nov 25 '19 at 17:42
  • Hello, how did you deal with that? I have the same issue, and i still can`t understant why it won`t connect. – Alexy Khilaev Jun 25 '20 at 06:19
0

Finally i done with that, after week of research of scala code:
Ports.scala

case object ExtMem1 extends Field[Option[MemoryPortParams]](None)

trait CanHaveMasterAHBMemPort {
  this: BaseSubsystem =>
  val module: CanHaveMasterAHBMemPortModuleImp

  val mem1_ahb_node = p(ExtMem1).map { case MemoryPortParams(memPortParams, nMemoryChannels) =>
    val portName = "ahbMem"
    val device = new MemoryDevice

    val mem1_AHB_node = AHBMasterSinkNode(Seq.tabulate(nMemoryChannels) { channel =>
    val base = AddressSet.misaligned(memPortParams.base, memPortParams.size)
    val filter = AddressSet(channel * mbus.blockBytes, ~((nMemoryChannels-1) * mbus.blockBytes))

      AHBSlavePortParameters(
        slaves = Seq(AHBSlaveParameters(
          //address = AddressSet.misaligned(memPortParams.base, memPortParams.size),
          address       = base.flatMap(_.intersect(filter)),
          resources     = device.reg,
          regionType = RegionType.UNCACHED, // cacheable
          executable = true,
          supportsWrite = TransferSizes(1, mbus.blockBytes),
          supportsRead  = TransferSizes(1, mbus.blockBytes))),
        beatBytes = memPortParams.beatBytes,
        lite = true)
    })

    mem1_AHB_node := mbus.toDRAMController(Some(portName)) {
      AHBLite() := TLToAHB()
    }
    mem1_AHB_node
  }
}

i'am using rocket-chip dated October 20, 2019 with hash 4f0cdea85c8a2b849fd582ccc8497892001d06b0 B

Alexy Khilaev
  • 415
  • 3
  • 13