separate RTC updates from HTIF
This commit is contained in:
parent
24f3fac90a
commit
bdc6972a8d
@ -4,7 +4,7 @@ package uncore
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import Chisel.ImplicitConversions._
|
import Chisel.ImplicitConversions._
|
||||||
import uncore._
|
import junctions.{SMIIO, MMIOBase}
|
||||||
|
|
||||||
case object HTIFWidth extends Field[Int]
|
case object HTIFWidth extends Field[Int]
|
||||||
case object HTIFNSCR extends Field[Int]
|
case object HTIFNSCR extends Field[Int]
|
||||||
@ -31,18 +31,10 @@ class HostIO extends HTIFBundle
|
|||||||
val debug_stats_pcr = Bool(OUTPUT)
|
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 {
|
class HTIFIO extends HTIFBundle {
|
||||||
val reset = Bool(INPUT)
|
val reset = Bool(INPUT)
|
||||||
val id = UInt(INPUT, log2Up(nCores))
|
val id = UInt(INPUT, log2Up(nCores))
|
||||||
val pcr_req = Decoupled(new PCRReq).flip
|
val pcr = new SMIIO(64, 12).flip
|
||||||
val pcr_rep = Decoupled(Bits(width = 64))
|
|
||||||
val ipi_req = Decoupled(Bits(width = log2Up(nCores)))
|
val ipi_req = Decoupled(Bits(width = log2Up(nCores)))
|
||||||
val ipi_rep = Decoupled(Bool()).flip
|
val ipi_rep = Decoupled(Bool()).flip
|
||||||
val debug_stats_pcr = Bool(OUTPUT)
|
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 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_coreid = addr(log2Up(nCores)-1+20+1,20)
|
||||||
val pcr_wdata = packet_ram(0)
|
val pcr_wdata = packet_ram(0)
|
||||||
|
|
||||||
@ -184,39 +176,19 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters {
|
|||||||
GetBlock(addr_block = init_addr))
|
GetBlock(addr_block = init_addr))
|
||||||
io.mem.grant.ready := Bool(true)
|
io.mem.grant.ready := Bool(true)
|
||||||
|
|
||||||
// real-time counter (which doesn't really belong here...)
|
val pcrReadData = Reg(Bits(width = io.cpu(0).pcr.resp.bits.getWidth))
|
||||||
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))
|
|
||||||
for (i <- 0 until nCores) {
|
for (i <- 0 until nCores) {
|
||||||
val my_reset = Reg(init=Bool(true))
|
val my_reset = Reg(init=Bool(true))
|
||||||
val my_ipi = Reg(init=Bool(false))
|
val my_ipi = Reg(init=Bool(false))
|
||||||
|
|
||||||
val cpu = io.cpu(i)
|
val cpu = io.cpu(i)
|
||||||
val me = pcr_coreid === UInt(i)
|
val me = pcr_coreid === UInt(i)
|
||||||
cpu.pcr_req.valid := state === state_pcr_req && me && pcr_addr != UInt(pcr_RESET)
|
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.rw := cmd === cmd_writecr
|
||||||
cpu.pcr_req.bits.addr := pcr_addr
|
cpu.pcr.req.bits.addr := pcr_addr
|
||||||
cpu.pcr_req.bits.data := pcr_wdata
|
cpu.pcr.req.bits.data := pcr_wdata
|
||||||
cpu.reset := my_reset
|
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) {
|
when (cpu.ipi_rep.ready) {
|
||||||
my_ipi := Bool(false)
|
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
|
state := state_pcr_resp
|
||||||
}
|
}
|
||||||
when (state === state_pcr_req && me && pcr_addr === UInt(pcr_RESET)) {
|
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
|
state := state_tx
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu.pcr_rep.ready := Bool(true)
|
cpu.pcr.resp.ready := Bool(true)
|
||||||
when (state === state_pcr_resp && cpu.pcr_rep.valid) {
|
when (state === state_pcr_resp && cpu.pcr.resp.valid) {
|
||||||
pcrReadData := cpu.pcr_rep.bits
|
pcrReadData := cpu.pcr.resp.bits
|
||||||
state := state_tx
|
state := state_tx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,7 +223,7 @@ class HTIF(pcr_RESET: Int) extends Module with HTIFParameters {
|
|||||||
for (i <- 0 until scr_rdata.size)
|
for (i <- 0 until scr_rdata.size)
|
||||||
scr_rdata(i) := io.scr.rdata(i)
|
scr_rdata(i) := io.scr.rdata(i)
|
||||||
scr_rdata(0) := UInt(nCores)
|
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.wen := Bool(false)
|
||||||
io.scr.wdata := pcr_wdata
|
io.scr.wdata := pcr_wdata
|
||||||
|
104
uncore/src/main/scala/rtc.scala
Normal file
104
uncore/src/main/scala/rtc.scala
Normal 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")
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user