248 lines
7.7 KiB
Scala
248 lines
7.7 KiB
Scala
// See LICENSE for license details.
|
|
package sifive.fpgashells.shell.xilinx.artyshell
|
|
|
|
import Chisel._
|
|
import chisel3.core.{Input, Output, attach}
|
|
import chisel3.experimental.{RawModule, Analog, withClockAndReset}
|
|
|
|
import freechips.rocketchip.config._
|
|
import freechips.rocketchip.devices.debug._
|
|
|
|
import sifive.blocks.devices.gpio._
|
|
import sifive.blocks.devices.pwm._
|
|
import sifive.blocks.devices.spi._
|
|
import sifive.blocks.devices.uart._
|
|
import sifive.blocks.devices.pinctrl.{BasePin}
|
|
|
|
import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, mmcm, reset_sys, PowerOnResetFPGAOnly}
|
|
|
|
//-------------------------------------------------------------------------
|
|
// ArtyShell
|
|
//-------------------------------------------------------------------------
|
|
|
|
abstract class ArtyShell(implicit val p: Parameters) extends RawModule {
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Interface
|
|
//-----------------------------------------------------------------------
|
|
|
|
// Clock & Reset
|
|
val CLK100MHZ = IO(Input(Clock()))
|
|
val ck_rst = IO(Input(Bool()))
|
|
|
|
// Green LEDs
|
|
val led_0 = IO(Analog(1.W))
|
|
val led_1 = IO(Analog(1.W))
|
|
val led_2 = IO(Analog(1.W))
|
|
val led_3 = IO(Analog(1.W))
|
|
|
|
// RGB LEDs, 3 pins each
|
|
val led0_r = IO(Analog(1.W))
|
|
val led0_g = IO(Analog(1.W))
|
|
val led0_b = IO(Analog(1.W))
|
|
|
|
val led1_r = IO(Analog(1.W))
|
|
val led1_g = IO(Analog(1.W))
|
|
val led1_b = IO(Analog(1.W))
|
|
|
|
val led2_r = IO(Analog(1.W))
|
|
val led2_g = IO(Analog(1.W))
|
|
val led2_b = IO(Analog(1.W))
|
|
|
|
// Sliding switches
|
|
val sw_0 = IO(Analog(1.W))
|
|
val sw_1 = IO(Analog(1.W))
|
|
val sw_2 = IO(Analog(1.W))
|
|
val sw_3 = IO(Analog(1.W))
|
|
|
|
// Buttons. First 3 used as GPIO, the last is used as wakeup
|
|
val btn_0 = IO(Analog(1.W))
|
|
val btn_1 = IO(Analog(1.W))
|
|
val btn_2 = IO(Analog(1.W))
|
|
val btn_3 = IO(Analog(1.W))
|
|
|
|
// Dedicated QSPI interface
|
|
val qspi_cs = IO(Analog(1.W))
|
|
val qspi_sck = IO(Analog(1.W))
|
|
val qspi_dq = IO(Vec(4, Analog(1.W)))
|
|
|
|
// UART0
|
|
val uart_rxd_out = IO(Analog(1.W))
|
|
val uart_txd_in = IO(Analog(1.W))
|
|
|
|
// JA (Used for more generic GPIOs)
|
|
val ja_0 = IO(Analog(1.W))
|
|
val ja_1 = IO(Analog(1.W))
|
|
val ja_2 = IO(Analog(1.W))
|
|
val ja_3 = IO(Analog(1.W))
|
|
val ja_4 = IO(Analog(1.W))
|
|
val ja_5 = IO(Analog(1.W))
|
|
val ja_6 = IO(Analog(1.W))
|
|
val ja_7 = IO(Analog(1.W))
|
|
|
|
// JD (used for JTAG connection)
|
|
val jd_0 = IO(Analog(1.W)) // TDO
|
|
val jd_1 = IO(Analog(1.W)) // TRST_n
|
|
val jd_2 = IO(Analog(1.W)) // TCK
|
|
val jd_4 = IO(Analog(1.W)) // TDI
|
|
val jd_5 = IO(Analog(1.W)) // TMS
|
|
val jd_6 = IO(Analog(1.W)) // SRST_n
|
|
|
|
// ChipKit Digital I/O Pins
|
|
val ck_io = IO(Vec(20, Analog(1.W)))
|
|
|
|
// ChipKit SPI
|
|
val ck_miso = IO(Analog(1.W))
|
|
val ck_mosi = IO(Analog(1.W))
|
|
val ck_ss = IO(Analog(1.W))
|
|
val ck_sck = IO(Analog(1.W))
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Wire declrations
|
|
//-----------------------------------------------------------------------
|
|
|
|
// Note: these frequencies are approximate.
|
|
val clock_8MHz = Wire(Clock())
|
|
val clock_32MHz = Wire(Clock())
|
|
val clock_65MHz = Wire(Clock())
|
|
|
|
val mmcm_locked = Wire(Bool())
|
|
|
|
val reset_core = Wire(Bool())
|
|
val reset_bus = Wire(Bool())
|
|
val reset_periph = Wire(Bool())
|
|
val reset_intcon_n = Wire(Bool())
|
|
val reset_periph_n = Wire(Bool())
|
|
|
|
val SRST_n = Wire(Bool())
|
|
|
|
val dut_jtag_TCK = Wire(Clock())
|
|
val dut_jtag_TMS = Wire(Bool())
|
|
val dut_jtag_TDI = Wire(Bool())
|
|
val dut_jtag_TDO = Wire(Bool())
|
|
val dut_jtag_reset = Wire(Bool())
|
|
val dut_ndreset = Wire(Bool())
|
|
|
|
//-----------------------------------------------------------------------
|
|
// Clock Generator
|
|
//-----------------------------------------------------------------------
|
|
// Mixed-mode clock generator
|
|
|
|
val ip_mmcm = Module(new mmcm())
|
|
|
|
ip_mmcm.io.clk_in1 := CLK100MHZ
|
|
clock_8MHz := ip_mmcm.io.clk_out1 // 8.388 MHz = 32.768 kHz * 256
|
|
clock_65MHz := ip_mmcm.io.clk_out2 // 65 Mhz
|
|
clock_32MHz := ip_mmcm.io.clk_out3 // 65/2 Mhz
|
|
ip_mmcm.io.resetn := ck_rst
|
|
mmcm_locked := ip_mmcm.io.locked
|
|
|
|
//-----------------------------------------------------------------------
|
|
// System Reset
|
|
//-----------------------------------------------------------------------
|
|
// processor system reset module
|
|
|
|
val ip_reset_sys = Module(new reset_sys())
|
|
|
|
ip_reset_sys.io.slowest_sync_clk := clock_8MHz
|
|
ip_reset_sys.io.ext_reset_in := ck_rst & SRST_n
|
|
ip_reset_sys.io.aux_reset_in := true.B
|
|
ip_reset_sys.io.mb_debug_sys_rst := dut_ndreset
|
|
ip_reset_sys.io.dcm_locked := mmcm_locked
|
|
|
|
reset_core := ip_reset_sys.io.mb_reset
|
|
reset_bus := ip_reset_sys.io.bus_struct_reset
|
|
reset_periph := ip_reset_sys.io.peripheral_reset
|
|
reset_intcon_n := ip_reset_sys.io.interconnect_aresetn
|
|
reset_periph_n := ip_reset_sys.io.peripheral_aresetn
|
|
|
|
//-----------------------------------------------------------------------
|
|
// SPI Flash
|
|
//-----------------------------------------------------------------------
|
|
|
|
def connectSPIFlash(dut: HasPeripherySPIFlashModuleImp): Unit = {
|
|
val qspiParams = p(PeripherySPIFlashKey)
|
|
if (!qspiParams.isEmpty) {
|
|
val qspi_params = qspiParams(0)
|
|
val qspi_pins = Wire(new SPIPins(() => {new BasePin()}, qspi_params))
|
|
|
|
qspi_pins.fromPort(
|
|
dut.qspi(0),
|
|
dut.clock,
|
|
dut.reset,
|
|
syncStages = qspi_params.sampleDelay
|
|
)
|
|
|
|
IOBUF(qspi_sck, dut.qspi(0).sck)
|
|
IOBUF(qspi_cs, dut.qspi(0).cs(0))
|
|
|
|
(qspi_dq zip qspi_pins.dq).foreach {
|
|
case(a, b) => IOBUF(a,b)
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// Debug JTAG
|
|
//---------------------------------------------------------------------
|
|
|
|
def connectDebugJTAG(dut: HasPeripheryDebugModuleImp): SystemJTAGIO = {
|
|
|
|
//-------------------------------------------------------------------
|
|
// JTAG Reset
|
|
//-------------------------------------------------------------------
|
|
|
|
val jtag_power_on_reset = PowerOnResetFPGAOnly(clock_32MHz)
|
|
|
|
dut_jtag_reset := jtag_power_on_reset
|
|
|
|
//-------------------------------------------------------------------
|
|
// JTAG IOBUFs
|
|
//-------------------------------------------------------------------
|
|
|
|
dut_jtag_TCK := IBUFG(IOBUF(jd_2).asClock)
|
|
|
|
dut_jtag_TMS := IOBUF(jd_5)
|
|
PULLUP(jd_5)
|
|
|
|
dut_jtag_TDI := IOBUF(jd_4)
|
|
PULLUP(jd_4)
|
|
|
|
IOBUF(jd_0, dut_jtag_TDO)
|
|
|
|
SRST_n := IOBUF(jd_6)
|
|
PULLUP(jd_6)
|
|
|
|
//-------------------------------------------------------------------
|
|
// JTAG PINS
|
|
//-------------------------------------------------------------------
|
|
|
|
val djtag = dut.debug.systemjtag.get
|
|
|
|
djtag.jtag.TCK := dut_jtag_TCK
|
|
djtag.jtag.TMS := dut_jtag_TMS
|
|
djtag.jtag.TDI := dut_jtag_TDI
|
|
dut_jtag_TDO := djtag.jtag.TDO.data
|
|
|
|
djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W)
|
|
|
|
djtag.reset := dut_jtag_reset
|
|
dut_ndreset := dut.debug.ndreset
|
|
|
|
djtag
|
|
}
|
|
|
|
//---------------------------------------------------------------------
|
|
// UART
|
|
//---------------------------------------------------------------------
|
|
|
|
def connectUART(dut: HasPeripheryUARTModuleImp): Unit = {
|
|
val uartParams = p(PeripheryUARTKey)
|
|
if (!uartParams.isEmpty) {
|
|
IOBUF(uart_rxd_out, dut.uart(0).txd)
|
|
dut.uart(0).rxd := IOBUF(uart_txd_in)
|
|
}
|
|
}
|
|
|
|
}
|