首页 > 解决方案 > 为什么我为在 Sifive 的 E310 SOC 上生成 axi4 引脚而编写的凿子代码不起作用?

问题描述

今年我有一个项目,旨在设计一个基于RISCV内核的SOC系统。我打算使用 Sifive E310 Soc,然后我需要做的只是做一些调整。其中的关键是在系统上增加一个 AXI4 端口。

幸运的是,火箭核心使用“蛋糕图案”来添加外围。我已将特征 CanHaveMasterAXI4MMIOPort 和 HasPeripheryVGAModuleImp 添加到 E300Nexys4DDRDevKitSystem。并编写了一个 AxiPins.scala 文件以将 AXI4 端口与系统顶部定义的 AXI4 引脚匹配。就像 Sifive 添加的任何其他外围设备一样。我已经通过了编译。遗憾的是,生成的 verilog 文件顶部没有看到任何 AXi4 引脚 :(:(:(
找不到添加的任何 AXI4 引脚 AXI4 引脚文件是这样写的:

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)

    }
  }
}

然后在系统的顶部,代码是这样的:

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)

我哪里错了?我已经坚持了一个月。我深感沮丧。有人帮我吗?

//2020年6月10日更新

感谢 Jack Koenig 的回复。

我已经厌倦了将 dontTouch 添加到 E300Nexys4DDRDevKitPlatformIO 初始化和蛋糕模式中。像这样。

蛋糕图案

E300Nexys4DDRDevKitPlatformIO初始化

但遗憾的是它仍然不起作用。

但启发了我去看看这个系统的顶部。我发现 gpio 12 和 13 也没有出现。而这两个管脚并没有在顶层文件中分配!看。

class E300Nexys4DDRDevKitFPGAChip(implicit override val p: Parameters) extends Nexys4DDRShell {

  //-----------------------------------------------------------------------
  // Clock divider
  //-----------------------------------------------------------------------
  val slow_clock = Wire(Bool())

  // Divide clock by 256, used to generate 32.768 kHz clock for AON block
  withClockAndReset(clock_8MHz, ~mmcm_locked) {
    val clockToggleReg = RegInit(false.B)
    val (_, slowTick) = Counter(true.B, 256)
    when (slowTick) {clockToggleReg := ~clockToggleReg}
    slow_clock := clockToggleReg
  }

  //-----------------------------------------------------------------------
  // DUT
  //-----------------------------------------------------------------------

  withClockAndReset(clock_32MHz, ~ck_rst) {
    val dut = Module(new E300Nexys4DDRDevKitPlatform)

    //---------------------------------------------------------------------
    // SPI flash IOBUFs
    //---------------------------------------------------------------------

    STARTUPE2(dut.io.pins.qspi.sck.o.oval)
    IOBUF(qspi_cs,  dut.io.pins.qspi.cs(0))

    IOBUF(qspi_dq(0), dut.io.pins.qspi.dq(0))
    IOBUF(qspi_dq(1), dut.io.pins.qspi.dq(1))
    IOBUF(qspi_dq(2), dut.io.pins.qspi.dq(2))
    IOBUF(qspi_dq(3), dut.io.pins.qspi.dq(3))

    //---------------------------------------------------------------------
    // JTAG IOBUFs
    //---------------------------------------------------------------------

    dut.io.pins.jtag.TCK.i.ival := IBUFG(IOBUF(jd_2).asClock).asUInt

    IOBUF(jd_5, dut.io.pins.jtag.TMS)
    PULLUP(jd_5)

    IOBUF(jd_4, dut.io.pins.jtag.TDI)
    PULLUP(jd_4)

    IOBUF(jd_0, dut.io.pins.jtag.TDO)

    // mimic putting a pullup on this line (part of reset vote)
    SRST_n := IOBUF(jd_6)
    PULLUP(jd_6)

    // jtag reset
    val jtag_power_on_reset = PowerOnResetFPGAOnly(clock_32MHz)
    dut.io.jtag_reset := jtag_power_on_reset

    // debug reset
    dut_ndreset := dut.io.ndreset

    // UART
    IOBUF(uart_txd_in, dut.io.pins.gpio.pins(16))
    IOBUF(uart_rxd_out, dut.io.pins.gpio.pins(17))
    val iobuf_uart_cts = Module(new IOBUF())
    iobuf_uart_cts.io.I := false.B
    iobuf_uart_cts.io.T := false.B

    // Mirror outputs of GPIOs with PWM peripherals to RGB LEDs on Arty
    // assign RGB LED0 R,G,B inputs = PWM0(1,2,3) when iof_1 is active
    IOBUF(led0_r, dut.io.pins.gpio.pins(1))
    IOBUF(led0_g, dut.io.pins.gpio.pins(2))
    IOBUF(led0_b, dut.io.pins.gpio.pins(3))

    // Note that this is the one which is actually connected on the HiFive/Crazy88
    // Board. Same with RGB LED1 R,G,B inputs = PWM1(1,2,3) when iof_1 is active
    IOBUF(led1_r, dut.io.pins.gpio.pins(19))
    IOBUF(led1_g, dut.io.pins.gpio.pins(21))
    IOBUF(led1_b, dut.io.pins.gpio.pins(22))

    // Only 19 out of 20 shield pins connected to GPIO pins
    // Shield pin A5 (pin 14) left unconnected
    // The buttons are connected to some extra GPIO pins not connected on the
    // HiFive1 board
    IOBUF(btn_0, dut.io.pins.gpio.pins(15))
    IOBUF(btn_1, dut.io.pins.gpio.pins(30))
    IOBUF(btn_2, dut.io.pins.gpio.pins(31))

    val iobuf_btn_3 = Module(new IOBUF())
    iobuf_btn_3.io.I := ~dut.io.pins.aon.pmu.dwakeup_n.o.oval
    iobuf_btn_3.io.T := ~dut.io.pins.aon.pmu.dwakeup_n.o.oe
    attach(btn_3, iobuf_btn_3.io.IO)
    dut.io.pins.aon.pmu.dwakeup_n.i.ival := ~iobuf_btn_3.io.O & dut.io.pins.aon.pmu.dwakeup_n.o.ie

    // UART1 RX/TX pins are assigned to PMOD_D connector pins 0/1
    IOBUF(ja_0, dut.io.pins.gpio.pins(25)) // UART1 TX
    IOBUF(ja_1, dut.io.pins.gpio.pins(24)) // UART1 RX

    // Use the LEDs for some more useful debugging things
    IOBUF(led_0, ck_rst)
    IOBUF(led_1, SRST_n)
    IOBUF(led_2, dut.io.pins.aon.pmu.dwakeup_n.i.ival)
    IOBUF(led_3, dut.io.pins.gpio.pins(14))

    IOBUF(led_4, dut.io.pins.gpio.pins(4))
    IOBUF(led_5, dut.io.pins.gpio.pins(5))
    IOBUF(led_6, dut.io.pins.gpio.pins(6))
    IOBUF(led_7, dut.io.pins.gpio.pins(7))
    IOBUF(led_8, dut.io.pins.gpio.pins(8))
    IOBUF(led_9, dut.io.pins.gpio.pins(9))
    IOBUF(led_10, dut.io.pins.gpio.pins(10))
    IOBUF(led_11, dut.io.pins.gpio.pins(11))
    IOBUF(led_12, dut.io.pins.gpio.pins(26))
    IOBUF(led_13, dut.io.pins.gpio.pins(27))
    IOBUF(led_14, dut.io.pins.gpio.pins(28))
    IOBUF(led_15, dut.io.pins.gpio.pins(29))

    // Seg 7 LED
    IOBUF(seg7_ca, dut.io.pins.seg7.cathodes(0))
    IOBUF(seg7_cb, dut.io.pins.seg7.cathodes(1))
    IOBUF(seg7_cc, dut.io.pins.seg7.cathodes(2))
    IOBUF(seg7_cd, dut.io.pins.seg7.cathodes(3))
    IOBUF(seg7_ce, dut.io.pins.seg7.cathodes(4))
    IOBUF(seg7_cf, dut.io.pins.seg7.cathodes(5))
    IOBUF(seg7_cg, dut.io.pins.seg7.cathodes(6))

    IOBUF(seg7_dp, dut.io.pins.seg7.decimalPoint)

    IOBUF(seg7_an_0, dut.io.pins.seg7.anodes(0))
    IOBUF(seg7_an_1, dut.io.pins.seg7.anodes(1))
    IOBUF(seg7_an_2, dut.io.pins.seg7.anodes(2))
    IOBUF(seg7_an_3, dut.io.pins.seg7.anodes(3))
    IOBUF(seg7_an_4, dut.io.pins.seg7.anodes(4))
    IOBUF(seg7_an_5, dut.io.pins.seg7.anodes(5))
    IOBUF(seg7_an_6, dut.io.pins.seg7.anodes(6))
    IOBUF(seg7_an_7, dut.io.pins.seg7.anodes(7))

    // VGA Display
    IOBUF(vga_red_0, dut.io.pins.vga.red(0))
    IOBUF(vga_red_1, dut.io.pins.vga.red(1))
    IOBUF(vga_red_2, dut.io.pins.vga.red(2))
    IOBUF(vga_red_3, dut.io.pins.vga.red(3))

    IOBUF(vga_green_0, dut.io.pins.vga.green(0))
    IOBUF(vga_green_1, dut.io.pins.vga.green(1))
    IOBUF(vga_green_2, dut.io.pins.vga.green(2))
    IOBUF(vga_green_3, dut.io.pins.vga.green(3))

    IOBUF(vga_blue_0, dut.io.pins.vga.blue(0))
    IOBUF(vga_blue_1, dut.io.pins.vga.blue(1))
    IOBUF(vga_blue_2, dut.io.pins.vga.blue(2))
    IOBUF(vga_blue_3, dut.io.pins.vga.blue(3))

    IOBUF(vga_hSync, dut.io.pins.vga.hSync)
    IOBUF(vga_vSync, dut.io.pins.vga.vSync)

    dut.io.pins.vga.clock := clock_25MHz
    dut.io.pins.vga.reset := ~ck_rst

    //---------------------------------------------------------------------
    // Unconnected inputs
    //---------------------------------------------------------------------

    dut.io.pins.aon.erst_n.i.ival       := ~reset_periph
    dut.io.pins.aon.lfextclk.i.ival     := slow_clock
    dut.io.pins.aon.pmu.vddpaden.i.ival := 1.U
  }
}

所以我想知道我是否可以稍微调整一下来解决这个问题。你有什么建议吗?

标签: scalariscvchisel

解决方案


推荐阅读