scala - 为什么我为在 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 初始化和蛋糕模式中。像这样。
但遗憾的是它仍然不起作用。
但启发了我去看看这个系统的顶部。我发现 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
}
}
所以我想知道我是否可以稍微调整一下来解决这个问题。你有什么建议吗?