diff --git a/uncore/src/main/scala/scr.scala b/uncore/src/main/scala/scr.scala index ddc35ded..08949ca9 100644 --- a/uncore/src/main/scala/scr.scala +++ b/uncore/src/main/scala/scr.scala @@ -3,25 +3,71 @@ package uncore import Chisel._ import junctions.{SmiIO, MMIOBase} import cde.Parameters +import scala.collection.mutable.HashMap +import scala.collection.mutable.ArrayBuffer -class SCRIO(implicit p: Parameters) extends HtifBundle()(p) { +/** Stores a map between SCR file names and address in the SCR file, which can + * later be dumped to a header file for the test bench. */ +class SCRFileMap(prefix: String, maxAddress: Int) { + private val addr2name = HashMap.empty[Int, String] + private val name2addr = HashMap.empty[String, Int] + + def allocate(address: Int, name: String): Int = { + Predef.assert(!addr2name.contains(address), "address already allocated") + Predef.assert(!name2addr.contains(name), "name already allocated") + Predef.assert(address < maxAddress, "address too large") + addr2name += (address -> name) + name2addr += (name -> address) + println(prefix + ": " + address + " -> " + name) + address + } + + def allocate(name: String): Int = { + val addr = (0 until maxAddress).filter{ addr => !addr2name.contains(addr) }(0) + allocate(addr, name) + } + + def as_c_header(): String = { + addr2name.map{ case(address, name) => + "#define " + prefix + "__" + name + " " + address + }.mkString("\n") + "\n" + } +} + +class SCRIO(map: SCRFileMap)(implicit p: Parameters) extends HtifBundle()(p) { val rdata = Vec(nSCR, Bits(INPUT, scrDataBits)) val wen = Bool(OUTPUT) val waddr = UInt(OUTPUT, log2Up(nSCR)) val wdata = Bits(OUTPUT, scrDataBits) + + def attach(reg: Data, name: String): Data = { + val addr = map.allocate(name) + when (wen && (waddr === UInt(addr))) { + reg := wdata + } + rdata(addr) := reg + reg + } + + def allocate(address: Int, name: String): Unit = { + map.allocate(address, name) + } } -class SCRFile(implicit p: Parameters) extends HtifModule()(p) { +class SCRFile(prefix: String)(implicit p: Parameters) extends HtifModule()(p) { + val map = new SCRFileMap(prefix, 64) + AllSCRFiles += map + val io = new Bundle { val smi = new SmiIO(scrDataBits, scrAddrBits).flip - val scr = new SCRIO + val scr = new SCRIO(map) } val scr_rdata = Wire(Vec(io.scr.rdata.size, Bits(width=scrDataBits))) for (i <- 0 until scr_rdata.size) scr_rdata(i) := io.scr.rdata(i) - scr_rdata(0) := UInt(nCores) - scr_rdata(1) := UInt(p(MMIOBase) >> 20) + scr_rdata(0) := UInt(nCores); map.allocate(0, "N_CORES") + scr_rdata(1) := UInt(p(MMIOBase) >> 20); map.allocate(1, "MMIO_BASE") val read_addr = Reg(init = UInt(0, scrAddrBits)) val resp_valid = Reg(init = Bool(false)) @@ -40,3 +86,12 @@ class SCRFile(implicit p: Parameters) extends HtifModule()(p) { } when (io.smi.resp.fire()) { resp_valid := Bool(false) } } + +/** Every elaborated SCR file ends up in this global arry so it can be printed + * out later. */ +object AllSCRFiles { + private var maps = ArrayBuffer.empty[SCRFileMap] + + def +=(map: SCRFileMap): Unit = { maps += map } + def foreach( f: (SCRFileMap => Unit) ): Unit = { maps.foreach{ m => f(m) } } +}