// See LICENSE for license details. package sifive.fpgashells.shell.xilinx.ml507shell import Chisel._ import chisel3.core.{Input, Output, attach} import chisel3.experimental.{RawModule, Analog, withClockAndReset} import freechips.rocketchip.config._ import freechips.rocketchip.devices.debug._ import freechips.rocketchip.util.{SyncResetSynchronizerShiftReg, ElaborationArtefacts, HeterogeneousBag} import sifive.blocks.devices.gpio._ import sifive.blocks.devices.spi._ import sifive.blocks.devices.uart._ import sifive.blocks.devices.chiplink._ import sifive.fpgashells.ip.xilinx.{IBUFDS, PowerOnResetFPGAOnly, sdio_spi_bridge, ml507_sys_clock , vc707reset} //------------------------------------------------------------------------- // ML507Shell //------------------------------------------------------------------------- // TODO: trait HasDDR2 { … } trait HasDebugJTAG { this: ML507Shell => // JTAG val jtag_TCK = IO(Input(Clock())) val jtag_TMS = IO(Input(Bool())) val jtag_TDI = IO(Input(Bool())) val jtag_TDO = IO(Output(Bool())) def connectDebugJTAG(dut: HasPeripheryDebugModuleImp, fmcxm105: Boolean = true): SystemJTAGIO = { val djtag = dut.debug.systemjtag.get djtag.jtag.TCK := jtag_TCK djtag.jtag.TMS := jtag_TMS djtag.jtag.TDI := jtag_TDI jtag_TDO := djtag.jtag.TDO.data djtag.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W) djtag.reset := PowerOnResetFPGAOnly(dut_clock) dut_ndreset := dut.debug.ndreset djtag } } abstract class ML507Shell(implicit val p: Parameters) extends RawModule { //----------------------------------------------------------------------- // Interface //----------------------------------------------------------------------- // 100Mhz sysclk val sys_clock_100 = IO(Input(Bool())) // active high reset val reset = IO(Input(Bool())) val reset_led = IO(Output(Bool())) // LED val led = IO(Vec(8, Output(Bool()))) // UART val uart_tx = IO(Output(Bool())) val uart_rx = IO(Input(Bool())) // SDIO val sdio_clk = IO(Output(Bool())) val sdio_cmd = IO(Analog(1.W)) val sdio_dat = IO(Analog(4.W)) //Buttons val btn_0 = IO(Input(Bool())) val btn_1 = IO(Input(Bool())) val btn_2 = IO(Input(Bool())) val btn_3 = IO(Input(Bool())) //Sliding switches val sw_0 = IO(Input(Bool())) val sw_1 = IO(Input(Bool())) val sw_2 = IO(Input(Bool())) val sw_3 = IO(Input(Bool())) val sw_4 = IO(Input(Bool())) val sw_5 = IO(Input(Bool())) val sw_6 = IO(Input(Bool())) val sw_7 = IO(Input(Bool())) //----------------------------------------------------------------------- // Wire declrations //----------------------------------------------------------------------- val sys_clock = Wire(Clock()) val sys_reset = Wire(Bool()) val dut_clock = Wire(Clock()) val dut_reset = Wire(Bool()) val dut_ndreset = Wire(Bool()) val sd_spi_sck = Wire(Bool()) val sd_spi_cs = Wire(Bool()) val sd_spi_dq_i = Wire(Vec(4, Bool())) val sd_spi_dq_o = Wire(Vec(4, Bool())) val do_reset = Wire(Bool()) val clk_locked = Wire(Bool()) //----------------------------------------------------------------------- // System clock and reset //----------------------------------------------------------------------- // Clock that drives the clock generator and the MIG sys_clock := sys_clock_100.asClock() // Allow the debug module to reset everything. Resets the MIG sys_reset := reset | dut_ndreset // Status LED for reset reset_led := reset //----------------------------------------------------------------------- // Clock Generator //----------------------------------------------------------------------- //50MHz (37.5MHz) val ml507_sys_clock = Module(new ml507_sys_clock) ml507_sys_clock.io.CLKIN_IN := sys_clock.asUInt val clk50 = ml507_sys_clock.io.CLKFX_OUT clk_locked := ml507_sys_clock.io.LOCKED_OUT // DUT clock dut_clock := clk50 //----------------------------------------------------------------------- // System reset //----------------------------------------------------------------------- do_reset := !clk_locked || sys_reset // TODO: adapt for ml507? val safe_reset = Module(new vc707reset) safe_reset.io.areset := do_reset safe_reset.io.clock1 := dut_clock safe_reset.io.clock2 := dut_clock safe_reset.io.clock3 := dut_clock safe_reset.io.clock4 := dut_clock dut_reset := safe_reset.io.reset4 //----------------------------------------------------------------------- // UART //----------------------------------------------------------------------- def connectUART(dut: HasPeripheryUARTModuleImp): Unit = { val uartParams = p(PeripheryUARTKey) if (!uartParams.isEmpty) { // uart connections dut.uart(0).rxd := SyncResetSynchronizerShiftReg(uart_rx, 2, init = Bool(true), name=Some("uart_rxd_sync")) uart_tx := dut.uart(0).txd } } //----------------------------------------------------------------------- // SPI //----------------------------------------------------------------------- def connectSPI(dut: HasPeripherySPIModuleImp): Unit = { // SPI sd_spi_sck := dut.spi(0).sck sd_spi_cs := dut.spi(0).cs(0) dut.spi(0).dq.zipWithIndex.foreach { case(pin, idx) => sd_spi_dq_o(idx) := pin.o pin.i := sd_spi_dq_i(idx) } //------------------------------------------------------------------- // SDIO <> SPI Bridge //------------------------------------------------------------------- val ip_sdio_spi = Module(new sdio_spi_bridge()) ip_sdio_spi.io.clk := dut_clock ip_sdio_spi.io.reset := dut_reset // SDIO attach(sdio_dat, ip_sdio_spi.io.sd_dat) attach(sdio_cmd, ip_sdio_spi.io.sd_cmd) sdio_clk := ip_sdio_spi.io.spi_sck // SPI ip_sdio_spi.io.spi_sck := sd_spi_sck ip_sdio_spi.io.spi_cs := sd_spi_cs sd_spi_dq_i := ip_sdio_spi.io.spi_dq_i.toBools ip_sdio_spi.io.spi_dq_o := sd_spi_dq_o.asUInt } }