From 18f1ca55589d6321bbd34c259a96c113de84b44e Mon Sep 17 00:00:00 2001 From: Yanqi Yang <45751663+midnighter95@users.noreply.github.com> Date: Fri, 26 May 2023 12:47:08 +0800 Subject: [PATCH 1/8] Add CI (#13) * fix hartid * add ci * update ci * add matrix --- .github/workflows/ci.yml | 41 +++++++++++++++++++++++++++++++++++ build.sc | 7 +++++- cosim/elaborate/src/DUT.scala | 2 +- 3 files changed, 48 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..002683cc3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,41 @@ +# This file describes the GitHub Actions workflow for continuous integration of rocket-chip. +# +# See +# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions +# for API reference documentation on this file format. + +name: Mill Continuous Integration +env: + USER: runner + +on: + push: + branches: + - split + pull_request: + branches: + - split + +jobs: + riscv-test: + name: riscv-tests + runs-on: ubuntu-latest + strategy: + matrix: + config: [rv32, rv64] + steps: + - uses: actions/checkout@v2 + with: + submodules: 'true' + + - uses: cachix/install-nix-action@v19 + with: + install_url: https://releases.nixos.org/nix/nix-2.13.3/install + nix_path: nixpkgs=channel:nixos-unstable + + - name: Coursier Cache + uses: coursier/cache-action@v5 + + - name: run riscv-tests + run: | + nix --experimental-features 'nix-command flakes' develop -c mill -i -j 0 tests.riscvtests.run[${{ matrix.config }}] diff --git a/build.sc b/build.sc index b8b204bcc..b3f1252be 100644 --- a/build.sc +++ b/build.sc @@ -227,6 +227,10 @@ object cosim extends Module { class emulator(xLen: String) extends Module { + val ncores: Int = Runtime.getRuntime.availableProcessors() + + val emulatorCores: Int = if(ncores > 8) 8 else ncores + val topName = "TestBench" def sources = T.sources(millSourcePath) @@ -291,7 +295,7 @@ object cosim extends Module { | TOP_MODULE TestBench | PREFIX VTestBench | OPT_FAST - | THREADS 8 + | THREADS ${emulatorCores} | VERILATOR_ARGS ${verilatorArgs().mkString(" ")} |) |""".stripMargin @@ -468,6 +472,7 @@ object tests extends Module() { PathRef(if (p.exitCode != 0) { os.move(T.dest / s"$name.running.log", T.dest / s"$name.failed.log") System.err.println(s"Test $name failed with exit code ${p.exitCode}") + System.exit(1) T.dest / s"$name.failed.log" } else { os.move(T.dest / s"$name.running.log", T.dest / s"$name.passed.log") diff --git a/cosim/elaborate/src/DUT.scala b/cosim/elaborate/src/DUT.scala index fcb14e7ea..e12796665 100644 --- a/cosim/elaborate/src/DUT.scala +++ b/cosim/elaborate/src/DUT.scala @@ -69,7 +69,7 @@ class DUT(xLen:Int)(p: Parameters) extends Module { val resetVector = InModuleBody { resetVectorNode.makeIO() } - val hartidNode = BundleBridgeSource(() => UInt(4.W)) + val hartidNode = BundleBridgeSource(() => UInt(1.W)) rocketTile.hartIdNode := hartidNode InModuleBody { hartidNode.bundle := 0.U From d77bc10e85ddb355fd404990a602947f0af4bf9d Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Thu, 27 Apr 2023 14:17:28 +0800 Subject: [PATCH 2/8] refactor ibuf,btb,rvc --- diplomatic/src/rocket/BTB.scala | 38 +++++++++++++------------- diplomatic/src/rocket/Frontend.scala | 16 +++++------ diplomatic/src/rocket/IBuf.scala | 15 +++++----- diplomatic/src/rocket/RVC.scala | 6 ++-- diplomatic/src/rocket/RocketCore.scala | 6 ++-- 5 files changed, 41 insertions(+), 40 deletions(-) diff --git a/diplomatic/src/rocket/BTB.scala b/diplomatic/src/rocket/BTB.scala index 8261f0692..3f824d4cb 100644 --- a/diplomatic/src/rocket/BTB.scala +++ b/diplomatic/src/rocket/BTB.scala @@ -59,9 +59,9 @@ class RAS(nras: Int) { private val stack = Reg(Vec(nras, UInt())) } -class BHTResp(implicit p: Parameters) extends BtbBundle()(p) { - val history = UInt(btbParams.bhtParams.map(_.historyLength).getOrElse(1).W) - val value = UInt(btbParams.bhtParams.map(_.counterLength).getOrElse(1).W) +class BHTResp(bhtParams:Option[BHTParams]) extends Bundle { + val history = UInt(bhtParams.map(_.historyLength).getOrElse(1).W) + val value = UInt(bhtParams.map(_.counterLength).getOrElse(1).W) def taken = value(0) def strongly_taken = value === 1.U } @@ -89,7 +89,7 @@ class BHT(params: BHTParams)(implicit val p: Parameters) extends HasCoreParamete hashAddr(addr) ^ (hashHistory(history) << (log2Up(params.nEntries) - params.historyBits)) } def get(addr: UInt): BHTResp = { - val res = Wire(new BHTResp) + val res = Wire(new BHTResp(Some(params))) res.value := Mux(resetting, 0.U, table(index(addr, history))) res.history := history res @@ -138,8 +138,8 @@ object CFIType { // BTB update occurs during branch resolution (and only on a mispredict). // - "pc" is what future fetch PCs will tag match against. // - "br_pc" is the PC of the branch instruction. -class BTBUpdate(implicit p: Parameters) extends BtbBundle()(p) { - val prediction = new BTBResp +class BTBUpdate(btbParams:BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { + val prediction = new BTBResp(btbParams,fetchWidth,vaddrBits) val pc = UInt(vaddrBits.W) val target = UInt(vaddrBits.W) val taken = Bool() @@ -150,15 +150,15 @@ class BTBUpdate(implicit p: Parameters) extends BtbBundle()(p) { // BHT update occurs during branch resolution on all conditional branches. // - "pc" is what future fetch PCs will tag match against. -class BHTUpdate(implicit p: Parameters) extends BtbBundle()(p) { - val prediction = new BHTResp +class BHTUpdate(btbParams:BTBParams,vaddrBits:Int) extends Bundle { + val prediction = new BHTResp(btbParams.bhtParams) val pc = UInt(vaddrBits.W) val branch = Bool() val taken = Bool() val mispredict = Bool() } -class RASUpdate(implicit p: Parameters) extends BtbBundle()(p) { +class RASUpdate(vaddrBits:Int) extends Bundle { val cfiType = CFIType() val returnAddr = UInt(vaddrBits.W) } @@ -167,17 +167,17 @@ class RASUpdate(implicit p: Parameters) extends BtbBundle()(p) { // shifting off the lowest log(inst_bytes) bits off). // - "mask" provides a mask of valid instructions (instructions are // masked off by the predicted taken branch from the BTB). -class BTBResp(implicit p: Parameters) extends BtbBundle()(p) { +class BTBResp(btbparams: BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { val cfiType = CFIType() val taken = Bool() val mask = Bits(fetchWidth.W) val bridx = Bits(log2Up(fetchWidth).W) val target = UInt(vaddrBits.W) - val entry = UInt(log2Up(entries + 1).W) - val bht = new BHTResp + val entry = UInt(log2Up(btbparams.nEntries + 1).W) + val bht = new BHTResp(btbparams.bhtParams) } -class BTBReq(implicit p: Parameters) extends BtbBundle()(p) { +class BTBReq(vaddrBits:Int) extends Bundle { val addr = UInt(vaddrBits.W) } @@ -187,12 +187,12 @@ class BTBReq(implicit p: Parameters) extends BtbBundle()(p) { // placed in BTB). class BTB(implicit p: Parameters) extends BtbModule { val io = IO(new Bundle { - val req = Flipped(Valid(new BTBReq)) - val resp = Valid(new BTBResp) - val btb_update = Flipped(Valid(new BTBUpdate)) - val bht_update = Flipped(Valid(new BHTUpdate)) - val bht_advance = Flipped(Valid(new BTBResp)) - val ras_update = Flipped(Valid(new RASUpdate)) + val req = Flipped(Valid(new BTBReq(vaddrBits))) + val resp = Valid(new BTBResp(btbParams,fetchWidth,vaddrBits)) + val btb_update = Flipped(Valid(new BTBUpdate(btbParams,fetchWidth,vaddrBits))) + val bht_update = Flipped(Valid(new BHTUpdate(btbParams,vaddrBits))) + val bht_advance = Flipped(Valid(new BTBResp(btbParams,fetchWidth,vaddrBits))) + val ras_update = Flipped(Valid(new RASUpdate(vaddrBits))) val ras_head = Valid(UInt(vaddrBits.W)) val flush = Input(Bool()) }) diff --git a/diplomatic/src/rocket/Frontend.scala b/diplomatic/src/rocket/Frontend.scala index 539a01511..3cf24b03c 100644 --- a/diplomatic/src/rocket/Frontend.scala +++ b/diplomatic/src/rocket/Frontend.scala @@ -30,8 +30,8 @@ class FrontendExceptions extends Bundle { } } -class FrontendResp(implicit p: Parameters) extends CoreBundle()(p) { - val btb = new BTBResp +class FrontendResp(BTBParams: BTBParams,vaddrBits:Int,vaddrBitsExtended:Int,fetchWidth:Int,coreInstBits:Int) extends Bundle { + val btb = new BTBResp(BTBParams,fetchWidth,vaddrBits) val pc = UInt(vaddrBitsExtended.W) // ID stage PC val data = UInt((fetchWidth * coreInstBits).W) val mask = Bits(fetchWidth.W) @@ -49,11 +49,11 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) { val clock_enabled = Input(Bool()) val req = Valid(new FrontendReq) val sfence = Valid(new SFenceReq) - val resp = Flipped(Decoupled(new FrontendResp)) + val resp = Flipped(Decoupled(new FrontendResp(tileParams.btb.get,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits))) val gpa = Flipped(Valid(UInt(vaddrBitsExtended.W))) - val btb_update = Valid(new BTBUpdate) - val bht_update = Valid(new BHTUpdate) - val ras_update = Valid(new RASUpdate) + val btb_update = Valid(new BTBUpdate(tileParams.btb.get,fetchWidth,vaddrBits)) + val bht_update = Valid(new BHTUpdate(tileParams.btb.get,vaddrBits)) + val ras_update = Valid(new RASUpdate(vaddrBits)) val flush_icache = Output(Bool()) val npc = Input(UInt(vaddrBitsExtended.W)) val perf = Input(new FrontendPerfEvents()) @@ -83,7 +83,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val icache = outer.icache.module require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes) - val fq = withReset(reset.asBool || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp, 5, flow = true)) } + val fq = withReset(reset.asBool || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp(tileParams.btb.get,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits), 5, flow = true)) } val clock_en_reg = Reg(Bool()) val clock_en = clock_en_reg || io.cpu.might_request @@ -111,7 +111,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val s1_speculative = Reg(Bool()) val s2_pc = RegInit(t = UInt(vaddrBitsExtended.W), alignPC(io_reset_vector)) val s2_btb_resp_valid = if (usingBTB) Reg(Bool()) else false.B - val s2_btb_resp_bits = Reg(new BTBResp) + val s2_btb_resp_bits = Reg(new BTBResp(tileParams.btb.get,fetchWidth,vaddrBits)) val s2_btb_taken = s2_btb_resp_valid && s2_btb_resp_bits.taken val s2_tlb_resp = Reg(tlb.io.resp.cloneType) val s2_xcpt = s2_tlb_resp.ae.inst || s2_tlb_resp.pf.inst || s2_tlb_resp.gf.inst diff --git a/diplomatic/src/rocket/IBuf.scala b/diplomatic/src/rocket/IBuf.scala index 78b64cc74..bfe223729 100644 --- a/diplomatic/src/rocket/IBuf.scala +++ b/diplomatic/src/rocket/IBuf.scala @@ -8,7 +8,7 @@ import org.chipsalliance.cde.config.Parameters import org.chipsalliance.rockettile._ import freechips.rocketchip.util._ -class Instruction(implicit val p: Parameters) extends ParameterizedBundle with HasCoreParameters { +class Instruction(coreInstBits:Int, usingCompressed:Boolean) extends Bundle { val xcpt0 = new FrontendExceptions // exceptions on first half of instruction val xcpt1 = new FrontendExceptions // exceptions on second half of instruction val replay = Bool() @@ -18,13 +18,14 @@ class Instruction(implicit val p: Parameters) extends ParameterizedBundle with H require(coreInstBits == (if (usingCompressed) 16 else 32)) } -class IBuf(implicit p: Parameters) extends CoreModule { +class IBuf(coreInstBits:Int, usingCompressed:Boolean,vaddrBits:Int,vaddrBitsExtended:Int,retireWidth:Int,decodeWidth:Int, + fetchWidth:Int,coreInstBytes:Int,BTBParams: BTBParams,xlen:Int) extends Module { val io = IO(new Bundle { - val imem = Flipped(Decoupled(new FrontendResp)) + val imem = Flipped(Decoupled(new FrontendResp(BTBParams,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits))) val kill = Input(Bool()) val pc = Output(UInt(vaddrBitsExtended.W)) - val btb_resp = Output(new BTBResp()) - val inst = Vec(retireWidth, Decoupled(new Instruction)) + val btb_resp = Output(new BTBResp(BTBParams,fetchWidth,vaddrBits)) + val inst = Vec(retireWidth, Decoupled(new Instruction(coreInstBits, usingCompressed))) }) // This module is meant to be more general, but it's not there yet @@ -33,7 +34,7 @@ class IBuf(implicit p: Parameters) extends CoreModule { val n = fetchWidth - 1 val nBufValid = if (n == 0) 0.U else RegInit(init=0.U(log2Ceil(fetchWidth).W)) val buf = Reg(chiselTypeOf(io.imem.bits)) - val ibufBTBResp = Reg(new BTBResp) + val ibufBTBResp = Reg(new BTBResp(BTBParams,fetchWidth,vaddrBits)) val pcWordMask = (coreInstBytes*fetchWidth-1).U(vaddrBitsExtended.W) val pcWordBits = io.imem.bits.pc.extract(log2Ceil(fetchWidth*coreInstBytes)-1, log2Ceil(coreInstBytes)) @@ -83,7 +84,7 @@ class IBuf(implicit p: Parameters) extends CoreModule { expand(0, 0.U, inst) def expand(i: Int, j: UInt, curInst: UInt): Unit = if (i < retireWidth) { - val exp = Module(new RVCExpander) + val exp = Module(new RVCExpander(usingCompressed=usingCompressed,XLen=xlen)) exp.io.in := curInst io.inst(i).bits.inst := exp.io.out io.inst(i).bits.raw := curInst diff --git a/diplomatic/src/rocket/RVC.scala b/diplomatic/src/rocket/RVC.scala index e9661fe9e..134b01ab7 100644 --- a/diplomatic/src/rocket/RVC.scala +++ b/diplomatic/src/rocket/RVC.scala @@ -155,7 +155,7 @@ class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { } } -class RVCExpander(useAddiForMv: Boolean = false)(implicit val p: Parameters) extends Module with HasCoreParameters { +class RVCExpander(useAddiForMv: Boolean = false,usingCompressed:Boolean,XLen:Int)extends Module { val io = IO(new Bundle { val in = Input(UInt(32.W)) val out = Output(new ExpandedInstruction) @@ -164,9 +164,9 @@ class RVCExpander(useAddiForMv: Boolean = false)(implicit val p: Parameters) ext if (usingCompressed) { io.rvc := io.in(1,0) =/= 3.U - io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).decode + io.out := new RVCDecoder(io.in, XLen, useAddiForMv).decode } else { io.rvc := false.B - io.out := new RVCDecoder(io.in, p(XLen), useAddiForMv).passthrough + io.out := new RVCDecoder(io.in, XLen, useAddiForMv).passthrough } } diff --git a/diplomatic/src/rocket/RocketCore.scala b/diplomatic/src/rocket/RocketCore.scala index 523819d94..65c08f6d2 100644 --- a/diplomatic/src/rocket/RocketCore.scala +++ b/diplomatic/src/rocket/RocketCore.scala @@ -213,7 +213,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val ex_reg_xcpt_interrupt = Reg(Bool()) val ex_reg_valid = Reg(Bool()) val ex_reg_rvc = Reg(Bool()) - val ex_reg_btb_resp = Reg(new BTBResp) + val ex_reg_btb_resp = Reg(new BTBResp(tileParams.btb.get,fetchWidth,vaddrBits)) val ex_reg_xcpt = Reg(Bool()) val ex_reg_flush_pipe = Reg(Bool()) val ex_reg_load_use = Reg(Bool()) @@ -231,7 +231,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val mem_reg_xcpt_interrupt = Reg(Bool()) val mem_reg_valid = Reg(Bool()) val mem_reg_rvc = Reg(Bool()) - val mem_reg_btb_resp = Reg(new BTBResp) + val mem_reg_btb_resp = Reg(new BTBResp(tileParams.btb.get,fetchWidth,vaddrBits)) val mem_reg_xcpt = Reg(Bool()) val mem_reg_replay = Reg(Bool()) val mem_reg_flush_pipe = Reg(Bool()) @@ -275,7 +275,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val take_pc = take_pc_mem_wb // decode stage - val ibuf = Module(new IBuf) + val ibuf = Module(new IBuf(coreInstBits,usingCompressed,vaddrBits,vaddrBitsExtended,retireWidth,decodeWidth,fetchWidth,coreInstBits,tileParams.btb.get,p(XLen))) val id_expanded_inst = ibuf.io.inst.map(_.bits.inst) val id_raw_inst = ibuf.io.inst.map(_.bits.raw) val id_inst = id_expanded_inst.map(_.bits) From a0f1a6d8261320f25e2dd392cc8b5c1aa858fa3e Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Thu, 27 Apr 2023 14:19:50 +0800 Subject: [PATCH 3/8] remove import --- diplomatic/src/rocket/IBuf.scala | 2 -- diplomatic/src/rocket/RVC.scala | 2 -- 2 files changed, 4 deletions(-) diff --git a/diplomatic/src/rocket/IBuf.scala b/diplomatic/src/rocket/IBuf.scala index bfe223729..45040fafe 100644 --- a/diplomatic/src/rocket/IBuf.scala +++ b/diplomatic/src/rocket/IBuf.scala @@ -4,8 +4,6 @@ package org.chipsalliance.rocket import chisel3._ import chisel3.util.{Decoupled,log2Ceil,Cat,UIntToOH,Fill} -import org.chipsalliance.cde.config.Parameters -import org.chipsalliance.rockettile._ import freechips.rocketchip.util._ class Instruction(coreInstBits:Int, usingCompressed:Boolean) extends Bundle { diff --git a/diplomatic/src/rocket/RVC.scala b/diplomatic/src/rocket/RVC.scala index 134b01ab7..331b3bd3c 100644 --- a/diplomatic/src/rocket/RVC.scala +++ b/diplomatic/src/rocket/RVC.scala @@ -4,8 +4,6 @@ package org.chipsalliance.rocket import chisel3._ import chisel3.util._ -import org.chipsalliance.cde.config.Parameters -import org.chipsalliance.rockettile._ import freechips.rocketchip.util._ class ExpandedInstruction extends Bundle { From 6e0eb80c183a39dbc3c5c9836cb5e1e4ccb9f781 Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Thu, 27 Apr 2023 14:40:55 +0800 Subject: [PATCH 4/8] finish btb --- diplomatic/src/rocket/BTB.scala | 60 ++++++++++------------------ diplomatic/src/rocket/BaseTile.scala | 8 ++-- diplomatic/src/rocket/Frontend.scala | 2 +- 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/diplomatic/src/rocket/BTB.scala b/diplomatic/src/rocket/BTB.scala index 3f824d4cb..1c745b084 100644 --- a/diplomatic/src/rocket/BTB.scala +++ b/diplomatic/src/rocket/BTB.scala @@ -5,11 +5,7 @@ package org.chipsalliance.rocket import chisel3._ import chisel3.util._ -import chisel3.internal.InstanceId -import org.chipsalliance.cde.config.Parameters -import freechips.rocketchip.subsystem.CacheBlockBytes import freechips.rocketchip.util._ -import org.chipsalliance.rockettile.HasCoreParameters case class BHTParams( nEntries: Int = 512, @@ -25,20 +21,6 @@ case class BTBParams( bhtParams: Option[BHTParams] = Some(BHTParams()), updatesOutOfOrder: Boolean = false) -trait HasBtbParameters extends HasCoreParameters { this: InstanceId => - val btbParams = tileParams.btb.getOrElse(BTBParams(nEntries = 0)) - val matchBits = btbParams.nMatchBits max log2Ceil(p(CacheBlockBytes) * tileParams.icache.get.nSets) - val entries = btbParams.nEntries - val updatesOutOfOrder = btbParams.updatesOutOfOrder - val nPages = (btbParams.nPages + 1) / 2 * 2 // control logic assumes 2 divides pages -} - -abstract class BtbModule(implicit val p: Parameters) extends Module with HasBtbParameters { - Annotated.params(this, btbParams) -} - -abstract class BtbBundle(implicit val p: Parameters) extends Bundle with HasBtbParameters - class RAS(nras: Int) { def push(addr: UInt): Unit = { when (count < nras.U) { count := count + 1.U } @@ -75,7 +57,7 @@ class BHTResp(bhtParams:Option[BHTParams]) extends Bundle { // - each counter corresponds with the address of the fetch packet ("fetch pc"). // - updated when a branch resolves (and BTB was a hit for that branch). // The updating branch must provide its "fetch pc". -class BHT(params: BHTParams)(implicit val p: Parameters) extends HasCoreParameters { +class BHT(params: BHTParams,fetchBytes:Int) extends Bundle { def index(addr: UInt, history: UInt) = { def hashHistory(hist: UInt) = if (params.historyLength == params.historyBits) hist else { val k = math.sqrt(3)/2 @@ -185,7 +167,7 @@ class BTBReq(vaddrBits:Int) extends Bundle { // Higher-performance processors may cause BTB updates to occur out-of-order, // which requires an extra CAM port for updates (to ensure no duplicates get // placed in BTB). -class BTB(implicit p: Parameters) extends BtbModule { +class BTB(btbParams: BTBParams,fetchBytes:Int,fetchWidth:Int,vaddrBits:Int,matchBits:Int,coreInstBytes:Int) extends Module { val io = IO(new Bundle { val req = Flipped(Valid(new BTBReq(vaddrBits))) val resp = Valid(new BTBResp(btbParams,fetchWidth,vaddrBits)) @@ -197,17 +179,17 @@ class BTB(implicit p: Parameters) extends BtbModule { val flush = Input(Bool()) }) - val idxs = Reg(Vec(entries, UInt((matchBits - log2Up(coreInstBytes)).W))) - val idxPages = Reg(Vec(entries, UInt(log2Up(nPages).W))) - val tgts = Reg(Vec(entries, UInt((matchBits - log2Up(coreInstBytes)).W))) - val tgtPages = Reg(Vec(entries, UInt(log2Up(nPages).W))) - val pages = Reg(Vec(nPages, UInt((vaddrBits - matchBits).W))) - val pageValid = RegInit(0.U(nPages.W)) + val idxs = Reg(Vec(btbParams.nEntries, UInt((matchBits - log2Up(coreInstBytes)).W))) + val idxPages = Reg(Vec(btbParams.nEntries, UInt(log2Up(btbParams.nPages).W))) + val tgts = Reg(Vec(btbParams.nEntries, UInt((matchBits - log2Up(coreInstBytes)).W))) + val tgtPages = Reg(Vec(btbParams.nEntries, UInt(log2Up(btbParams.nPages).W))) + val pages = Reg(Vec(btbParams.nPages, UInt((vaddrBits - matchBits).W))) + val pageValid = RegInit(0.U(btbParams.nPages.W)) val pagesMasked = (pageValid.asBools zip pages).map { case (v, p) => Mux(v, p, 0.U) } - val isValid = RegInit(0.U(entries.W)) - val cfiType = Reg(Vec(entries, CFIType())) - val brIdx = Reg(Vec(entries, UInt(log2Up(fetchWidth).W))) + val isValid = RegInit(0.U(btbParams.nEntries.W)) + val cfiType = Reg(Vec(btbParams.nEntries, CFIType())) + val brIdx = Reg(Vec(btbParams.nEntries, UInt(log2Up(fetchWidth).W))) private def page(addr: UInt) = addr >> matchBits private def pageMatch(addr: UInt) = { @@ -227,33 +209,33 @@ class BTB(implicit p: Parameters) extends BtbModule { val updatePageHit = pageMatch(r_btb_update.bits.pc) val (updateHit, updateHitAddr) = - if (updatesOutOfOrder) { + if (btbParams.updatesOutOfOrder) { val updateHits = (pageHit << 1)(Mux1H(idxMatch(r_btb_update.bits.pc), idxPages)) (updateHits.orR, OHToUInt(updateHits)) - } else (r_btb_update.bits.prediction.entry < entries.U, r_btb_update.bits.prediction.entry) + } else (r_btb_update.bits.prediction.entry < btbParams.nEntries.U, r_btb_update.bits.prediction.entry) val useUpdatePageHit = updatePageHit.orR val usePageHit = pageHit.orR val doIdxPageRepl = !useUpdatePageHit - val nextPageRepl = RegInit(0.U(log2Ceil(nPages).W)) - val idxPageRepl = Cat(pageHit(nPages-2,0), pageHit(nPages-1)) | Mux(usePageHit, 0.U, UIntToOH(nextPageRepl)) + val nextPageRepl = RegInit(0.U(log2Ceil(btbParams.nPages).W)) + val idxPageRepl = Cat(pageHit(btbParams.nPages-2,0), pageHit(btbParams.nPages-1)) | Mux(usePageHit, 0.U, UIntToOH(nextPageRepl)) val idxPageUpdateOH = Mux(useUpdatePageHit, updatePageHit, idxPageRepl) val idxPageUpdate = OHToUInt(idxPageUpdateOH) val idxPageReplEn = Mux(doIdxPageRepl, idxPageRepl, 0.U) val samePage = page(r_btb_update.bits.pc) === page(update_target) val doTgtPageRepl = !samePage && !usePageHit - val tgtPageRepl = Mux(samePage, idxPageUpdateOH, Cat(idxPageUpdateOH(nPages-2,0), idxPageUpdateOH(nPages-1))) + val tgtPageRepl = Mux(samePage, idxPageUpdateOH, Cat(idxPageUpdateOH(btbParams.nPages-2,0), idxPageUpdateOH(btbParams.nPages-1))) val tgtPageUpdate = OHToUInt(pageHit | Mux(usePageHit, 0.U, tgtPageRepl)) val tgtPageReplEn = Mux(doTgtPageRepl, tgtPageRepl, 0.U) when (r_btb_update.valid && (doIdxPageRepl || doTgtPageRepl)) { val both = doIdxPageRepl && doTgtPageRepl val next = nextPageRepl + Mux[UInt](both, 2.U, 1.U) - nextPageRepl := Mux(next >= nPages.U, next(0), next) + nextPageRepl := Mux(next >= btbParams.nPages.U, next(0), next) } - val repl = new PseudoLRU(entries) + val repl = new PseudoLRU(btbParams.nEntries) val waddr = Mux(updateHit, updateHitAddr, repl.way) val r_resp = Pipe(io.resp) when (r_resp.valid && r_resp.bits.taken || r_btb_update.valid) { @@ -271,11 +253,11 @@ class BTB(implicit p: Parameters) extends BtbModule { if (fetchWidth > 1) brIdx(waddr) := r_btb_update.bits.br_pc >> log2Up(coreInstBytes) - require(nPages % 2 == 0) + require(btbParams.nPages % 2 == 0) val idxWritesEven = !idxPageUpdate(0) def writeBank(i: Int, mod: Int, en: UInt, data: UInt) = - for (i <- i until nPages by mod) + for (i <- i until btbParams.nPages by mod) when (en(i)) { pages(i) := data } writeBank(0, 2, Mux(idxWritesEven, idxPageReplEn, tgtPageReplEn), @@ -302,7 +284,7 @@ class BTB(implicit p: Parameters) extends BtbModule { } if (btbParams.bhtParams.nonEmpty) { - val bht = new BHT(Annotated.params(this, btbParams.bhtParams.get)) + val bht = new BHT(btbParams.bhtParams.get,fetchBytes) val isBranch = (idxHit & cfiType.map(_ === CFIType.branch).asUInt).orR val res = bht.get(io.req.bits.addr) when (io.bht_advance.valid) { diff --git a/diplomatic/src/rocket/BaseTile.scala b/diplomatic/src/rocket/BaseTile.scala index b7aea6e74..947fc8fcc 100644 --- a/diplomatic/src/rocket/BaseTile.scala +++ b/diplomatic/src/rocket/BaseTile.scala @@ -3,16 +3,15 @@ package org.chipsalliance.rockettile import Chisel._ - +import chisel3.util.log2Ceil import org.chipsalliance.cde.config._ import org.chipsalliance.rocket._ import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy._ - import freechips.rocketchip.interrupts._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util._ -import freechips.rocketchip.prci.{ClockSinkParameters} +import freechips.rocketchip.prci.ClockSinkParameters case object TileVisibilityNodeKey extends Field[TLEphemeralNode] case object TileKey extends Field[TileParams] @@ -70,11 +69,14 @@ trait HasNonDiplomaticTileParameters { require(pgLevels >= res) res } + def matchBits = tileParams.btb.get.nMatchBits max log2Ceil(p(CacheBlockBytes) * tileParams.icache.get.nSets) def asIdBits: Int = p(ASIdBits) def vmIdBits: Int = p(VMIdBits) lazy val maxPAddrBits: Int = { require(xLen == 32 || xLen == 64, s"Only XLENs of 32 or 64 are supported, but got $xLen") xLen match { case 32 => 34; case 64 => 56 } + + } /** Use staticIdForMetadataUseOnly to emit information during the build or identify a component to diplomacy. diff --git a/diplomatic/src/rocket/Frontend.scala b/diplomatic/src/rocket/Frontend.scala index 3cf24b03c..324b9a382 100644 --- a/diplomatic/src/rocket/Frontend.scala +++ b/diplomatic/src/rocket/Frontend.scala @@ -190,7 +190,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) when (icache.io.resp.valid && icache.io.resp.bits.ae) { fq.io.enq.bits.xcpt.ae.inst := true.B } if (usingBTB) { - val btb = Module(new BTB) + val btb = Module(new BTB(tileParams.btb.get,fetchBytes,fetchWidth,vaddrBits,matchBits,coreInstBits)) btb.io.flush := false.B btb.io.req.valid := false.B btb.io.req.bits.addr := s1_pc From c895032eec38927908db0d6254f226a15ad8f693 Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Tue, 9 May 2023 10:46:57 +0800 Subject: [PATCH 5/8] able to compile rocket --- diplomatic/src/rocket/Frontend.scala | 9 +- rocket/src/BTB.scala | 325 +++++++++++++++++++++++++++ rocket/src/IBuf.scala | 152 +++++++++++++ rocket/src/Misc.scala | 45 ++++ rocket/src/Property.scala | 154 +++++++++++++ rocket/src/RVC.scala | 170 ++++++++++++++ rocket/src/Replacement.scala | 325 +++++++++++++++++++++++++++ rocket/src/util.scala | 186 +++++++++++++++ 8 files changed, 1358 insertions(+), 8 deletions(-) create mode 100644 rocket/src/BTB.scala create mode 100644 rocket/src/IBuf.scala create mode 100644 rocket/src/Misc.scala create mode 100644 rocket/src/Property.scala create mode 100644 rocket/src/RVC.scala create mode 100644 rocket/src/Replacement.scala create mode 100644 rocket/src/util.scala diff --git a/diplomatic/src/rocket/Frontend.scala b/diplomatic/src/rocket/Frontend.scala index 324b9a382..5e3409889 100644 --- a/diplomatic/src/rocket/Frontend.scala +++ b/diplomatic/src/rocket/Frontend.scala @@ -30,14 +30,7 @@ class FrontendExceptions extends Bundle { } } -class FrontendResp(BTBParams: BTBParams,vaddrBits:Int,vaddrBitsExtended:Int,fetchWidth:Int,coreInstBits:Int) extends Bundle { - val btb = new BTBResp(BTBParams,fetchWidth,vaddrBits) - val pc = UInt(vaddrBitsExtended.W) // ID stage PC - val data = UInt((fetchWidth * coreInstBits).W) - val mask = Bits(fetchWidth.W) - val xcpt = new FrontendExceptions - val replay = Bool() -} + class FrontendPerfEvents extends Bundle { val acquire = Bool() diff --git a/rocket/src/BTB.scala b/rocket/src/BTB.scala new file mode 100644 index 000000000..42b9856ba --- /dev/null +++ b/rocket/src/BTB.scala @@ -0,0 +1,325 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package org.chipsalliance.rocket + +import chisel3._ +import chisel3.util._ +import org.chipsalliance.rocket.util._ +import org.chipsalliance.rocket.util.property._ + + +case class BHTParams( + nEntries: Int = 512, + counterLength: Int = 1, + historyLength: Int = 8, + historyBits: Int = 3) + +case class BTBParams( + nEntries: Int = 28, + nMatchBits: Int = 14, + nPages: Int = 6, + nRAS: Int = 6, + bhtParams: Option[BHTParams] = Some(BHTParams()), + updatesOutOfOrder: Boolean = false) + +class RAS(nras: Int) { + def push(addr: UInt): Unit = { + when (count < nras.U) { count := count + 1.U } + val nextPos = Mux((isPow2(nras)).B || pos < (nras-1).U, pos+1.U, 0.U) + stack(nextPos) := addr + pos := nextPos + } + def peek: UInt = stack(pos) + def pop(): Unit = when (!isEmpty) { + count := count - 1.U + pos := Mux((isPow2(nras)).B || pos > 0.U, pos-1.U, (nras-1).U) + } + def clear(): Unit = count := 0.U + def isEmpty: Bool = count === 0.U + + private val count = RegInit(0.U(log2Up(nras+1).W)) + private val pos = RegInit(0.U(log2Up(nras).W)) + private val stack = Reg(Vec(nras, UInt())) +} + +class BHTResp(bhtParams:Option[BHTParams]) extends Bundle { + val history = UInt(bhtParams.map(_.historyLength).getOrElse(1).W) + val value = UInt(bhtParams.map(_.counterLength).getOrElse(1).W) + def taken = value(0) + def strongly_taken = value === 1.U +} + +// BHT contains table of 2-bit counters and a global history register. +// The BHT only predicts and updates when there is a BTB hit. +// The global history: +// - updated speculatively in fetch (if there's a BTB hit). +// - on a mispredict, the history register is reset (again, only if BTB hit). +// The counter table: +// - each counter corresponds with the address of the fetch packet ("fetch pc"). +// - updated when a branch resolves (and BTB was a hit for that branch). +// The updating branch must provide its "fetch pc". +class BHT(params: BHTParams,fetchBytes:Int) extends Bundle { + def index(addr: UInt, history: UInt) = { + def hashHistory(hist: UInt) = if (params.historyLength == params.historyBits) hist else { + val k = math.sqrt(3)/2 + val i = BigDecimal(k * math.pow(2, params.historyLength)).toBigInt + (i.U * hist)(params.historyLength-1, params.historyLength-params.historyBits) + } + def hashAddr(addr: UInt) = { + val hi = addr >> log2Ceil(fetchBytes) + hi(log2Ceil(params.nEntries)-1, 0) ^ (hi >> log2Ceil(params.nEntries))(1, 0) + } + hashAddr(addr) ^ (hashHistory(history) << (log2Up(params.nEntries) - params.historyBits)) + } + def get(addr: UInt): BHTResp = { + val res = Wire(new BHTResp(Some(params))) + res.value := Mux(resetting, 0.U, table(index(addr, history))) + res.history := history + res + } + def updateTable(addr: UInt, d: BHTResp, taken: Bool): Unit = { + wen := true.B + when (!resetting) { + waddr := index(addr, d.history) + wdata := (params.counterLength match { + case 1 => taken + case 2 => Cat(taken ^ d.value(0), d.value === 1.U || d.value(1) && taken) + }) + } + } + def resetHistory(d: BHTResp): Unit = { + history := d.history + } + def updateHistory(addr: UInt, d: BHTResp, taken: Bool): Unit = { + history := Cat(taken, d.history >> 1) + } + def advanceHistory(taken: Bool): Unit = { + history := Cat(taken, history >> 1) + } + + private val table = Mem(params.nEntries, UInt(params.counterLength.W)) + val history = RegInit(0.U(params.historyLength.W)) + + private val reset_waddr = RegInit(0.U((params.nEntries.log2+1).W)) + private val resetting = !reset_waddr(params.nEntries.log2) + private val wen = WireInit(resetting) + private val waddr = WireInit(reset_waddr) + private val wdata = WireInit(0.U) + when (resetting) { reset_waddr := reset_waddr + 1.U } + when (wen) { table(waddr) := wdata } +} + +object CFIType { + def SZ = 2 + def apply() = UInt(SZ.W) + def branch = 0.U + def jump = 1.U + def call = 2.U + def ret = 3.U +} + +// BTB update occurs during branch resolution (and only on a mispredict). +// - "pc" is what future fetch PCs will tag match against. +// - "br_pc" is the PC of the branch instruction. +class BTBUpdate(btbParams:BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { + val prediction = new BTBResp(btbParams,fetchWidth,vaddrBits) + val pc = UInt(vaddrBits.W) + val target = UInt(vaddrBits.W) + val taken = Bool() + val isValid = Bool() + val br_pc = UInt(vaddrBits.W) + val cfiType = CFIType() +} + +// BHT update occurs during branch resolution on all conditional branches. +// - "pc" is what future fetch PCs will tag match against. +class BHTUpdate(btbParams:BTBParams,vaddrBits:Int) extends Bundle { + val prediction = new BHTResp(btbParams.bhtParams) + val pc = UInt(vaddrBits.W) + val branch = Bool() + val taken = Bool() + val mispredict = Bool() +} + +class RASUpdate(vaddrBits:Int) extends Bundle { + val cfiType = CFIType() + val returnAddr = UInt(vaddrBits.W) +} + +// - "bridx" is the low-order PC bits of the predicted branch (after +// shifting off the lowest log(inst_bytes) bits off). +// - "mask" provides a mask of valid instructions (instructions are +// masked off by the predicted taken branch from the BTB). +class BTBResp(btbparams: BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { + val cfiType = CFIType() + val taken = Bool() + val mask = Bits(fetchWidth.W) + val bridx = Bits(log2Up(fetchWidth).W) + val target = UInt(vaddrBits.W) + val entry = UInt(log2Up(btbparams.nEntries + 1).W) + val bht = new BHTResp(btbparams.bhtParams) +} + +class BTBReq(vaddrBits:Int) extends Bundle { + val addr = UInt(vaddrBits.W) +} + +// fully-associative branch target buffer +// Higher-performance processors may cause BTB updates to occur out-of-order, +// which requires an extra CAM port for updates (to ensure no duplicates get +// placed in BTB). +class BTB(btbParams: BTBParams,fetchBytes:Int,fetchWidth:Int,vaddrBits:Int,matchBits:Int,coreInstBytes:Int) extends Module { + val io = IO(new Bundle { + val req = Flipped(Valid(new BTBReq(vaddrBits))) + val resp = Valid(new BTBResp(btbParams,fetchWidth,vaddrBits)) + val btb_update = Flipped(Valid(new BTBUpdate(btbParams,fetchWidth,vaddrBits))) + val bht_update = Flipped(Valid(new BHTUpdate(btbParams,vaddrBits))) + val bht_advance = Flipped(Valid(new BTBResp(btbParams,fetchWidth,vaddrBits))) + val ras_update = Flipped(Valid(new RASUpdate(vaddrBits))) + val ras_head = Valid(UInt(vaddrBits.W)) + val flush = Input(Bool()) + }) + + val idxs = Reg(Vec(btbParams.nEntries, UInt((matchBits - log2Up(coreInstBytes)).W))) + val idxPages = Reg(Vec(btbParams.nEntries, UInt(log2Up(btbParams.nPages).W))) + val tgts = Reg(Vec(btbParams.nEntries, UInt((matchBits - log2Up(coreInstBytes)).W))) + val tgtPages = Reg(Vec(btbParams.nEntries, UInt(log2Up(btbParams.nPages).W))) + val pages = Reg(Vec(btbParams.nPages, UInt((vaddrBits - matchBits).W))) + val pageValid = RegInit(0.U(btbParams.nPages.W)) + val pagesMasked = (pageValid.asBools zip pages).map { case (v, p) => Mux(v, p, 0.U) } + + val isValid = RegInit(0.U(btbParams.nEntries.W)) + val cfiType = Reg(Vec(btbParams.nEntries, CFIType())) + val brIdx = Reg(Vec(btbParams.nEntries, UInt(log2Up(fetchWidth).W))) + + private def page(addr: UInt) = addr >> matchBits + private def pageMatch(addr: UInt) = { + val p = page(addr) + pageValid & pages.map(_ === p).asUInt + } + private def idxMatch(addr: UInt) = { + val idx = addr(matchBits-1, log2Up(coreInstBytes)) + idxs.map(_ === idx).asUInt & isValid + } + + val r_btb_update = Pipe(io.btb_update) + val update_target = io.req.bits.addr + + val pageHit = pageMatch(io.req.bits.addr) + val idxHit = idxMatch(io.req.bits.addr) + + val updatePageHit = pageMatch(r_btb_update.bits.pc) + val (updateHit, updateHitAddr) = + if (btbParams.updatesOutOfOrder) { + val updateHits = (pageHit << 1)(Mux1H(idxMatch(r_btb_update.bits.pc), idxPages)) + (updateHits.orR, OHToUInt(updateHits)) + } else (r_btb_update.bits.prediction.entry < btbParams.nEntries.U, r_btb_update.bits.prediction.entry) + + val useUpdatePageHit = updatePageHit.orR + val usePageHit = pageHit.orR + val doIdxPageRepl = !useUpdatePageHit + val nextPageRepl = RegInit(0.U(log2Ceil(btbParams.nPages).W)) + val idxPageRepl = Cat(pageHit(btbParams.nPages-2,0), pageHit(btbParams.nPages-1)) | Mux(usePageHit, 0.U, UIntToOH(nextPageRepl)) + val idxPageUpdateOH = Mux(useUpdatePageHit, updatePageHit, idxPageRepl) + val idxPageUpdate = OHToUInt(idxPageUpdateOH) + val idxPageReplEn = Mux(doIdxPageRepl, idxPageRepl, 0.U) + + val samePage = page(r_btb_update.bits.pc) === page(update_target) + val doTgtPageRepl = !samePage && !usePageHit + val tgtPageRepl = Mux(samePage, idxPageUpdateOH, Cat(idxPageUpdateOH(btbParams.nPages-2,0), idxPageUpdateOH(btbParams.nPages-1))) + val tgtPageUpdate = OHToUInt(pageHit | Mux(usePageHit, 0.U, tgtPageRepl)) + val tgtPageReplEn = Mux(doTgtPageRepl, tgtPageRepl, 0.U) + + when (r_btb_update.valid && (doIdxPageRepl || doTgtPageRepl)) { + val both = doIdxPageRepl && doTgtPageRepl + val next = nextPageRepl + Mux[UInt](both, 2.U, 1.U) + nextPageRepl := Mux(next >= btbParams.nPages.U, next(0), next) + } + + val repl = new PseudoLRU(btbParams.nEntries) + val waddr = Mux(updateHit, updateHitAddr, repl.way) + val r_resp = Pipe(io.resp) + when (r_resp.valid && r_resp.bits.taken || r_btb_update.valid) { + repl.access(Mux(r_btb_update.valid, waddr, r_resp.bits.entry)) + } + + when (r_btb_update.valid) { + val mask = UIntToOH(waddr) + idxs(waddr) := r_btb_update.bits.pc(matchBits-1, log2Up(coreInstBytes)) + tgts(waddr) := update_target(matchBits-1, log2Up(coreInstBytes)) + idxPages(waddr) := idxPageUpdate +& 1.U // the +1 corresponds to the <<1 on io.resp.valid + tgtPages(waddr) := tgtPageUpdate + cfiType(waddr) := r_btb_update.bits.cfiType + isValid := Mux(r_btb_update.bits.isValid, isValid | mask, isValid & ~mask) + if (fetchWidth > 1) + brIdx(waddr) := r_btb_update.bits.br_pc >> log2Up(coreInstBytes) + + require(btbParams.nPages % 2 == 0) + val idxWritesEven = !idxPageUpdate(0) + + def writeBank(i: Int, mod: Int, en: UInt, data: UInt) = + for (i <- i until btbParams.nPages by mod) + when (en(i)) { pages(i) := data } + + writeBank(0, 2, Mux(idxWritesEven, idxPageReplEn, tgtPageReplEn), + Mux(idxWritesEven, page(r_btb_update.bits.pc), page(update_target))) + writeBank(1, 2, Mux(idxWritesEven, tgtPageReplEn, idxPageReplEn), + Mux(idxWritesEven, page(update_target), page(r_btb_update.bits.pc))) + pageValid := pageValid | tgtPageReplEn | idxPageReplEn + } + + io.resp.valid := (pageHit << 1)(Mux1H(idxHit, idxPages)) + io.resp.bits.taken := true.B + io.resp.bits.target := Cat(pagesMasked(Mux1H(idxHit, tgtPages)), Mux1H(idxHit, tgts) << log2Up(coreInstBytes)) + io.resp.bits.entry := OHToUInt(idxHit) + io.resp.bits.bridx := (if (fetchWidth > 1) Mux1H(idxHit, brIdx) else 0.U) + io.resp.bits.mask := Cat((1.U << ~Mux(io.resp.bits.taken, ~io.resp.bits.bridx, 0.U))-1.U, 1.U) + io.resp.bits.cfiType := Mux1H(idxHit, cfiType) + + // if multiple entries for same PC land in BTB, zap them + when (PopCountAtLeast(idxHit, 2)) { + isValid := isValid & ~idxHit + } + when (io.flush) { + isValid := 0.U + } + + if (btbParams.bhtParams.nonEmpty) { + val bht = new BHT(btbParams.bhtParams.get,fetchBytes) + val isBranch = (idxHit & cfiType.map(_ === CFIType.branch).asUInt).orR + val res = bht.get(io.req.bits.addr) + when (io.bht_advance.valid) { + bht.advanceHistory(io.bht_advance.bits.bht.taken) + } + when (io.bht_update.valid) { + when (io.bht_update.bits.branch) { + bht.updateTable(io.bht_update.bits.pc, io.bht_update.bits.prediction, io.bht_update.bits.taken) + when (io.bht_update.bits.mispredict) { + bht.updateHistory(io.bht_update.bits.pc, io.bht_update.bits.prediction, io.bht_update.bits.taken) + } + }.elsewhen (io.bht_update.bits.mispredict) { + bht.resetHistory(io.bht_update.bits.prediction) + } + } + when (!res.taken && isBranch) { io.resp.bits.taken := false.B } + io.resp.bits.bht := res + } + + if (btbParams.nRAS > 0) { + val ras = new RAS(btbParams.nRAS) + val doPeek = (idxHit & cfiType.map(_ === CFIType.ret).asUInt).orR + io.ras_head.valid := !ras.isEmpty + io.ras_head.bits := ras.peek + when (!ras.isEmpty && doPeek) { + io.resp.bits.target := ras.peek + } + when (io.ras_update.valid) { + when (io.ras_update.bits.cfiType === CFIType.call) { + ras.push(io.ras_update.bits.returnAddr) + }.elsewhen (io.ras_update.bits.cfiType === CFIType.ret) { + ras.pop() + } + } + } +} diff --git a/rocket/src/IBuf.scala b/rocket/src/IBuf.scala new file mode 100644 index 000000000..c90ed73fd --- /dev/null +++ b/rocket/src/IBuf.scala @@ -0,0 +1,152 @@ +// See LICENSE.SiFive for license details. + +package org.chipsalliance.rocket + +import chisel3._ +import chisel3.util.{Decoupled,log2Ceil,Cat,UIntToOH,Fill} +import org.chipsalliance.rocket.util._ +import org.chipsalliance.rocket.util.property._ + +//todo: move to Fronted +class FrontendExceptions extends Bundle { + val pf = new Bundle { + val inst = Bool() + } + val gf = new Bundle { + val inst = Bool() + } + val ae = new Bundle { + val inst = Bool() + } +} + +class FrontendResp(BTBParams: BTBParams,vaddrBits:Int,vaddrBitsExtended:Int,fetchWidth:Int,coreInstBits:Int) extends Bundle { + val btb = new BTBResp(BTBParams,fetchWidth,vaddrBits) + val pc = UInt(vaddrBitsExtended.W) // ID stage PC + val data = UInt((fetchWidth * coreInstBits).W) + val mask = Bits(fetchWidth.W) + val xcpt = new FrontendExceptions + val replay = Bool() +} + +class Instruction(coreInstBits:Int, usingCompressed:Boolean) extends Bundle { + val xcpt0 = new FrontendExceptions // exceptions on first half of instruction + val xcpt1 = new FrontendExceptions // exceptions on second half of instruction + val replay = Bool() + val rvc = Bool() + val inst = new ExpandedInstruction + val raw = UInt(32.W) + require(coreInstBits == (if (usingCompressed) 16 else 32)) +} + +class IBuf(coreInstBits:Int, usingCompressed:Boolean,vaddrBits:Int,vaddrBitsExtended:Int,retireWidth:Int,decodeWidth:Int, + fetchWidth:Int,coreInstBytes:Int,BTBParams: BTBParams,xlen:Int) extends Module { + val io = IO(new Bundle { + val imem = Flipped(Decoupled(new FrontendResp(BTBParams,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits))) + val kill = Input(Bool()) + val pc = Output(UInt(vaddrBitsExtended.W)) + val btb_resp = Output(new BTBResp(BTBParams,fetchWidth,vaddrBits)) + val inst = Vec(retireWidth, Decoupled(new Instruction(coreInstBits, usingCompressed))) + }) + + // This module is meant to be more general, but it's not there yet + require(decodeWidth == 1) + + val n = fetchWidth - 1 + val nBufValid = if (n == 0) 0.U else RegInit(init=0.U(log2Ceil(fetchWidth).W)) + val buf = Reg(chiselTypeOf(io.imem.bits)) + val ibufBTBResp = Reg(new BTBResp(BTBParams,fetchWidth,vaddrBits)) + val pcWordMask = (coreInstBytes*fetchWidth-1).U(vaddrBitsExtended.W) + + val pcWordBits = io.imem.bits.pc.extract(log2Ceil(fetchWidth*coreInstBytes)-1, log2Ceil(coreInstBytes)) + val nReady = WireDefault(0.U(log2Ceil(fetchWidth+1).W)) + val nIC = Mux(io.imem.bits.btb.taken, io.imem.bits.btb.bridx +& 1.U, fetchWidth.U) - pcWordBits + val nICReady = nReady - nBufValid + val nValid = Mux(io.imem.valid, nIC, 0.U) + nBufValid + io.imem.ready := io.inst(0).ready && nReady >= nBufValid && (nICReady >= nIC || n.U >= nIC - nICReady) + + if (n > 0) { + when (io.inst(0).ready) { + nBufValid := Mux(nReady >== nBufValid, 0.U, nBufValid - nReady) + if (n > 1) when (nReady > 0.U && nReady < nBufValid) { + val shiftedBuf = shiftInsnRight(buf.data(n*coreInstBits-1, coreInstBits), (nReady-1.U)(log2Ceil(n-1)-1,0)) + buf.data := Cat(buf.data(n*coreInstBits-1, (n-1)*coreInstBits), shiftedBuf((n-1)*coreInstBits-1, 0)) + buf.pc := buf.pc & ~pcWordMask | (buf.pc + (nReady << log2Ceil(coreInstBytes))) & pcWordMask + } + when (io.imem.valid && nReady >= nBufValid && nICReady < nIC && n.U >= nIC - nICReady) { + val shamt = pcWordBits + nICReady + nBufValid := nIC - nICReady + buf := io.imem.bits + buf.data := shiftInsnRight(io.imem.bits.data, shamt)(n*coreInstBits-1,0) + buf.pc := io.imem.bits.pc & ~pcWordMask | (io.imem.bits.pc + (nICReady << log2Ceil(coreInstBytes))) & pcWordMask + ibufBTBResp := io.imem.bits.btb + } + } + when (io.kill) { + nBufValid := 0.U + } + } + + val icShiftAmt = (fetchWidth.U + nBufValid - pcWordBits)(log2Ceil(fetchWidth), 0) + val icData = shiftInsnLeft(Cat(io.imem.bits.data, Fill(fetchWidth, io.imem.bits.data(coreInstBits-1, 0))), icShiftAmt) + .extract(3*fetchWidth*coreInstBits-1, 2*fetchWidth*coreInstBits) + val icMask = (~0.U((fetchWidth*coreInstBits).W) << (nBufValid << log2Ceil(coreInstBits)))(fetchWidth*coreInstBits-1,0) + val inst = icData & icMask | buf.data & ~icMask + + val valid = (UIntToOH(nValid) - 1.U)(fetchWidth-1, 0) + val bufMask = UIntToOH(nBufValid) - 1.U + val xcpt = (0 until bufMask.getWidth).map(i => Mux(bufMask(i), buf.xcpt, io.imem.bits.xcpt)) + val buf_replay = Mux(buf.replay, bufMask, 0.U) + val ic_replay = buf_replay | Mux(io.imem.bits.replay, valid & ~bufMask, 0.U) + assert(!io.imem.valid || !io.imem.bits.btb.taken || io.imem.bits.btb.bridx >= pcWordBits) + + io.btb_resp := io.imem.bits.btb + io.pc := Mux(nBufValid > 0.U, buf.pc, io.imem.bits.pc) + expand(0, 0.U, inst) + + def expand(i: Int, j: UInt, curInst: UInt): Unit = if (i < retireWidth) { + val exp = Module(new RVCExpander(usingCompressed=usingCompressed,XLen=xlen)) + exp.io.in := curInst + io.inst(i).bits.inst := exp.io.out + io.inst(i).bits.raw := curInst + + if (usingCompressed) { + val replay = ic_replay(j) || (!exp.io.rvc && ic_replay(j+1.U)) + val full_insn = exp.io.rvc || valid(j+1.U) || buf_replay(j) + io.inst(i).valid := valid(j) && full_insn + io.inst(i).bits.xcpt0 := xcpt(j) + io.inst(i).bits.xcpt1 := Mux(exp.io.rvc, 0.U, xcpt(j+1.U).asUInt).asTypeOf(new FrontendExceptions) + io.inst(i).bits.replay := replay + io.inst(i).bits.rvc := exp.io.rvc + + when ((bufMask(j) && exp.io.rvc) || bufMask(j+1.U)) { io.btb_resp := ibufBTBResp } + + when (full_insn && ((i == 0).B || io.inst(i).ready)) { nReady := Mux(exp.io.rvc, j+1.U, j+2.U) } + + expand(i+1, Mux(exp.io.rvc, j+1.U, j+2.U), Mux(exp.io.rvc, curInst >> 16, curInst >> 32)) + } else { + when ((i == 0).B || io.inst(i).ready) { nReady := (i+1).U } + io.inst(i).valid := valid(i) + io.inst(i).bits.xcpt0 := xcpt(i) + io.inst(i).bits.xcpt1 := 0.U.asTypeOf(new FrontendExceptions) + io.inst(i).bits.replay := ic_replay(i) + io.inst(i).bits.rvc := false.B + + expand(i+1, null, curInst >> 32) + } + } + + def shiftInsnLeft(in: UInt, dist: UInt) = { + val r = in.getWidth/coreInstBits + require(in.getWidth % coreInstBits == 0) + val data = Cat(Fill((1 << (log2Ceil(r) + 1)) - r, in >> (r-1)*coreInstBits), in) + data << (dist << log2Ceil(coreInstBits)) + } + + def shiftInsnRight(in: UInt, dist: UInt) = { + val r = in.getWidth/coreInstBits + require(in.getWidth % coreInstBits == 0) + val data = Cat(Fill((1 << (log2Ceil(r) + 1)) - r, in >> (r-1)*coreInstBits), in) + data >> (dist << log2Ceil(coreInstBits)) + } +} diff --git a/rocket/src/Misc.scala b/rocket/src/Misc.scala new file mode 100644 index 000000000..d87b17cdd --- /dev/null +++ b/rocket/src/Misc.scala @@ -0,0 +1,45 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package org.chipsalliance.rocket.util + +import Chisel._ +import chisel3.util.random.LFSR +import scala.math._ + +object Random +{ + def apply(mod: Int, random: UInt): UInt = { + if (isPow2(mod)) random.extract(log2Ceil(mod)-1,0) + else PriorityEncoder(partition(apply(1 << log2Up(mod*8), random), mod)) + } + def apply(mod: Int): UInt = apply(mod, randomizer) + def oneHot(mod: Int, random: UInt): UInt = { + if (isPow2(mod)) UIntToOH(random(log2Up(mod)-1,0)) + else PriorityEncoderOH(partition(apply(1 << log2Up(mod*8), random), mod)).asUInt + } + def oneHot(mod: Int): UInt = oneHot(mod, randomizer) + + private def randomizer = LFSR(16) + private def partition(value: UInt, slices: Int) = + Seq.tabulate(slices)(i => value < UInt(((i + 1) << value.getWidth) / slices)) +} + +object PopCountAtLeast { + private def two(x: UInt): (Bool, Bool) = x.getWidth match { + case 1 => (x.asBool, Bool(false)) + case n => + val half = x.getWidth / 2 + val (leftOne, leftTwo) = two(x(half - 1, 0)) + val (rightOne, rightTwo) = two(x(x.getWidth - 1, half)) + (leftOne || rightOne, leftTwo || rightTwo || (leftOne && rightOne)) + } + def apply(x: UInt, n: Int): Bool = n match { + case 0 => Bool(true) + case 1 => x.orR + case 2 => two(x)._2 + case 3 => PopCount(x) >= UInt(n) + } +} + + diff --git a/rocket/src/Property.scala b/rocket/src/Property.scala new file mode 100644 index 000000000..997670bb2 --- /dev/null +++ b/rocket/src/Property.scala @@ -0,0 +1,154 @@ +// See LICENSE.SiFive for license details. + +package org.chipsalliance.rocket.util.property + +import Chisel._ +import chisel3.internal.sourceinfo.SourceInfo +import chisel3.util.{ReadyValidIO} + +sealed abstract class PropertyType(name: String) { + override def toString: String = name +} + +object PropertyType { + object Assert extends PropertyType("Assert") + object Assume extends PropertyType("Assume") + object Cover extends PropertyType("Cover") +} + +trait BasePropertyParameters { + val pType: PropertyType + val cond: Bool + val label: String + val message: String +} + +case class CoverPropertyParameters( + cond: Bool, + label: String = "", + message: String = "") extends BasePropertyParameters { + val pType = PropertyType.Cover +} + +abstract class BasePropertyLibrary { + def generateProperty(prop_param: BasePropertyParameters)(implicit sourceInfo: SourceInfo): Unit +} + +class DefaultPropertyLibrary extends BasePropertyLibrary { + def generateProperty(prop_param: BasePropertyParameters)(implicit sourceInfo: SourceInfo): Unit = { + // default is to do nothing + () + } +} + +abstract class BaseProperty { + def generateProperties(): Seq[BasePropertyParameters] +} + +case class CoverBoolean(cond: Bool, labels: Seq[String]) { +} + +// CrossProperty.generateProperties() will generate Boolean crosses for the cond sequence +// E.g. +// Cond = [ [A1, A2, A3], +// [B2], +// [C1, C2] ] +// It will generate the following properties +// [ A1 && B2 && C1, +// A1 && B2 && C2, +// A2 && B2 && C1, +// A2 && B2 && C2, +// A3 && B2 && C1, +// A3 && B2 && C2 ] +// Each of the boolean expression (A1, A2, C1, etc.) have a label associated with it +// User can exclude a particular cross from being generated by adding it to the exclude list +// e.g. +// exclude = [ ["A1_label", "C2_Label"], +// ["A3_label", "B2_label"] ] +// will exclude all crosses with those labels, so the new cross list will be +// [ A1 && B2 && C1, +// A2 && B2 && C1, +// A2 && B2 && C2 ] + +// Each boolean expression can be associated with more than one label + +class CrossProperty(cond: Seq[Seq[CoverBoolean]], exclude: Seq[Seq[String]], message: String) extends BaseProperty { + def listProperties(c1: CoverBoolean, c2: Seq[CoverBoolean]): Seq[CoverBoolean] = { + if (c2.isEmpty) { + Seq(c1) + } else { + c2.map( (c: CoverBoolean) => { + new CoverBoolean(c1.cond && c.cond, c1.labels ++ c.labels) + }) + } + } + + def crossProperties(cond: Seq[Seq[CoverBoolean]]): Seq[CoverBoolean] = { + if (cond.isEmpty) { + Seq() + } else { + cond.head.map( (c1: CoverBoolean) => { + listProperties(c1, crossProperties(cond.tail)) + }).reduce(_ ++ _) + } + } + def inSequence(search: Seq[String], find: Seq[String]): Boolean = { + if (find.isEmpty) { + true + } else { + find.map( (s:String) => { + search.contains(s) + }).reduce( _ && _ ) + } + } + def SeqsinSequence(search: Seq[String], find: Seq[Seq[String]]): Boolean = { + if (find.isEmpty) { + false + } else { + find.map( (s: Seq[String]) => { + inSequence(search, s) + }).reduce (_ || _) + } + } + + def generateProperties(): Seq[CoverPropertyParameters] = { + crossProperties(cond).filter(c => !SeqsinSequence(c.labels, exclude)).map( (c: CoverBoolean) => { + new CoverPropertyParameters( + cond = c.cond, + label = c.labels.reduce( (s1: String, s2: String) => {s1 + "_" + s2} ), + message = message + " " + c.labels.map("<" + _ + ">").reduce ( (s1: String, s2: String) => { s1 + " X " + s2 })) + }) + } + +} + +// The implementation using a setable global is bad, but removes dependence on Parameters +// This change was made in anticipation of a proper cover library +object cover { + private var propLib: BasePropertyLibrary = new DefaultPropertyLibrary + def setPropLib(lib: BasePropertyLibrary): Unit = this.synchronized { + propLib = lib + } + def apply(cond: Bool)(implicit sourceInfo: SourceInfo): Unit = { + propLib.generateProperty(CoverPropertyParameters(cond)) + } + def apply(cond: Bool, label: String)(implicit sourceInfo: SourceInfo): Unit = { + propLib.generateProperty(CoverPropertyParameters(cond, label)) + } + def apply(cond: Bool, label: String, message: String)(implicit sourceInfo: SourceInfo): Unit = { + propLib.generateProperty(CoverPropertyParameters(cond, label, message)) + } + def apply(prop: BaseProperty)(implicit sourceInfo: SourceInfo): Unit = { + prop.generateProperties().foreach( (pp: BasePropertyParameters) => { + if (pp.pType == PropertyType.Cover) { + propLib.generateProperty(CoverPropertyParameters(pp.cond, pp.label, pp.message)) + } + }) + } + def apply[T <: Data](rv: ReadyValidIO[T], label: String, message: String)(implicit sourceInfo: SourceInfo): Unit = { + apply( rv.valid && rv.ready, label + "_FIRE", message + ": valid and ready") + apply( rv.valid && !rv.ready, label + "_STALL", message + ": valid and not ready") + apply(!rv.valid && rv.ready, label + "_IDLE", message + ": not valid and ready") + apply(!rv.valid && !rv.ready, label + "_FULL", message + ": not valid and not ready") + } +} diff --git a/rocket/src/RVC.scala b/rocket/src/RVC.scala new file mode 100644 index 000000000..6b44bcdd0 --- /dev/null +++ b/rocket/src/RVC.scala @@ -0,0 +1,170 @@ +// See LICENSE.SiFive for license details. + +package org.chipsalliance.rocket + +import chisel3._ +import chisel3.util._ +import org.chipsalliance.rocket.util._ + +class ExpandedInstruction extends Bundle { + val bits = UInt(32.W) + val rd = UInt(5.W) + val rs1 = UInt(5.W) + val rs2 = UInt(5.W) + val rs3 = UInt(5.W) +} + +class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { + def inst(bits: UInt, rd: UInt = x(11,7), rs1: UInt = x(19,15), rs2: UInt = x(24,20), rs3: UInt = x(31,27)) = { + val res = Wire(new ExpandedInstruction) + res.bits := bits + res.rd := rd + res.rs1 := rs1 + res.rs2 := rs2 + res.rs3 := rs3 + res + } + + def rs1p = Cat(1.U(2.W), x(9,7)) + def rs2p = Cat(1.U(2.W), x(4,2)) + def rs2 = x(6,2) + def rd = x(11,7) + def addi4spnImm = Cat(x(10,7), x(12,11), x(5), x(6), 0.U(2.W)) + def lwImm = Cat(x(5), x(12,10), x(6), 0.U(2.W)) + def ldImm = Cat(x(6,5), x(12,10), 0.U(3.W)) + def lwspImm = Cat(x(3,2), x(12), x(6,4), 0.U(2.W)) + def ldspImm = Cat(x(4,2), x(12), x(6,5), 0.U(3.W)) + def swspImm = Cat(x(8,7), x(12,9), 0.U(2.W)) + def sdspImm = Cat(x(9,7), x(12,10), 0.U(3.W)) + def luiImm = Cat(Fill(15, x(12)), x(6,2), 0.U(12.W)) + def addi16spImm = Cat(Fill(3, x(12)), x(4,3), x(5), x(2), x(6), 0.U(4.W)) + def addiImm = Cat(Fill(7, x(12)), x(6,2)) + def jImm = Cat(Fill(10, x(12)), x(8), x(10,9), x(6), x(7), x(2), x(11), x(5,3), 0.U(1.W)) + def bImm = Cat(Fill(5, x(12)), x(6,5), x(2), x(11,10), x(4,3), 0.U(1.W)) + def shamt = Cat(x(12), x(6,2)) + def x0 = 0.U(5.W) + def ra = 1.U(5.W) + def sp = 2.U(5.W) + + def q0 = { + def addi4spn = { + val opc = Mux(x(12,5).orR, 0x13.U(7.W), 0x1F.U(7.W)) + inst(Cat(addi4spnImm, sp, 0.U(3.W), rs2p, opc), rs2p, sp, rs2p) + } + def ld = inst(Cat(ldImm, rs1p, 3.U(3.W), rs2p, 0x03.U(7.W)), rs2p, rs1p, rs2p) + def lw = inst(Cat(lwImm, rs1p, 2.U(3.W), rs2p, 0x03.U(7.W)), rs2p, rs1p, rs2p) + def fld = inst(Cat(ldImm, rs1p, 3.U(3.W), rs2p, 0x07.U(7.W)), rs2p, rs1p, rs2p) + def flw = { + if (xLen == 32) inst(Cat(lwImm, rs1p, 2.U(3.W), rs2p, 0x07.U(7.W)), rs2p, rs1p, rs2p) + else ld + } + def unimp = inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x3F.U(7.W)), rs2p, rs1p, rs2p) + def sd = inst(Cat(ldImm >> 5, rs2p, rs1p, 3.U(3.W), ldImm(4,0), 0x23.U(7.W)), rs2p, rs1p, rs2p) + def sw = inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x23.U(7.W)), rs2p, rs1p, rs2p) + def fsd = inst(Cat(ldImm >> 5, rs2p, rs1p, 3.U(3.W), ldImm(4,0), 0x27.U(7.W)), rs2p, rs1p, rs2p) + def fsw = { + if (xLen == 32) inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x27.U(7.W)), rs2p, rs1p, rs2p) + else sd + } + Seq(addi4spn, fld, lw, flw, unimp, fsd, sw, fsw) + } + + def q1 = { + def addi = inst(Cat(addiImm, rd, 0.U(3.W), rd, 0x13.U(7.W)), rd, rd, rs2p) + def addiw = { + val opc = Mux(rd.orR, 0x1B.U(7.W), 0x1F.U(7.W)) + inst(Cat(addiImm, rd, 0.U(3.W), rd, opc), rd, rd, rs2p) + } + def jal = { + if (xLen == 32) inst(Cat(jImm(20), jImm(10,1), jImm(11), jImm(19,12), ra, 0x6F.U(7.W)), ra, rd, rs2p) + else addiw + } + def li = inst(Cat(addiImm, x0, 0.U(3.W), rd, 0x13.U(7.W)), rd, x0, rs2p) + def addi16sp = { + val opc = Mux(addiImm.orR, 0x13.U(7.W), 0x1F.U(7.W)) + inst(Cat(addi16spImm, rd, 0.U(3.W), rd, opc), rd, rd, rs2p) + } + def lui = { + val opc = Mux(addiImm.orR, 0x37.U(7.W), 0x3F.U(7.W)) + val me = inst(Cat(luiImm(31,12), rd, opc), rd, rd, rs2p) + Mux(rd === x0 || rd === sp, addi16sp, me) + } + def j = inst(Cat(jImm(20), jImm(10,1), jImm(11), jImm(19,12), x0, 0x6F.U(7.W)), x0, rs1p, rs2p) + def beqz = inst(Cat(bImm(12), bImm(10,5), x0, rs1p, 0.U(3.W), bImm(4,1), bImm(11), 0x63.U(7.W)), rs1p, rs1p, x0) + def bnez = inst(Cat(bImm(12), bImm(10,5), x0, rs1p, 1.U(3.W), bImm(4,1), bImm(11), 0x63.U(7.W)), x0, rs1p, x0) + def arith = { + def srli = Cat(shamt, rs1p, 5.U(3.W), rs1p, 0x13.U(7.W)) + def srai = srli | (1 << 30).U + def andi = Cat(addiImm, rs1p, 7.U(3.W), rs1p, 0x13.U(7.W)) + def rtype = { + val funct = Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U)(Cat(x(12), x(6,5))) + val sub = Mux(x(6,5) === 0.U, (1 << 30).U, 0.U) + val opc = Mux(x(12), 0x3B.U(7.W), 0x33.U(7.W)) + Cat(rs2p, rs1p, funct, rs1p, opc) | sub + } + inst(Seq(srli, srai, andi, rtype)(x(11,10)), rs1p, rs1p, rs2p) + } + Seq(addi, jal, li, lui, arith, j, beqz, bnez) + } + + def q2 = { + val load_opc = Mux(rd.orR, 0x03.U(7.W), 0x1F.U(7.W)) + def slli = inst(Cat(shamt, rd, 1.U(3.W), rd, 0x13.U(7.W)), rd, rd, rs2) + def ldsp = inst(Cat(ldspImm, sp, 3.U(3.W), rd, load_opc), rd, sp, rs2) + def lwsp = inst(Cat(lwspImm, sp, 2.U(3.W), rd, load_opc), rd, sp, rs2) + def fldsp = inst(Cat(ldspImm, sp, 3.U(3.W), rd, 0x07.U(7.W)), rd, sp, rs2) + def flwsp = { + if (xLen == 32) inst(Cat(lwspImm, sp, 2.U(3.W), rd, 0x07.U(7.W)), rd, sp, rs2) + else ldsp + } + def sdsp = inst(Cat(sdspImm >> 5, rs2, sp, 3.U(3.W), sdspImm(4,0), 0x23.U(7.W)), rd, sp, rs2) + def swsp = inst(Cat(swspImm >> 5, rs2, sp, 2.U(3.W), swspImm(4,0), 0x23.U(7.W)), rd, sp, rs2) + def fsdsp = inst(Cat(sdspImm >> 5, rs2, sp, 3.U(3.W), sdspImm(4,0), 0x27.U(7.W)), rd, sp, rs2) + def fswsp = { + if (xLen == 32) inst(Cat(swspImm >> 5, rs2, sp, 2.U(3.W), swspImm(4,0), 0x27.U(7.W)), rd, sp, rs2) + else sdsp + } + def jalr = { + val mv = { + if (useAddiForMv) inst(Cat(rs2, 0.U(3.W), rd, 0x13.U(7.W)), rd, rs2, x0) + else inst(Cat(rs2, x0, 0.U(3.W), rd, 0x33.U(7.W)), rd, x0, rs2) + } + val add = inst(Cat(rs2, rd, 0.U(3.W), rd, 0x33.U(7.W)), rd, rd, rs2) + val jr = Cat(rs2, rd, 0.U(3.W), x0, 0x67.U(7.W)) + val reserved = Cat(jr >> 7, 0x1F.U(7.W)) + val jr_reserved = inst(Mux(rd.orR, jr, reserved), x0, rd, rs2) + val jr_mv = Mux(rs2.orR, mv, jr_reserved) + val jalr = Cat(rs2, rd, 0.U(3.W), ra, 0x67.U(7.W)) + val ebreak = Cat(jr >> 7, 0x73.U(7.W)) | (1 << 20).U + val jalr_ebreak = inst(Mux(rd.orR, jalr, ebreak), ra, rd, rs2) + val jalr_add = Mux(rs2.orR, add, jalr_ebreak) + Mux(x(12), jalr_add, jr_mv) + } + Seq(slli, fldsp, lwsp, flwsp, jalr, fsdsp, swsp, fswsp) + } + + def q3 = Seq.fill(8)(passthrough) + + def passthrough = inst(x) + + def decode = { + val s = q0 ++ q1 ++ q2 ++ q3 + s(Cat(x(1,0), x(15,13))) + } +} + +class RVCExpander(useAddiForMv: Boolean = false,usingCompressed:Boolean,XLen:Int)extends Module { + val io = IO(new Bundle { + val in = Input(UInt(32.W)) + val out = Output(new ExpandedInstruction) + val rvc = Output(Bool()) + }) + + if (usingCompressed) { + io.rvc := io.in(1,0) =/= 3.U + io.out := new RVCDecoder(io.in, XLen, useAddiForMv).decode + } else { + io.rvc := false.B + io.out := new RVCDecoder(io.in, XLen, useAddiForMv).passthrough + } +} diff --git a/rocket/src/Replacement.scala b/rocket/src/Replacement.scala new file mode 100644 index 000000000..e145dae17 --- /dev/null +++ b/rocket/src/Replacement.scala @@ -0,0 +1,325 @@ +// See LICENSE.Berkeley for license details. +// See LICENSE.SiFive for license details. + +package org.chipsalliance.rocket.util + +import chisel3._ +import chisel3.util._ +import chisel3.util.random.LFSR + + +abstract class ReplacementPolicy { + def nBits: Int + def perSet: Boolean + def way: UInt + def miss: Unit + def hit: Unit + def access(touch_way: UInt): Unit + def access(touch_ways: Seq[Valid[UInt]]): Unit + def state_read: UInt + def get_next_state(state: UInt, touch_way: UInt): UInt + def get_next_state(state: UInt, touch_ways: Seq[Valid[UInt]]): UInt = { + touch_ways.foldLeft(state)((prev, touch_way) => Mux(touch_way.valid, get_next_state(prev, touch_way.bits), prev)) + } + def get_replace_way(state: UInt): UInt +} + +object ReplacementPolicy { + def fromString(s: String, n_ways: Int): ReplacementPolicy = s.toLowerCase match { + case "random" => new RandomReplacement(n_ways) + case "lru" => new TrueLRU(n_ways) + case "plru" => new PseudoLRU(n_ways) + case t => throw new IllegalArgumentException(s"unknown Replacement Policy type $t") + } +} + +class RandomReplacement(n_ways: Int) extends ReplacementPolicy { + private val replace = Wire(Bool()) + replace := false.B + def nBits = 16 + def perSet = false + private val lfsr = LFSR(nBits, replace) + def state_read = WireDefault(lfsr) + + def way = Random(n_ways, lfsr) + def miss = replace := true.B + def hit = {} + def access(touch_way: UInt) = {} + def access(touch_ways: Seq[Valid[UInt]]) = {} + def get_next_state(state: UInt, touch_way: UInt) = 0.U //DontCare + def get_replace_way(state: UInt) = way +} + +abstract class SeqReplacementPolicy { + def access(set: UInt): Unit + def update(valid: Bool, hit: Bool, set: UInt, way: UInt): Unit + def way: UInt +} + +abstract class SetAssocReplacementPolicy { + def access(set: UInt, touch_way: UInt): Unit + def access(sets: Seq[UInt], touch_ways: Seq[Valid[UInt]]): Unit + def way(set: UInt): UInt +} + +class SeqRandom(n_ways: Int) extends SeqReplacementPolicy { + val logic = new RandomReplacement(n_ways) + def access(set: UInt) = { } + def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = { + when (valid && !hit) { logic.miss } + } + def way = logic.way +} + +class TrueLRU(n_ways: Int) extends ReplacementPolicy { + // True LRU replacement policy, using a triangular matrix to track which sets are more recently used than others. + // The matrix is packed into a single UInt (or Bits). Example 4-way (6-bits): + // [5] - 3 more recent than 2 + // [4] - 3 more recent than 1 + // [3] - 2 more recent than 1 + // [2] - 3 more recent than 0 + // [1] - 2 more recent than 0 + // [0] - 1 more recent than 0 + def nBits = (n_ways * (n_ways-1)) / 2 + def perSet = true + private val state_reg = RegInit(0.U(nBits.W)) + def state_read = WireDefault(state_reg) + + private def extractMRUVec(state: UInt): Seq[UInt] = { + // Extract per-way information about which higher-indexed ways are more recently used + val moreRecentVec = Wire(Vec(n_ways-1, UInt(n_ways.W))) + var lsb = 0 + for (i <- 0 until n_ways-1) { + moreRecentVec(i) := Cat(state(lsb+n_ways-i-2,lsb), 0.U((i+1).W)) + lsb = lsb + (n_ways - i - 1) + } + moreRecentVec + } + + def get_next_state(state: UInt, touch_way: UInt): UInt = { + val nextState = Wire(Vec(n_ways-1, UInt(n_ways.W))) + val moreRecentVec = extractMRUVec(state) // reconstruct lower triangular matrix + val wayDec = UIntToOH(touch_way, n_ways) + + // Compute next value of triangular matrix + // set the touched way as more recent than every other way + nextState.zipWithIndex.map { case (e, i) => + e := Mux(i.U === touch_way, 0.U(n_ways.W), moreRecentVec(i) | wayDec) + } + + nextState.zipWithIndex.tail.foldLeft((nextState.head.apply(n_ways-1,1),0)) { case ((pe,pi),(ce,ci)) => (Cat(ce.apply(n_ways-1,ci+1), pe), ci) }._1 + } + + def access(touch_way: UInt): Unit = { + state_reg := get_next_state(state_reg, touch_way) + } + def access(touch_ways: Seq[Valid[UInt]]): Unit = { + when (touch_ways.map(_.valid).orR) { + state_reg := get_next_state(state_reg, touch_ways) + } + for (i <- 1 until touch_ways.size) { + cover(PopCount(touch_ways.map(_.valid)) === i.U, s"LRU_UpdateCount$i, LRU Update $i simultaneous") + } + } + + def get_replace_way(state: UInt): UInt = { + val moreRecentVec = extractMRUVec(state) // reconstruct lower triangular matrix + // For each way, determine if all other ways are more recent + val mruWayDec = (0 until n_ways).map { i => + val upperMoreRecent = (if (i == n_ways-1) true.B else moreRecentVec(i).apply(n_ways-1,i+1).andR) + val lowerMoreRecent = (if (i == 0) true.B else moreRecentVec.map(e => !e(i)).reduce(_ && _)) + upperMoreRecent && lowerMoreRecent + } + OHToUInt(mruWayDec) + } + + def way = get_replace_way(state_reg) + def miss = access(way) + def hit = {} + @deprecated("replace 'replace' with 'way' from abstract class ReplacementPolicy","Rocket Chip 2020.05") + def replace: UInt = way +} + +class PseudoLRU(n_ways: Int) extends ReplacementPolicy { + // Pseudo-LRU tree algorithm: https://en.wikipedia.org/wiki/Pseudo-LRU#Tree-PLRU + // + // + // - bits storage example for 4-way PLRU binary tree: + // bit[2]: ways 3+2 older than ways 1+0 + // / \ + // bit[1]: way 3 older than way 2 bit[0]: way 1 older than way 0 + // + // + // - bits storage example for 3-way PLRU binary tree: + // bit[1]: way 2 older than ways 1+0 + // \ + // bit[0]: way 1 older than way 0 + // + // + // - bits storage example for 8-way PLRU binary tree: + // bit[6]: ways 7-4 older than ways 3-0 + // / \ + // bit[5]: ways 7+6 > 5+4 bit[2]: ways 3+2 > 1+0 + // / \ / \ + // bit[4]: way 7>6 bit[3]: way 5>4 bit[1]: way 3>2 bit[0]: way 1>0 + + def nBits = n_ways - 1 + def perSet = true + private val state_reg = if (nBits == 0) Reg(UInt(0.W)) else RegInit(0.U(nBits.W)) + def state_read = WireDefault(state_reg) + + def access(touch_way: UInt): Unit = { + state_reg := get_next_state(state_reg, touch_way) + } + def access(touch_ways: Seq[Valid[UInt]]): Unit = { + when (touch_ways.map(_.valid).orR) { + state_reg := get_next_state(state_reg, touch_ways) + } + for (i <- 1 until touch_ways.size) { + cover(PopCount(touch_ways.map(_.valid)) === i.U, s"PLRU_UpdateCount$i, PLRU Update $i simultaneous") + } + } + + + /** @param state state_reg bits for this sub-tree + * @param touch_way touched way encoded value bits for this sub-tree + * @param tree_nways number of ways in this sub-tree + */ + def get_next_state(state: UInt, touch_way: UInt, tree_nways: Int): UInt = { + require(state.getWidth == (tree_nways-1), s"wrong state bits width ${state.getWidth} for $tree_nways ways") + require(touch_way.getWidth == (log2Ceil(tree_nways) max 1), s"wrong encoded way width ${touch_way.getWidth} for $tree_nways ways") + + if (tree_nways > 2) { + // we are at a branching node in the tree, so recurse + val right_nways: Int = 1 << (log2Ceil(tree_nways) - 1) // number of ways in the right sub-tree + val left_nways: Int = tree_nways - right_nways // number of ways in the left sub-tree + val set_left_older = !touch_way(log2Ceil(tree_nways)-1) + val left_subtree_state = state.extract(tree_nways-3, right_nways-1) + val right_subtree_state = state(right_nways-2, 0) + + if (left_nways > 1) { + // we are at a branching node in the tree with both left and right sub-trees, so recurse both sub-trees + Cat(set_left_older, + Mux(set_left_older, + left_subtree_state, // if setting left sub-tree as older, do NOT recurse into left sub-tree + get_next_state(left_subtree_state, touch_way.extract(log2Ceil(left_nways)-1,0), left_nways)), // recurse left if newer + Mux(set_left_older, + get_next_state(right_subtree_state, touch_way(log2Ceil(right_nways)-1,0), right_nways), // recurse right if newer + right_subtree_state)) // if setting right sub-tree as older, do NOT recurse into right sub-tree + } else { + // we are at a branching node in the tree with only a right sub-tree, so recurse only right sub-tree + Cat(set_left_older, + Mux(set_left_older, + get_next_state(right_subtree_state, touch_way(log2Ceil(right_nways)-1,0), right_nways), // recurse right if newer + right_subtree_state)) // if setting right sub-tree as older, do NOT recurse into right sub-tree + } + } else if (tree_nways == 2) { + // we are at a leaf node at the end of the tree, so set the single state bit opposite of the lsb of the touched way encoded value + !touch_way(0) + } else { // tree_nways <= 1 + // we are at an empty node in an empty tree for 1 way, so return single zero bit for Chisel (no zero-width wires) + 0.U(1.W) + } + } + + def get_next_state(state: UInt, touch_way: UInt): UInt = { + val touch_way_sized = if (touch_way.getWidth < log2Ceil(n_ways)) touch_way.padTo (log2Ceil(n_ways)) + else touch_way.extract(log2Ceil(n_ways)-1,0) + get_next_state(state, touch_way_sized, n_ways) + } + + + /** @param state state_reg bits for this sub-tree + * @param tree_nways number of ways in this sub-tree + */ + def get_replace_way(state: UInt, tree_nways: Int): UInt = { + require(state.getWidth == (tree_nways-1), s"wrong state bits width ${state.getWidth} for $tree_nways ways") + + // this algorithm recursively descends the binary tree, filling in the way-to-replace encoded value from msb to lsb + if (tree_nways > 2) { + // we are at a branching node in the tree, so recurse + val right_nways: Int = 1 << (log2Ceil(tree_nways) - 1) // number of ways in the right sub-tree + val left_nways: Int = tree_nways - right_nways // number of ways in the left sub-tree + val left_subtree_older = state(tree_nways-2) + val left_subtree_state = state.extract(tree_nways-3, right_nways-1) + val right_subtree_state = state(right_nways-2, 0) + + if (left_nways > 1) { + // we are at a branching node in the tree with both left and right sub-trees, so recurse both sub-trees + Cat(left_subtree_older, // return the top state bit (current tree node) as msb of the way-to-replace encoded value + Mux(left_subtree_older, // if left sub-tree is older, recurse left, else recurse right + get_replace_way(left_subtree_state, left_nways), // recurse left + get_replace_way(right_subtree_state, right_nways))) // recurse right + } else { + // we are at a branching node in the tree with only a right sub-tree, so recurse only right sub-tree + Cat(left_subtree_older, // return the top state bit (current tree node) as msb of the way-to-replace encoded value + Mux(left_subtree_older, // if left sub-tree is older, return and do not recurse right + 0.U(1.W), + get_replace_way(right_subtree_state, right_nways))) // recurse right + } + } else if (tree_nways == 2) { + // we are at a leaf node at the end of the tree, so just return the single state bit as lsb of the way-to-replace encoded value + state(0) + } else { // tree_nways <= 1 + // we are at an empty node in an unbalanced tree for non-power-of-2 ways, so return single zero bit as lsb of the way-to-replace encoded value + 0.U(1.W) + } + } + + def get_replace_way(state: UInt): UInt = get_replace_way(state, n_ways) + + def way = get_replace_way(state_reg) + def miss = access(way) + def hit = {} +} + +class SeqPLRU(n_sets: Int, n_ways: Int) extends SeqReplacementPolicy { + val logic = new PseudoLRU(n_ways) + val state = SyncReadMem(n_sets, UInt(logic.nBits.W)) + val current_state = Wire(UInt(logic.nBits.W)) + val next_state = Wire(UInt(logic.nBits.W)) + val plru_way = logic.get_replace_way(current_state) + + def access(set: UInt) = { + current_state := state.read(set) + } + + def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = { + val update_way = Mux(hit, way, plru_way) + next_state := logic.get_next_state(current_state, update_way) + when (valid) { state.write(set, next_state) } + } + + def way = plru_way +} + + +class SetAssocLRU(n_sets: Int, n_ways: Int, policy: String) extends SetAssocReplacementPolicy { + val logic = policy.toLowerCase match { + case "plru" => new PseudoLRU(n_ways) + case "lru" => new TrueLRU(n_ways) + case t => throw new IllegalArgumentException(s"unknown Replacement Policy type $t") + } + val state_vec = + if (logic.nBits == 0) Reg(Vec(n_sets, UInt(logic.nBits.W))) // Work around elaboration error on following line + else RegInit(VecInit(Seq.fill(n_sets)(0.U(logic.nBits.W)))) + + def access(set: UInt, touch_way: UInt) = { + state_vec(set) := logic.get_next_state(state_vec(set), touch_way) + } + + def access(sets: Seq[UInt], touch_ways: Seq[Valid[UInt]]) = { + require(sets.size == touch_ways.size, "internal consistency check: should be same number of simultaneous updates for sets and touch_ways") + for (set <- 0 until n_sets) { + val set_touch_ways = (sets zip touch_ways).map { case (touch_set, touch_way) => + Pipe(touch_way.valid && (touch_set === set.U), touch_way.bits, 0)} + when (set_touch_ways.map(_.valid).orR) { + state_vec(set) := logic.get_next_state(state_vec(set), set_touch_ways) + } + } + } + + def way(set: UInt) = logic.get_replace_way(state_vec(set)) + +} + diff --git a/rocket/src/util.scala b/rocket/src/util.scala new file mode 100644 index 000000000..f2f50a799 --- /dev/null +++ b/rocket/src/util.scala @@ -0,0 +1,186 @@ +package org.chipsalliance.rocket + +import chisel3._ +import chisel3.util._ + +//todo: remove util +package object util { + implicit class UIntIsOneOf(private val x: UInt) extends AnyVal { + def isOneOf(s: Seq[UInt]): Bool = s.map(x === _).orR + + def isOneOf(u1: UInt, u2: UInt*): Bool = isOneOf(u1 +: u2.toSeq) + } + + implicit class SeqToAugmentedSeq[T <: Data](private val x: Seq[T]) extends AnyVal { + def apply(idx: UInt): T = { + if (x.size <= 1) { + x.head + } else if (!isPow2(x.size)) { + // For non-power-of-2 seqs, reflect elements to simplify decoder + (x ++ x.takeRight(x.size & -x.size)).toSeq(idx) + } else { + // Ignore MSBs of idx + val truncIdx = + if (idx.isWidthKnown && idx.getWidth <= log2Ceil(x.size)) idx + else (idx | 0.U(log2Ceil(x.size).W))(log2Ceil(x.size)-1, 0) + x.zipWithIndex.tail.foldLeft(x.head) { case (prev, (cur, i)) => Mux(truncIdx === i.U, cur, prev) } + } + } + + def asUInt: UInt = Cat(x.map(_.asUInt).reverse) + + def rotate(n: Int): Seq[T] = x.drop(n) ++ x.take(n) + + def rotate(n: UInt): Seq[T] = { + if (x.size <= 1) { + x + } else { + require(isPow2(x.size)) + val amt = n.padTo(log2Ceil(x.size)) + (0 until log2Ceil(x.size)).foldLeft(x)((r, i) => (r.rotate(1 << i) zip r).map { case (s, a) => Mux(amt(i), s, a) }) + } + } + + def rotateRight(n: Int): Seq[T] = x.takeRight(n) ++ x.dropRight(n) + + def rotateRight(n: UInt): Seq[T] = { + if (x.size <= 1) { + x + } else { + require(isPow2(x.size)) + val amt = n.padTo(log2Ceil(x.size)) + (0 until log2Ceil(x.size)).foldLeft(x)((r, i) => (r.rotateRight(1 << i) zip r).map { case (s, a) => Mux(amt(i), s, a) }) + } + } + } + + implicit class UIntToAugmentedUInt(private val x: UInt) extends AnyVal { + def sextTo(n: Int): UInt = { + require(x.getWidth <= n) + if (x.getWidth == n) x + else Cat(Fill(n - x.getWidth, x(x.getWidth - 1)), x) + } + + def padTo(n: Int): UInt = { + require(x.getWidth <= n) + if (x.getWidth == n) x + else Cat(0.U((n - x.getWidth).W), x) + } + + // shifts left by n if n >= 0, or right by -n if n < 0 + def <<(n: SInt): UInt = { + val w = n.getWidth - 1 + require(w <= 30) + + val shifted = x << n(w - 1, 0) + Mux(n(w), shifted >> (1 << w), shifted) + } + + // shifts right by n if n >= 0, or left by -n if n < 0 + def >>(n: SInt): UInt = { + val w = n.getWidth - 1 + require(w <= 30) + + val shifted = x << (1 << w) >> n(w - 1, 0) + Mux(n(w), shifted, shifted >> (1 << w)) + } + + // Like UInt.apply(hi, lo), but returns 0.U for zero-width extracts + def extract(hi: Int, lo: Int): UInt = { + require(hi >= lo - 1) + if (hi == lo - 1) 0.U + else x(hi, lo) + } + + // Like Some(UInt.apply(hi, lo)), but returns None for zero-width extracts + def extractOption(hi: Int, lo: Int): Option[UInt] = { + require(hi >= lo - 1) + if (hi == lo - 1) None + else Some(x(hi, lo)) + } + + // like x & ~y, but first truncate or zero-extend y to x's width + def andNot(y: UInt): UInt = x & ~(y | (x & 0.U)) + + def rotateRight(n: Int): UInt = if (n == 0) x else Cat(x(n - 1, 0), x >> n) + + def rotateRight(n: UInt): UInt = { + if (x.getWidth <= 1) { + x + } else { + val amt = n.padTo(log2Ceil(x.getWidth)) + (0 until log2Ceil(x.getWidth)).foldLeft(x)((r, i) => Mux(amt(i), r.rotateRight(1 << i), r)) + } + } + + def rotateLeft(n: Int): UInt = if (n == 0) x else Cat(x(x.getWidth - 1 - n, 0), x(x.getWidth - 1, x.getWidth - n)) + + def rotateLeft(n: UInt): UInt = { + if (x.getWidth <= 1) { + x + } else { + val amt = n.padTo(log2Ceil(x.getWidth)) + (0 until log2Ceil(x.getWidth)).foldLeft(x)((r, i) => Mux(amt(i), r.rotateLeft(1 << i), r)) + } + } + + // compute (this + y) % n, given (this < n) and (y < n) + def addWrap(y: UInt, n: Int): UInt = { + val z = x +& y + if (isPow2(n)) z(n.log2 - 1, 0) else Mux(z >= n.U, z - n.U, z)(log2Ceil(n) - 1, 0) + } + + // compute (this - y) % n, given (this < n) and (y < n) + def subWrap(y: UInt, n: Int): UInt = { + val z = x -& y + if (isPow2(n)) z(n.log2 - 1, 0) else Mux(z(z.getWidth - 1), z + n.U, z)(log2Ceil(n) - 1, 0) + } + + def grouped(width: Int): Seq[UInt] = + (0 until x.getWidth by width).map(base => x(base + width - 1, base)) + + def inRange(base: UInt, bounds: UInt) = x >= base && x < bounds + + def ##(y: Option[UInt]): UInt = y.map(x ## _).getOrElse(x) + + // Like >=, but prevents x-prop for ('x >= 0) + def >==(y: UInt): Bool = x >= y || y === 0.U + } + + implicit class IntToAugmentedInt(private val x: Int) extends AnyVal { + // exact log2 + def log2: Int = { + require(isPow2(x)) + log2Ceil(x) + } + } + + implicit class SeqBoolBitwiseOps(private val x: Seq[Bool]) extends AnyVal { + def &(y: Seq[Bool]): Seq[Bool] = (x zip y).map { case (a, b) => a && b } + + def |(y: Seq[Bool]): Seq[Bool] = padZip(x, y).map { case (a, b) => a || b } + + def ^(y: Seq[Bool]): Seq[Bool] = padZip(x, y).map { case (a, b) => a ^ b } + + def <<(n: Int): Seq[Bool] = Seq.fill(n)(false.B) ++ x + + def >>(n: Int): Seq[Bool] = x drop n + + def unary_~(): Seq[Bool] = x.map(!_) + + def andR: Bool = if (x.isEmpty) true.B else x.reduce(_ && _) + + def orR: Bool = if (x.isEmpty) false.B else x.reduce(_ || _) + + def xorR: Bool = if (x.isEmpty) false.B else x.reduce(_ ^ _) + + private def padZip(y: Seq[Bool], z: Seq[Bool]): Seq[(Bool, Bool)] = y.padTo(z.size, false.B) zip z.padTo(y.size, false.B) + } + + implicit class OptionUIntToAugmentedOptionUInt(private val x: Option[UInt]) extends AnyVal { + def ##(y: UInt): UInt = x.map(_ ## y).getOrElse(y) + + def ##(y: Option[UInt]): Option[UInt] = x.map(_ ## y) + } + +} \ No newline at end of file From 647358003fd252efb492334c19f2e7b8baf02f1d Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Tue, 9 May 2023 10:50:02 +0800 Subject: [PATCH 6/8] remove unused --- diplomatic/src/rocket/BTB.scala | 323 ------------------------------- diplomatic/src/rocket/IBuf.scala | 129 ------------ diplomatic/src/rocket/RVC.scala | 170 ---------------- 3 files changed, 622 deletions(-) delete mode 100644 diplomatic/src/rocket/BTB.scala delete mode 100644 diplomatic/src/rocket/IBuf.scala delete mode 100644 diplomatic/src/rocket/RVC.scala diff --git a/diplomatic/src/rocket/BTB.scala b/diplomatic/src/rocket/BTB.scala deleted file mode 100644 index 1c745b084..000000000 --- a/diplomatic/src/rocket/BTB.scala +++ /dev/null @@ -1,323 +0,0 @@ -// See LICENSE.Berkeley for license details. -// See LICENSE.SiFive for license details. - -package org.chipsalliance.rocket - -import chisel3._ -import chisel3.util._ -import freechips.rocketchip.util._ - -case class BHTParams( - nEntries: Int = 512, - counterLength: Int = 1, - historyLength: Int = 8, - historyBits: Int = 3) - -case class BTBParams( - nEntries: Int = 28, - nMatchBits: Int = 14, - nPages: Int = 6, - nRAS: Int = 6, - bhtParams: Option[BHTParams] = Some(BHTParams()), - updatesOutOfOrder: Boolean = false) - -class RAS(nras: Int) { - def push(addr: UInt): Unit = { - when (count < nras.U) { count := count + 1.U } - val nextPos = Mux((isPow2(nras)).B || pos < (nras-1).U, pos+1.U, 0.U) - stack(nextPos) := addr - pos := nextPos - } - def peek: UInt = stack(pos) - def pop(): Unit = when (!isEmpty) { - count := count - 1.U - pos := Mux((isPow2(nras)).B || pos > 0.U, pos-1.U, (nras-1).U) - } - def clear(): Unit = count := 0.U - def isEmpty: Bool = count === 0.U - - private val count = RegInit(0.U(log2Up(nras+1).W)) - private val pos = RegInit(0.U(log2Up(nras).W)) - private val stack = Reg(Vec(nras, UInt())) -} - -class BHTResp(bhtParams:Option[BHTParams]) extends Bundle { - val history = UInt(bhtParams.map(_.historyLength).getOrElse(1).W) - val value = UInt(bhtParams.map(_.counterLength).getOrElse(1).W) - def taken = value(0) - def strongly_taken = value === 1.U -} - -// BHT contains table of 2-bit counters and a global history register. -// The BHT only predicts and updates when there is a BTB hit. -// The global history: -// - updated speculatively in fetch (if there's a BTB hit). -// - on a mispredict, the history register is reset (again, only if BTB hit). -// The counter table: -// - each counter corresponds with the address of the fetch packet ("fetch pc"). -// - updated when a branch resolves (and BTB was a hit for that branch). -// The updating branch must provide its "fetch pc". -class BHT(params: BHTParams,fetchBytes:Int) extends Bundle { - def index(addr: UInt, history: UInt) = { - def hashHistory(hist: UInt) = if (params.historyLength == params.historyBits) hist else { - val k = math.sqrt(3)/2 - val i = BigDecimal(k * math.pow(2, params.historyLength)).toBigInt - (i.U * hist)(params.historyLength-1, params.historyLength-params.historyBits) - } - def hashAddr(addr: UInt) = { - val hi = addr >> log2Ceil(fetchBytes) - hi(log2Ceil(params.nEntries)-1, 0) ^ (hi >> log2Ceil(params.nEntries))(1, 0) - } - hashAddr(addr) ^ (hashHistory(history) << (log2Up(params.nEntries) - params.historyBits)) - } - def get(addr: UInt): BHTResp = { - val res = Wire(new BHTResp(Some(params))) - res.value := Mux(resetting, 0.U, table(index(addr, history))) - res.history := history - res - } - def updateTable(addr: UInt, d: BHTResp, taken: Bool): Unit = { - wen := true.B - when (!resetting) { - waddr := index(addr, d.history) - wdata := (params.counterLength match { - case 1 => taken - case 2 => Cat(taken ^ d.value(0), d.value === 1.U || d.value(1) && taken) - }) - } - } - def resetHistory(d: BHTResp): Unit = { - history := d.history - } - def updateHistory(addr: UInt, d: BHTResp, taken: Bool): Unit = { - history := Cat(taken, d.history >> 1) - } - def advanceHistory(taken: Bool): Unit = { - history := Cat(taken, history >> 1) - } - - private val table = Mem(params.nEntries, UInt(params.counterLength.W)) - val history = RegInit(0.U(params.historyLength.W)) - - private val reset_waddr = RegInit(0.U((params.nEntries.log2+1).W)) - private val resetting = !reset_waddr(params.nEntries.log2) - private val wen = WireInit(resetting) - private val waddr = WireInit(reset_waddr) - private val wdata = WireInit(0.U) - when (resetting) { reset_waddr := reset_waddr + 1.U } - when (wen) { table(waddr) := wdata } -} - -object CFIType { - def SZ = 2 - def apply() = UInt(SZ.W) - def branch = 0.U - def jump = 1.U - def call = 2.U - def ret = 3.U -} - -// BTB update occurs during branch resolution (and only on a mispredict). -// - "pc" is what future fetch PCs will tag match against. -// - "br_pc" is the PC of the branch instruction. -class BTBUpdate(btbParams:BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { - val prediction = new BTBResp(btbParams,fetchWidth,vaddrBits) - val pc = UInt(vaddrBits.W) - val target = UInt(vaddrBits.W) - val taken = Bool() - val isValid = Bool() - val br_pc = UInt(vaddrBits.W) - val cfiType = CFIType() -} - -// BHT update occurs during branch resolution on all conditional branches. -// - "pc" is what future fetch PCs will tag match against. -class BHTUpdate(btbParams:BTBParams,vaddrBits:Int) extends Bundle { - val prediction = new BHTResp(btbParams.bhtParams) - val pc = UInt(vaddrBits.W) - val branch = Bool() - val taken = Bool() - val mispredict = Bool() -} - -class RASUpdate(vaddrBits:Int) extends Bundle { - val cfiType = CFIType() - val returnAddr = UInt(vaddrBits.W) -} - -// - "bridx" is the low-order PC bits of the predicted branch (after -// shifting off the lowest log(inst_bytes) bits off). -// - "mask" provides a mask of valid instructions (instructions are -// masked off by the predicted taken branch from the BTB). -class BTBResp(btbparams: BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { - val cfiType = CFIType() - val taken = Bool() - val mask = Bits(fetchWidth.W) - val bridx = Bits(log2Up(fetchWidth).W) - val target = UInt(vaddrBits.W) - val entry = UInt(log2Up(btbparams.nEntries + 1).W) - val bht = new BHTResp(btbparams.bhtParams) -} - -class BTBReq(vaddrBits:Int) extends Bundle { - val addr = UInt(vaddrBits.W) -} - -// fully-associative branch target buffer -// Higher-performance processors may cause BTB updates to occur out-of-order, -// which requires an extra CAM port for updates (to ensure no duplicates get -// placed in BTB). -class BTB(btbParams: BTBParams,fetchBytes:Int,fetchWidth:Int,vaddrBits:Int,matchBits:Int,coreInstBytes:Int) extends Module { - val io = IO(new Bundle { - val req = Flipped(Valid(new BTBReq(vaddrBits))) - val resp = Valid(new BTBResp(btbParams,fetchWidth,vaddrBits)) - val btb_update = Flipped(Valid(new BTBUpdate(btbParams,fetchWidth,vaddrBits))) - val bht_update = Flipped(Valid(new BHTUpdate(btbParams,vaddrBits))) - val bht_advance = Flipped(Valid(new BTBResp(btbParams,fetchWidth,vaddrBits))) - val ras_update = Flipped(Valid(new RASUpdate(vaddrBits))) - val ras_head = Valid(UInt(vaddrBits.W)) - val flush = Input(Bool()) - }) - - val idxs = Reg(Vec(btbParams.nEntries, UInt((matchBits - log2Up(coreInstBytes)).W))) - val idxPages = Reg(Vec(btbParams.nEntries, UInt(log2Up(btbParams.nPages).W))) - val tgts = Reg(Vec(btbParams.nEntries, UInt((matchBits - log2Up(coreInstBytes)).W))) - val tgtPages = Reg(Vec(btbParams.nEntries, UInt(log2Up(btbParams.nPages).W))) - val pages = Reg(Vec(btbParams.nPages, UInt((vaddrBits - matchBits).W))) - val pageValid = RegInit(0.U(btbParams.nPages.W)) - val pagesMasked = (pageValid.asBools zip pages).map { case (v, p) => Mux(v, p, 0.U) } - - val isValid = RegInit(0.U(btbParams.nEntries.W)) - val cfiType = Reg(Vec(btbParams.nEntries, CFIType())) - val brIdx = Reg(Vec(btbParams.nEntries, UInt(log2Up(fetchWidth).W))) - - private def page(addr: UInt) = addr >> matchBits - private def pageMatch(addr: UInt) = { - val p = page(addr) - pageValid & pages.map(_ === p).asUInt - } - private def idxMatch(addr: UInt) = { - val idx = addr(matchBits-1, log2Up(coreInstBytes)) - idxs.map(_ === idx).asUInt & isValid - } - - val r_btb_update = Pipe(io.btb_update) - val update_target = io.req.bits.addr - - val pageHit = pageMatch(io.req.bits.addr) - val idxHit = idxMatch(io.req.bits.addr) - - val updatePageHit = pageMatch(r_btb_update.bits.pc) - val (updateHit, updateHitAddr) = - if (btbParams.updatesOutOfOrder) { - val updateHits = (pageHit << 1)(Mux1H(idxMatch(r_btb_update.bits.pc), idxPages)) - (updateHits.orR, OHToUInt(updateHits)) - } else (r_btb_update.bits.prediction.entry < btbParams.nEntries.U, r_btb_update.bits.prediction.entry) - - val useUpdatePageHit = updatePageHit.orR - val usePageHit = pageHit.orR - val doIdxPageRepl = !useUpdatePageHit - val nextPageRepl = RegInit(0.U(log2Ceil(btbParams.nPages).W)) - val idxPageRepl = Cat(pageHit(btbParams.nPages-2,0), pageHit(btbParams.nPages-1)) | Mux(usePageHit, 0.U, UIntToOH(nextPageRepl)) - val idxPageUpdateOH = Mux(useUpdatePageHit, updatePageHit, idxPageRepl) - val idxPageUpdate = OHToUInt(idxPageUpdateOH) - val idxPageReplEn = Mux(doIdxPageRepl, idxPageRepl, 0.U) - - val samePage = page(r_btb_update.bits.pc) === page(update_target) - val doTgtPageRepl = !samePage && !usePageHit - val tgtPageRepl = Mux(samePage, idxPageUpdateOH, Cat(idxPageUpdateOH(btbParams.nPages-2,0), idxPageUpdateOH(btbParams.nPages-1))) - val tgtPageUpdate = OHToUInt(pageHit | Mux(usePageHit, 0.U, tgtPageRepl)) - val tgtPageReplEn = Mux(doTgtPageRepl, tgtPageRepl, 0.U) - - when (r_btb_update.valid && (doIdxPageRepl || doTgtPageRepl)) { - val both = doIdxPageRepl && doTgtPageRepl - val next = nextPageRepl + Mux[UInt](both, 2.U, 1.U) - nextPageRepl := Mux(next >= btbParams.nPages.U, next(0), next) - } - - val repl = new PseudoLRU(btbParams.nEntries) - val waddr = Mux(updateHit, updateHitAddr, repl.way) - val r_resp = Pipe(io.resp) - when (r_resp.valid && r_resp.bits.taken || r_btb_update.valid) { - repl.access(Mux(r_btb_update.valid, waddr, r_resp.bits.entry)) - } - - when (r_btb_update.valid) { - val mask = UIntToOH(waddr) - idxs(waddr) := r_btb_update.bits.pc(matchBits-1, log2Up(coreInstBytes)) - tgts(waddr) := update_target(matchBits-1, log2Up(coreInstBytes)) - idxPages(waddr) := idxPageUpdate +& 1.U // the +1 corresponds to the <<1 on io.resp.valid - tgtPages(waddr) := tgtPageUpdate - cfiType(waddr) := r_btb_update.bits.cfiType - isValid := Mux(r_btb_update.bits.isValid, isValid | mask, isValid & ~mask) - if (fetchWidth > 1) - brIdx(waddr) := r_btb_update.bits.br_pc >> log2Up(coreInstBytes) - - require(btbParams.nPages % 2 == 0) - val idxWritesEven = !idxPageUpdate(0) - - def writeBank(i: Int, mod: Int, en: UInt, data: UInt) = - for (i <- i until btbParams.nPages by mod) - when (en(i)) { pages(i) := data } - - writeBank(0, 2, Mux(idxWritesEven, idxPageReplEn, tgtPageReplEn), - Mux(idxWritesEven, page(r_btb_update.bits.pc), page(update_target))) - writeBank(1, 2, Mux(idxWritesEven, tgtPageReplEn, idxPageReplEn), - Mux(idxWritesEven, page(update_target), page(r_btb_update.bits.pc))) - pageValid := pageValid | tgtPageReplEn | idxPageReplEn - } - - io.resp.valid := (pageHit << 1)(Mux1H(idxHit, idxPages)) - io.resp.bits.taken := true.B - io.resp.bits.target := Cat(pagesMasked(Mux1H(idxHit, tgtPages)), Mux1H(idxHit, tgts) << log2Up(coreInstBytes)) - io.resp.bits.entry := OHToUInt(idxHit) - io.resp.bits.bridx := (if (fetchWidth > 1) Mux1H(idxHit, brIdx) else 0.U) - io.resp.bits.mask := Cat((1.U << ~Mux(io.resp.bits.taken, ~io.resp.bits.bridx, 0.U))-1.U, 1.U) - io.resp.bits.cfiType := Mux1H(idxHit, cfiType) - - // if multiple entries for same PC land in BTB, zap them - when (PopCountAtLeast(idxHit, 2)) { - isValid := isValid & ~idxHit - } - when (io.flush) { - isValid := 0.U - } - - if (btbParams.bhtParams.nonEmpty) { - val bht = new BHT(btbParams.bhtParams.get,fetchBytes) - val isBranch = (idxHit & cfiType.map(_ === CFIType.branch).asUInt).orR - val res = bht.get(io.req.bits.addr) - when (io.bht_advance.valid) { - bht.advanceHistory(io.bht_advance.bits.bht.taken) - } - when (io.bht_update.valid) { - when (io.bht_update.bits.branch) { - bht.updateTable(io.bht_update.bits.pc, io.bht_update.bits.prediction, io.bht_update.bits.taken) - when (io.bht_update.bits.mispredict) { - bht.updateHistory(io.bht_update.bits.pc, io.bht_update.bits.prediction, io.bht_update.bits.taken) - } - }.elsewhen (io.bht_update.bits.mispredict) { - bht.resetHistory(io.bht_update.bits.prediction) - } - } - when (!res.taken && isBranch) { io.resp.bits.taken := false.B } - io.resp.bits.bht := res - } - - if (btbParams.nRAS > 0) { - val ras = new RAS(btbParams.nRAS) - val doPeek = (idxHit & cfiType.map(_ === CFIType.ret).asUInt).orR - io.ras_head.valid := !ras.isEmpty - io.ras_head.bits := ras.peek - when (!ras.isEmpty && doPeek) { - io.resp.bits.target := ras.peek - } - when (io.ras_update.valid) { - when (io.ras_update.bits.cfiType === CFIType.call) { - ras.push(io.ras_update.bits.returnAddr) - }.elsewhen (io.ras_update.bits.cfiType === CFIType.ret) { - ras.pop() - } - } - } -} diff --git a/diplomatic/src/rocket/IBuf.scala b/diplomatic/src/rocket/IBuf.scala deleted file mode 100644 index 45040fafe..000000000 --- a/diplomatic/src/rocket/IBuf.scala +++ /dev/null @@ -1,129 +0,0 @@ -// See LICENSE.SiFive for license details. - -package org.chipsalliance.rocket - -import chisel3._ -import chisel3.util.{Decoupled,log2Ceil,Cat,UIntToOH,Fill} -import freechips.rocketchip.util._ - -class Instruction(coreInstBits:Int, usingCompressed:Boolean) extends Bundle { - val xcpt0 = new FrontendExceptions // exceptions on first half of instruction - val xcpt1 = new FrontendExceptions // exceptions on second half of instruction - val replay = Bool() - val rvc = Bool() - val inst = new ExpandedInstruction - val raw = UInt(32.W) - require(coreInstBits == (if (usingCompressed) 16 else 32)) -} - -class IBuf(coreInstBits:Int, usingCompressed:Boolean,vaddrBits:Int,vaddrBitsExtended:Int,retireWidth:Int,decodeWidth:Int, - fetchWidth:Int,coreInstBytes:Int,BTBParams: BTBParams,xlen:Int) extends Module { - val io = IO(new Bundle { - val imem = Flipped(Decoupled(new FrontendResp(BTBParams,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits))) - val kill = Input(Bool()) - val pc = Output(UInt(vaddrBitsExtended.W)) - val btb_resp = Output(new BTBResp(BTBParams,fetchWidth,vaddrBits)) - val inst = Vec(retireWidth, Decoupled(new Instruction(coreInstBits, usingCompressed))) - }) - - // This module is meant to be more general, but it's not there yet - require(decodeWidth == 1) - - val n = fetchWidth - 1 - val nBufValid = if (n == 0) 0.U else RegInit(init=0.U(log2Ceil(fetchWidth).W)) - val buf = Reg(chiselTypeOf(io.imem.bits)) - val ibufBTBResp = Reg(new BTBResp(BTBParams,fetchWidth,vaddrBits)) - val pcWordMask = (coreInstBytes*fetchWidth-1).U(vaddrBitsExtended.W) - - val pcWordBits = io.imem.bits.pc.extract(log2Ceil(fetchWidth*coreInstBytes)-1, log2Ceil(coreInstBytes)) - val nReady = WireDefault(0.U(log2Ceil(fetchWidth+1).W)) - val nIC = Mux(io.imem.bits.btb.taken, io.imem.bits.btb.bridx +& 1.U, fetchWidth.U) - pcWordBits - val nICReady = nReady - nBufValid - val nValid = Mux(io.imem.valid, nIC, 0.U) + nBufValid - io.imem.ready := io.inst(0).ready && nReady >= nBufValid && (nICReady >= nIC || n.U >= nIC - nICReady) - - if (n > 0) { - when (io.inst(0).ready) { - nBufValid := Mux(nReady >== nBufValid, 0.U, nBufValid - nReady) - if (n > 1) when (nReady > 0.U && nReady < nBufValid) { - val shiftedBuf = shiftInsnRight(buf.data(n*coreInstBits-1, coreInstBits), (nReady-1.U)(log2Ceil(n-1)-1,0)) - buf.data := Cat(buf.data(n*coreInstBits-1, (n-1)*coreInstBits), shiftedBuf((n-1)*coreInstBits-1, 0)) - buf.pc := buf.pc & ~pcWordMask | (buf.pc + (nReady << log2Ceil(coreInstBytes))) & pcWordMask - } - when (io.imem.valid && nReady >= nBufValid && nICReady < nIC && n.U >= nIC - nICReady) { - val shamt = pcWordBits + nICReady - nBufValid := nIC - nICReady - buf := io.imem.bits - buf.data := shiftInsnRight(io.imem.bits.data, shamt)(n*coreInstBits-1,0) - buf.pc := io.imem.bits.pc & ~pcWordMask | (io.imem.bits.pc + (nICReady << log2Ceil(coreInstBytes))) & pcWordMask - ibufBTBResp := io.imem.bits.btb - } - } - when (io.kill) { - nBufValid := 0.U - } - } - - val icShiftAmt = (fetchWidth.U + nBufValid - pcWordBits)(log2Ceil(fetchWidth), 0) - val icData = shiftInsnLeft(Cat(io.imem.bits.data, Fill(fetchWidth, io.imem.bits.data(coreInstBits-1, 0))), icShiftAmt) - .extract(3*fetchWidth*coreInstBits-1, 2*fetchWidth*coreInstBits) - val icMask = (~0.U((fetchWidth*coreInstBits).W) << (nBufValid << log2Ceil(coreInstBits)))(fetchWidth*coreInstBits-1,0) - val inst = icData & icMask | buf.data & ~icMask - - val valid = (UIntToOH(nValid) - 1.U)(fetchWidth-1, 0) - val bufMask = UIntToOH(nBufValid) - 1.U - val xcpt = (0 until bufMask.getWidth).map(i => Mux(bufMask(i), buf.xcpt, io.imem.bits.xcpt)) - val buf_replay = Mux(buf.replay, bufMask, 0.U) - val ic_replay = buf_replay | Mux(io.imem.bits.replay, valid & ~bufMask, 0.U) - assert(!io.imem.valid || !io.imem.bits.btb.taken || io.imem.bits.btb.bridx >= pcWordBits) - - io.btb_resp := io.imem.bits.btb - io.pc := Mux(nBufValid > 0.U, buf.pc, io.imem.bits.pc) - expand(0, 0.U, inst) - - def expand(i: Int, j: UInt, curInst: UInt): Unit = if (i < retireWidth) { - val exp = Module(new RVCExpander(usingCompressed=usingCompressed,XLen=xlen)) - exp.io.in := curInst - io.inst(i).bits.inst := exp.io.out - io.inst(i).bits.raw := curInst - - if (usingCompressed) { - val replay = ic_replay(j) || (!exp.io.rvc && ic_replay(j+1.U)) - val full_insn = exp.io.rvc || valid(j+1.U) || buf_replay(j) - io.inst(i).valid := valid(j) && full_insn - io.inst(i).bits.xcpt0 := xcpt(j) - io.inst(i).bits.xcpt1 := Mux(exp.io.rvc, 0.U, xcpt(j+1.U).asUInt).asTypeOf(new FrontendExceptions) - io.inst(i).bits.replay := replay - io.inst(i).bits.rvc := exp.io.rvc - - when ((bufMask(j) && exp.io.rvc) || bufMask(j+1.U)) { io.btb_resp := ibufBTBResp } - - when (full_insn && ((i == 0).B || io.inst(i).ready)) { nReady := Mux(exp.io.rvc, j+1.U, j+2.U) } - - expand(i+1, Mux(exp.io.rvc, j+1.U, j+2.U), Mux(exp.io.rvc, curInst >> 16, curInst >> 32)) - } else { - when ((i == 0).B || io.inst(i).ready) { nReady := (i+1).U } - io.inst(i).valid := valid(i) - io.inst(i).bits.xcpt0 := xcpt(i) - io.inst(i).bits.xcpt1 := 0.U.asTypeOf(new FrontendExceptions) - io.inst(i).bits.replay := ic_replay(i) - io.inst(i).bits.rvc := false.B - - expand(i+1, null, curInst >> 32) - } - } - - def shiftInsnLeft(in: UInt, dist: UInt) = { - val r = in.getWidth/coreInstBits - require(in.getWidth % coreInstBits == 0) - val data = Cat(Fill((1 << (log2Ceil(r) + 1)) - r, in >> (r-1)*coreInstBits), in) - data << (dist << log2Ceil(coreInstBits)) - } - - def shiftInsnRight(in: UInt, dist: UInt) = { - val r = in.getWidth/coreInstBits - require(in.getWidth % coreInstBits == 0) - val data = Cat(Fill((1 << (log2Ceil(r) + 1)) - r, in >> (r-1)*coreInstBits), in) - data >> (dist << log2Ceil(coreInstBits)) - } -} diff --git a/diplomatic/src/rocket/RVC.scala b/diplomatic/src/rocket/RVC.scala deleted file mode 100644 index 331b3bd3c..000000000 --- a/diplomatic/src/rocket/RVC.scala +++ /dev/null @@ -1,170 +0,0 @@ -// See LICENSE.SiFive for license details. - -package org.chipsalliance.rocket - -import chisel3._ -import chisel3.util._ -import freechips.rocketchip.util._ - -class ExpandedInstruction extends Bundle { - val bits = UInt(32.W) - val rd = UInt(5.W) - val rs1 = UInt(5.W) - val rs2 = UInt(5.W) - val rs3 = UInt(5.W) -} - -class RVCDecoder(x: UInt, xLen: Int, useAddiForMv: Boolean = false) { - def inst(bits: UInt, rd: UInt = x(11,7), rs1: UInt = x(19,15), rs2: UInt = x(24,20), rs3: UInt = x(31,27)) = { - val res = Wire(new ExpandedInstruction) - res.bits := bits - res.rd := rd - res.rs1 := rs1 - res.rs2 := rs2 - res.rs3 := rs3 - res - } - - def rs1p = Cat(1.U(2.W), x(9,7)) - def rs2p = Cat(1.U(2.W), x(4,2)) - def rs2 = x(6,2) - def rd = x(11,7) - def addi4spnImm = Cat(x(10,7), x(12,11), x(5), x(6), 0.U(2.W)) - def lwImm = Cat(x(5), x(12,10), x(6), 0.U(2.W)) - def ldImm = Cat(x(6,5), x(12,10), 0.U(3.W)) - def lwspImm = Cat(x(3,2), x(12), x(6,4), 0.U(2.W)) - def ldspImm = Cat(x(4,2), x(12), x(6,5), 0.U(3.W)) - def swspImm = Cat(x(8,7), x(12,9), 0.U(2.W)) - def sdspImm = Cat(x(9,7), x(12,10), 0.U(3.W)) - def luiImm = Cat(Fill(15, x(12)), x(6,2), 0.U(12.W)) - def addi16spImm = Cat(Fill(3, x(12)), x(4,3), x(5), x(2), x(6), 0.U(4.W)) - def addiImm = Cat(Fill(7, x(12)), x(6,2)) - def jImm = Cat(Fill(10, x(12)), x(8), x(10,9), x(6), x(7), x(2), x(11), x(5,3), 0.U(1.W)) - def bImm = Cat(Fill(5, x(12)), x(6,5), x(2), x(11,10), x(4,3), 0.U(1.W)) - def shamt = Cat(x(12), x(6,2)) - def x0 = 0.U(5.W) - def ra = 1.U(5.W) - def sp = 2.U(5.W) - - def q0 = { - def addi4spn = { - val opc = Mux(x(12,5).orR, 0x13.U(7.W), 0x1F.U(7.W)) - inst(Cat(addi4spnImm, sp, 0.U(3.W), rs2p, opc), rs2p, sp, rs2p) - } - def ld = inst(Cat(ldImm, rs1p, 3.U(3.W), rs2p, 0x03.U(7.W)), rs2p, rs1p, rs2p) - def lw = inst(Cat(lwImm, rs1p, 2.U(3.W), rs2p, 0x03.U(7.W)), rs2p, rs1p, rs2p) - def fld = inst(Cat(ldImm, rs1p, 3.U(3.W), rs2p, 0x07.U(7.W)), rs2p, rs1p, rs2p) - def flw = { - if (xLen == 32) inst(Cat(lwImm, rs1p, 2.U(3.W), rs2p, 0x07.U(7.W)), rs2p, rs1p, rs2p) - else ld - } - def unimp = inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x3F.U(7.W)), rs2p, rs1p, rs2p) - def sd = inst(Cat(ldImm >> 5, rs2p, rs1p, 3.U(3.W), ldImm(4,0), 0x23.U(7.W)), rs2p, rs1p, rs2p) - def sw = inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x23.U(7.W)), rs2p, rs1p, rs2p) - def fsd = inst(Cat(ldImm >> 5, rs2p, rs1p, 3.U(3.W), ldImm(4,0), 0x27.U(7.W)), rs2p, rs1p, rs2p) - def fsw = { - if (xLen == 32) inst(Cat(lwImm >> 5, rs2p, rs1p, 2.U(3.W), lwImm(4,0), 0x27.U(7.W)), rs2p, rs1p, rs2p) - else sd - } - Seq(addi4spn, fld, lw, flw, unimp, fsd, sw, fsw) - } - - def q1 = { - def addi = inst(Cat(addiImm, rd, 0.U(3.W), rd, 0x13.U(7.W)), rd, rd, rs2p) - def addiw = { - val opc = Mux(rd.orR, 0x1B.U(7.W), 0x1F.U(7.W)) - inst(Cat(addiImm, rd, 0.U(3.W), rd, opc), rd, rd, rs2p) - } - def jal = { - if (xLen == 32) inst(Cat(jImm(20), jImm(10,1), jImm(11), jImm(19,12), ra, 0x6F.U(7.W)), ra, rd, rs2p) - else addiw - } - def li = inst(Cat(addiImm, x0, 0.U(3.W), rd, 0x13.U(7.W)), rd, x0, rs2p) - def addi16sp = { - val opc = Mux(addiImm.orR, 0x13.U(7.W), 0x1F.U(7.W)) - inst(Cat(addi16spImm, rd, 0.U(3.W), rd, opc), rd, rd, rs2p) - } - def lui = { - val opc = Mux(addiImm.orR, 0x37.U(7.W), 0x3F.U(7.W)) - val me = inst(Cat(luiImm(31,12), rd, opc), rd, rd, rs2p) - Mux(rd === x0 || rd === sp, addi16sp, me) - } - def j = inst(Cat(jImm(20), jImm(10,1), jImm(11), jImm(19,12), x0, 0x6F.U(7.W)), x0, rs1p, rs2p) - def beqz = inst(Cat(bImm(12), bImm(10,5), x0, rs1p, 0.U(3.W), bImm(4,1), bImm(11), 0x63.U(7.W)), rs1p, rs1p, x0) - def bnez = inst(Cat(bImm(12), bImm(10,5), x0, rs1p, 1.U(3.W), bImm(4,1), bImm(11), 0x63.U(7.W)), x0, rs1p, x0) - def arith = { - def srli = Cat(shamt, rs1p, 5.U(3.W), rs1p, 0x13.U(7.W)) - def srai = srli | (1 << 30).U - def andi = Cat(addiImm, rs1p, 7.U(3.W), rs1p, 0x13.U(7.W)) - def rtype = { - val funct = Seq(0.U, 4.U, 6.U, 7.U, 0.U, 0.U, 2.U, 3.U)(Cat(x(12), x(6,5))) - val sub = Mux(x(6,5) === 0.U, (1 << 30).U, 0.U) - val opc = Mux(x(12), 0x3B.U(7.W), 0x33.U(7.W)) - Cat(rs2p, rs1p, funct, rs1p, opc) | sub - } - inst(Seq(srli, srai, andi, rtype)(x(11,10)), rs1p, rs1p, rs2p) - } - Seq(addi, jal, li, lui, arith, j, beqz, bnez) - } - - def q2 = { - val load_opc = Mux(rd.orR, 0x03.U(7.W), 0x1F.U(7.W)) - def slli = inst(Cat(shamt, rd, 1.U(3.W), rd, 0x13.U(7.W)), rd, rd, rs2) - def ldsp = inst(Cat(ldspImm, sp, 3.U(3.W), rd, load_opc), rd, sp, rs2) - def lwsp = inst(Cat(lwspImm, sp, 2.U(3.W), rd, load_opc), rd, sp, rs2) - def fldsp = inst(Cat(ldspImm, sp, 3.U(3.W), rd, 0x07.U(7.W)), rd, sp, rs2) - def flwsp = { - if (xLen == 32) inst(Cat(lwspImm, sp, 2.U(3.W), rd, 0x07.U(7.W)), rd, sp, rs2) - else ldsp - } - def sdsp = inst(Cat(sdspImm >> 5, rs2, sp, 3.U(3.W), sdspImm(4,0), 0x23.U(7.W)), rd, sp, rs2) - def swsp = inst(Cat(swspImm >> 5, rs2, sp, 2.U(3.W), swspImm(4,0), 0x23.U(7.W)), rd, sp, rs2) - def fsdsp = inst(Cat(sdspImm >> 5, rs2, sp, 3.U(3.W), sdspImm(4,0), 0x27.U(7.W)), rd, sp, rs2) - def fswsp = { - if (xLen == 32) inst(Cat(swspImm >> 5, rs2, sp, 2.U(3.W), swspImm(4,0), 0x27.U(7.W)), rd, sp, rs2) - else sdsp - } - def jalr = { - val mv = { - if (useAddiForMv) inst(Cat(rs2, 0.U(3.W), rd, 0x13.U(7.W)), rd, rs2, x0) - else inst(Cat(rs2, x0, 0.U(3.W), rd, 0x33.U(7.W)), rd, x0, rs2) - } - val add = inst(Cat(rs2, rd, 0.U(3.W), rd, 0x33.U(7.W)), rd, rd, rs2) - val jr = Cat(rs2, rd, 0.U(3.W), x0, 0x67.U(7.W)) - val reserved = Cat(jr >> 7, 0x1F.U(7.W)) - val jr_reserved = inst(Mux(rd.orR, jr, reserved), x0, rd, rs2) - val jr_mv = Mux(rs2.orR, mv, jr_reserved) - val jalr = Cat(rs2, rd, 0.U(3.W), ra, 0x67.U(7.W)) - val ebreak = Cat(jr >> 7, 0x73.U(7.W)) | (1 << 20).U - val jalr_ebreak = inst(Mux(rd.orR, jalr, ebreak), ra, rd, rs2) - val jalr_add = Mux(rs2.orR, add, jalr_ebreak) - Mux(x(12), jalr_add, jr_mv) - } - Seq(slli, fldsp, lwsp, flwsp, jalr, fsdsp, swsp, fswsp) - } - - def q3 = Seq.fill(8)(passthrough) - - def passthrough = inst(x) - - def decode = { - val s = q0 ++ q1 ++ q2 ++ q3 - s(Cat(x(1,0), x(15,13))) - } -} - -class RVCExpander(useAddiForMv: Boolean = false,usingCompressed:Boolean,XLen:Int)extends Module { - val io = IO(new Bundle { - val in = Input(UInt(32.W)) - val out = Output(new ExpandedInstruction) - val rvc = Output(Bool()) - }) - - if (usingCompressed) { - io.rvc := io.in(1,0) =/= 3.U - io.out := new RVCDecoder(io.in, XLen, useAddiForMv).decode - } else { - io.rvc := false.B - io.out := new RVCDecoder(io.in, XLen, useAddiForMv).passthrough - } -} From e7f2e0a517dcaa68e2ed51f5dca4c46801cf8df6 Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Tue, 9 May 2023 10:54:05 +0800 Subject: [PATCH 7/8] reformat --- diplomatic/src/rocket/Frontend.scala | 12 +++++------ diplomatic/src/rocket/RocketCore.scala | 6 +++--- rocket/src/BTB.scala | 29 +++++++++++++------------- rocket/src/IBuf.scala | 12 +++++------ 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/diplomatic/src/rocket/Frontend.scala b/diplomatic/src/rocket/Frontend.scala index 5e3409889..567eed569 100644 --- a/diplomatic/src/rocket/Frontend.scala +++ b/diplomatic/src/rocket/Frontend.scala @@ -42,10 +42,10 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) { val clock_enabled = Input(Bool()) val req = Valid(new FrontendReq) val sfence = Valid(new SFenceReq) - val resp = Flipped(Decoupled(new FrontendResp(tileParams.btb.get,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits))) + val resp = Flipped(Decoupled(new FrontendResp(tileParams.btb.get, vaddrBits, vaddrBitsExtended, fetchWidth, coreInstBits))) val gpa = Flipped(Valid(UInt(vaddrBitsExtended.W))) - val btb_update = Valid(new BTBUpdate(tileParams.btb.get,fetchWidth,vaddrBits)) - val bht_update = Valid(new BHTUpdate(tileParams.btb.get,vaddrBits)) + val btb_update = Valid(new BTBUpdate(tileParams.btb.get, fetchWidth, vaddrBits)) + val bht_update = Valid(new BHTUpdate(tileParams.btb.get, vaddrBits)) val ras_update = Valid(new RASUpdate(vaddrBits)) val flush_icache = Output(Bool()) val npc = Input(UInt(vaddrBitsExtended.W)) @@ -76,7 +76,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val icache = outer.icache.module require(fetchWidth*coreInstBytes == outer.icacheParams.fetchBytes) - val fq = withReset(reset.asBool || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp(tileParams.btb.get,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits), 5, flow = true)) } + val fq = withReset(reset.asBool || io.cpu.req.valid) { Module(new ShiftQueue(new FrontendResp(tileParams.btb.get, vaddrBits, vaddrBitsExtended, fetchWidth, coreInstBits), 5, flow = true))} val clock_en_reg = Reg(Bool()) val clock_en = clock_en_reg || io.cpu.might_request @@ -104,7 +104,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) val s1_speculative = Reg(Bool()) val s2_pc = RegInit(t = UInt(vaddrBitsExtended.W), alignPC(io_reset_vector)) val s2_btb_resp_valid = if (usingBTB) Reg(Bool()) else false.B - val s2_btb_resp_bits = Reg(new BTBResp(tileParams.btb.get,fetchWidth,vaddrBits)) + val s2_btb_resp_bits = Reg(new BTBResp(tileParams.btb.get, fetchWidth, vaddrBits)) val s2_btb_taken = s2_btb_resp_valid && s2_btb_resp_bits.taken val s2_tlb_resp = Reg(tlb.io.resp.cloneType) val s2_xcpt = s2_tlb_resp.ae.inst || s2_tlb_resp.pf.inst || s2_tlb_resp.gf.inst @@ -183,7 +183,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) when (icache.io.resp.valid && icache.io.resp.bits.ae) { fq.io.enq.bits.xcpt.ae.inst := true.B } if (usingBTB) { - val btb = Module(new BTB(tileParams.btb.get,fetchBytes,fetchWidth,vaddrBits,matchBits,coreInstBits)) + val btb = Module(new BTB(tileParams.btb.get, fetchBytes, fetchWidth, vaddrBits, matchBits, coreInstBits)) btb.io.flush := false.B btb.io.req.valid := false.B btb.io.req.bits.addr := s1_pc diff --git a/diplomatic/src/rocket/RocketCore.scala b/diplomatic/src/rocket/RocketCore.scala index 65c08f6d2..9080b1c69 100644 --- a/diplomatic/src/rocket/RocketCore.scala +++ b/diplomatic/src/rocket/RocketCore.scala @@ -213,7 +213,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val ex_reg_xcpt_interrupt = Reg(Bool()) val ex_reg_valid = Reg(Bool()) val ex_reg_rvc = Reg(Bool()) - val ex_reg_btb_resp = Reg(new BTBResp(tileParams.btb.get,fetchWidth,vaddrBits)) + val ex_reg_btb_resp = Reg(new BTBResp(tileParams.btb.get, fetchWidth, vaddrBits)) val ex_reg_xcpt = Reg(Bool()) val ex_reg_flush_pipe = Reg(Bool()) val ex_reg_load_use = Reg(Bool()) @@ -231,7 +231,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val mem_reg_xcpt_interrupt = Reg(Bool()) val mem_reg_valid = Reg(Bool()) val mem_reg_rvc = Reg(Bool()) - val mem_reg_btb_resp = Reg(new BTBResp(tileParams.btb.get,fetchWidth,vaddrBits)) + val mem_reg_btb_resp = Reg(new BTBResp(tileParams.btb.get, fetchWidth, vaddrBits)) val mem_reg_xcpt = Reg(Bool()) val mem_reg_replay = Reg(Bool()) val mem_reg_flush_pipe = Reg(Bool()) @@ -275,7 +275,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val take_pc = take_pc_mem_wb // decode stage - val ibuf = Module(new IBuf(coreInstBits,usingCompressed,vaddrBits,vaddrBitsExtended,retireWidth,decodeWidth,fetchWidth,coreInstBits,tileParams.btb.get,p(XLen))) + val ibuf = Module(new IBuf(coreInstBits, usingCompressed, vaddrBits, vaddrBitsExtended, retireWidth, decodeWidth, fetchWidth, coreInstBits, tileParams.btb.get, p(XLen))) val id_expanded_inst = ibuf.io.inst.map(_.bits.inst) val id_raw_inst = ibuf.io.inst.map(_.bits.raw) val id_inst = id_expanded_inst.map(_.bits) diff --git a/rocket/src/BTB.scala b/rocket/src/BTB.scala index 42b9856ba..d392fbf31 100644 --- a/rocket/src/BTB.scala +++ b/rocket/src/BTB.scala @@ -8,7 +8,6 @@ import chisel3.util._ import org.chipsalliance.rocket.util._ import org.chipsalliance.rocket.util.property._ - case class BHTParams( nEntries: Int = 512, counterLength: Int = 1, @@ -43,7 +42,7 @@ class RAS(nras: Int) { private val stack = Reg(Vec(nras, UInt())) } -class BHTResp(bhtParams:Option[BHTParams]) extends Bundle { +class BHTResp(bhtParams: Option[BHTParams]) extends Bundle { val history = UInt(bhtParams.map(_.historyLength).getOrElse(1).W) val value = UInt(bhtParams.map(_.counterLength).getOrElse(1).W) def taken = value(0) @@ -59,7 +58,7 @@ class BHTResp(bhtParams:Option[BHTParams]) extends Bundle { // - each counter corresponds with the address of the fetch packet ("fetch pc"). // - updated when a branch resolves (and BTB was a hit for that branch). // The updating branch must provide its "fetch pc". -class BHT(params: BHTParams,fetchBytes:Int) extends Bundle { +class BHT(params: BHTParams, fetchBytes: Int) extends Bundle { def index(addr: UInt, history: UInt) = { def hashHistory(hist: UInt) = if (params.historyLength == params.historyBits) hist else { val k = math.sqrt(3)/2 @@ -122,8 +121,8 @@ object CFIType { // BTB update occurs during branch resolution (and only on a mispredict). // - "pc" is what future fetch PCs will tag match against. // - "br_pc" is the PC of the branch instruction. -class BTBUpdate(btbParams:BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { - val prediction = new BTBResp(btbParams,fetchWidth,vaddrBits) +class BTBUpdate(btbParams: BTBParams, fetchWidth: Int, vaddrBits: Int) extends Bundle { + val prediction = new BTBResp(btbParams, fetchWidth, vaddrBits) val pc = UInt(vaddrBits.W) val target = UInt(vaddrBits.W) val taken = Bool() @@ -134,7 +133,7 @@ class BTBUpdate(btbParams:BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle // BHT update occurs during branch resolution on all conditional branches. // - "pc" is what future fetch PCs will tag match against. -class BHTUpdate(btbParams:BTBParams,vaddrBits:Int) extends Bundle { +class BHTUpdate(btbParams: BTBParams, vaddrBits: Int) extends Bundle { val prediction = new BHTResp(btbParams.bhtParams) val pc = UInt(vaddrBits.W) val branch = Bool() @@ -142,7 +141,7 @@ class BHTUpdate(btbParams:BTBParams,vaddrBits:Int) extends Bundle { val mispredict = Bool() } -class RASUpdate(vaddrBits:Int) extends Bundle { +class RASUpdate(vaddrBits: Int) extends Bundle { val cfiType = CFIType() val returnAddr = UInt(vaddrBits.W) } @@ -151,7 +150,7 @@ class RASUpdate(vaddrBits:Int) extends Bundle { // shifting off the lowest log(inst_bytes) bits off). // - "mask" provides a mask of valid instructions (instructions are // masked off by the predicted taken branch from the BTB). -class BTBResp(btbparams: BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle { +class BTBResp(btbparams: BTBParams, fetchWidth: Int, vaddrBits: Int) extends Bundle { val cfiType = CFIType() val taken = Bool() val mask = Bits(fetchWidth.W) @@ -161,21 +160,21 @@ class BTBResp(btbparams: BTBParams,fetchWidth:Int,vaddrBits:Int) extends Bundle val bht = new BHTResp(btbparams.bhtParams) } -class BTBReq(vaddrBits:Int) extends Bundle { - val addr = UInt(vaddrBits.W) +class BTBReq(vaddrBits: Int) extends Bundle { + val addr = UInt(vaddrBits.W) } // fully-associative branch target buffer // Higher-performance processors may cause BTB updates to occur out-of-order, // which requires an extra CAM port for updates (to ensure no duplicates get // placed in BTB). -class BTB(btbParams: BTBParams,fetchBytes:Int,fetchWidth:Int,vaddrBits:Int,matchBits:Int,coreInstBytes:Int) extends Module { +class BTB(btbParams: BTBParams, fetchBytes: Int, fetchWidth: Int, vaddrBits: Int, matchBits: Int, coreInstBytes: Int) extends Module { val io = IO(new Bundle { val req = Flipped(Valid(new BTBReq(vaddrBits))) - val resp = Valid(new BTBResp(btbParams,fetchWidth,vaddrBits)) - val btb_update = Flipped(Valid(new BTBUpdate(btbParams,fetchWidth,vaddrBits))) - val bht_update = Flipped(Valid(new BHTUpdate(btbParams,vaddrBits))) - val bht_advance = Flipped(Valid(new BTBResp(btbParams,fetchWidth,vaddrBits))) + val resp = Valid(new BTBResp(btbParams, fetchWidth, vaddrBits)) + val btb_update = Flipped(Valid(new BTBUpdate(btbParams, fetchWidth, vaddrBits))) + val bht_update = Flipped(Valid(new BHTUpdate(btbParams, vaddrBits))) + val bht_advance = Flipped(Valid(new BTBResp(btbParams, fetchWidth, vaddrBits))) val ras_update = Flipped(Valid(new RASUpdate(vaddrBits))) val ras_head = Valid(UInt(vaddrBits.W)) val flush = Input(Bool()) diff --git a/rocket/src/IBuf.scala b/rocket/src/IBuf.scala index c90ed73fd..3b2236240 100644 --- a/rocket/src/IBuf.scala +++ b/rocket/src/IBuf.scala @@ -39,13 +39,13 @@ class Instruction(coreInstBits:Int, usingCompressed:Boolean) extends Bundle { require(coreInstBits == (if (usingCompressed) 16 else 32)) } -class IBuf(coreInstBits:Int, usingCompressed:Boolean,vaddrBits:Int,vaddrBitsExtended:Int,retireWidth:Int,decodeWidth:Int, - fetchWidth:Int,coreInstBytes:Int,BTBParams: BTBParams,xlen:Int) extends Module { +class IBuf(coreInstBits: Int, usingCompressed: Boolean, vaddrBits: Int, vaddrBitsExtended: Int, retireWidth: Int, decodeWidth: Int, + fetchWidth: Int, coreInstBytes: Int, BTBParams: BTBParams, xlen: Int) extends Module { val io = IO(new Bundle { - val imem = Flipped(Decoupled(new FrontendResp(BTBParams,vaddrBits,vaddrBitsExtended,fetchWidth, coreInstBits))) + val imem = Flipped(Decoupled(new FrontendResp(BTBParams, vaddrBits, vaddrBitsExtended, fetchWidth, coreInstBits))) val kill = Input(Bool()) val pc = Output(UInt(vaddrBitsExtended.W)) - val btb_resp = Output(new BTBResp(BTBParams,fetchWidth,vaddrBits)) + val btb_resp = Output(new BTBResp(BTBParams, fetchWidth, vaddrBits)) val inst = Vec(retireWidth, Decoupled(new Instruction(coreInstBits, usingCompressed))) }) @@ -55,7 +55,7 @@ class IBuf(coreInstBits:Int, usingCompressed:Boolean,vaddrBits:Int,vaddrBitsExte val n = fetchWidth - 1 val nBufValid = if (n == 0) 0.U else RegInit(init=0.U(log2Ceil(fetchWidth).W)) val buf = Reg(chiselTypeOf(io.imem.bits)) - val ibufBTBResp = Reg(new BTBResp(BTBParams,fetchWidth,vaddrBits)) + val ibufBTBResp = Reg(new BTBResp(BTBParams, fetchWidth, vaddrBits)) val pcWordMask = (coreInstBytes*fetchWidth-1).U(vaddrBitsExtended.W) val pcWordBits = io.imem.bits.pc.extract(log2Ceil(fetchWidth*coreInstBytes)-1, log2Ceil(coreInstBytes)) @@ -105,7 +105,7 @@ class IBuf(coreInstBits:Int, usingCompressed:Boolean,vaddrBits:Int,vaddrBitsExte expand(0, 0.U, inst) def expand(i: Int, j: UInt, curInst: UInt): Unit = if (i < retireWidth) { - val exp = Module(new RVCExpander(usingCompressed=usingCompressed,XLen=xlen)) + val exp = Module(new RVCExpander(usingCompressed = usingCompressed, XLen = xlen)) exp.io.in := curInst io.inst(i).bits.inst := exp.io.out io.inst(i).bits.raw := curInst From 1686ab331827f4fe9ba4b42f863e07cd9efdf55a Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Tue, 9 May 2023 11:02:28 +0800 Subject: [PATCH 8/8] reformat --- diplomatic/src/rocket/BaseTile.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/diplomatic/src/rocket/BaseTile.scala b/diplomatic/src/rocket/BaseTile.scala index 947fc8fcc..8170a88ac 100644 --- a/diplomatic/src/rocket/BaseTile.scala +++ b/diplomatic/src/rocket/BaseTile.scala @@ -75,8 +75,6 @@ trait HasNonDiplomaticTileParameters { lazy val maxPAddrBits: Int = { require(xLen == 32 || xLen == 64, s"Only XLENs of 32 or 64 are supported, but got $xLen") xLen match { case 32 => 34; case 64 => 56 } - - } /** Use staticIdForMetadataUseOnly to emit information during the build or identify a component to diplomacy.