Updates to Freedom SoCs
This commit is contained in:
committed by
Yunsup Lee
parent
f4375c2266
commit
ec70d85cbc
65
src/main/scala/everywhere/e300artydevkit/Config.scala
Normal file
65
src/main/scala/everywhere/e300artydevkit/Config.scala
Normal file
@ -0,0 +1,65 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.everywhere.e300artydevkit
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.coreplex._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase}
|
||||
import freechips.rocketchip.system._
|
||||
import freechips.rocketchip.tile._
|
||||
|
||||
import sifive.blocks.devices.mockaon._
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.pwm._
|
||||
import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.i2c._
|
||||
|
||||
// Default FreedomEConfig
|
||||
class DefaultFreedomEConfig extends Config (
|
||||
new WithNBreakpoints(2) ++
|
||||
new WithNExtTopInterrupts(0) ++
|
||||
new WithJtagDTM ++
|
||||
new TinyConfig
|
||||
)
|
||||
|
||||
// Freedom E300 Arty Dev Kit Peripherals
|
||||
class E300DevKitPeripherals extends Config((site, here, up) => {
|
||||
case PeripheryGPIOKey => List(
|
||||
GPIOParams(address = 0x10012000, width = 32, includeIOF = true))
|
||||
case PeripheryPWMKey => List(
|
||||
PWMParams(address = 0x10015000, cmpWidth = 8),
|
||||
PWMParams(address = 0x10025000, cmpWidth = 16),
|
||||
PWMParams(address = 0x10035000, cmpWidth = 16))
|
||||
case PeripherySPIKey => List(
|
||||
SPIParams(csWidth = 4, rAddress = 0x10024000, sampleDelay = 3),
|
||||
SPIParams(csWidth = 1, rAddress = 0x10034000, sampleDelay = 3))
|
||||
case PeripherySPIFlashKey => List(
|
||||
SPIFlashParams(
|
||||
fAddress = 0x20000000,
|
||||
rAddress = 0x10014000,
|
||||
sampleDelay = 3))
|
||||
case PeripheryUARTKey => List(
|
||||
UARTParams(address = 0x10013000),
|
||||
UARTParams(address = 0x10023000))
|
||||
case PeripheryI2CKey => List(
|
||||
I2CParams(address = 0x10016000))
|
||||
case PeripheryMockAONKey =>
|
||||
MockAONParams(address = 0x10000000)
|
||||
case PeripheryMaskROMKey => List(
|
||||
MaskROMParams(address = 0x10000, name = "BootROM"))
|
||||
})
|
||||
|
||||
// Freedom E300 Arty Dev Kit Peripherals
|
||||
class E300ArtyDevKitConfig extends Config(
|
||||
new E300DevKitPeripherals ++
|
||||
new DefaultFreedomEConfig().alter((site,here,up) => {
|
||||
case DTSTimebase => BigInt(32768)
|
||||
case JtagDTMKey => new JtagDTMConfig (
|
||||
idcodeVersion = 2,
|
||||
idcodePartNum = 0x000,
|
||||
idcodeManufId = 0x489,
|
||||
debugIdleCycles = 5)
|
||||
})
|
||||
)
|
@ -1,37 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.everywhere.e300artydevkit
|
||||
|
||||
import config._
|
||||
import coreplex._
|
||||
import rocketchip._
|
||||
|
||||
|
||||
class DefaultFreedomEConfig extends Config(
|
||||
new WithStatelessBridge ++
|
||||
new WithNBreakpoints(2) ++
|
||||
new WithRV32 ++
|
||||
new DefaultSmallConfig
|
||||
)
|
||||
|
||||
class WithBootROMFile(bootROMFile: String) extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case BootROMFile => bootROMFile
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
|
||||
class E300ArtyDevKitConfig extends Config(
|
||||
new WithBootROMFile("./bootrom/e300artydevkit.img") ++
|
||||
new WithNExtTopInterrupts(0) ++
|
||||
new WithJtagDTM ++
|
||||
new WithL1ICacheSets(8192/32) ++ // 8 KiB **per set**
|
||||
new WithCacheBlockBytes(32) ++
|
||||
new WithL1ICacheWays(2) ++
|
||||
new WithDefaultBtb ++
|
||||
new WithFastMulDiv ++
|
||||
new WithDataScratchpad(16384) ++
|
||||
new WithNMemoryChannels(0) ++
|
||||
new WithoutFPU ++
|
||||
new WithTLMonitors ++
|
||||
new DefaultFreedomEConfig
|
||||
)
|
193
src/main/scala/everywhere/e300artydevkit/FPGAChip.scala
Normal file
193
src/main/scala/everywhere/e300artydevkit/FPGAChip.scala
Normal file
@ -0,0 +1,193 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.everywhere.e300artydevkit
|
||||
|
||||
import Chisel._
|
||||
import chisel3.core.{attach}
|
||||
import chisel3.experimental.{withClockAndReset}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.spi._
|
||||
|
||||
import sifive.fpgashells.shell.xilinx.artyshell.{ArtyShell}
|
||||
import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// E300ArtyDevKitFPGAChip
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class E300ArtyDevKitFPGAChip(implicit override val p: Parameters) extends ArtyShell {
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// 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 E300ArtyDevKitPlatform)
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// SPI flash IOBUFs
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
IOBUF(qspi_sck, dut.io.pins.qspi.sck)
|
||||
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
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Assignment to package pins
|
||||
//---------------------------------------------------------------------
|
||||
// Pins IO0-IO13
|
||||
//
|
||||
// FTDI UART TX/RX are not connected to ck_io[0,1]
|
||||
// the way they are on Arduino boards. We copy outgoing
|
||||
// data to both places, switch 3 (sw[3]) determines whether
|
||||
// input to UART comes from FTDI chip or gpio_16 (shield pin PD0)
|
||||
|
||||
val iobuf_ck0 = Module(new IOBUF())
|
||||
iobuf_ck0.io.I := dut.io.pins.gpio.pins(16).o.oval
|
||||
iobuf_ck0.io.T := ~dut.io.pins.gpio.pins(16).o.oe
|
||||
attach(iobuf_ck0.io.IO, ck_io(0)) // UART0 RX
|
||||
|
||||
val iobuf_uart_txd = Module(new IOBUF())
|
||||
iobuf_uart_txd.io.I := dut.io.pins.gpio.pins(16).o.oval
|
||||
iobuf_uart_txd.io.T := ~dut.io.pins.gpio.pins(16).o.oe
|
||||
attach(iobuf_uart_txd.io.IO, uart_txd_in)
|
||||
|
||||
// gpio(16) input is shared between FTDI TX pin and the Arduino shield pin using SW[3]
|
||||
val sw_3_in = IOBUF(sw_3)
|
||||
dut.io.pins.gpio.pins(16).i.ival := Mux(sw_3_in,
|
||||
iobuf_ck0.io.O & dut.io.pins.gpio.pins(16).o.ie,
|
||||
iobuf_uart_txd.io.O & dut.io.pins.gpio.pins(16).o.ie)
|
||||
|
||||
IOBUF(uart_rxd_out, dut.io.pins.gpio.pins(17))
|
||||
|
||||
// Shield header row 0: PD2-PD7
|
||||
IOBUF(ck_io(2), dut.io.pins.gpio.pins(18))
|
||||
IOBUF(ck_io(3), dut.io.pins.gpio.pins(19)) // PWM1(1)
|
||||
IOBUF(ck_io(4), dut.io.pins.gpio.pins(20)) // PWM1(0)
|
||||
IOBUF(ck_io(5), dut.io.pins.gpio.pins(21)) // PWM1(2)
|
||||
IOBUF(ck_io(6), dut.io.pins.gpio.pins(22)) // PWM1(3)
|
||||
IOBUF(ck_io(7), dut.io.pins.gpio.pins(23))
|
||||
|
||||
// Header row 1: PB0-PB5
|
||||
IOBUF(ck_io(8), dut.io.pins.gpio.pins(0)) // PWM0(0)
|
||||
IOBUF(ck_io(9), dut.io.pins.gpio.pins(1)) // PWM0(1)
|
||||
IOBUF(ck_io(10), dut.io.pins.gpio.pins(2)) // SPI CS(0) / PWM0(2)
|
||||
IOBUF(ck_io(11), dut.io.pins.gpio.pins(3)) // SPI MOSI / PWM0(3)
|
||||
IOBUF(ck_io(12), dut.io.pins.gpio.pins(4)) // SPI MISO
|
||||
IOBUF(ck_io(13), dut.io.pins.gpio.pins(5)) // SPI SCK
|
||||
|
||||
dut.io.pins.gpio.pins(6).i.ival := 0.U
|
||||
dut.io.pins.gpio.pins(7).i.ival := 0.U
|
||||
dut.io.pins.gpio.pins(8).i.ival := 0.U
|
||||
|
||||
// Header row 3: A0-A5 (we don't support using them as analog inputs)
|
||||
// just treat them as regular digital GPIOs
|
||||
IOBUF(ck_io(15), dut.io.pins.gpio.pins(9)) // A1 = CS(2)
|
||||
IOBUF(ck_io(16), dut.io.pins.gpio.pins(10)) // A2 = CS(3) / PWM2(0)
|
||||
IOBUF(ck_io(17), dut.io.pins.gpio.pins(11)) // A3 = PWM2(1)
|
||||
IOBUF(ck_io(18), dut.io.pins.gpio.pins(12)) // A4 = PWM2(2) / SDA
|
||||
IOBUF(ck_io(19), dut.io.pins.gpio.pins(13)) // A5 = PWM2(3) / SCL
|
||||
|
||||
// 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))
|
||||
|
||||
// and RGB LED2 R,G,B inputs = PWM2(1,2,3) when iof_1 is active
|
||||
IOBUF(led2_r, dut.io.pins.gpio.pins(11))
|
||||
IOBUF(led2_g, dut.io.pins.gpio.pins(12))
|
||||
IOBUF(led2_b, dut.io.pins.gpio.pins(13))
|
||||
|
||||
// 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
|
||||
|
||||
// SPI2 pins mapped to 6 pin ICSP connector (standard on later
|
||||
// arduinos) These are connected to some extra GPIO pins not connected
|
||||
// on the HiFive1 board
|
||||
IOBUF(ck_ss, dut.io.pins.gpio.pins(26))
|
||||
IOBUF(ck_mosi, dut.io.pins.gpio.pins(27))
|
||||
IOBUF(ck_miso, dut.io.pins.gpio.pins(28))
|
||||
IOBUF(ck_sck, dut.io.pins.gpio.pins(29))
|
||||
|
||||
// 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))
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// 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
|
||||
}
|
||||
}
|
177
src/main/scala/everywhere/e300artydevkit/Platform.scala
Normal file
177
src/main/scala/everywhere/e300artydevkit/Platform.scala
Normal file
@ -0,0 +1,177 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.everywhere.e300artydevkit
|
||||
|
||||
import Chisel._
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.coreplex._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.system._
|
||||
|
||||
import sifive.blocks.util.{ResetCatchAndSync}
|
||||
import sifive.blocks.devices.mockaon._
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.jtag._
|
||||
import sifive.blocks.devices.pwm._
|
||||
import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.i2c._
|
||||
import sifive.blocks.devices.pinctrl._
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// PinGen
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
object PinGen {
|
||||
def apply(): BasePin = {
|
||||
val pin = new BasePin()
|
||||
pin
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// E300ArtyDevKitPlatformIO
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class E300ArtyDevKitPlatformIO(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 aon = new MockAONWrapperPins()
|
||||
}
|
||||
val jtag_reset = Bool(INPUT)
|
||||
val ndreset = Bool(OUTPUT)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// E300ArtyDevKitPlatform
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class E300ArtyDevKitPlatform(implicit val p: Parameters) extends Module {
|
||||
val sys = Module(LazyModule(new E300ArtyDevKitSystem).module)
|
||||
val io = new E300ArtyDevKitPlatformIO
|
||||
|
||||
// This needs to be de-asserted synchronously to the coreClk.
|
||||
val async_corerst = sys.aon.rsts.corerst
|
||||
// Add in debug-controlled reset.
|
||||
sys.reset := ResetCatchAndSync(clock, async_corerst, 20)
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Check for unsupported rocket-chip connections
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
require (p(NExtTopInterrupts) == 0, "No Top-level interrupts supported");
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Build GPIO Pin Mux
|
||||
//-----------------------------------------------------------------------
|
||||
// Pin Mux for UART, SPI, PWM
|
||||
// First convert the System outputs into "IOF" using the respective *GPIOPort
|
||||
// converters.
|
||||
|
||||
val sys_uart = sys.uart
|
||||
val sys_pwm = sys.pwm
|
||||
val sys_spi = sys.spi
|
||||
val sys_i2c = sys.i2c
|
||||
|
||||
val uart_pins = sys.outer.uartParams.map { c => Wire(new UARTPins(() => PinGen()))}
|
||||
val pwm_pins = sys.outer.pwmParams.map { c => Wire(new PWMPins(() => PinGen(), c))}
|
||||
val spi_pins = sys.outer.spiParams.map { c => Wire(new SPIPins(() => PinGen(), c))}
|
||||
val i2c_pins = sys.outer.i2cParams.map { c => Wire(new I2CPins(() => PinGen()))}
|
||||
|
||||
(uart_pins zip sys_uart) map {case (p, r) => p.fromPort(r, clock = clock, reset = reset, syncStages = 0)}
|
||||
(pwm_pins zip sys_pwm) map {case (p, r) => p.fromPort(r)}
|
||||
(spi_pins zip sys_spi) map {case (p, r) => p.fromPort(r, clock = clock, reset = reset, syncStages = 0)}
|
||||
(i2c_pins zip sys_i2c) map {case (p, r) => p.fromPort(r, clock = clock, reset = reset, syncStages = 0)}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Default Pin connections before attaching pinmux
|
||||
|
||||
for (iof_0 <- sys.gpio(0).iof_0.get) {
|
||||
iof_0.default()
|
||||
}
|
||||
|
||||
for (iof_1 <- sys.gpio(0).iof_1.get) {
|
||||
iof_1.default()
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
val iof_0 = sys.gpio(0).iof_0.get
|
||||
val iof_1 = sys.gpio(0).iof_1.get
|
||||
|
||||
// SPI1 (0 is the dedicated)
|
||||
BasePinToIOF(spi_pins(0).cs(0), iof_0(2))
|
||||
BasePinToIOF(spi_pins(0).dq(0), iof_0(3))
|
||||
BasePinToIOF(spi_pins(0).dq(1), iof_0(4))
|
||||
BasePinToIOF(spi_pins(0).sck, iof_0(5))
|
||||
BasePinToIOF(spi_pins(0).dq(2), iof_0(6))
|
||||
BasePinToIOF(spi_pins(0).dq(3), iof_0(7))
|
||||
BasePinToIOF(spi_pins(0).cs(1), iof_0(8))
|
||||
BasePinToIOF(spi_pins(0).cs(2), iof_0(9))
|
||||
BasePinToIOF(spi_pins(0).cs(3), iof_0(10))
|
||||
|
||||
// SPI2
|
||||
BasePinToIOF(spi_pins(1).cs(0), iof_0(26))
|
||||
BasePinToIOF(spi_pins(1).dq(0), iof_0(27))
|
||||
BasePinToIOF(spi_pins(1).dq(1), iof_0(28))
|
||||
BasePinToIOF(spi_pins(1).sck, iof_0(29))
|
||||
BasePinToIOF(spi_pins(1).dq(2), iof_0(30))
|
||||
BasePinToIOF(spi_pins(1).dq(3), iof_0(31))
|
||||
|
||||
// I2C
|
||||
if (sys.outer.i2cParams.length == 1) {
|
||||
BasePinToIOF(i2c_pins(0).sda, iof_0(12))
|
||||
BasePinToIOF(i2c_pins(0).scl, iof_0(13))
|
||||
}
|
||||
|
||||
// UART0
|
||||
BasePinToIOF(uart_pins(0).rxd, iof_0(16))
|
||||
BasePinToIOF(uart_pins(0).txd, iof_0(17))
|
||||
|
||||
// UART1
|
||||
BasePinToIOF(uart_pins(1).rxd, iof_0(24))
|
||||
BasePinToIOF(uart_pins(1).txd, iof_0(25))
|
||||
|
||||
//PWM
|
||||
BasePinToIOF(pwm_pins(0).pwm(0), iof_1(0) )
|
||||
BasePinToIOF(pwm_pins(0).pwm(1), iof_1(1) )
|
||||
BasePinToIOF(pwm_pins(0).pwm(2), iof_1(2) )
|
||||
BasePinToIOF(pwm_pins(0).pwm(3), iof_1(3) )
|
||||
|
||||
BasePinToIOF(pwm_pins(1).pwm(1), iof_1(19))
|
||||
BasePinToIOF(pwm_pins(1).pwm(0), iof_1(20))
|
||||
BasePinToIOF(pwm_pins(1).pwm(2), iof_1(21))
|
||||
BasePinToIOF(pwm_pins(1).pwm(3), iof_1(22))
|
||||
|
||||
BasePinToIOF(pwm_pins(2).pwm(0), iof_1(10))
|
||||
BasePinToIOF(pwm_pins(2).pwm(1), iof_1(11))
|
||||
BasePinToIOF(pwm_pins(2).pwm(2), iof_1(12))
|
||||
BasePinToIOF(pwm_pins(2).pwm(3), iof_1(13))
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// Drive actual Pads
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
// Result of Pin Mux
|
||||
io.pins.gpio.fromPort(sys.gpio(0))
|
||||
|
||||
// Dedicated SPI Pads
|
||||
io.pins.qspi.fromPort(sys.qspi(0), clock = sys.clock, reset = sys.reset, syncStages = 3)
|
||||
|
||||
// JTAG Debug Interface
|
||||
val sjtag = sys.debug.systemjtag.get
|
||||
io.pins.jtag.fromPort(sjtag.jtag)
|
||||
sjtag.reset := io.jtag_reset
|
||||
sjtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
|
||||
|
||||
io.ndreset := sys.debug.ndreset
|
||||
|
||||
// AON Pads -- direct connection is OK because
|
||||
// EnhancedPin is hard-coded in MockAONPads
|
||||
// and thus there is no .fromPort method.
|
||||
io.pins.aon <> sys.aon.pins
|
||||
}
|
50
src/main/scala/everywhere/e300artydevkit/System.scala
Normal file
50
src/main/scala/everywhere/e300artydevkit/System.scala
Normal file
@ -0,0 +1,50 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.everywhere.e300artydevkit
|
||||
|
||||
import Chisel._
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.coreplex._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.system._
|
||||
|
||||
import sifive.blocks.devices.mockaon._
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.pwm._
|
||||
import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.devices.i2c._
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// E300ArtyDevKitSystem
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class E300ArtyDevKitSystem(implicit p: Parameters) extends RocketCoreplex
|
||||
with HasPeripheryMaskROMSlave
|
||||
with HasPeripheryDebug
|
||||
with HasPeripheryMockAON
|
||||
with HasPeripheryUART
|
||||
with HasPeripherySPIFlash
|
||||
with HasPeripherySPI
|
||||
with HasPeripheryGPIO
|
||||
with HasPeripheryPWM
|
||||
with HasPeripheryI2C {
|
||||
override lazy val module = new E300ArtyDevKitSystemModule(this)
|
||||
}
|
||||
|
||||
class E300ArtyDevKitSystemModule[+L <: E300ArtyDevKitSystem](_outer: L)
|
||||
extends RocketCoreplexModule(_outer)
|
||||
with HasPeripheryDebugModuleImp
|
||||
with HasPeripheryUARTModuleImp
|
||||
with HasPeripherySPIModuleImp
|
||||
with HasPeripheryGPIOModuleImp
|
||||
with HasPeripherySPIFlashModuleImp
|
||||
with HasPeripheryMockAONModuleImp
|
||||
with HasPeripheryPWMModuleImp
|
||||
with HasPeripheryI2CModuleImp {
|
||||
// Reset vector is set to the location of the mask rom
|
||||
val maskROMParams = p(PeripheryMaskROMKey)
|
||||
global_reset_vector := maskROMParams(0).address.U
|
||||
}
|
@ -1,230 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.everywhere.e300artydevkit
|
||||
|
||||
import Chisel._
|
||||
import config._
|
||||
import diplomacy._
|
||||
import coreplex._
|
||||
import rocketchip._
|
||||
import uncore.devices.DebugBusIO
|
||||
import sifive.blocks.devices.gpio.{GPIOConfig, PeripheryGPIO, PeripheryGPIOBundle, PeripheryGPIOModule, GPIOPin, GPIOPinToIOF, GPIOPinIOFCtrl, GPIOInputPinCtrl, JTAGPinsIO, JTAGGPIOPort}
|
||||
import sifive.blocks.devices.mockaon.{MockAONConfig, PeripheryMockAON, PeripheryMockAONBundle, PeripheryMockAONModule, MockAONWrapperPadsIO}
|
||||
import sifive.blocks.devices.pwm.{PWMConfig, PeripheryPWM, PeripheryPWMBundle, PeripheryPWMModule, PWMGPIOPort}
|
||||
import sifive.blocks.devices.spi.{SPIConfig, PeripherySPI, PeripherySPIBundle, PeripherySPIModule, SPIFlashConfig, PeripherySPIFlash, PeripherySPIFlashBundle, PeripherySPIFlashModule, SPIPinsIO, SPIGPIOPort}
|
||||
import sifive.blocks.devices.uart.{UARTConfig, PeripheryUART, PeripheryUARTBundle, PeripheryUARTModule, UARTGPIOPort}
|
||||
import sifive.blocks.util.ResetCatchAndSync
|
||||
import util._
|
||||
|
||||
// Coreplex and Periphery
|
||||
|
||||
trait E300ArtyDevKitPeripheryConfigs {
|
||||
val mockAONConfig = MockAONConfig(address = 0x10000000)
|
||||
val gpioConfig = GPIOConfig(address = 0x10012000, width = 32)
|
||||
val pwmConfigs = List(
|
||||
PWMConfig(address = 0x10015000, cmpWidth = 8),
|
||||
PWMConfig(address = 0x10025000, cmpWidth = 16),
|
||||
PWMConfig(address = 0x10035000, cmpWidth = 16))
|
||||
val spiConfigs = List(
|
||||
SPIConfig(csWidth = 4, rAddress = 0x10024000, sampleDelay = 3),
|
||||
SPIConfig(csWidth = 1, rAddress = 0x10034000, sampleDelay = 3))
|
||||
val spiFlashConfig = SPIFlashConfig(
|
||||
fAddress = 0x20000000, rAddress = 0x10014000, sampleDelay = 3)
|
||||
val uartConfigs = List(
|
||||
UARTConfig(address = 0x10013000),
|
||||
UARTConfig(address = 0x10023000))
|
||||
}
|
||||
|
||||
// This custom E300ArtyDevKit coreplex has no port into the L2 and no memory subsystem
|
||||
|
||||
class E300ArtyDevKitCoreplex(implicit p: Parameters) extends BareCoreplex
|
||||
with CoreplexNetwork
|
||||
with CoreplexRISCVPlatform
|
||||
with RocketTiles {
|
||||
override lazy val module = new E300ArtyDevKitCoreplexModule(this, () => new E300ArtyDevKitCoreplexBundle(this))
|
||||
}
|
||||
|
||||
class E300ArtyDevKitCoreplexBundle[+L <: E300ArtyDevKitCoreplex](_outer: L) extends BareCoreplexBundle(_outer)
|
||||
with CoreplexNetworkBundle
|
||||
with CoreplexRISCVPlatformBundle
|
||||
with RocketTilesBundle
|
||||
|
||||
class E300ArtyDevKitCoreplexModule[+L <: E300ArtyDevKitCoreplex, +B <: E300ArtyDevKitCoreplexBundle[L]](_outer: L, _io: () => B)
|
||||
extends BareCoreplexModule(_outer, _io)
|
||||
with CoreplexNetworkModule
|
||||
with CoreplexRISCVPlatformModule
|
||||
with RocketTilesModule
|
||||
|
||||
class E300ArtyDevKitSystem(implicit p: Parameters) extends BaseTop
|
||||
with E300ArtyDevKitPeripheryConfigs
|
||||
with PeripheryBootROM
|
||||
with PeripheryDebug
|
||||
with PeripheryMockAON
|
||||
with PeripheryUART
|
||||
with PeripherySPIFlash
|
||||
with PeripherySPI
|
||||
with PeripheryGPIO
|
||||
with PeripheryPWM
|
||||
with HardwiredResetVector {
|
||||
override lazy val module = new E300ArtyDevKitSystemModule(this, () => new E300ArtyDevKitSystemBundle(this))
|
||||
|
||||
val coreplex = LazyModule(new E300ArtyDevKitCoreplex)
|
||||
socBus.node := coreplex.mmio
|
||||
coreplex.mmioInt := intBus.intnode
|
||||
}
|
||||
|
||||
class E300ArtyDevKitSystemBundle[+L <: E300ArtyDevKitSystem](_outer: L) extends BaseTopBundle(_outer)
|
||||
with E300ArtyDevKitPeripheryConfigs
|
||||
with PeripheryBootROMBundle
|
||||
with PeripheryDebugBundle
|
||||
with PeripheryUARTBundle
|
||||
with PeripherySPIBundle
|
||||
with PeripheryGPIOBundle
|
||||
with PeripherySPIFlashBundle
|
||||
with PeripheryMockAONBundle
|
||||
with PeripheryPWMBundle
|
||||
with HardwiredResetVectorBundle
|
||||
|
||||
class E300ArtyDevKitSystemModule[+L <: E300ArtyDevKitSystem, +B <: E300ArtyDevKitSystemBundle[L]](_outer: L, _io: () => B)
|
||||
extends BaseTopModule(_outer, _io)
|
||||
with E300ArtyDevKitPeripheryConfigs
|
||||
with PeripheryBootROMModule
|
||||
with PeripheryDebugModule
|
||||
with PeripheryUARTModule
|
||||
with PeripherySPIModule
|
||||
with PeripheryGPIOModule
|
||||
with PeripherySPIFlashModule
|
||||
with PeripheryMockAONModule
|
||||
with PeripheryPWMModule
|
||||
with HardwiredResetVectorModule
|
||||
|
||||
// Top
|
||||
|
||||
class E300ArtyDevKitTopIO(implicit val p: Parameters) extends Bundle with E300ArtyDevKitPeripheryConfigs {
|
||||
val pads = new Bundle {
|
||||
val jtag = new JTAGPinsIO
|
||||
val gpio = Vec(gpioConfig.width, new GPIOPin)
|
||||
val qspi = new SPIPinsIO(spiFlashConfig)
|
||||
val aon = new MockAONWrapperPadsIO()
|
||||
}
|
||||
}
|
||||
|
||||
class E300ArtyDevKitTop(implicit val p: Parameters) extends Module with E300ArtyDevKitPeripheryConfigs {
|
||||
val sys = Module(LazyModule(new E300ArtyDevKitSystem).module)
|
||||
val io = new E300ArtyDevKitTopIO
|
||||
|
||||
// This needs to be de-asserted synchronously to the coreClk.
|
||||
val async_corerst = sys.io.aon.rsts.corerst
|
||||
sys.reset := ResetCatchAndSync(clock, async_corerst, 20)
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Check for unsupported RCT Connections
|
||||
// ------------------------------------------------------------
|
||||
|
||||
require (p(NExtTopInterrupts) == 0, "No Top-level interrupts supported");
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Build GPIO Pin Mux
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Pin Mux for UART, SPI, PWM
|
||||
// First convert the System outputs into "IOF" using the respective *GPIOPort
|
||||
// converters.
|
||||
val sys_uarts = sys.io.uarts
|
||||
val sys_pwms = sys.io.pwms
|
||||
val sys_spis = sys.io.spis
|
||||
|
||||
val uart_pins = uartConfigs.map { c => Module (new UARTGPIOPort) }
|
||||
val pwm_pins = pwmConfigs.map { c => Module (new PWMGPIOPort(c.bc)) }
|
||||
val spi_pins = spiConfigs.map { c => Module (new SPIGPIOPort(c)) }
|
||||
|
||||
(uart_pins zip sys_uarts) map {case (p, r) => p.io.uart <> r}
|
||||
(pwm_pins zip sys_pwms) map {case (p, r) => p.io.pwm <> r}
|
||||
(spi_pins zip sys_spis) map {case (p, r) => p.io.spi <> r}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Default Pin connections before attaching pinmux
|
||||
|
||||
for (iof_0 <- sys.io.gpio.iof_0) {
|
||||
iof_0.o := GPIOPinIOFCtrl()
|
||||
}
|
||||
|
||||
for (iof_1 <- sys.io.gpio.iof_1) {
|
||||
iof_1.o := GPIOPinIOFCtrl()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// TODO: Make this mapping more programmatic.
|
||||
|
||||
val iof_0 = sys.io.gpio.iof_0
|
||||
val iof_1 = sys.io.gpio.iof_1
|
||||
|
||||
// SPI1 (0 is the dedicated)
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.cs(0), iof_0(2))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.dq(0), iof_0(3))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.dq(1), iof_0(4))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.sck, iof_0(5))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.dq(2), iof_0(6))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.dq(3), iof_0(7))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.cs(1), iof_0(8))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.cs(2), iof_0(9))
|
||||
GPIOPinToIOF(spi_pins(0).io.pins.cs(3), iof_0(10))
|
||||
|
||||
// SPI2
|
||||
GPIOPinToIOF(spi_pins(1).io.pins.cs(0), iof_0(26))
|
||||
GPIOPinToIOF(spi_pins(1).io.pins.dq(0), iof_0(27))
|
||||
GPIOPinToIOF(spi_pins(1).io.pins.dq(1), iof_0(28))
|
||||
GPIOPinToIOF(spi_pins(1).io.pins.sck, iof_0(29))
|
||||
GPIOPinToIOF(spi_pins(1).io.pins.dq(2), iof_0(30))
|
||||
GPIOPinToIOF(spi_pins(1).io.pins.dq(3), iof_0(31))
|
||||
|
||||
// UART0
|
||||
GPIOPinToIOF(uart_pins(0).io.pins.rxd, iof_0(16))
|
||||
GPIOPinToIOF(uart_pins(0).io.pins.txd, iof_0(17))
|
||||
|
||||
// UART1
|
||||
GPIOPinToIOF(uart_pins(1).io.pins.rxd, iof_0(24))
|
||||
GPIOPinToIOF(uart_pins(1).io.pins.txd, iof_0(25))
|
||||
|
||||
//PWM
|
||||
GPIOPinToIOF(pwm_pins(0).io.pins.pwm(0), iof_1(0) )
|
||||
GPIOPinToIOF(pwm_pins(0).io.pins.pwm(1), iof_1(1) )
|
||||
GPIOPinToIOF(pwm_pins(0).io.pins.pwm(2), iof_1(2) )
|
||||
GPIOPinToIOF(pwm_pins(0).io.pins.pwm(3), iof_1(3) )
|
||||
|
||||
GPIOPinToIOF(pwm_pins(1).io.pins.pwm(1), iof_1(19))
|
||||
GPIOPinToIOF(pwm_pins(1).io.pins.pwm(0), iof_1(20))
|
||||
GPIOPinToIOF(pwm_pins(1).io.pins.pwm(2), iof_1(21))
|
||||
GPIOPinToIOF(pwm_pins(1).io.pins.pwm(3), iof_1(22))
|
||||
|
||||
GPIOPinToIOF(pwm_pins(2).io.pins.pwm(0), iof_1(10))
|
||||
GPIOPinToIOF(pwm_pins(2).io.pins.pwm(1), iof_1(11))
|
||||
GPIOPinToIOF(pwm_pins(2).io.pins.pwm(2), iof_1(12))
|
||||
GPIOPinToIOF(pwm_pins(2).io.pins.pwm(3), iof_1(13))
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Drive actual Pads
|
||||
// ------------------------------------------------------------
|
||||
|
||||
// Result of Pin Mux
|
||||
io.pads.gpio <> sys.io.gpio.pins
|
||||
|
||||
val dedicated_spi_pins = Module (new SPIGPIOPort(spiFlashConfig, syncStages=3, driveStrength=Bool(true)))
|
||||
dedicated_spi_pins.clock := sys.clock
|
||||
dedicated_spi_pins.reset := sys.reset
|
||||
io.pads.qspi <> dedicated_spi_pins.io.pins
|
||||
dedicated_spi_pins.io.spi <> sys.io.qspi
|
||||
|
||||
// JTAG Debug Interface
|
||||
|
||||
val jtag_pins = Module (new JTAGGPIOPort(true))
|
||||
io.pads.jtag <> jtag_pins.io.pins
|
||||
sys.io.jtag.get <> jtag_pins.io.jtag
|
||||
// Override TRST to reset this logic IFF the core is in reset.
|
||||
// This will require 3 ticks of TCK before the debug logic
|
||||
// comes out of reset, but JTAG needs 5 ticks anyway.
|
||||
// This means that the "real" TRST is never actually used in this design.
|
||||
sys.io.jtag.get.TRST := ResetCatchAndSync(sys.io.jtag.get.TCK, async_corerst)
|
||||
|
||||
// AON Pads
|
||||
io.pads.aon <> sys.io.aon.pads
|
||||
}
|
52
src/main/scala/unleashed/u500vc707devkit/Config.scala
Normal file
52
src/main/scala/unleashed/u500vc707devkit/Config.scala
Normal file
@ -0,0 +1,52 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.unleashed.u500vc707devkit
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.coreplex._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.system._
|
||||
import freechips.rocketchip.tile._
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.uart._
|
||||
|
||||
// Default FreedomUVC707Config
|
||||
class FreedomUVC707Config extends Config(
|
||||
new WithJtagDTM ++
|
||||
new WithNMemoryChannels(1) ++
|
||||
new WithNBigCores(1) ++
|
||||
new BaseConfig
|
||||
)
|
||||
|
||||
// Freedom U500 VC707 Dev Kit Peripherals
|
||||
class U500VC707DevKitPeripherals extends Config((site, here, up) => {
|
||||
case PeripheryUARTKey => List(
|
||||
UARTParams(address = BigInt(0x54000000L)))
|
||||
case PeripherySPIKey => List(
|
||||
SPIParams(rAddress = BigInt(0x54001000L)))
|
||||
case PeripheryGPIOKey => List(
|
||||
GPIOParams(address = BigInt(0x54002000L), width = 4))
|
||||
case PeripheryMaskROMKey => List(
|
||||
MaskROMParams(address = 0x10000, name = "BootROM"))
|
||||
})
|
||||
|
||||
// Freedom U500 VC707 Dev Kit
|
||||
class U500VC707DevKitConfig extends Config(
|
||||
new WithoutFPU ++
|
||||
new WithNExtTopInterrupts(0) ++
|
||||
new U500VC707DevKitPeripherals ++
|
||||
new FreedomUVC707Config().alter((site,here,up) => {
|
||||
case ErrorParams => ErrorParams(Seq(AddressSet(0x3000, 0xfff)))
|
||||
case PeripheryBusParams => up(PeripheryBusParams, site).copy(frequency = 50000000) // 50 MHz hperiphery
|
||||
case DTSTimebase => BigInt(1000000)
|
||||
case ExtMem => up(ExtMem).copy(size = 0x40000000L)
|
||||
case JtagDTMKey => new JtagDTMConfig (
|
||||
idcodeVersion = 2, // 1 was legacy (FE310-G000, Acai).
|
||||
idcodePartNum = 0x000, // Decided to simplify.
|
||||
idcodeManufId = 0x489, // As Assigned by JEDEC to SiFive. Only used in wrappers / test harnesses.
|
||||
debugIdleCycles = 5) // Reasonable guess for synchronization
|
||||
})
|
||||
)
|
@ -1,28 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.unleashed.u500vc707devkit
|
||||
|
||||
import config._
|
||||
import coreplex.{WithL1DCacheWays, WithSmallCores, WithoutFPU, BootROMFile}
|
||||
import rocketchip.{BaseConfig,WithRTCPeriod,WithJtagDTM}
|
||||
|
||||
// Don't use directly. Requires additional bootfile configuration
|
||||
class DefaultFreedomUConfig extends Config(
|
||||
new WithJtagDTM ++ new BaseConfig
|
||||
)
|
||||
|
||||
class WithBootROMFile(bootROMFile: String) extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case BootROMFile => bootROMFile
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Freedom U500 VC707 Dev Kit
|
||||
|
||||
class U500VC707DevKitConfig extends Config(
|
||||
new WithBootROMFile("./bootrom/u500vc707devkit.img") ++
|
||||
new WithRTCPeriod(62) ++ //Default value of 100 generates 1 Mhz clock @ 100Mhz, then corrected in sbi_entry.c
|
||||
//Value 62 generates ~ 1Mhz clock @ 62.5Mhz
|
||||
new WithoutFPU ++
|
||||
new DefaultFreedomUConfig)
|
69
src/main/scala/unleashed/u500vc707devkit/FPGAChip.scala
Normal file
69
src/main/scala/unleashed/u500vc707devkit/FPGAChip.scala
Normal file
@ -0,0 +1,69 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.unleashed.u500vc707devkit
|
||||
|
||||
import Chisel._
|
||||
import chisel3.experimental.{withClockAndReset}
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.pinctrl.{BasePin}
|
||||
|
||||
import sifive.fpgashells.shell.xilinx.vc707shell.{VC707Shell}
|
||||
import sifive.fpgashells.ip.xilinx.{IOBUF}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// PinGen
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
object PinGen {
|
||||
def apply(): BasePin = {
|
||||
new BasePin()
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// U500VC707DevKitFPGAChip
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class U500VC707DevKitFPGAChip(implicit override val p: Parameters) extends VC707Shell {
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// DUT
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
// Connect the clock to the 50 Mhz output from the PLL
|
||||
dut_clock := clk50
|
||||
withClockAndReset(dut_clock, dut_reset) {
|
||||
val dut = Module(LazyModule(new U500VC707DevKitSystem).module)
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Connect peripherals
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
connectDebugJTAG(dut)
|
||||
connectSPI (dut)
|
||||
connectUART (dut)
|
||||
connectPCIe (dut)
|
||||
connectMIG (dut)
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// GPIO
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
val gpioParams = p(PeripheryGPIOKey)
|
||||
val gpio_pins = Wire(new GPIOPins(() => PinGen(), gpioParams(0)))
|
||||
|
||||
gpio_pins.fromPort(dut.gpio(0))
|
||||
|
||||
gpio_pins.pins.foreach { _.i.ival := Bool(false) }
|
||||
gpio_pins.pins.zipWithIndex.foreach {
|
||||
case(pin, idx) => led(idx) := pin.o.oval
|
||||
}
|
||||
|
||||
// tie to zero
|
||||
for( idx <- 7 to 4 ) { led(idx) := false.B }
|
||||
}
|
||||
|
||||
}
|
48
src/main/scala/unleashed/u500vc707devkit/System.scala
Normal file
48
src/main/scala/unleashed/u500vc707devkit/System.scala
Normal file
@ -0,0 +1,48 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.unleashed.u500vc707devkit
|
||||
|
||||
import Chisel._
|
||||
|
||||
import freechips.rocketchip.config._
|
||||
import freechips.rocketchip.coreplex._
|
||||
import freechips.rocketchip.devices.debug._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.system._
|
||||
|
||||
import sifive.blocks.devices.gpio._
|
||||
import sifive.blocks.devices.spi._
|
||||
import sifive.blocks.devices.uart._
|
||||
|
||||
import sifive.fpgashells.devices.xilinx.xilinxvc707mig._
|
||||
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1._
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// U500VC707DevKitSystem
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
class U500VC707DevKitSystem(implicit p: Parameters) extends RocketCoreplex
|
||||
with HasPeripheryMaskROMSlave
|
||||
with HasPeripheryDebug
|
||||
with HasSystemErrorSlave
|
||||
with HasPeripheryUART
|
||||
with HasPeripherySPI
|
||||
with HasPeripheryGPIO
|
||||
with HasMemoryXilinxVC707MIG
|
||||
with HasSystemXilinxVC707PCIeX1 {
|
||||
override lazy val module = new U500VC707DevKitSystemModule(this)
|
||||
}
|
||||
|
||||
class U500VC707DevKitSystemModule[+L <: U500VC707DevKitSystem](_outer: L)
|
||||
extends RocketCoreplexModule(_outer)
|
||||
with HasRTCModuleImp
|
||||
with HasPeripheryDebugModuleImp
|
||||
with HasPeripheryUARTModuleImp
|
||||
with HasPeripherySPIModuleImp
|
||||
with HasPeripheryGPIOModuleImp
|
||||
with HasMemoryXilinxVC707MIGModuleImp
|
||||
with HasSystemXilinxVC707PCIeX1ModuleImp {
|
||||
// Reset vector is set to the location of the mask rom
|
||||
val maskROMParams = p(PeripheryMaskROMKey)
|
||||
global_reset_vector := maskROMParams(0).address.U
|
||||
}
|
@ -1,299 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.unleashed.u500vc707devkit
|
||||
|
||||
import Chisel._
|
||||
import config._
|
||||
import util._
|
||||
import junctions._
|
||||
import diplomacy._
|
||||
import uncore.tilelink._
|
||||
import uncore.devices._
|
||||
import uncore.util._
|
||||
import uncore.converters._
|
||||
import rocket._
|
||||
import coreplex._
|
||||
import rocketchip._
|
||||
|
||||
import sifive.blocks.devices.xilinxvc707mig._
|
||||
import sifive.blocks.devices.xilinxvc707pciex1._
|
||||
import sifive.blocks.devices.gpio.{GPIOConfig, PeripheryGPIO, PeripheryGPIOBundle, PeripheryGPIOModule}
|
||||
import sifive.blocks.devices.spi.{SPIConfig, PeripherySPI, PeripherySPIBundle, PeripherySPIModule}
|
||||
import sifive.blocks.devices.uart._
|
||||
import sifive.blocks.util.ResetCatchAndSync
|
||||
|
||||
trait PeripheryConfigs {
|
||||
val uartConfigs = List(UARTConfig(address = BigInt(0x54000000L)))
|
||||
val spiConfigs = List(SPIConfig(rAddress = BigInt(0x54001000L)))
|
||||
val gpioConfig = GPIOConfig(address = BigInt(0x54002000L), width = 4)
|
||||
}
|
||||
|
||||
class U500VC707DevKitSystem(implicit p: Parameters) extends BaseTop
|
||||
with PeripheryConfigs
|
||||
with PeripheryBootROM
|
||||
with PeripheryDebug
|
||||
with PeripheryCounter
|
||||
with PeripheryUART
|
||||
with PeripherySPI
|
||||
with PeripheryGPIO
|
||||
with PeripheryXilinxVC707MIG
|
||||
with PeripheryXilinxVC707PCIeX1
|
||||
with HardwiredResetVector
|
||||
with RocketPlexMaster {
|
||||
override lazy val module = new U500VC707DevKitSystemModule(this, () => new U500VC707DevKitSystemBundle(this))
|
||||
|
||||
// scalastyle:off method.length
|
||||
ConfigStringOutput.contents = Some {
|
||||
"""platform {
|
||||
| vendor ucb;
|
||||
| arch spike;
|
||||
|};
|
||||
|plic {
|
||||
| interface "plic";
|
||||
| ndevs 9;
|
||||
| priority { mem { 0x0c000000 0x0c00ffff; }; };
|
||||
| pending { mem { 0x0c001000 0x0c00107f; }; };
|
||||
| 0 {
|
||||
| 0 {
|
||||
| m {
|
||||
| ie { mem { 0x0c002000 0x0c00207f; }; };
|
||||
| ctl { mem { 0x0c200000 0x0c200007; }; };
|
||||
| };
|
||||
| s {
|
||||
| ie { mem { 0x0c002080 0x0c0020ff; }; };
|
||||
| ctl { mem { 0x0c201000 0x0c201007; }; };
|
||||
| };
|
||||
| };
|
||||
| };
|
||||
|};
|
||||
|pcie {
|
||||
| interface "xilinx-pcie-rv";
|
||||
| bus {
|
||||
| mem { 0x60000000 0x7fffffff; } { 0x200000000 0x3ffffffff; };
|
||||
| bus { 1 63; };
|
||||
| };
|
||||
| bridge {
|
||||
| mem { 0x50000000 0x53ffffff; };
|
||||
| bus 0;
|
||||
| irq 6;
|
||||
| };
|
||||
|};
|
||||
|leds {
|
||||
| interface "gpio";
|
||||
| ngpio 4;
|
||||
| mem { 0x54002000 0x54002003; };
|
||||
|};
|
||||
|rtc {
|
||||
| addr 0x200bff8;
|
||||
|};
|
||||
|ram {
|
||||
| 0 {
|
||||
| addr 0x80000000;
|
||||
| size 0x10000000;
|
||||
| };
|
||||
|};
|
||||
|uart {
|
||||
| addr 0x54000000;
|
||||
|};
|
||||
|core {
|
||||
| 0 {
|
||||
| 0 {
|
||||
| isa rv64ima;
|
||||
| timecmp 0x02004000;
|
||||
| ipi 0x02000000;
|
||||
| };
|
||||
| };
|
||||
|};
|
||||
|\u0000""".stripMargin
|
||||
}
|
||||
// scalastyle:on method.length
|
||||
}
|
||||
|
||||
class U500VC707DevKitSystemBundle[+L <: U500VC707DevKitSystem](_outer: L) extends BaseTopBundle(_outer)
|
||||
with PeripheryConfigs
|
||||
with PeripheryBootROMBundle
|
||||
with PeripheryDebugBundle
|
||||
with PeripheryCounterBundle
|
||||
with PeripheryUARTBundle
|
||||
with PeripherySPIBundle
|
||||
with PeripheryGPIOBundle
|
||||
with PeripheryXilinxVC707MIGBundle
|
||||
with PeripheryXilinxVC707PCIeX1Bundle
|
||||
with HardwiredResetVectorBundle
|
||||
with RocketPlexMasterBundle
|
||||
|
||||
class U500VC707DevKitSystemModule[+L <: U500VC707DevKitSystem, +B <: U500VC707DevKitSystemBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io)
|
||||
with PeripheryConfigs
|
||||
with PeripheryBootROMModule
|
||||
with PeripheryDebugModule
|
||||
with PeripheryCounterModule
|
||||
with PeripheryUARTModule
|
||||
with PeripherySPIModule
|
||||
with PeripheryGPIOModule
|
||||
with PeripheryXilinxVC707MIGModule
|
||||
with PeripheryXilinxVC707PCIeX1Module
|
||||
with HardwiredResetVectorModule
|
||||
with RocketPlexMasterModule
|
||||
|
||||
/////
|
||||
|
||||
class ResetDone extends Module {
|
||||
//unused - in future io.resetdone can set rocketchip STOP_COND/PRINTF_COND
|
||||
val io = new Bundle{
|
||||
val reset = Bool(INPUT)
|
||||
val resetdone = Bool(OUTPUT)
|
||||
}
|
||||
val resetdonereg = Reg(init = Bool(false))
|
||||
val resetff = Reg(init = Bool(false))
|
||||
resetff := io.reset;
|
||||
resetdonereg := Mux( ((!io.reset)&&resetff), UInt("b1"), resetdonereg)
|
||||
io.resetdone := resetdonereg
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
class U500VC707DevKitIO(implicit val p: Parameters) extends Bundle
|
||||
with PeripheryConfigs
|
||||
with PeripheryUARTBundle
|
||||
with PeripherySPIBundle
|
||||
with PeripheryGPIOBundle
|
||||
{
|
||||
val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip)
|
||||
val jtag = p(IncludeJtagDTM).option(new JTAGIO(true).flip)
|
||||
//MIG
|
||||
val xilinxvc707mig = new XilinxVC707MIGPads
|
||||
//PCIe
|
||||
val xilinxvc707pcie = new XilinxVC707PCIeX1Pads
|
||||
//Clocks
|
||||
val sys_clk_n = Bool(INPUT)
|
||||
val sys_clk_p = Bool(INPUT)
|
||||
val pcie_refclk_p = Bool(INPUT)
|
||||
val pcie_refclk_n = Bool(INPUT)
|
||||
//Reset
|
||||
val sys_reset = Bool(INPUT)
|
||||
//Misc outputs used in system.v
|
||||
val core_reset = Bool(OUTPUT)
|
||||
val core_clock = Clock(OUTPUT)
|
||||
}
|
||||
|
||||
/////
|
||||
|
||||
class U500VC707DevKitTop(implicit val p: Parameters) extends Module {
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Instantiate U500 VC707 Dev Kit system (sys)
|
||||
// ------------------------------------------------------------
|
||||
val sys = Module(LazyModule(new U500VC707DevKitSystem).module)
|
||||
val io = new U500VC707DevKitIO
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Clock and Reset
|
||||
// ------------------------------------------------------------
|
||||
val mig_mmcm_locked = Wire(Bool())
|
||||
val mig_sys_reset = Wire(Bool())
|
||||
val init_calib_complete = Wire(Bool())
|
||||
val mmcm_lock_pcie = Wire(Bool())
|
||||
val do_reset = Wire(Bool())
|
||||
val mig_clock = Wire(Clock())
|
||||
val mig_resetn = Wire(Bool())
|
||||
val top_resetn = Wire(Bool())
|
||||
val pcie_dat_reset = Wire(Bool())
|
||||
val pcie_dat_resetn = Wire(Bool())
|
||||
val pcie_cfg_reset = Wire(Bool())
|
||||
val pcie_cfg_resetn = Wire(Bool())
|
||||
val pcie_dat_clock = Wire(Clock())
|
||||
val pcie_cfg_clock = Wire(Clock())
|
||||
val top_clock = Wire(Clock())
|
||||
val top_reset = Wire(Bool())
|
||||
val mig_reset = Wire(Bool())
|
||||
|
||||
do_reset := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset
|
||||
mig_resetn := !mig_reset
|
||||
top_resetn := !top_reset
|
||||
pcie_dat_resetn := !pcie_dat_reset
|
||||
pcie_cfg_resetn := !pcie_cfg_reset
|
||||
// For now, run the CPU synchronous to the PCIe data bus
|
||||
top_clock := pcie_dat_clock
|
||||
val safe_reset = Module(new vc707reset)
|
||||
safe_reset.io.areset := do_reset
|
||||
safe_reset.io.clock1 := mig_clock
|
||||
mig_reset := safe_reset.io.reset1
|
||||
safe_reset.io.clock2 := pcie_dat_clock
|
||||
pcie_dat_reset := safe_reset.io.reset2
|
||||
safe_reset.io.clock3 := pcie_cfg_clock
|
||||
pcie_cfg_reset := safe_reset.io.reset3
|
||||
safe_reset.io.clock4 := top_clock
|
||||
top_reset := safe_reset.io.reset4
|
||||
|
||||
sys.clock := top_clock
|
||||
sys.reset := top_reset
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// UART
|
||||
// ------------------------------------------------------------
|
||||
io.uarts <> sys.io.uarts
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// SPI
|
||||
// ------------------------------------------------------------
|
||||
io.spis <> sys.io.spis
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// GPIO
|
||||
// ------------------------------------------------------------
|
||||
io.gpio <> sys.io.gpio
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// MIG
|
||||
// ------------------------------------------------------------
|
||||
sys.io.xilinxvc707mig.sys_clk_p := io.sys_clk_p
|
||||
sys.io.xilinxvc707mig.sys_clk_n := io.sys_clk_n
|
||||
mig_clock := sys.io.xilinxvc707mig.ui_clk
|
||||
mig_sys_reset := sys.io.xilinxvc707mig.ui_clk_sync_rst
|
||||
mig_mmcm_locked := sys.io.xilinxvc707mig.mmcm_locked
|
||||
sys.io.xilinxvc707mig.aresetn := mig_resetn
|
||||
init_calib_complete := sys.io.xilinxvc707mig.init_calib_complete
|
||||
sys.io.xilinxvc707mig.sys_rst := io.sys_reset
|
||||
//the below bundle assignment is dangerous and relies on matching signal names
|
||||
// io.xilinxvc707 is of type XilinxVC707MIGPads
|
||||
// sys.io.xilinxvc707mig is of type XilinxVC707MIGIO
|
||||
io.xilinxvc707mig <> sys.io.xilinxvc707mig
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// PCIe
|
||||
// ------------------------------------------------------------
|
||||
sys.io.xilinxvc707pcie.axi_aresetn := pcie_dat_resetn
|
||||
pcie_dat_clock := sys.io.xilinxvc707pcie.axi_aclk_out
|
||||
pcie_cfg_clock := sys.io.xilinxvc707pcie.axi_ctl_aclk_out
|
||||
mmcm_lock_pcie := sys.io.xilinxvc707pcie.mmcm_lock
|
||||
sys.io.xilinxvc707pcie.axi_ctl_aresetn := pcie_dat_resetn
|
||||
sys.io.xilinxvc707pcie.REFCLK_rxp := io.pcie_refclk_p
|
||||
sys.io.xilinxvc707pcie.REFCLK_rxn := io.pcie_refclk_n
|
||||
//another dangerous bundle assignment which relies on matching signal names
|
||||
// io.xilinxvc707pcie is of type XilinxVC707PCIeX1Pads
|
||||
// sys.io.xilinxvc707pcie is of type XilinxVC707PCIeX1IO
|
||||
io.xilinxvc707pcie <> sys.io.xilinxvc707pcie
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Debug
|
||||
// ------------------------------------------------------------
|
||||
if (p(IncludeJtagDTM)) {
|
||||
sys.io.jtag.get <> io.jtag.get
|
||||
//Override TRST to reset this logic IFF the core is in reset.
|
||||
// This will require 3 ticks of TCK before the debug logic
|
||||
// comes out of reset, but JTAG needs 5 ticks anyway.
|
||||
// This means that the "real" TRST is never actually used.
|
||||
sys.io.jtag.get.TRST := ResetCatchAndSync(sys.io.jtag.get.TCK, top_reset)
|
||||
}else{
|
||||
// SimDTM; only for simulation use
|
||||
sys.io.debug.get := io.debug.get
|
||||
// test_mode_clk shouldn't be used for simulation
|
||||
//sys.io.test_mode_clk := Bool(false).asClock
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Misc outputs used in system.v
|
||||
// ------------------------------------------------------------
|
||||
io.core_clock := top_clock
|
||||
io.core_reset := top_reset
|
||||
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
package sifive.freedom.unleashed.u500vc707devkit
|
||||
|
||||
import Chisel._
|
||||
|
||||
//scalastyle:off
|
||||
//turn off linter: blackbox name must match verilog module
|
||||
class vc707reset() extends BlackBox
|
||||
{
|
||||
val io = new Bundle{
|
||||
val areset = Bool(INPUT)
|
||||
val clock1 = Clock(INPUT)
|
||||
val reset1 = Bool(OUTPUT)
|
||||
val clock2 = Clock(INPUT)
|
||||
val reset2 = Bool(OUTPUT)
|
||||
val clock3 = Clock(INPUT)
|
||||
val reset3 = Bool(OUTPUT)
|
||||
val clock4 = Clock(INPUT)
|
||||
val reset4 = Bool(OUTPUT)
|
||||
}
|
||||
}
|
||||
//scalastyle:on
|
Reference in New Issue
Block a user