package chipyard.fpga.arty100t import chisel3._ import chisel3.util._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.config.{Parameters} import freechips.rocketchip.tilelink.{TLClientNode, TLBlockDuringReset} import sifive.fpgashells.shell.xilinx._ import sifive.fpgashells.shell._ import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler} import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly} import sifive.blocks.devices.uart._ import chipyard._ import chipyard.harness.{ApplyHarnessBinders} import chipyard.iobinders.{HasIOBinders} class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell with HasHarnessSignalReferences { def dp = designParameters val chiptop = LazyModule(p(BuildTop)(p)) val clockOverlay = dp(ClockInputOverlayKey).map(_.place(ClockInputDesignInput())).head val harnessSysPLL = dp(PLLFactoryKey) val harnessSysPLLNode = harnessSysPLL() println(s"Arty100T FPGA Base Clock Freq: ${dp(DefaultClockFrequencyKey)} MHz") val dutClock = ClockSinkNode(freqMHz = dp(DefaultClockFrequencyKey)) val dutWrangler = LazyModule(new ResetWrangler()) val dutGroup = ClockGroup() dutClock := dutWrangler.node := dutGroup := harnessSysPLLNode harnessSysPLLNode := clockOverlay.overlayOutput.node val io_uart_bb = BundleBridgeSource(() => new UARTPortIO(dp(PeripheryUARTKey).headOption.getOrElse(UARTParams(0)))) val uartOverlay = dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb)) val ddrOverlay = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRArtyPlacedOverlay] val ddrInParams = chiptop match { case td: ChipTop => td.lazySystem match { case lsys: CanHaveMasterTLMemPort => lsys.memTLNode.edges.in(0) } } val ddrClient = TLClientNode(Seq(ddrInParams.master)) val ddrBlockDuringReset = LazyModule(new TLBlockDuringReset(4)) ddrOverlay.overlayOutput.ddr := ddrBlockDuringReset.node := ddrClient val ledOverlays = dp(LEDOverlayKey).map(_.place(LEDDesignInput())) val all_leds = ledOverlays.map(_.overlayOutput.led) val status_leds = all_leds.take(3) val other_leds = all_leds.drop(3) def buildtopClock = dutClock.in.head._1.clock def buildtopReset = dutClock.in.head._1.reset def success = { require(false, "Unused"); false.B } InModuleBody { clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin val clk_100mhz = clockOverlay.overlayOutput.node.out.head._1.clock // Blink the status LEDs for sanity withClock(clk_100mhz) { val period = (BigInt(100) << 20) / status_leds.size val counter = RegInit(0.U(log2Ceil(period).W)) val on = RegInit(0.U(log2Ceil(status_leds.size).W)) status_leds.zipWithIndex.map { case (o,s) => o := on === s.U } counter := Mux(counter === (period-1).U, 0.U, counter + 1.U) when (counter === 0.U) { on := Mux(on === (status_leds.size-1).U, 0.U, on + 1.U) } } other_leds(0) := resetPin harnessSysPLL.plls.foreach(_._1.getReset.get := pllReset) ddrOverlay.mig.module.clock := buildtopClock ddrOverlay.mig.module.reset := buildtopReset ddrBlockDuringReset.module.clock := buildtopClock ddrBlockDuringReset.module.reset := buildtopReset || !ddrOverlay.mig.module.io.port.init_calib_complete other_leds(6) := ddrOverlay.mig.module.io.port.init_calib_complete chiptop match { case d: HasIOBinders => ApplyHarnessBinders(this, d.lazySystem, d.portMap) } } }