diff --git a/uncore/src/main/scala/htif.scala b/uncore/src/main/scala/htif.scala index d162be98..360eaebb 100644 --- a/uncore/src/main/scala/htif.scala +++ b/uncore/src/main/scala/htif.scala @@ -4,7 +4,7 @@ package uncore import Chisel._ import Chisel.ImplicitConversions._ -import uncore._ +import junctions.{SMIIO, MMIOBase} case object HTIFWidth extends Field[Int] case object HTIFNSCR extends Field[Int] @@ -31,18 +31,10 @@ class HostIO extends HTIFBundle val debug_stats_pcr = Bool(OUTPUT) } -class PCRReq extends Bundle -{ - val rw = Bool() - val addr = Bits(width = 12) - val data = Bits(width = 64) -} - class HTIFIO extends HTIFBundle { val reset = Bool(INPUT) val id = UInt(INPUT, log2Up(nCores)) - val pcr_req = Decoupled(new PCRReq).flip - val pcr_rep = Decoupled(Bits(width = 64)) + val pcr = new SMIIO(64, 12).flip val ipi_req = Decoupled(Bits(width = log2Up(nCores))) val ipi_rep = Decoupled(Bool()).flip val debug_stats_pcr = Bool(OUTPUT) @@ -106,7 +98,7 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters { val cmd_readmem :: cmd_writemem :: cmd_readcr :: cmd_writecr :: cmd_ack :: cmd_nack :: Nil = Enum(UInt(), 6) - val pcr_addr = addr(io.cpu(0).pcr_req.bits.addr.getWidth-1, 0) + val pcr_addr = addr(io.cpu(0).pcr.req.bits.addr.getWidth-1, 0) val pcr_coreid = addr(log2Up(nCores)-1+20+1,20) val pcr_wdata = packet_ram(0) @@ -184,39 +176,19 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters { GetBlock(addr_block = init_addr)) io.mem.grant.ready := Bool(true) - // real-time counter (which doesn't really belong here...) - val rtc = Reg(init=UInt(0,64)) - val rtc_tick = Counter(params(RTCPeriod)).inc() - when (rtc_tick) { rtc := rtc + UInt(1) } - - val pcrReadData = Reg(Bits(width = io.cpu(0).pcr_rep.bits.getWidth)) + val pcrReadData = Reg(Bits(width = io.cpu(0).pcr.resp.bits.getWidth)) for (i <- 0 until nCores) { val my_reset = Reg(init=Bool(true)) val my_ipi = Reg(init=Bool(false)) val cpu = io.cpu(i) val me = pcr_coreid === UInt(i) - cpu.pcr_req.valid := state === state_pcr_req && me && pcr_addr != UInt(pcr_RESET) - cpu.pcr_req.bits.rw := cmd === cmd_writecr - cpu.pcr_req.bits.addr := pcr_addr - cpu.pcr_req.bits.data := pcr_wdata + cpu.pcr.req.valid := state === state_pcr_req && me && pcr_addr != UInt(pcr_RESET) + cpu.pcr.req.bits.rw := cmd === cmd_writecr + cpu.pcr.req.bits.addr := pcr_addr + cpu.pcr.req.bits.data := pcr_wdata cpu.reset := my_reset - // use pcr port to update core's rtc value periodically - val rtc_sent = Reg(init=Bool(false)) - val rtc_outstanding = Reg(init=Bool(false)) - when (rtc_tick) { rtc_sent := Bool(false) } - when (cpu.pcr_rep.valid) { rtc_outstanding := Bool(false) } - when (rtc_outstanding) { cpu.pcr_req.valid := Bool(false) } - when (state != state_pcr_req && state != state_pcr_resp && !rtc_sent && !rtc_outstanding) { - cpu.pcr_req.valid := Bool(true) - cpu.pcr_req.bits.rw := Bool(true) - cpu.pcr_req.bits.addr := UInt(pcr_RESET) /* XXX this means write mtime */ - cpu.pcr_req.bits.data := rtc - rtc_sent := cpu.pcr_req.ready - rtc_outstanding := cpu.pcr_req.ready - } - when (cpu.ipi_rep.ready) { my_ipi := Bool(false) } @@ -228,7 +200,7 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters { } } - when (state === state_pcr_req && cpu.pcr_req.fire()) { + when (state === state_pcr_req && cpu.pcr.req.fire()) { state := state_pcr_resp } when (state === state_pcr_req && me && pcr_addr === UInt(pcr_RESET)) { @@ -239,9 +211,9 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters { state := state_tx } - cpu.pcr_rep.ready := Bool(true) - when (state === state_pcr_resp && cpu.pcr_rep.valid) { - pcrReadData := cpu.pcr_rep.bits + cpu.pcr.resp.ready := Bool(true) + when (state === state_pcr_resp && cpu.pcr.resp.valid) { + pcrReadData := cpu.pcr.resp.bits state := state_tx } } @@ -251,7 +223,7 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters { for (i <- 0 until scr_rdata.size) scr_rdata(i) := io.scr.rdata(i) scr_rdata(0) := UInt(nCores) - scr_rdata(1) := UInt((BigInt(dataBits*dataBeats/8) << params(TLBlockAddrBits)) >> 20) + scr_rdata(1) := UInt(params(MMIOBase) >> 20) io.scr.wen := Bool(false) io.scr.wdata := pcr_wdata diff --git a/uncore/src/main/scala/rtc.scala b/uncore/src/main/scala/rtc.scala new file mode 100644 index 00000000..9253d0ea --- /dev/null +++ b/uncore/src/main/scala/rtc.scala @@ -0,0 +1,104 @@ +package uncore + +import Chisel._ +import junctions.{NASTIMasterIO, NASTIAddrHashMap, SMIIO} + +class RTC(pcr_MTIME: Int) extends Module { + private val nCores = params(HTIFNCores) + + val io = new Bundle { + val smi = Vec.fill(nCores) { new SMIIO(64, 12) } + } + + val rtc = Reg(init=UInt(0,64)) + val rtc_tick = Counter(params(RTCPeriod)).inc() + + for ((smi, i) <- io.smi.zipWithIndex) { + val rtc_sending = Reg(init = Bool(false)) + val rtc_outstanding = Reg(init = Bool(false)) + + when (rtc_tick) { + rtc := rtc + UInt(1) + rtc_sending := Bool(true) + rtc_outstanding := Bool(true) + } + when (smi.req.fire()) { rtc_sending := Bool(false) } + when (smi.resp.fire()) { rtc_outstanding := Bool(false) } + + assert(!rtc_tick || !rtc_outstanding, "Last rtc tick not yet sent") + + smi.req.bits.addr := UInt(pcr_MTIME) + smi.req.bits.rw := Bool(true) + smi.req.bits.data := rtc + smi.req.valid := rtc_sending + smi.resp.ready := Bool(true) + } +} + +class RTCNASTI(pcr_MTIME: Int) extends Module { + val io = new NASTIMasterIO + + private val nCores = params(HTIFNCores) + private val addrMap = params(NASTIAddrHashMap) + + val addrTable = Vec.tabulate(nCores) { i => + UInt(addrMap(s"conf:csr$i").start + pcr_MTIME * 8) + } + + val rtc = Reg(init=UInt(0,64)) + val rtc_tick = Counter(params(RTCPeriod)).inc() + + val sending_addr = Reg(init = Bool(false)) + val sending_data = Reg(init = Bool(false)) + val send_acked = Reg(init = Vec(nCores, Bool(true))) + + when (rtc_tick) { + rtc := rtc + UInt(1) + send_acked := Vec(nCores, Bool(false)) + sending_addr := Bool(true) + sending_data := Bool(true) + } + + if (nCores > 1) { + val (core, addr_send_done) = Counter(io.aw.fire(), nCores) + val (_, data_send_done) = Counter(io.w.fire(), nCores) + + when (addr_send_done) { sending_addr := Bool(false) } + when (data_send_done) { sending_data := Bool(false) } + + io.aw.bits.id := core + io.aw.bits.addr := addrTable(core) + } else { + when (io.aw.fire()) { sending_addr := Bool(false) } + when (io.w.fire()) { sending_addr := Bool(false) } + + io.aw.bits.id := UInt(0) + io.aw.bits.addr := addrTable(0) + } + + when (io.b.fire()) { send_acked(io.b.bits.id) := Bool(true) } + + io.aw.valid := sending_addr + io.aw.bits.size := UInt(3) // 8 bytes + io.aw.bits.len := UInt(0) + io.aw.bits.burst := Bits("b01") + io.aw.bits.lock := Bool(false) + io.aw.bits.cache := UInt("b0000") + io.aw.bits.prot := UInt("b000") + io.aw.bits.qos := UInt("b0000") + io.aw.bits.region := UInt("b0000") + io.aw.bits.user := UInt(0) + + io.w.valid := sending_data + io.w.bits.data := rtc + io.w.bits.strb := Bits(0x00FF) + io.w.bits.user := UInt(0) + io.w.bits.last := Bool(true) + + io.b.ready := Bool(true) + io.ar.valid := Bool(false) + io.r.ready := Bool(false) + + assert(!rtc_tick || send_acked.toBits.andR, + s"Not all clocks were updated for rtc tick") +}