1
0

Allow SCR files to be enumerated in C headers

Right now there's no way to ensure that SCR addresses don't conflict within
RocketChip.  Since upstream only has one of them this isn't a big deal, but we
want to add a whole bunch more to control all the IP on Hurricane.

This patch adds some Scala code to allocate registers inside the SCR file,
ensure they don't conflict, to provide names for SCRs, attach registers to the
SCR file, and generate a C header file that contains the addresses of every SCR
on a chip.

With this patch we'll be able to get rid of that constant in the testbench.
This also allows us to kill one of the Raven diffs, which is does pretty much
the same thing (just in a second SCR file, and hacked in).
This commit is contained in:
Palmer Dabbelt 2016-02-17 14:06:34 -08:00
parent 53ad8387cc
commit 1ac9f59b31

View File

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