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:
parent
53ad8387cc
commit
1ac9f59b31
@ -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) } }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user