separate RTC updates from HTIF
This commit is contained in:
		| @@ -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 | ||||
|   | ||||
							
								
								
									
										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") | ||||
| } | ||||
		Reference in New Issue
	
	Block a user