Add initial ML507Shell stub based on VC707Shell
This commit is contained in:
		| @@ -94,6 +94,14 @@ object PowerOnResetFPGAOnly { | |||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // ML507 clock generation | ||||||
|  | class ml507_sys_clock extends BlackBox { | ||||||
|  |   val io = new Bundle { | ||||||
|  |     val CLKIN_IN  = Bool(INPUT) | ||||||
|  |     val CLKFX_OUT = Clock(OUTPUT) | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
| //------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||||
| // vc707_sys_clock_mmcm | // vc707_sys_clock_mmcm | ||||||
| //------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||||
|   | |||||||
							
								
								
									
										275
									
								
								src/main/scala/shell/xilinx/ML507Shell.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										275
									
								
								src/main/scala/shell/xilinx/ML507Shell.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,275 @@ | |||||||
|  | // 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 = { | ||||||
|  |  | ||||||
|  |     ElaborationArtefacts.add( | ||||||
|  |     """debugjtag.vivado.tcl""", | ||||||
|  |     """set vc707debugjtag_vivado_tcl_dir [file dirname [file normalize [info script]]] | ||||||
|  |        add_files -fileset [current_fileset -constrset] [glob -directory $vc707debugjtag_vivado_tcl_dir {*.vc707debugjtag.xdc}]""" | ||||||
|  |     ) | ||||||
|  |  | ||||||
|  |     if(fmcxm105) { | ||||||
|  |       //VC707 constraints for Xilinx FMC XM105 Debug Card | ||||||
|  |       ElaborationArtefacts.add( | ||||||
|  |         """vc707debugjtag.xdc""", | ||||||
|  |         """set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_TCK_IBUF] | ||||||
|  |            set_property -dict { PACKAGE_PIN R32  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TCK}] | ||||||
|  |            set_property -dict { PACKAGE_PIN W36  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TMS}] | ||||||
|  |            set_property -dict { PACKAGE_PIN W37  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TDI}] | ||||||
|  |            set_property -dict { PACKAGE_PIN V40  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TDO}] """ | ||||||
|  |       ) | ||||||
|  |     } else { | ||||||
|  |       //VC707 constraints for Olimex connect to LCD panel header | ||||||
|  |      ElaborationArtefacts.add( | ||||||
|  |         """vc707debugjtag.xdc""", | ||||||
|  |         """ | ||||||
|  |            #Olimex Pin  Olimex Function LCD Pin LCD Function FPGA Pin | ||||||
|  |            #1           VREF            14      5V | ||||||
|  |            #3           TTRST_N         1       LCD_DB7       AN40 | ||||||
|  |            #5           TTDI            2       LCD_DB6       AR39 | ||||||
|  |            #7           TTMS            3       LCD_DB5       AR38 | ||||||
|  |            #9           TTCK            4       LCD_DB4       AT42 | ||||||
|  |            #11          TRTCK           NC      NC            NC | ||||||
|  |            #13          TTDO            9       LCD_E         AT40 | ||||||
|  |            #15          TSRST_N         10      LCD_RW        AR42 | ||||||
|  |            #2           VREF            14      5V | ||||||
|  |            #18          GND             13      GND | ||||||
|  |            set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_TCK_IBUF] | ||||||
|  |            set_property -dict { PACKAGE_PIN AT42  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TCK}] | ||||||
|  |            set_property -dict { PACKAGE_PIN AR38  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TMS}] | ||||||
|  |            set_property -dict { PACKAGE_PIN AR39  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TDI}] | ||||||
|  |            set_property -dict { PACKAGE_PIN AT40  IOSTANDARD LVCMOS18  PULLUP TRUE } [get_ports {jtag_TDO}] """ | ||||||
|  |       ) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     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())) | ||||||
|  |  | ||||||
|  |   // LED | ||||||
|  |   val led                  = IO(Vec(8, Output(Bool()))) | ||||||
|  |  | ||||||
|  |   // UART | ||||||
|  |   val uart_tx              = IO(Output(Bool())) | ||||||
|  |   val uart_rx              = IO(Input(Bool())) | ||||||
|  |   val uart_rtsn            = IO(Output(Bool())) | ||||||
|  |   val uart_ctsn            = 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(Analog(1.W)) | ||||||
|  |   val btn_1                = IO(Analog(1.W)) | ||||||
|  |   val btn_2                = IO(Analog(1.W)) | ||||||
|  |   val btn_3                = 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)) | ||||||
|  |   val sw_4                 = IO(Analog(1.W)) | ||||||
|  |   val sw_5                 = IO(Analog(1.W)) | ||||||
|  |   val sw_6                 = IO(Analog(1.W)) | ||||||
|  |   val sw_7                 = IO(Analog(1.W)) | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   //----------------------------------------------------------------------- | ||||||
|  |   // Wire declrations | ||||||
|  |   //----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |   val sys_clock       = Wire(Clock()) | ||||||
|  |   val sys_reset       = Wire(Bool()) | ||||||
|  |  | ||||||
|  |   val dut_clock       = Wire(Clock()) | ||||||
|  |   val dut_reset       = Wire(Bool()) | ||||||
|  |   val dut_resetn      = 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 mig_mmcm_locked = Wire(Bool()) | ||||||
|  |   val mig_sys_reset   = Wire(Bool()) | ||||||
|  |  | ||||||
|  |   val mig_clock       = Wire(Clock()) | ||||||
|  |   val mig_reset       = Wire(Bool()) | ||||||
|  |   val mig_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 mmcm_lock_pcie  = 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 | ||||||
|  |  | ||||||
|  |   //----------------------------------------------------------------------- | ||||||
|  |   // 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 | ||||||
|  |  | ||||||
|  |   // DUT clock | ||||||
|  |   dut_clock := clk50 | ||||||
|  |  | ||||||
|  |   //----------------------------------------------------------------------- | ||||||
|  |   // System reset | ||||||
|  |   //----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |   do_reset             := !mig_mmcm_locked || !mmcm_lock_pcie || mig_sys_reset | ||||||
|  |   mig_resetn           := !mig_reset | ||||||
|  |   dut_resetn           := !dut_reset | ||||||
|  |   pcie_dat_resetn      := !pcie_dat_reset | ||||||
|  |   pcie_cfg_resetn      := !pcie_cfg_reset | ||||||
|  |  | ||||||
|  |   // TODO: adapt for ml507? | ||||||
|  |   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 := dut_clock | ||||||
|  |   dut_reset            := safe_reset.io.reset4 | ||||||
|  |  | ||||||
|  |   //overrided in connectMIG and connect PCIe | ||||||
|  |   //provide defaults to allow above reset sequencing logic to work without both | ||||||
|  |   mig_clock            := dut_clock | ||||||
|  |   pcie_dat_clock       := dut_clock | ||||||
|  |   pcie_cfg_clock       := dut_clock | ||||||
|  |   mig_mmcm_locked      := UInt("b1") | ||||||
|  |   mmcm_lock_pcie       := UInt("b1") | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |   //----------------------------------------------------------------------- | ||||||
|  |   // UART | ||||||
|  |   //----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |   uart_rtsn := false.B | ||||||
|  |  | ||||||
|  |   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 | ||||||
|  |   } | ||||||
|  |  | ||||||
|  | } | ||||||
		Reference in New Issue
	
	Block a user