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 Chisel._
import junctions.{SmiIO, MMIOBase} import junctions.{SmiIO, MMIOBase}
import cde.Parameters 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 rdata = Vec(nSCR, Bits(INPUT, scrDataBits))
val wen = Bool(OUTPUT) val wen = Bool(OUTPUT)
val waddr = UInt(OUTPUT, log2Up(nSCR)) val waddr = UInt(OUTPUT, log2Up(nSCR))
val wdata = Bits(OUTPUT, scrDataBits) 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 io = new Bundle {
val smi = new SmiIO(scrDataBits, scrAddrBits).flip 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))) val scr_rdata = Wire(Vec(io.scr.rdata.size, Bits(width=scrDataBits)))
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); map.allocate(0, "N_CORES")
scr_rdata(1) := UInt(p(MMIOBase) >> 20) scr_rdata(1) := UInt(p(MMIOBase) >> 20); map.allocate(1, "MMIO_BASE")
val read_addr = Reg(init = UInt(0, scrAddrBits)) val read_addr = Reg(init = UInt(0, scrAddrBits))
val resp_valid = Reg(init = Bool(false)) 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) } 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) } }
}