Why my chisel code written to generate axi4 pins on Sifive's E310 SOC didn't work?

This year I got a project aims to design a SOC system based on RISCV core. I intended to used the Sifive E310 Soc then what I need to do is just to do a little bit tunning. The key of which is to add a AXI4 port on the system.

Luckily the rocket core uses “cake pattern” to add peripheries. I have added trait CanHaveMasterAXI4MMIOPort and HasPeripheryVGAModuleImp to E300Nexys4DDRDevKitSystem. And wrote a AxiPins.scala file to match the AXI4 ports to with the Pins of AXI4 defined at the top of the system. just like any other peripheries added by Sifive. I’v passed the compiliation. Sadly, the generated verilog file didn’t see any AXi4 Pins at top :frowning:


The AXI4 pins file is written like this:

    ```
    package sifive.blocks.devices.axi

    import Chisel._
    import chisel3.util.{Irrevocable}
    import freechips.rocketchip.config.{Field, Parameters}
    import chisel3.experimental.{withClockAndReset}
    import freechips.rocketchip.util._
    import freechips.rocketchip.amba.axi4.{AXI4Bundle,AXI4BundleBase,AXI4BundleParameters}
    import sifive.blocks.devices.pinctrl.{Pin, PinCtrl}

    case object PeripheryaxiKey extends Field[Seq[AXI4BundleParameters]]

        class AXI4_Pins_BASE[T <: Data](private val pingen: () => T, private val c:AXI4BundleParameters) extends Bundle


        class AXI4BundleB_pin[T <: Data](pingen:() => T, c:AXI4BundleParameters) extends AXI4_Pins_BASE(pingen, c) {
         val id   = UInt(width = c.idBits)
         val resp = UInt(width = c.respBits)
        }

    class AXI4BundleR_pin[T <: Data](pingen:() => T, c:AXI4BundleParameters) extends AXI4_Pins_BASE(pingen, c) {
      val id   = UInt(width = c.idBits)
      val data = UInt(width = c.dataBits)
      val resp = UInt(width = c.respBits)
      val last = Bool()

    }



class AXI4_Pins[T <: Pin]( pingen: () => T, c:AXI4BundleParameters) extends AXI4_Pins_BASE(pingen, c) {

  val aw_id     = Vec(c.idBits, pingen())
  val aw_addr   = Vec(c.addrBits, pingen())
  val aw_len    = Vec(c.lenBits, pingen())  // number of beats - 1
  val aw_size   = Vec(c.sizeBits, pingen()) // bytes in beat = 2^size
  val aw_burst  = Vec(c.burstBits, pingen())
  val aw_lock   = Vec(c.lockBits, pingen())
  val aw_cache  = Vec(c.cacheBits, pingen())
  val aw_prot   = Vec(c.protBits, pingen())
  val aw_qos    = Vec(c.qosBits, pingen())  // 0=no QoS, bigger = higher priority
  val aw_valid =  pingen()
  val aw_ready =  pingen()


  val w_data = Vec(c.dataBits, pingen()) 
  val w_strb = Vec(c.dataBits/8, pingen())
  val w_last = pingen()
  val w_ready  = pingen()
  val w_valid  = pingen()


  val b_bits  = new AXI4BundleB_pin(()=>pingen(),c) 
  val b_ready  = pingen()
  val b_valid  = pingen()

  val ar_id     = Vec(c.idBits, pingen())
  val ar_addr   = Vec(c.addrBits, pingen())
  val ar_len    = Vec(c.lenBits, pingen())  // number of beats - 1
  val ar_size   = Vec(c.sizeBits, pingen()) // bytes in beat = 2^size
  val ar_burst  = Vec(c.burstBits, pingen())
  val ar_lock   = Vec(c.lockBits, pingen())
  val ar_cache  = Vec(c.cacheBits, pingen())
  val ar_prot   = Vec(c.protBits, pingen())
  val ar_qos    = Vec(c.qosBits, pingen())  // 0=no QoS, bigger = higher priority
  val ar_valid =  pingen()
  val ar_ready =  pingen()

  val r_bits  = new AXI4BundleR_pin(()=>pingen(),c)
  val r_ready  = pingen()
  val r_valid  = pingen()
}

object AXI4PinsFromPort {

  def apply[T <: Pin](pins: AXI4_Pins[T], port: AXI4Bundle, clock: Clock, reset: Bool, syncStages: Int = 0, driveStrength: Bool = false.B){

    // This will just match up the components of the Bundle that
    // exist in both.
    withClockAndReset(clock, reset) {
 pins.aw_id.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.id(i), pue=true.B, ie = true.B)
    }
    pins.aw_addr.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.addr(i), pue=true.B, ie = true.B)
    }
    pins.aw_len.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.len(i), pue=true.B, ie = true.B)
    }
    pins.aw_size.zipWithIndex.map { case (p, i) =>
       p.outputPin(port.aw.bits.size(i), pue=true.B, ie = true.B)
    }
    pins.aw_burst.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.burst(i), pue=true.B, ie = true.B)
    }
    pins.aw_lock.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.lock(i), pue=true.B, ie = true.B)
    }
    pins.aw_cache.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.cache(i), pue=true.B, ie = true.B)
    }
    pins.aw_prot.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.prot(i), pue=true.B, ie = true.B)
    }
    pins.aw_qos.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.aw.bits.qos(i), pue=true.B, ie = true.B)
    }
    pins.aw_valid.outputPin(port.aw.valid, pue=true.B, ie = true.B)
    port.aw.ready := pins.aw_ready.inputPin(pue = true.B)




    pins.w_data.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.w.bits.data(i), pue=true.B, ie = true.B)
    }
    pins.w_strb.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.w.bits.strb(i), pue=true.B, ie = true.B)
    }
      pins.w_last.outputPin(port.w.bits.last, pue=true.B, ie = true.B)
    pins.w_valid.outputPin(port.w.valid, pue=true.B, ie = true.B)
    port.w.ready := pins.w_ready.inputPin(pue = true.B)


    val b_bits_pin = Wire(pins.b_bits)
    port.b :=  b_bits_pin
    port.b.valid := pins.b_valid.inputPin(pue = true.B)
    pins.b_ready.outputPin(port.b.ready, pue=true.B, ie = true.B)


    pins.ar_id.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.id(i), pue=true.B, ie = true.B)
    }
    pins.ar_addr.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.addr(i), pue=true.B, ie = true.B)
    }
    pins.ar_len.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.len(i), pue=true.B, ie = true.B)
    }
    pins.ar_size.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.size(i), pue=true.B, ie = true.B)
    }
    pins.ar_burst.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.burst(i), pue=true.B, ie = true.B)
    }
    pins.ar_lock.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.lock(i), pue=true.B, ie = true.B)
    }
    pins.ar_cache.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.cache(i), pue=true.B, ie = true.B)
    }
    pins.ar_prot.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.prot(i), pue=true.B, ie = true.B)
    }
    pins.ar_qos.zipWithIndex.map { case (p, i) =>
      p.outputPin(port.ar.bits.qos(i), pue=true.B, ie = true.B)
    }
    pins.ar_valid.outputPin(port.ar.valid, pue=true.B, ie = true.B)
    port.ar.ready  := pins.ar_ready.inputPin(pue = true.B)

    val r_bits_pin = Wire(pins.r_bits)
    port.r := r_bits_pin
    port.r.valid := pins.r_valid.inputPin(pue = true.B)
    pins.r_ready.outputPin(port.r.ready, pue=true.B, ie = true.B)

    }
  }
}
```

And then at the top of system, the codes are like this:`

```
class E300Nexys4DDRDevKitPlatformIO(implicit val p: Parameters) extends Bundle {
  val pins = new Bundle {
    val jtag = new JTAGPins(() => PinGen(), false)
    val gpio = new GPIOPins(() => PinGen(), p(PeripheryGPIOKey)(0))
    val qspi = new SPIPins(() => PinGen(), p(PeripherySPIFlashKey)(0))
    val seg7 = new Seg7LEDPins(() => PinGen())
    val vga  = new VGAPins(() => PinGen())
    val aon  = new MockAONWrapperPins()
    val axi  = new AXI4_Pins(() => PinGen(), p(PeripheryaxiKey)(0))  //added by me
   }
  val jtag_reset = Bool(INPUT)
  val ndreset    = Bool(OUTPUT)
}

....
 // Dedicated AXI Pads
  AXI4PinsFromPort(io.pins.axi, sys.mmio_axi4(0), clock = sys.clock, reset = sys.reset)
```

Where I was wrong? I ve stuck at this stuff for a month. I m deeply frustrated . Does anyone help me out?