DebugModule: translate to TL2 with {32,64}-bit XLen width
This commit is contained in:
parent
3e08d615f0
commit
d530ef7236
@ -4,8 +4,9 @@ package uncore.devices
|
|||||||
|
|
||||||
import Chisel._
|
import Chisel._
|
||||||
import junctions._
|
import junctions._
|
||||||
import uncore.tilelink._
|
|
||||||
import util._
|
import util._
|
||||||
|
import regmapper._
|
||||||
|
import uncore.tilelink2._
|
||||||
import cde.{Parameters, Config, Field}
|
import cde.{Parameters, Config, Field}
|
||||||
|
|
||||||
// *****************************************
|
// *****************************************
|
||||||
@ -15,6 +16,7 @@ import cde.{Parameters, Config, Field}
|
|||||||
|
|
||||||
object DbRegAddrs{
|
object DbRegAddrs{
|
||||||
|
|
||||||
|
def DMRAMBASE = UInt(0x0)
|
||||||
def DMCONTROL = UInt(0x10)
|
def DMCONTROL = UInt(0x10)
|
||||||
|
|
||||||
def DMINFO = UInt(0x11)
|
def DMINFO = UInt(0x11)
|
||||||
@ -69,7 +71,7 @@ object DsbBusConsts {
|
|||||||
// See $RISCV/riscv-tools/riscv-isa-sim/debug_rom/debug_rom.h/S
|
// See $RISCV/riscv-tools/riscv-isa-sim/debug_rom/debug_rom.h/S
|
||||||
// The code assumes 64 bytes of Debug RAM.
|
// The code assumes 64 bytes of Debug RAM.
|
||||||
|
|
||||||
def defaultRomContents : Array[Byte] = Array(
|
def xlenAnyRomContents : Array[Byte] = Array(
|
||||||
0x6f, 0x00, 0xc0, 0x04, 0x6f, 0x00, 0xc0, 0x00, 0x13, 0x04, 0xf0, 0xff,
|
0x6f, 0x00, 0xc0, 0x04, 0x6f, 0x00, 0xc0, 0x00, 0x13, 0x04, 0xf0, 0xff,
|
||||||
0x6f, 0x00, 0x80, 0x00, 0x13, 0x04, 0x00, 0x00, 0x0f, 0x00, 0xf0, 0x0f,
|
0x6f, 0x00, 0x80, 0x00, 0x13, 0x04, 0x00, 0x00, 0x0f, 0x00, 0xf0, 0x0f,
|
||||||
0xf3, 0x24, 0x00, 0xf1, 0x63, 0xc6, 0x04, 0x00, 0x83, 0x24, 0xc0, 0x43,
|
0xf3, 0x24, 0x00, 0xf1, 0x63, 0xc6, 0x04, 0x00, 0x83, 0x24, 0xc0, 0x43,
|
||||||
@ -121,10 +123,10 @@ object DsbBusConsts {
|
|||||||
|
|
||||||
object DsbRegAddrs{
|
object DsbRegAddrs{
|
||||||
|
|
||||||
def CLEARDEBINT = UInt(0x100)
|
def CLEARDEBINT = 0x100
|
||||||
def SETHALTNOT = UInt(0x10C)
|
def SETHALTNOT = 0x10C
|
||||||
def SERINFO = UInt(0x110)
|
def SERINFO = 0x110
|
||||||
def SERBASE = UInt(0x114)
|
def SERBASE = 0x114
|
||||||
// For each serial, there are
|
// For each serial, there are
|
||||||
// 3 registers starting here:
|
// 3 registers starting here:
|
||||||
// SERSEND0
|
// SERSEND0
|
||||||
@ -132,9 +134,11 @@ object DsbRegAddrs{
|
|||||||
// SERSTATUS0
|
// SERSTATUS0
|
||||||
// ...
|
// ...
|
||||||
// SERSTATUS7
|
// SERSTATUS7
|
||||||
def SERTX_OFFSET = UInt(0)
|
def SERTX_OFFSET = 0
|
||||||
def SERRX_OFFSET = UInt(4)
|
def SERRX_OFFSET = 4
|
||||||
def SERSTAT_OFFSET = UInt(8)
|
def SERSTAT_OFFSET = 8
|
||||||
|
def RAMBASE = 0x400
|
||||||
|
def ROMBASE = 0x800
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +306,24 @@ class DebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p
|
|||||||
val resp = new DecoupledIO(new DebugBusResp).flip()
|
val resp = new DecoupledIO(new DebugBusResp).flip()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait HasDebugModuleParameters {
|
||||||
|
val params : Parameters
|
||||||
|
implicit val p = params
|
||||||
|
val cfg = p(DMKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Debug Module I/O, with the exclusion of the RegisterRouter
|
||||||
|
* Access interface.
|
||||||
|
*/
|
||||||
|
|
||||||
|
trait DebugModuleBundle extends Bundle with HasDebugModuleParameters {
|
||||||
|
val db = new DebugBusIO()(p).flip()
|
||||||
|
val debugInterrupts = Vec(cfg.nComponents, Bool()).asOutput
|
||||||
|
val ndreset = Bool(OUTPUT)
|
||||||
|
val fullreset = Bool(OUTPUT)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// *****************************************
|
// *****************************************
|
||||||
// The Module
|
// The Module
|
||||||
//
|
//
|
||||||
@ -313,7 +335,7 @@ class DebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p
|
|||||||
* DebugModule is a slave to two masters:
|
* DebugModule is a slave to two masters:
|
||||||
* The Debug Bus -- implemented as a generic Decoupled IO with request
|
* The Debug Bus -- implemented as a generic Decoupled IO with request
|
||||||
* and response channels
|
* and response channels
|
||||||
* The System Bus -- implemented as Uncached Tile Link.
|
* The System Bus -- implemented as generic RegisterRouter
|
||||||
*
|
*
|
||||||
* DebugModule is responsible for holding registers, RAM, and ROM
|
* DebugModule is responsible for holding registers, RAM, and ROM
|
||||||
* to support debug interactions, as well as driving interrupts
|
* to support debug interactions, as well as driving interrupts
|
||||||
@ -321,10 +343,9 @@ class DebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p
|
|||||||
* It is also responsible for some reset lines.
|
* It is also responsible for some reset lines.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class DebugModule ()(implicit val p:cde.Parameters)
|
trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap {
|
||||||
extends Module
|
|
||||||
with HasTileLinkParameters {
|
val io: DebugModuleBundle
|
||||||
val cfg = p(DMKey)
|
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Import constants for shorter variable names
|
// Import constants for shorter variable names
|
||||||
@ -344,6 +365,7 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
require (cfg.hasBusMaster == false)
|
require (cfg.hasBusMaster == false)
|
||||||
require (cfg.nDebugRamBytes <= 64)
|
require (cfg.nDebugRamBytes <= 64)
|
||||||
require (cfg.authType == DebugModuleAuthType.None)
|
require (cfg.authType == DebugModuleAuthType.None)
|
||||||
|
require((DbBusConsts.dbRamWordBits % 8) == 0)
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Private Classes (Register Fields)
|
// Private Classes (Register Fields)
|
||||||
@ -403,17 +425,6 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
// Module I/O
|
|
||||||
//--------------------------------------------------------------
|
|
||||||
|
|
||||||
val io = new Bundle {
|
|
||||||
val db = new DebugBusIO()(p).flip()
|
|
||||||
val debugInterrupts = Vec(cfg.nComponents, Bool()).asOutput
|
|
||||||
val tl = new ClientUncachedTileLinkIO().flip
|
|
||||||
val ndreset = Bool(OUTPUT)
|
|
||||||
val fullreset = Bool(OUTPUT)
|
|
||||||
}
|
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Register & Wire Declarations
|
// Register & Wire Declarations
|
||||||
@ -455,47 +466,21 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
|
|
||||||
// --- Debug RAM
|
// --- Debug RAM
|
||||||
|
|
||||||
// Since the access size from Debug Bus and System Bus may not be consistent,
|
val ramDataWidth = DbBusConsts.dbRamWordBits
|
||||||
// use the maximum to build the RAM, and then select as needed for the smaller
|
val ramDataBytes = ramDataWidth / 8;
|
||||||
// size.
|
val ramAddrWidth = log2Up(cfg.nDebugRamBytes / ramDataBytes)
|
||||||
|
|
||||||
val dbRamDataWidth = DbBusConsts.dbRamWordBits
|
val ramMem = Reg(init = Vec.fill(cfg.nDebugRamBytes){UInt(0, width = 8)})
|
||||||
val sbRamDataWidth = tlDataBits
|
|
||||||
val dbRamAddrWidth = log2Up((cfg.nDebugRamBytes * 8) / dbRamDataWidth)
|
|
||||||
val sbRamAddrWidth = log2Up((cfg.nDebugRamBytes * 8) / sbRamDataWidth)
|
|
||||||
val sbRamAddrOffset = log2Up(tlDataBits/8)
|
|
||||||
|
|
||||||
val ramDataWidth = dbRamDataWidth max sbRamDataWidth
|
val dbRamAddr = Wire(UInt(width=ramAddrWidth))
|
||||||
val ramAddrWidth = dbRamAddrWidth min sbRamAddrWidth
|
|
||||||
val ramMem = Mem(1 << ramAddrWidth , UInt(width=ramDataWidth))
|
|
||||||
val ramAddr = Wire(UInt(width=ramAddrWidth))
|
|
||||||
val ramRdData = Wire(UInt(width=ramDataWidth))
|
|
||||||
val ramWrData = Wire(UInt(width=ramDataWidth))
|
|
||||||
val ramWrMask = Wire(UInt(width=ramDataWidth))
|
|
||||||
val ramWrEn = Wire(Bool())
|
|
||||||
|
|
||||||
val dbRamAddr = Wire(UInt(width=dbRamAddrWidth))
|
|
||||||
val dbRamAddrValid = Wire(Bool())
|
val dbRamAddrValid = Wire(Bool())
|
||||||
val dbRamRdData = Wire (UInt(width=dbRamDataWidth))
|
val dbRamRdData = Wire (UInt(width=ramDataWidth))
|
||||||
val dbRamWrData = Wire(UInt(width=dbRamDataWidth))
|
val dbRamWrData = Wire(UInt(width=ramDataWidth))
|
||||||
val dbRamWrEn = Wire(Bool())
|
val dbRamWrEn = Wire(Bool())
|
||||||
val dbRamRdEn = Wire(Bool())
|
val dbRamRdEn = Wire(Bool())
|
||||||
val dbRamWrEnFinal = Wire(Bool())
|
val dbRamWrEnFinal = Wire(Bool())
|
||||||
val dbRamRdEnFinal = Wire(Bool())
|
val dbRamRdEnFinal = Wire(Bool())
|
||||||
|
|
||||||
val sbRamAddr = Wire(UInt(width=sbRamAddrWidth))
|
|
||||||
val sbRamAddrValid = Wire(Bool())
|
|
||||||
val sbRamRdData = Wire (UInt(width=sbRamDataWidth))
|
|
||||||
val sbRamWrData = Wire(UInt(width=sbRamDataWidth))
|
|
||||||
val sbRamWrEn = Wire(Bool())
|
|
||||||
val sbRamRdEn = Wire(Bool())
|
|
||||||
val sbRamWrEnFinal = Wire(Bool())
|
|
||||||
val sbRamRdEnFinal = Wire(Bool())
|
|
||||||
|
|
||||||
|
|
||||||
val sbRomRdData = Wire(UInt(width=tlDataBits))
|
|
||||||
val sbRomAddrOffset = log2Up(tlDataBits/8)
|
|
||||||
|
|
||||||
// --- Debug Bus Accesses
|
// --- Debug Bus Accesses
|
||||||
|
|
||||||
val dbRdEn = Wire(Bool())
|
val dbRdEn = Wire(Bool())
|
||||||
@ -513,16 +498,6 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
val rdCondWrFailure = Wire(Bool())
|
val rdCondWrFailure = Wire(Bool())
|
||||||
val dbWrNeeded = Wire(Bool())
|
val dbWrNeeded = Wire(Bool())
|
||||||
|
|
||||||
// --- System Bus Access
|
|
||||||
val sbAddr = Wire(UInt(width=sbAddrWidth))
|
|
||||||
val sbRdData = Wire(UInt(width=tlDataBits))
|
|
||||||
val sbWrData = Wire(UInt(width=tlDataBits))
|
|
||||||
val sbWrMask = Wire(UInt(width=tlDataBits))
|
|
||||||
val sbWrEn = Wire(Bool())
|
|
||||||
val sbRdEn = Wire(Bool())
|
|
||||||
|
|
||||||
val stallFromDb = Wire(Bool())
|
|
||||||
val stallFromSb = Wire(Bool())
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Interrupt Registers
|
// Interrupt Registers
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
@ -622,63 +597,32 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
HALTSUMRdData.acks := haltnotSummary
|
HALTSUMRdData.acks := haltnotSummary
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Debug RAM Access (Debug Bus & System Bus)
|
// Debug RAM Access (Debug Bus ... System Bus can override)
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
dbReq := io.db.req.bits
|
dbReq := io.db.req.bits
|
||||||
// Debug Bus RAM Access
|
// Debug Bus RAM Access
|
||||||
// From Specification: Debug RAM is 0x00 - 0x0F
|
// From Specification: Debug RAM is 0x00 - 0x0F
|
||||||
// 0x40 - 0x6F Not Implemented
|
// 0x40 - 0x6F Not Implemented
|
||||||
dbRamAddr := dbReq.addr( dbRamAddrWidth-1 , 0)
|
dbRamAddr := dbReq.addr( ramAddrWidth-1 , 0)
|
||||||
dbRamWrData := dbReq.data
|
dbRamWrData := dbReq.data
|
||||||
dbRamAddrValid := Bool(true)
|
dbRamAddrValid := Bool(true)
|
||||||
if (dbRamAddrWidth < 4){
|
if (ramAddrWidth < 4){
|
||||||
dbRamAddrValid := (dbReq.addr(3, dbRamAddrWidth) === UInt(0))
|
dbRamAddrValid := (dbReq.addr(3, ramAddrWidth) === UInt(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
sbRamAddr := sbAddr(sbRamAddrWidth + sbRamAddrOffset - 1, sbRamAddrOffset)
|
val dbRamRdDataFields = List.tabulate(cfg.nDebugRamBytes / ramDataBytes) { ii =>
|
||||||
sbRamWrData := sbWrData
|
val slice = ramMem.slice(ii * ramDataBytes, (ii+1)*ramDataBytes)
|
||||||
sbRamAddrValid := Bool(true)
|
slice.reduce[UInt]{ case (x: UInt, y: UInt) => Cat(y, x)}
|
||||||
// From Specification: Debug RAM is 0x400 - 0x4FF
|
|
||||||
if ((sbRamAddrWidth + sbRamAddrOffset) < 8){
|
|
||||||
sbRamAddrValid := (sbAddr(7, sbRamAddrWidth + sbRamAddrOffset) === UInt(0))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
require (dbRamAddrWidth >= ramAddrWidth) // SB accesses less than 32 bits Not Implemented.
|
dbRamRdData := dbRamRdDataFields(dbRamAddr)
|
||||||
val dbRamWrMask = Wire(init=Vec.fill(1 << (dbRamAddrWidth - ramAddrWidth)){Fill(dbRamDataWidth, UInt(1, width=1))})
|
|
||||||
|
|
||||||
if (dbRamDataWidth < ramDataWidth){
|
when (dbRamWrEnFinal) {
|
||||||
|
for (ii <- 0 until ramDataBytes) {
|
||||||
val dbRamSel = dbRamAddr(dbRamAddrWidth - ramAddrWidth - 1 , 0)
|
ramMem(dbRamAddr * UInt(ramDataBytes) + UInt(ii)) := dbRamWrData((8*(ii+1)-1), (8*ii))
|
||||||
val rdDataWords = Vec.tabulate(1 << (dbRamAddrWidth - ramAddrWidth)){ ii =>
|
}
|
||||||
ramRdData((ii+1)*dbRamDataWidth - 1 , ii*dbRamDataWidth)}
|
|
||||||
|
|
||||||
dbRamWrMask := Vec.fill(1 << (dbRamAddrWidth - ramAddrWidth)){UInt(0, width = dbRamDataWidth)}
|
|
||||||
dbRamWrMask(dbRamSel) := Fill(dbRamDataWidth, UInt(1, width=1))
|
|
||||||
dbRamRdData := rdDataWords(dbRamSel)
|
|
||||||
} else {
|
|
||||||
dbRamRdData := ramRdData
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sbRamRdData := ramRdData
|
|
||||||
|
|
||||||
ramWrMask := Mux(sbRamWrEn, sbWrMask, dbRamWrMask.asUInt)
|
|
||||||
|
|
||||||
assert (!((dbRamWrEn | dbRamRdEn) & (sbRamRdEn | sbRamWrEn)), "Stall logic should have prevented concurrent SB/DB RAM Access")
|
|
||||||
|
|
||||||
// Make copies of DB RAM data before writing.
|
|
||||||
val dbRamWrDataVec = Fill(1 << (dbRamAddrWidth - ramAddrWidth), dbRamWrData)
|
|
||||||
ramWrData := Mux(sbRamWrEn,
|
|
||||||
(ramWrMask & sbRamWrData ) | (~ramWrMask & ramRdData),
|
|
||||||
(ramWrMask & dbRamWrDataVec) | (~ramWrMask & ramRdData))
|
|
||||||
|
|
||||||
ramAddr := Mux(sbRamWrEn | sbRamRdEn, sbRamAddr,
|
|
||||||
dbRamAddr >> (dbRamAddrWidth - ramAddrWidth))
|
|
||||||
|
|
||||||
ramRdData := ramMem(ramAddr)
|
|
||||||
when (ramWrEn) { ramMem(ramAddr) := ramWrData }
|
|
||||||
|
|
||||||
ramWrEn := sbRamWrEnFinal | dbRamWrEnFinal
|
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Debug Bus Access
|
// Debug Bus Access
|
||||||
@ -813,8 +757,8 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
|
|
||||||
// -----------------------------------------
|
// -----------------------------------------
|
||||||
// DB Access State Machine Decode (Combo)
|
// DB Access State Machine Decode (Combo)
|
||||||
io.db.req.ready := !stallFromSb && ((dbStateReg === s_DB_READY) ||
|
io.db.req.ready := (dbStateReg === s_DB_READY) ||
|
||||||
(dbStateReg === s_DB_RESP && io.db.resp.fire()))
|
(dbStateReg === s_DB_RESP && io.db.resp.fire())
|
||||||
|
|
||||||
io.db.resp.valid := (dbStateReg === s_DB_RESP)
|
io.db.resp.valid := (dbStateReg === s_DB_RESP)
|
||||||
io.db.resp.bits := dbRespReg
|
io.db.resp.bits := dbRespReg
|
||||||
@ -844,172 +788,37 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
// Debug ROM
|
// Debug ROM
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
sbRomRdData := UInt(0)
|
val romRegFields = if (cfg.hasDebugRom) {
|
||||||
if (cfg.hasDebugRom) {
|
|
||||||
// Inspired by ROMSlave
|
// Inspired by ROMSlave
|
||||||
val romContents = cfg.debugRomContents.get
|
val romContents = cfg.debugRomContents.get
|
||||||
val romByteWidth = tlDataBits / 8
|
val romByteWidth = ramDataWidth / 8
|
||||||
val romRows = (romContents.size + romByteWidth - 1)/romByteWidth
|
val romRows = (romContents.size + romByteWidth - 1)/romByteWidth
|
||||||
val romMem = Vec.tabulate(romRows) { ii =>
|
List.tabulate(romRows) { ii => {
|
||||||
val slice = romContents.slice(ii*romByteWidth, (ii+1)*romByteWidth)
|
val slice = romContents.slice(ii*romByteWidth, (ii+1)*romByteWidth)
|
||||||
UInt(slice.foldRight(BigInt(0)) { case (x,y) => ((y << 8) + (x.toInt & 0xFF))}, width = romByteWidth*8)
|
val line = UInt(slice.foldRight(BigInt(0)) { case (x,y) => ((y << 8) + (x.toInt & 0xFF))}, width = romByteWidth*8)
|
||||||
|
RegField.r(ramDataWidth, line)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val sbRomRdAddr = Wire(UInt())
|
|
||||||
|
|
||||||
if (romRows == 1) {
|
|
||||||
sbRomRdAddr := UInt(0)
|
|
||||||
} else {
|
} else {
|
||||||
sbRomRdAddr := sbAddr(log2Up(romRows) + sbRomAddrOffset - 1, sbRomAddrOffset)
|
Seq(RegField(ramDataWidth))
|
||||||
}
|
|
||||||
sbRomRdData := romMem (sbRomRdAddr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// System Bus Access
|
// System Bus Access
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
|
|
||||||
|
// Local reg mapper function : Notify when written, but give the value.
|
||||||
// -----------------------------------------
|
def wValue (n: Int, value: UInt, set: Bool) : RegField = {
|
||||||
// SB Access Write Decoder
|
RegField(n, value, RegWriteFn((valid, data) => {set := valid ; value := data; Bool(true)}))
|
||||||
|
|
||||||
sbRamWrEn := Bool(false)
|
|
||||||
sbRamWrEnFinal := Bool(false)
|
|
||||||
SETHALTNOTWrEn := Bool(false)
|
|
||||||
CLEARDEBINTWrEn := Bool(false)
|
|
||||||
|
|
||||||
if (tlDataBits == 32) {
|
|
||||||
SETHALTNOTWrData := sbWrData
|
|
||||||
CLEARDEBINTWrData := sbWrData
|
|
||||||
when (sbAddr(11, 8) === UInt(4)){ // 0x400-0x4ff is Debug RAM
|
|
||||||
sbRamWrEn := sbWrEn
|
|
||||||
sbRamRdEn := sbRdEn
|
|
||||||
when (sbRamAddrValid) {
|
|
||||||
sbRamWrEnFinal := sbWrEn
|
|
||||||
sbRamRdEnFinal := sbRdEn
|
|
||||||
}
|
|
||||||
}.elsewhen (sbAddr === SETHALTNOT){
|
|
||||||
SETHALTNOTWrEn := sbWrEn
|
|
||||||
}.elsewhen (sbAddr === CLEARDEBINT){
|
|
||||||
CLEARDEBINTWrEn := sbWrEn
|
|
||||||
}.otherwise {
|
|
||||||
//Other registers/RAM are Not Implemented.
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Pick out the correct word based on the address.
|
|
||||||
val sbWrDataWords = Vec.tabulate (tlDataBits / 32) {ii => sbWrData((ii+1)*32 - 1, ii*32)}
|
|
||||||
val sbWrMaskWords = Vec.tabulate (tlDataBits / 32) {ii => sbWrMask ((ii+1)*32 -1, ii*32)}
|
|
||||||
|
|
||||||
val sbWrSelTop = log2Up(tlDataBits/8) - 1
|
|
||||||
val sbWrSelBottom = 2
|
|
||||||
|
|
||||||
SETHALTNOTWrData := sbWrDataWords(SETHALTNOT(sbWrSelTop, sbWrSelBottom))
|
|
||||||
CLEARDEBINTWrData := sbWrDataWords(CLEARDEBINT(sbWrSelTop, sbWrSelBottom))
|
|
||||||
|
|
||||||
when (sbAddr(11,8) === UInt(4)){ //0x400-0x4ff is Debug RAM
|
|
||||||
sbRamWrEn := sbWrEn
|
|
||||||
sbRamRdEn := sbRdEn
|
|
||||||
when (sbRamAddrValid){
|
|
||||||
sbRamWrEnFinal := sbWrEn
|
|
||||||
sbRamRdEnFinal := sbRdEn
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SETHALTNOTWrEn := sbAddr(sbAddrWidth - 1, sbWrSelTop + 1) === SETHALTNOT(sbAddrWidth-1, sbWrSelTop + 1) &&
|
regmap(
|
||||||
(sbWrMaskWords(SETHALTNOT(sbWrSelTop, sbWrSelBottom))).orR &&
|
CLEARDEBINT -> Seq(wValue(sbIdWidth, CLEARDEBINTWrData, CLEARDEBINTWrEn)),
|
||||||
sbWrEn
|
SETHALTNOT -> Seq(wValue(sbIdWidth, SETHALTNOTWrData, SETHALTNOTWrEn)),
|
||||||
|
RAMBASE -> ramMem.map(x => RegField(8, x)),
|
||||||
CLEARDEBINTWrEn := sbAddr(sbAddrWidth - 1, sbWrSelTop + 1) === CLEARDEBINT(sbAddrWidth-1, sbWrSelTop + 1) &&
|
ROMBASE -> romRegFields
|
||||||
(sbWrMaskWords(CLEARDEBINT(sbWrSelTop, sbWrSelBottom))).orR &&
|
|
||||||
sbWrEn
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
// SB Access Read Mux
|
|
||||||
|
|
||||||
sbRdData := UInt(0)
|
|
||||||
sbRamRdEn := Bool(false)
|
|
||||||
sbRamRdEnFinal := Bool(false)
|
|
||||||
|
|
||||||
when (sbAddr(11, 8) === UInt(4)) { //0x400-0x4FF Debug RAM
|
|
||||||
sbRamRdEn := sbRdEn
|
|
||||||
when (sbRamAddrValid) {
|
|
||||||
sbRdData := sbRamRdData
|
|
||||||
sbRamRdEnFinal := sbRdEn
|
|
||||||
}
|
|
||||||
}.elsewhen (sbAddr(11,8).isOneOf(UInt(8), UInt(9))){ //0x800-0x9FF Debug ROM
|
|
||||||
if (cfg.hasDebugRom) {
|
|
||||||
sbRdData := sbRomRdData
|
|
||||||
} else {
|
|
||||||
sbRdData := UInt(0)
|
|
||||||
}
|
|
||||||
}. otherwise {
|
|
||||||
// All readable registers are Not Implemented.
|
|
||||||
sbRdData := UInt(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
// SB Access State Machine -- based on BRAM Slave
|
|
||||||
|
|
||||||
val sbAcqReg = Reg(io.tl.acquire.bits)
|
|
||||||
val sbAcqValidReg = Reg(init = Bool(false))
|
|
||||||
|
|
||||||
val (sbReg_get :: sbReg_getblk :: sbReg_put :: sbReg_putblk :: Nil) = Seq(
|
|
||||||
Acquire.getType, Acquire.getBlockType, Acquire.putType, Acquire.putBlockType
|
|
||||||
).map(sbAcqReg.isBuiltInType _)
|
|
||||||
|
|
||||||
val sbMultibeat = sbReg_getblk & sbAcqValidReg;
|
|
||||||
|
|
||||||
val sbBeatInc1 = sbAcqReg.addr_beat + UInt(1)
|
|
||||||
|
|
||||||
val sbLast = (sbAcqReg.addr_beat === UInt(tlDataBeats - 1))
|
|
||||||
|
|
||||||
sbAddr := sbAcqReg.full_addr()
|
|
||||||
sbRdEn := (sbAcqValidReg && (sbReg_get || sbReg_getblk))
|
|
||||||
sbWrEn := (sbAcqValidReg && (sbReg_put || sbReg_putblk))
|
|
||||||
sbWrData := sbAcqReg.data
|
|
||||||
sbWrMask := sbAcqReg.full_wmask()
|
|
||||||
|
|
||||||
// -----------------------------------------
|
|
||||||
// SB Access State Machine Update (Seq)
|
|
||||||
|
|
||||||
when (io.tl.acquire.fire()){
|
|
||||||
sbAcqReg := io.tl.acquire.bits
|
|
||||||
sbAcqValidReg := Bool(true)
|
|
||||||
} .elsewhen (io.tl.grant.fire()) {
|
|
||||||
when (sbMultibeat){
|
|
||||||
sbAcqReg.addr_beat := sbBeatInc1
|
|
||||||
when (sbLast) {
|
|
||||||
sbAcqValidReg := Bool(false)
|
|
||||||
}
|
|
||||||
} . otherwise {
|
|
||||||
sbAcqValidReg := Bool(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
io.tl.grant.valid := sbAcqValidReg
|
|
||||||
io.tl.grant.bits := Grant(
|
|
||||||
is_builtin_type = Bool(true),
|
|
||||||
g_type = sbAcqReg.getBuiltInGrantType(),
|
|
||||||
client_xact_id = sbAcqReg.client_xact_id,
|
|
||||||
manager_xact_id = UInt(0),
|
|
||||||
addr_beat = sbAcqReg.addr_beat,
|
|
||||||
data = sbRdData
|
|
||||||
)
|
)
|
||||||
|
|
||||||
stallFromDb := Bool(false) // SB always wins, and DB latches its read data so it is not necessary for SB to wait
|
|
||||||
|
|
||||||
stallFromSb := sbRamRdEn || sbRamWrEn // pessimistically assume that DB/SB are going to conflict on the RAM,
|
|
||||||
// and SB doesn't latch its read data to it is necessary for DB hold
|
|
||||||
// off while SB is accessing the RAM and waiting to send its result.
|
|
||||||
|
|
||||||
val sbStall = (sbMultibeat & !sbLast) || (io.tl.grant.valid && !io.tl.grant.ready) || stallFromDb
|
|
||||||
|
|
||||||
io.tl.acquire.ready := !sbStall
|
|
||||||
|
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
// Misc. Outputs
|
// Misc. Outputs
|
||||||
//--------------------------------------------------------------
|
//--------------------------------------------------------------
|
||||||
@ -1019,6 +828,21 @@ class DebugModule ()(implicit val p:cde.Parameters)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create a concrete TL2 Slave for the DebugModule RegMapper interface.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
class TLDebugModule(beatBytes: Int) (implicit p: Parameters)
|
||||||
|
extends TLRegisterRouter(0x0, beatBytes=beatBytes)(
|
||||||
|
new TLRegBundle(p, _ ) with DebugModuleBundle)(
|
||||||
|
new TLRegModule(p, _, _) with DebugModule)
|
||||||
|
|
||||||
|
|
||||||
|
/** Synchronizers for DebugBus
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
object AsyncDebugBusCrossing {
|
object AsyncDebugBusCrossing {
|
||||||
// takes from_source from the 'from' clock domain to the 'to' clock domain
|
// takes from_source from the 'from' clock domain to the 'to' clock domain
|
||||||
def apply(from_clock: Clock, from_reset: Bool, from_source: DebugBusIO, to_clock: Clock, to_reset: Bool, depth: Int = 1, sync: Int = 3) = {
|
def apply(from_clock: Clock, from_reset: Bool, from_source: DebugBusIO, to_clock: Clock, to_reset: Bool, depth: Int = 1, sync: Int = 3) = {
|
||||||
@ -1029,6 +853,7 @@ object AsyncDebugBusCrossing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
object AsyncDebugBusFrom { // OutsideClockDomain
|
object AsyncDebugBusFrom { // OutsideClockDomain
|
||||||
// takes from_source from the 'from' clock domain and puts it into your clock domain
|
// takes from_source from the 'from' clock domain and puts it into your clock domain
|
||||||
def apply(from_clock: Clock, from_reset: Bool, from_source: DebugBusIO, depth: Int = 1, sync: Int = 3): DebugBusIO = {
|
def apply(from_clock: Clock, from_reset: Bool, from_source: DebugBusIO, depth: Int = 1, sync: Int = 3): DebugBusIO = {
|
||||||
|
Loading…
Reference in New Issue
Block a user