From 4645b61fd372f3a8ddd77936bf37e3b41380ef4b Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 5 Oct 2017 22:23:58 -0700 Subject: [PATCH 1/7] Decouple BaseTile from HasTileLinkMasterPort --- src/main/scala/groundtest/Coreplex.scala | 2 +- src/main/scala/groundtest/Tile.scala | 1 - src/main/scala/tile/BaseTile.scala | 7 ++----- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index 63730436..d6dab576 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -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)) pbusRAM.node := pbus.toVariableWidthSlaves diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 78a4aa63..5484466b 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -31,7 +31,6 @@ case object GroundTestTilesKey extends Field[Seq[GroundTestTileParams]] abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Parameters) extends BaseTile(params)(p) { val slave = None 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)) } diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index a6f5bebe..03e24429 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -99,19 +99,16 @@ trait CanHaveInstructionTracePort extends Bundle with HasTileParameters { /** Base class for all Tiles that use TileLink */ abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile - with HasTileParameters - with HasTileLinkMasterPort { + with HasTileParameters { override lazy val module = new BaseTileModule(this, () => new BaseTileBundle(this)) } class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer) - with HasTileLinkMasterPortBundle with HasExternallyDrivenTileConstants with CanHaveInstructionTracePort class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io) - with HasTileParameters - with HasTileLinkMasterPortModule { + with HasTileParameters { require(xLen == 32 || xLen == 64) require(paddrBits <= maxPAddrBits) require(resetVectorLen <= xLen) From 71205b70cc56b9c07cea3d8d9ea5ebd50b01e9a6 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 5 Oct 2017 22:46:16 -0700 Subject: [PATCH 2/7] Make RocketTileWrapper a BaseTile --- src/main/scala/coreplex/RocketCoreplex.scala | 2 +- src/main/scala/tile/RocketTile.scala | 15 +++++++-------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index e7009316..43a3c4c1 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -36,7 +36,7 @@ trait HasRocketTiles extends HasSystemBus // Make a wrapper for each tile that will wire it to coreplex devices and crossbars, // according to the specified type of clock crossing. val wiringTuple = localIntNodes.zip(tileParams) - val rocket_tiles: Seq[RocketTileWrapper] = wiringTuple.map { case (lip, tp) => + val rocket_tiles: Seq[BaseTile] = wiringTuple.map { case (lip, tp) => val pWithExtra = p.alterPartial { case TileKey => tp case BuildRoCC => tp.rocc diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index 9d9b7b94..6fec665f 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -181,7 +181,12 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne 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 asyncIntNode : IntInwardNode val periphIntNode : IntInwardNode @@ -213,13 +218,7 @@ abstract class RocketTileWrapper(rtp: RocketTileParams)(implicit p: Parameters) def outputInterruptXingLatency: Int - lazy val module = new LazyModuleImp(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) - }) + override lazy val module = new BaseTileModule(this, () => new RocketTileWrapperBundle(this)) { // signals that do not change based on crossing type: rocket.module.io.hartid := io.hartid rocket.module.io.reset_vector := io.reset_vector From 34e96c03b149a6a572d2de3fb0265075faba60d5 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Thu, 5 Oct 2017 23:49:35 -0700 Subject: [PATCH 3/7] Move HCF to BaseTile --- src/main/scala/groundtest/Tile.scala | 1 + src/main/scala/tile/BaseTile.scala | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 5484466b..573e71c6 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -37,6 +37,7 @@ abstract class GroundTestTile(params: GroundTestTileParams)(implicit p: Paramete class GroundTestTileBundle[+L <: GroundTestTile](_outer: L) extends BaseTileBundle(_outer) { 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) { diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 03e24429..ff2f8d95 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -100,12 +100,13 @@ trait CanHaveInstructionTracePort extends Bundle with HasTileParameters { /** Base class for all Tiles that use TileLink */ abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile with HasTileParameters { - override lazy val module = new BaseTileModule(this, () => new BaseTileBundle(this)) + def module: BaseTileModule[BaseTile, BaseTileBundle[BaseTile]] } -class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer) +abstract class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer) with HasExternallyDrivenTileConstants with CanHaveInstructionTracePort + with CanHaltAndCatchFire class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io) with HasTileParameters { From 70a4127cb829356c86d47953417dee79b35c279f Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Fri, 6 Oct 2017 00:56:23 -0700 Subject: [PATCH 4/7] Factor out some of HaveRocketTiles into HaveTiles --- src/main/scala/coreplex/BaseCoreplex.scala | 18 ++++++++++++++++++ src/main/scala/coreplex/RocketCoreplex.scala | 18 ++++-------------- src/main/scala/groundtest/TraceGen.scala | 1 + src/main/scala/tile/BaseTile.scala | 1 + 4 files changed, 24 insertions(+), 14 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 963bf2b2..ba0d34dc 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -6,6 +6,9 @@ import Chisel._ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.tile.{BaseTile, TileParams} +import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp} import freechips.rocketchip.util._ /** 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) } +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 rocket_tiles: Seq[BaseTile] +} + /** Base Coreplex class with no peripheral devices or ports added */ abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex with HasInterruptBus diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 43a3c4c1..88f9b2e7 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -14,7 +14,7 @@ import freechips.rocketchip.util._ case object RocketTilesKey extends Field[Seq[RocketTileParams]](Nil) case object RocketCrossing extends Field[CoreplexClockCrossing](SynchronousCrossing()) -trait HasRocketTiles extends HasSystemBus +trait HasRocketTiles extends HasTiles with HasPeripheryBus with HasPeripheryPLIC with HasPeripheryClint @@ -22,21 +22,11 @@ trait HasRocketTiles extends HasSystemBus val module: HasRocketTilesModuleImp private val crossing = p(RocketCrossing) - private 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) - } + protected val tileParams = p(RocketTilesKey) // Make a wrapper for each tile that will wire it to coreplex devices and crossbars, // according to the specified type of clock crossing. - val wiringTuple = localIntNodes.zip(tileParams) - val rocket_tiles: Seq[BaseTile] = wiringTuple.map { case (lip, tp) => + val rocket_tiles: Seq[BaseTile] = localIntNodes.zip(tileParams).map { case (lip, tp) => val pWithExtra = p.alterPartial { case TileKey => tp case BuildRoCC => tp.rocc @@ -107,7 +97,7 @@ trait HasRocketTilesModuleImp extends LazyModuleImp with HasRocketTilesBundle with HasResetVectorWire with HasPeripheryDebugModuleImp { - val outer: HasRocketTiles + val outer: HasTiles with HasPeripheryDebug def resetVectorBits: Int = { // Consider using the minimum over all widths, rather than enforcing homogeneity diff --git a/src/main/scala/groundtest/TraceGen.scala b/src/main/scala/groundtest/TraceGen.scala index f1779776..5d10d30e 100644 --- a/src/main/scala/groundtest/TraceGen.scala +++ b/src/main/scala/groundtest/TraceGen.scala @@ -65,6 +65,7 @@ case class TraceGenParams( memStart: BigInt, //p(ExtMem).base numGens: Int) extends GroundTestTileParams { def build(i: Int, p: Parameters): GroundTestTile = new TraceGenTile(i, this)(p) + val hartid = 0 val trace = false } diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index ff2f8d95..8b1953cd 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -22,6 +22,7 @@ trait TileParams { val rocc: Seq[RoCCParams] val btb: Option[BTBParams] val trace: Boolean + val hartid: Int } trait HasTileParameters { From 36c39d01e4e7ee358d5793aea0be0492bcb83575 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 7 Oct 2017 17:29:50 -0700 Subject: [PATCH 5/7] Factor out most of HasRocketTiles into HasTiles --- src/main/scala/coreplex/BaseCoreplex.scala | 44 +++++++++++++++++++- src/main/scala/coreplex/RocketCoreplex.scala | 42 ++----------------- 2 files changed, 45 insertions(+), 41 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index ba0d34dc..ae54c9a6 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -7,7 +7,7 @@ import freechips.rocketchip.config.Parameters import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.devices.tilelink._ -import freechips.rocketchip.tile.{BaseTile, TileParams} +import freechips.rocketchip.tile.{BaseTile, TileParams, SharedMemoryTLEdge, HasExternallyDrivenTileConstants} import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp} import freechips.rocketchip.util._ @@ -44,7 +44,7 @@ trait HasTiles extends HasSystemBus { (t.core.nLocalInterrupts > 0).option(LazyModule(new IntXbar).intnode) } - val rocket_tiles: Seq[BaseTile] + val tiles: Seq[BaseTile] } /** Base Coreplex class with no peripheral devices or ports added */ @@ -105,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) { println("Generated Address Map") private val aw = (outer.sharedMemoryTLEdge.bundle.addressBits-1)/4 + 1 diff --git a/src/main/scala/coreplex/RocketCoreplex.scala b/src/main/scala/coreplex/RocketCoreplex.scala index 88f9b2e7..fa315ddb 100644 --- a/src/main/scala/coreplex/RocketCoreplex.scala +++ b/src/main/scala/coreplex/RocketCoreplex.scala @@ -26,7 +26,7 @@ trait HasRocketTiles extends HasTiles // Make a wrapper for each tile that will wire it to coreplex devices and crossbars, // according to the specified type of clock crossing. - val rocket_tiles: Seq[BaseTile] = localIntNodes.zip(tileParams).map { case (lip, tp) => + val tiles: Seq[BaseTile] = localIntNodes.zip(tileParams).map { case (lip, tp) => val pWithExtra = p.alterPartial { case TileKey => tp case BuildRoCC => tp.rocc @@ -85,45 +85,9 @@ trait HasRocketTiles extends HasTiles } } -class ClockedRocketTileInputs(implicit val p: Parameters) extends ParameterizedBundle - with HasExternallyDrivenTileConstants - with Clocked - -trait HasRocketTilesBundle { - val rocket_tile_inputs: Vec[ClockedRocketTileInputs] -} - -trait HasRocketTilesModuleImp extends LazyModuleImp - with HasRocketTilesBundle - with HasResetVectorWire +trait HasRocketTilesModuleImp extends HasTilesModuleImp with HasPeripheryDebugModuleImp { - val outer: HasTiles with HasPeripheryDebug - - 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 - } + val outer: HasRocketTiles } class RocketCoreplex(implicit p: Parameters) extends BaseCoreplex From a0e5a20b60b17fa3fff2dd26e37aad8b227a7817 Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 7 Oct 2017 17:31:23 -0700 Subject: [PATCH 6/7] Don't route branch comparison result through ALU output mux This potentially mitigates a critical path, and makes the ALU usable in processors that have dedicated branch comparators. --- src/main/scala/rocket/ALU.scala | 10 +++++----- src/main/scala/rocket/RocketCore.scala | 3 ++- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/scala/rocket/ALU.scala b/src/main/scala/rocket/ALU.scala index 9636bbed..7791a4ee 100644 --- a/src/main/scala/rocket/ALU.scala +++ b/src/main/scala/rocket/ALU.scala @@ -38,7 +38,7 @@ object ALU def isMulFN(fn: UInt, cmp: UInt) = fn(1,0) === cmp(1,0) 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 cmpInverted(cmd: UInt) = cmd(0) 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) // SLT, SLTU - io.cmp_out := cmpInverted(io.fn) ^ - Mux(cmpEq(io.fn), in1_xor_in2 === UInt(0), + val slt = 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 val (shamt, shin_r) = @@ -88,7 +88,7 @@ class ALU(implicit p: Parameters) extends CoreModule()(p) { // AND, OR, XOR 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)) - 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) io.out := out diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index f5c4b78f..7ac6b43d 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -152,6 +152,7 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) val mem_reg_raw_inst = Reg(UInt()) val mem_reg_wdata = Reg(Bits()) val mem_reg_rs2 = Reg(Bits()) + val mem_br_taken = Reg(Bool()) val take_pc_mem = Wire(Bool()) val wb_reg_valid = Reg(Bool()) @@ -361,7 +362,6 @@ class Rocket(implicit p: Parameters) extends CoreModule()(p) // memory stage 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 + Mux(mem_ctrl.branch && mem_br_taken, ImmGen(IMM_SB, 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_pc := ex_reg_pc 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)) { val typ = Mux(ex_ctrl.rocc, log2Ceil(xLen/8).U, ex_ctrl.mem_type) From 986cbfb6b1266c7c293b1f9968096b65e09d5d0a Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Sat, 7 Oct 2017 17:33:36 -0700 Subject: [PATCH 7/7] For Rockets without VM, widen vaddrBits to paddrBits This supports addressing a >39-bit physical address space. --- src/main/scala/rocket/PTW.scala | 9 +++++---- src/main/scala/rocket/TLB.scala | 14 +++++++------- src/main/scala/tile/BaseTile.scala | 11 +++++++++-- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 70ec7b12..118abdb1 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -84,9 +84,6 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( val r_req = Reg(new PTWReq) val r_req_dest = Reg(Bits()) 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)) arb.io.in <> io.requestor.map(_.req) @@ -104,7 +101,11 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( (res, (tmp.ppn >> ppnBits) =/= 0) } 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()) { r_req := arb.io.out.bits diff --git a/src/main/scala/rocket/TLB.scala b/src/main/scala/rocket/TLB.scala index da25dd0e..47619484 100644 --- a/src/main/scala/rocket/TLB.scala +++ b/src/main/scala/rocket/TLB.scala @@ -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 // 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 do_refill = Bool(usingVM) && io.ptw.resp.valid 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_eff = fastCheck(Seq(RegionType.PUT_EFFECTS, RegionType.GET_EFFECTS) contains _.regionType) - val lookup_tag = Cat(io.ptw.ptbr.asid, vpn(vpnBits-1,0)) - val hitsVec = (0 until totalEntries).map { i => vm_enabled && { + val lookup_tag = Cat(io.ptw.ptbr.asid, vpn) + val hitsVec = (0 until totalEntries).map { i => if (!usingVM) false.B else vm_enabled && { var tagMatch = valid(i) for (j <- 0 until pgLevels) { 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 level = Mux1H(hitsVec.init, entries.map(_.level)) 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)) for (i <- 1 until pgLevels) 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 bad_va = vm_enabled && (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 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.prefetchable := (prefetchable_array & hits).orR && edge.manager.managers.forall(m => !m.supportsAcquireB || m.supportsHint) 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.bits <> io.ptw.status @@ -256,7 +256,7 @@ class TLB(instruction: Boolean, lgMaxSize: Int, nEntries: Int)(implicit edge: TL } 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), Mux(io.req.bits.sfence.bits.rs2, valid & entries.map(_.g).asUInt, 0)) } diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index 8b1953cd..71e3f909 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -42,7 +42,14 @@ trait HasTileParameters { def iLen: Int = 32 def pgIdxBits: Int = 12 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 vpnBits: Int = vaddrBits - pgIdxBits def ppnBits: Int = paddrBits - pgIdxBits @@ -53,7 +60,7 @@ trait HasTileParameters { def maxPAddrBits: Int = xLen match { case 32 => 34; case 64 => 56 } 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 }