1
0

separate RTC updates from HTIF

This commit is contained in:
Howard Mao 2015-08-12 21:23:17 -07:00
parent 24f3fac90a
commit bdc6972a8d
2 changed files with 117 additions and 41 deletions

View File

@ -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

View File

@ -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")
}