Merge pull request #1034 from freechipsproject/base-tile
Generalize Tile/Coreplex hierarchy
This commit is contained in:
commit
d78ad857ee
@ -6,6 +6,9 @@ import Chisel._
|
|||||||
import freechips.rocketchip.config.Parameters
|
import freechips.rocketchip.config.Parameters
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
|
import freechips.rocketchip.devices.tilelink._
|
||||||
|
import freechips.rocketchip.tile.{BaseTile, TileParams, SharedMemoryTLEdge, HasExternallyDrivenTileConstants}
|
||||||
|
import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp}
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
/** Enumerates the three types of clock crossing between tiles and system bus */
|
/** Enumerates the three types of clock crossing between tiles and system bus */
|
||||||
@ -29,6 +32,21 @@ abstract class BareCoreplexModule[+L <: BareCoreplex](_outer: L) extends LazyMod
|
|||||||
println(outer.dts)
|
println(outer.dts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait HasTiles extends HasSystemBus {
|
||||||
|
protected def tileParams: Seq[TileParams]
|
||||||
|
def nRocketTiles = tileParams.size
|
||||||
|
def hartIdList = tileParams.map(_.hartid)
|
||||||
|
|
||||||
|
// Handle interrupts to be routed directly into each tile
|
||||||
|
// TODO: figure out how to merge the localIntNodes and coreIntXbar
|
||||||
|
def localIntCounts = tileParams.map(_.core.nLocalInterrupts)
|
||||||
|
def localIntNodes = tileParams map { t =>
|
||||||
|
(t.core.nLocalInterrupts > 0).option(LazyModule(new IntXbar).intnode)
|
||||||
|
}
|
||||||
|
|
||||||
|
val tiles: Seq[BaseTile]
|
||||||
|
}
|
||||||
|
|
||||||
/** Base Coreplex class with no peripheral devices or ports added */
|
/** Base Coreplex class with no peripheral devices or ports added */
|
||||||
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
||||||
with HasInterruptBus
|
with HasInterruptBus
|
||||||
@ -87,6 +105,46 @@ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ClockedTileInputs(implicit val p: Parameters) extends ParameterizedBundle
|
||||||
|
with HasExternallyDrivenTileConstants
|
||||||
|
with Clocked
|
||||||
|
|
||||||
|
trait HasTilesBundle {
|
||||||
|
val tile_inputs: Vec[ClockedTileInputs]
|
||||||
|
}
|
||||||
|
|
||||||
|
trait HasTilesModuleImp extends LazyModuleImp
|
||||||
|
with HasTilesBundle
|
||||||
|
with HasResetVectorWire {
|
||||||
|
val outer: HasTiles
|
||||||
|
|
||||||
|
def resetVectorBits: Int = {
|
||||||
|
// Consider using the minimum over all widths, rather than enforcing homogeneity
|
||||||
|
val vectors = outer.tiles.map(_.module.io.reset_vector)
|
||||||
|
require(vectors.tail.forall(_.getWidth == vectors.head.getWidth))
|
||||||
|
vectors.head.getWidth
|
||||||
|
}
|
||||||
|
val tile_inputs = Wire(Vec(outer.nRocketTiles, new ClockedTileInputs()(p.alterPartial {
|
||||||
|
case SharedMemoryTLEdge => outer.sharedMemoryTLEdge
|
||||||
|
})))
|
||||||
|
|
||||||
|
// Unconditionally wire up the non-diplomatic tile inputs
|
||||||
|
outer.tiles.map(_.module).zip(tile_inputs).foreach { case(tile, wire) =>
|
||||||
|
tile.clock := wire.clock
|
||||||
|
tile.reset := wire.reset
|
||||||
|
tile.io.hartid := wire.hartid
|
||||||
|
tile.io.reset_vector := wire.reset_vector
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default values for tile inputs; may be overriden in other traits
|
||||||
|
tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
|
||||||
|
wire.clock := clock
|
||||||
|
wire.reset := reset
|
||||||
|
wire.hartid := UInt(i)
|
||||||
|
wire.reset_vector := global_reset_vector
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) {
|
abstract class BaseCoreplexModule[+L <: BaseCoreplex](_outer: L) extends BareCoreplexModule(_outer) {
|
||||||
println("Generated Address Map")
|
println("Generated Address Map")
|
||||||
private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1
|
private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1
|
||||||
|
@ -14,7 +14,7 @@ import freechips.rocketchip.util._
|
|||||||
case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
|
case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil)
|
||||||
case object RocketCrossing extends Field[CoreplexClockCrossing](SynchronousCrossing())
|
case object RocketCrossing extends Field[CoreplexClockCrossing](SynchronousCrossing())
|
||||||
|
|
||||||
trait HasRocketTiles extends HasSystemBus
|
trait HasRocketTiles extends HasTiles
|
||||||
with HasPeripheryBus
|
with HasPeripheryBus
|
||||||
with HasPeripheryPLIC
|
with HasPeripheryPLIC
|
||||||
with HasPeripheryClint
|
with HasPeripheryClint
|
||||||
@ -22,21 +22,11 @@ trait HasRocketTiles extends HasSystemBus
|
|||||||
val module: HasRocketTilesModuleImp
|
val module: HasRocketTilesModuleImp
|
||||||
|
|
||||||
private val crossing = p(RocketCrossing)
|
private val crossing = p(RocketCrossing)
|
||||||
private val tileParams = p(RocketTilesKey)
|
protected val tileParams = p(RocketTilesKey)
|
||||||
val nRocketTiles = tileParams.size
|
|
||||||
val hartIdList = tileParams.map(_.hartid)
|
|
||||||
|
|
||||||
// Handle interrupts to be routed directly into each tile
|
|
||||||
// TODO: figure out how to merge the localIntNodes and coreIntXbar below
|
|
||||||
val localIntCounts = tileParams.map(_.core.nLocalInterrupts)
|
|
||||||
val localIntNodes = tileParams map { t =>
|
|
||||||
(t.core.nLocalInterrupts > 0).option(LazyModule(new IntXbar).intnode)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
// Make a wrapper for each tile that will wire it to coreplex devices and crossbars,
|
||||||
// according to the specified type of clock crossing.
|
// according to the specified type of clock crossing.
|
||||||
val wiringTuple = localIntNodes.zip(tileParams)
|
val tiles: Seq[BaseTile] = localIntNodes.zip(tileParams).map { case (lip, tp) =>
|
||||||
val rocket_tiles: Seq[RocketTileWrapper] = wiringTuple.map { case (lip, tp) =>
|
|
||||||
val pWithExtra = p.alterPartial {
|
val pWithExtra = p.alterPartial {
|
||||||
case TileKey => tp
|
case TileKey => tp
|
||||||
case BuildRoCC => tp.rocc
|
case BuildRoCC => tp.rocc
|
||||||
@ -95,45 +85,9 @@ trait HasRocketTiles extends HasSystemBus
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ClockedRocketTileInputs(implicit val p: Parameters) extends ParameterizedBundle
|
trait HasRocketTilesModuleImp extends HasTilesModuleImp
|
||||||
with HasExternallyDrivenTileConstants
|
|
||||||
with Clocked
|
|
||||||
|
|
||||||
trait HasRocketTilesBundle {
|
|
||||||
val rocket_tile_inputs: Vec[ClockedRocketTileInputs]
|
|
||||||
}
|
|
||||||
|
|
||||||
trait HasRocketTilesModuleImp extends LazyModuleImp
|
|
||||||
with HasRocketTilesBundle
|
|
||||||
with HasResetVectorWire
|
|
||||||
with HasPeripheryDebugModuleImp {
|
with HasPeripheryDebugModuleImp {
|
||||||
val outer: HasRocketTiles
|
val outer: HasRocketTiles
|
||||||
|
|
||||||
def resetVectorBits: Int = {
|
|
||||||
// Consider using the minimum over all widths, rather than enforcing homogeneity
|
|
||||||
val vectors = outer.rocket_tiles.map(_.module.io.reset_vector)
|
|
||||||
require(vectors.tail.forall(_.getWidth == vectors.head.getWidth))
|
|
||||||
vectors.head.getWidth
|
|
||||||
}
|
|
||||||
val rocket_tile_inputs = Wire(Vec(outer.nRocketTiles, new ClockedRocketTileInputs()(p.alterPartial {
|
|
||||||
case SharedMemoryTLEdge => outer.sharedMemoryTLEdge
|
|
||||||
})))
|
|
||||||
|
|
||||||
// Unconditionally wire up the non-diplomatic tile inputs
|
|
||||||
outer.rocket_tiles.map(_.module).zip(rocket_tile_inputs).foreach { case(tile, wire) =>
|
|
||||||
tile.clock := wire.clock
|
|
||||||
tile.reset := wire.reset
|
|
||||||
tile.io.hartid := wire.hartid
|
|
||||||
tile.io.reset_vector := wire.reset_vector
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default values for tile inputs; may be overriden in other traits
|
|
||||||
rocket_tile_inputs.zip(outer.hartIdList).foreach { case(wire, i) =>
|
|
||||||
wire.clock := clock
|
|
||||||
wire.reset := reset
|
|
||||||
wire.hartid := UInt(i)
|
|
||||||
wire.reset_vector := global_reset_vector
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex
|
class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex
|
||||||
|
@ -25,7 +25,7 @@ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
|
|||||||
})
|
})
|
||||||
)}
|
)}
|
||||||
|
|
||||||
tiles.foreach { sbus.fromSyncTiles(BufferParams.default) :=* _.masterNode }
|
tiles.flatMap(_.dcacheOpt).foreach { sbus.fromSyncTiles(BufferParams.default) :=* _.node }
|
||||||
|
|
||||||
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbus.beatBytes))
|
val pbusRAM = LazyModule(new TLRAM(AddressSet(testRamAddr, 0xffff), false, pbus.beatBytes))
|
||||||
pbusRAM.node := pbus.toVariableWidthSlaves
|
pbusRAM.node := pbus.toVariableWidthSlaves
|
||||||
|
@ -31,13 +31,13 @@ case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]]
|
|||||||
abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) {
|
abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) {
|
||||||
val slave = None
|
val slave = None
|
||||||
val dcacheOpt = params.dcache.map { dc => LazyModule(HellaCache(0, dc.nMSHRs == 0)) }
|
val dcacheOpt = params.dcache.map { dc => LazyModule(HellaCache(0, dc.nMSHRs == 0)) }
|
||||||
dcacheOpt.foreach { tileBus.node := _.node }
|
|
||||||
|
|
||||||
override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this))
|
override lazy val module = new GroundTestTileModule(this, () => new GroundTestTileBundle(this))
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroundTestTileBundle[+L <: GroundTestTile](_outer: L) extends BaseTileBundle(_outer) {
|
class GroundTestTileBundle[+L <: GroundTestTile](_outer: L) extends BaseTileBundle(_outer) {
|
||||||
val status = new GroundTestStatus
|
val status = new GroundTestStatus
|
||||||
|
val halt_and_catch_fire = None
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroundTestTileModule[+L <: GroundTestTile, +B <: GroundTestTileBundle[L]](_outer: L, _io: () => B) extends BaseTileModule(_outer, _io) {
|
class GroundTestTileModule[+L <: GroundTestTile, +B <: GroundTestTileBundle[L]](_outer: L, _io: () => B) extends BaseTileModule(_outer, _io) {
|
||||||
|
@ -65,6 +65,7 @@ case class TraceGenParams(
|
|||||||
memStart: BigInt, //p(ExtMem).base
|
memStart: BigInt, //p(ExtMem).base
|
||||||
numGens: Int) extends GroundTestTileParams {
|
numGens: Int) extends GroundTestTileParams {
|
||||||
def build(i: Int, p: Parameters): GroundTestTile = new TraceGenTile(i, this)(p)
|
def build(i: Int, p: Parameters): GroundTestTile = new TraceGenTile(i, this)(p)
|
||||||
|
val hartid = 0
|
||||||
val trace = false
|
val trace = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ object ALU
|
|||||||
|
|
||||||
def isMulFN(fn: UInt, cmp: UInt) = fn(1,0) === cmp(1,0)
|
def isMulFN(fn: UInt, cmp: UInt) = fn(1,0) === cmp(1,0)
|
||||||
def isSub(cmd: UInt) = cmd(3)
|
def isSub(cmd: UInt) = cmd(3)
|
||||||
def isCmp(cmd: UInt) = cmd === FN_SEQ || cmd === FN_SNE || cmd >= FN_SLT
|
def isCmp(cmd: UInt) = cmd >= FN_SLT
|
||||||
def cmpUnsigned(cmd: UInt) = cmd(1)
|
def cmpUnsigned(cmd: UInt) = cmd(1)
|
||||||
def cmpInverted(cmd: UInt) = cmd(0)
|
def cmpInverted(cmd: UInt) = cmd(0)
|
||||||
def cmpEq(cmd: UInt) = !cmd(3)
|
def cmpEq(cmd: UInt) = !cmd(3)
|
||||||
@ -64,10 +64,10 @@ class ALU(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
io.adder_out := io.in1 + in2_inv + isSub(io.fn)
|
io.adder_out := io.in1 + in2_inv + isSub(io.fn)
|
||||||
|
|
||||||
// SLT, SLTU
|
// SLT, SLTU
|
||||||
io.cmp_out := cmpInverted(io.fn) ^
|
val slt =
|
||||||
Mux(cmpEq(io.fn), in1_xor_in2 === UInt(0),
|
|
||||||
Mux(io.in1(xLen-1) === io.in2(xLen-1), io.adder_out(xLen-1),
|
Mux(io.in1(xLen-1) === io.in2(xLen-1), io.adder_out(xLen-1),
|
||||||
Mux(cmpUnsigned(io.fn), io.in2(xLen-1), io.in1(xLen-1))))
|
Mux(cmpUnsigned(io.fn), io.in2(xLen-1), io.in1(xLen-1)))
|
||||||
|
io.cmp_out := cmpInverted(io.fn) ^ Mux(cmpEq(io.fn), in1_xor_in2 === UInt(0), slt)
|
||||||
|
|
||||||
// SLL, SRL, SRA
|
// SLL, SRL, SRA
|
||||||
val (shamt, shin_r) =
|
val (shamt, shin_r) =
|
||||||
@ -88,7 +88,7 @@ class ALU(implicit p: Parameters) extends CoreModule()(p) {
|
|||||||
// AND, OR, XOR
|
// AND, OR, XOR
|
||||||
val logic = Mux(io.fn === FN_XOR || io.fn === FN_OR, in1_xor_in2, UInt(0)) |
|
val logic = Mux(io.fn === FN_XOR || io.fn === FN_OR, in1_xor_in2, UInt(0)) |
|
||||||
Mux(io.fn === FN_OR || io.fn === FN_AND, io.in1 & io.in2, UInt(0))
|
Mux(io.fn === FN_OR || io.fn === FN_AND, io.in1 & io.in2, UInt(0))
|
||||||
val shift_logic = (isCmp(io.fn) && io.cmp_out) | logic | shout
|
val shift_logic = (isCmp(io.fn) && slt) | logic | shout
|
||||||
val out = Mux(io.fn === FN_ADD || io.fn === FN_SUB, io.adder_out, shift_logic)
|
val out = Mux(io.fn === FN_ADD || io.fn === FN_SUB, io.adder_out, shift_logic)
|
||||||
|
|
||||||
io.out := out
|
io.out := out
|
||||||
|
@ -85,9 +85,6 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
|
|||||||
val r_req_dest = Reg(Bits())
|
val r_req_dest = Reg(Bits())
|
||||||
val r_pte = Reg(new PTE)
|
val r_pte = Reg(new PTE)
|
||||||
|
|
||||||
val vpn_idxs = (0 until pgLevels).map(i => (r_req.addr >> (pgLevels-i-1)*pgLevelBits)(pgLevelBits-1,0))
|
|
||||||
val vpn_idx = vpn_idxs(count)
|
|
||||||
|
|
||||||
val arb = Module(new RRArbiter(new PTWReq, n))
|
val arb = Module(new RRArbiter(new PTWReq, n))
|
||||||
arb.io.in <> io.requestor.map(_.req)
|
arb.io.in <> io.requestor.map(_.req)
|
||||||
arb.io.out.ready := state === s_ready
|
arb.io.out.ready := state === s_ready
|
||||||
@ -104,7 +101,11 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
|
|||||||
(res, (tmp.ppn >> ppnBits) =/= 0)
|
(res, (tmp.ppn >> ppnBits) =/= 0)
|
||||||
}
|
}
|
||||||
val traverse = pte.table() && !invalid_paddr && count < pgLevels-1
|
val traverse = pte.table() && !invalid_paddr && count < pgLevels-1
|
||||||
val pte_addr = Cat(r_pte.ppn, vpn_idx) << log2Ceil(xLen/8)
|
val pte_addr = if (!usingVM) 0.U else {
|
||||||
|
val vpn_idxs = (0 until pgLevels).map(i => (r_req.addr >> (pgLevels-i-1)*pgLevelBits)(pgLevelBits-1,0))
|
||||||
|
val vpn_idx = vpn_idxs(count)
|
||||||
|
Cat(r_pte.ppn, vpn_idx) << log2Ceil(xLen/8)
|
||||||
|
}
|
||||||
|
|
||||||
when (arb.io.out.fire()) {
|
when (arb.io.out.fire()) {
|
||||||
r_req := arb.io.out.bits
|
r_req := arb.io.out.bits
|
||||||
|
@ -152,6 +152,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
val mem_reg_raw_inst = Reg(UInt())
|
val mem_reg_raw_inst = Reg(UInt())
|
||||||
val mem_reg_wdata = Reg(Bits())
|
val mem_reg_wdata = Reg(Bits())
|
||||||
val mem_reg_rs2 = Reg(Bits())
|
val mem_reg_rs2 = Reg(Bits())
|
||||||
|
val mem_br_taken = Reg(Bool())
|
||||||
val take_pc_mem = Wire(Bool())
|
val take_pc_mem = Wire(Bool())
|
||||||
|
|
||||||
val wb_reg_valid = Reg(Bool())
|
val wb_reg_valid = Reg(Bool())
|
||||||
@ -361,7 +362,6 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
|
|
||||||
// memory stage
|
// memory stage
|
||||||
val mem_pc_valid = mem_reg_valid || mem_reg_replay || mem_reg_xcpt_interrupt
|
val mem_pc_valid = mem_reg_valid || mem_reg_replay || mem_reg_xcpt_interrupt
|
||||||
val mem_br_taken = mem_reg_wdata(0)
|
|
||||||
val mem_br_target = mem_reg_pc.asSInt +
|
val mem_br_target = mem_reg_pc.asSInt +
|
||||||
Mux(mem_ctrl.branch && mem_br_taken, ImmGen(IMM_SB, mem_reg_inst),
|
Mux(mem_ctrl.branch && mem_br_taken, ImmGen(IMM_SB, mem_reg_inst),
|
||||||
Mux(mem_ctrl.jal, ImmGen(IMM_UJ, mem_reg_inst),
|
Mux(mem_ctrl.jal, ImmGen(IMM_UJ, mem_reg_inst),
|
||||||
@ -403,6 +403,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p)
|
|||||||
mem_reg_raw_inst := ex_reg_raw_inst
|
mem_reg_raw_inst := ex_reg_raw_inst
|
||||||
mem_reg_pc := ex_reg_pc
|
mem_reg_pc := ex_reg_pc
|
||||||
mem_reg_wdata := alu.io.out
|
mem_reg_wdata := alu.io.out
|
||||||
|
mem_br_taken := alu.io.cmp_out
|
||||||
|
|
||||||
when (ex_ctrl.rxs2 && (ex_ctrl.mem || ex_ctrl.rocc || ex_sfence)) {
|
when (ex_ctrl.rxs2 && (ex_ctrl.mem || ex_ctrl.rocc || ex_sfence)) {
|
||||||
val typ = Mux(ex_ctrl.rocc, log2Ceil(xLen/8).U, ex_ctrl.mem_type)
|
val typ = Mux(ex_ctrl.rocc, log2Ceil(xLen/8).U, ex_ctrl.mem_type)
|
||||||
|
@ -97,7 +97,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL
|
|||||||
val vm_enabled = Bool(usingVM) && io.ptw.ptbr.mode(io.ptw.ptbr.mode.getWidth-1) && priv_uses_vm && !io.req.bits.passthrough
|
val vm_enabled = Bool(usingVM) && io.ptw.ptbr.mode(io.ptw.ptbr.mode.getWidth-1) && priv_uses_vm && !io.req.bits.passthrough
|
||||||
|
|
||||||
// share a single physical memory attribute checker (unshare if critical path)
|
// share a single physical memory attribute checker (unshare if critical path)
|
||||||
val (vpn, pgOffset) = Split(io.req.bits.vaddr, pgIdxBits)
|
val vpn = io.req.bits.vaddr(vaddrBits-1, pgIdxBits)
|
||||||
val refill_ppn = io.ptw.resp.bits.pte.ppn(ppnBits-1, 0)
|
val refill_ppn = io.ptw.resp.bits.pte.ppn(ppnBits-1, 0)
|
||||||
val do_refill = Bool(usingVM) && io.ptw.resp.valid
|
val do_refill = Bool(usingVM) && io.ptw.resp.valid
|
||||||
val invalidate_refill = state.isOneOf(s_request /* don't care */, s_wait_invalidate)
|
val invalidate_refill = state.isOneOf(s_request /* don't care */, s_wait_invalidate)
|
||||||
@ -121,8 +121,8 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL
|
|||||||
val prot_x = fastCheck(_.executable) && pmp.io.x
|
val prot_x = fastCheck(_.executable) && pmp.io.x
|
||||||
val prot_eff = fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType)
|
val prot_eff = fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType)
|
||||||
|
|
||||||
val lookup_tag = Cat(io.ptw.ptbr.asid, vpn(vpnBits-1,0))
|
val lookup_tag = Cat(io.ptw.ptbr.asid, vpn)
|
||||||
val hitsVec = (0 until totalEntries).map { i => vm_enabled && {
|
val hitsVec = (0 until totalEntries).map { i => if (!usingVM) false.B else vm_enabled && {
|
||||||
var tagMatch = valid(i)
|
var tagMatch = valid(i)
|
||||||
for (j <- 0 until pgLevels) {
|
for (j <- 0 until pgLevels) {
|
||||||
val base = vpnBits - (j + 1) * pgLevelBits
|
val base = vpnBits - (j + 1) * pgLevelBits
|
||||||
@ -133,7 +133,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL
|
|||||||
val hits = hitsVec.asUInt
|
val hits = hitsVec.asUInt
|
||||||
val level = Mux1H(hitsVec.init, entries.map(_.level))
|
val level = Mux1H(hitsVec.init, entries.map(_.level))
|
||||||
val partialPPN = Mux1H(hitsVec.init, entries.map(_.ppn))
|
val partialPPN = Mux1H(hitsVec.init, entries.map(_.ppn))
|
||||||
val ppn = {
|
val ppn = if (!usingVM) vpn else {
|
||||||
var ppn = Mux(vm_enabled, partialPPN, vpn)(pgLevelBits*pgLevels - 1, pgLevelBits*(pgLevels - 1))
|
var ppn = Mux(vm_enabled, partialPPN, vpn)(pgLevelBits*pgLevels - 1, pgLevelBits*(pgLevels - 1))
|
||||||
for (i <- 1 until pgLevels)
|
for (i <- 1 until pgLevels)
|
||||||
ppn = Cat(ppn, (Mux(level < i, vpn, 0.U) | partialPPN)(vpnBits - i*pgLevelBits - 1, vpnBits - (i + 1)*pgLevelBits))
|
ppn = Cat(ppn, (Mux(level < i, vpn, 0.U) | partialPPN)(vpnBits - i*pgLevelBits - 1, vpnBits - (i + 1)*pgLevelBits))
|
||||||
@ -187,7 +187,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL
|
|||||||
val misaligned = (io.req.bits.vaddr & (UIntToOH(io.req.bits.size) - 1)).orR
|
val misaligned = (io.req.bits.vaddr & (UIntToOH(io.req.bits.size) - 1)).orR
|
||||||
val bad_va = vm_enabled &&
|
val bad_va = vm_enabled &&
|
||||||
(if (vpnBits == vpnBitsExtended) Bool(false)
|
(if (vpnBits == vpnBitsExtended) Bool(false)
|
||||||
else vpn(vpnBits) =/= vpn(vpnBits-1))
|
else (io.req.bits.vaddr.asSInt < 0.S) =/= (vpn.asSInt < 0.S))
|
||||||
|
|
||||||
val lrscAllowed = Mux(Bool(usingDataScratchpad), 0.U, c_array)
|
val lrscAllowed = Mux(Bool(usingDataScratchpad), 0.U, c_array)
|
||||||
val ae_array =
|
val ae_array =
|
||||||
@ -230,7 +230,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL
|
|||||||
io.resp.cacheable := (c_array & hits).orR
|
io.resp.cacheable := (c_array & hits).orR
|
||||||
io.resp.prefetchable := (prefetchable_array & hits).orR && edge.manager.managers.forall(m => !m.supportsAcquireB || m.supportsHint)
|
io.resp.prefetchable := (prefetchable_array & hits).orR && edge.manager.managers.forall(m => !m.supportsAcquireB || m.supportsHint)
|
||||||
io.resp.miss := do_refill || tlb_miss || multipleHits
|
io.resp.miss := do_refill || tlb_miss || multipleHits
|
||||||
io.resp.paddr := Cat(ppn, pgOffset)
|
io.resp.paddr := Cat(ppn, io.req.bits.vaddr(pgIdxBits-1, 0))
|
||||||
|
|
||||||
io.ptw.req.valid := state === s_request
|
io.ptw.req.valid := state === s_request
|
||||||
io.ptw.req.bits <> io.ptw.status
|
io.ptw.req.bits <> io.ptw.status
|
||||||
@ -256,7 +256,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (sfence) {
|
when (sfence) {
|
||||||
assert((io.req.bits.sfence.bits.addr >> pgIdxBits) === vpn(vpnBits-1,0))
|
assert((io.req.bits.sfence.bits.addr >> pgIdxBits) === vpn)
|
||||||
valid := Mux(io.req.bits.sfence.bits.rs1, valid & ~hits(totalEntries-1, 0),
|
valid := Mux(io.req.bits.sfence.bits.rs1, valid & ~hits(totalEntries-1, 0),
|
||||||
Mux(io.req.bits.sfence.bits.rs2, valid & entries.map(_.g).asUInt, 0))
|
Mux(io.req.bits.sfence.bits.rs2, valid & entries.map(_.g).asUInt, 0))
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ trait TileParams {
|
|||||||
val rocc: Seq[RoCCParams]
|
val rocc: Seq[RoCCParams]
|
||||||
val btb: Option[BTBParams]
|
val btb: Option[BTBParams]
|
||||||
val trace: Boolean
|
val trace: Boolean
|
||||||
|
val hartid: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasTileParameters {
|
trait HasTileParameters {
|
||||||
@ -41,7 +42,14 @@ trait HasTileParameters {
|
|||||||
def iLen: Int = 32
|
def iLen: Int = 32
|
||||||
def pgIdxBits: Int = 12
|
def pgIdxBits: Int = 12
|
||||||
def pgLevelBits: Int = 10 - log2Ceil(xLen / 32)
|
def pgLevelBits: Int = 10 - log2Ceil(xLen / 32)
|
||||||
def vaddrBits: Int = pgIdxBits + pgLevels * pgLevelBits
|
def vaddrBits: Int =
|
||||||
|
if (usingVM) {
|
||||||
|
val v = pgIdxBits + pgLevels * pgLevelBits
|
||||||
|
require(v == xLen || xLen > v && v > paddrBits)
|
||||||
|
v
|
||||||
|
} else {
|
||||||
|
paddrBits min xLen
|
||||||
|
}
|
||||||
def paddrBits: Int = p(SharedMemoryTLEdge).bundle.addressBits
|
def paddrBits: Int = p(SharedMemoryTLEdge).bundle.addressBits
|
||||||
def vpnBits: Int = vaddrBits - pgIdxBits
|
def vpnBits: Int = vaddrBits - pgIdxBits
|
||||||
def ppnBits: Int = paddrBits - pgIdxBits
|
def ppnBits: Int = paddrBits - pgIdxBits
|
||||||
@ -52,7 +60,7 @@ trait HasTileParameters {
|
|||||||
def maxPAddrBits: Int = xLen match { case 32 => 34; case 64 => 56 }
|
def maxPAddrBits: Int = xLen match { case 32 => 34; case 64 => 56 }
|
||||||
|
|
||||||
def hartIdLen: Int = p(MaxHartIdBits)
|
def hartIdLen: Int = p(MaxHartIdBits)
|
||||||
def resetVectorLen: Int = paddrBits min vaddrBitsExtended
|
def resetVectorLen: Int = paddrBits
|
||||||
|
|
||||||
def dcacheArbPorts = 1 + usingVM.toInt + usingDataScratchpad.toInt + tileParams.rocc.size
|
def dcacheArbPorts = 1 + usingVM.toInt + usingDataScratchpad.toInt + tileParams.rocc.size
|
||||||
}
|
}
|
||||||
@ -99,19 +107,17 @@ trait CanHaveInstructionTracePort extends Bundle with HasTileParameters {
|
|||||||
|
|
||||||
/** Base class for all Tiles that use TileLink */
|
/** Base class for all Tiles that use TileLink */
|
||||||
abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile
|
abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile
|
||||||
with HasTileParameters
|
with HasTileParameters {
|
||||||
with HasTileLinkMasterPort {
|
def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]]
|
||||||
override lazy val module = new BaseTileModule(this, () => new BaseTileBundle(this))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
|
abstract class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
|
||||||
with HasTileLinkMasterPortBundle
|
|
||||||
with HasExternallyDrivenTileConstants
|
with HasExternallyDrivenTileConstants
|
||||||
with CanHaveInstructionTracePort
|
with CanHaveInstructionTracePort
|
||||||
|
with CanHaltAndCatchFire
|
||||||
|
|
||||||
class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io)
|
class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io)
|
||||||
with HasTileParameters
|
with HasTileParameters {
|
||||||
with HasTileLinkMasterPortModule {
|
|
||||||
require(xLen == 32 || xLen == 64)
|
require(xLen == 32 || xLen == 64)
|
||||||
require(paddrBits <= maxPAddrBits)
|
require(paddrBits <= maxPAddrBits)
|
||||||
require(resetVectorLen <= xLen)
|
require(resetVectorLen <= xLen)
|
||||||
|
@ -181,7 +181,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
|
|||||||
ptw.io.requestor <> ptwPorts
|
ptw.io.requestor <> ptwPorts
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class RocketTileWrapper(rtp: RocketTileParams)(implicit p: Parameters) extends LazyModule {
|
class RocketTileWrapperBundle[+L <: RocketTileWrapper](_outer: L) extends BaseTileBundle(_outer)
|
||||||
|
with CanHaltAndCatchFire {
|
||||||
|
val halt_and_catch_fire = _outer.rocket.module.io.halt_and_catch_fire.map(_.cloneType)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class RocketTileWrapper(rtp: RocketTileParams)(implicit p: Parameters) extends BaseTile(rtp) {
|
||||||
val rocket = LazyModule(new RocketTile(rtp))
|
val rocket = LazyModule(new RocketTile(rtp))
|
||||||
val asyncIntNode : IntInwardNode
|
val asyncIntNode : IntInwardNode
|
||||||
val periphIntNode : IntInwardNode
|
val periphIntNode : IntInwardNode
|
||||||
@ -213,13 +218,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams)(implicit p: Parameters)
|
|||||||
|
|
||||||
def outputInterruptXingLatency: Int
|
def outputInterruptXingLatency: Int
|
||||||
|
|
||||||
lazy val module = new LazyModuleImp(this) {
|
override lazy val module = new BaseTileModule(this, () => new RocketTileWrapperBundle(this)) {
|
||||||
val io = IO(new CoreBundle
|
|
||||||
with HasExternallyDrivenTileConstants
|
|
||||||
with CanHaveInstructionTracePort
|
|
||||||
with CanHaltAndCatchFire {
|
|
||||||
val halt_and_catch_fire = rocket.module.io.halt_and_catch_fire.map(_.cloneType)
|
|
||||||
})
|
|
||||||
// signals that do not change based on crossing type:
|
// signals that do not change based on crossing type:
|
||||||
rocket.module.io.hartid := io.hartid
|
rocket.module.io.hartid := io.hartid
|
||||||
rocket.module.io.reset_vector := io.reset_vector
|
rocket.module.io.reset_vector := io.reset_vector
|
||||||
|
Loading…
Reference in New Issue
Block a user