// 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) } } }