From 1fc86583a462a158e1f68b9be88599584c3d2e17 Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Sat, 29 Apr 2023 16:40:21 +0800 Subject: [PATCH 1/4] rename breakpoint --- diplomatic/src/rocket/Breakpoint.scala | 36 +++--- diplomatic/src/rocket/CSR.scala | 6 +- diplomatic/src/rocket/RocketCore.scala | 2 +- diplomatic/src/rocket/util.scala | 153 +++++++++++++++++++++++++ 4 files changed, 174 insertions(+), 23 deletions(-) create mode 100644 diplomatic/src/rocket/util.scala diff --git a/diplomatic/src/rocket/Breakpoint.scala b/diplomatic/src/rocket/Breakpoint.scala index fc18209bd..2ed76db6c 100644 --- a/diplomatic/src/rocket/Breakpoint.scala +++ b/diplomatic/src/rocket/Breakpoint.scala @@ -4,16 +4,14 @@ package org.chipsalliance.rocket import chisel3._ import chisel3.util.{Cat} -import org.chipsalliance.cde.config.Parameters -import freechips.rocketchip.tile.{CoreBundle, HasCoreParameters} -import freechips.rocketchip.util._ - -class BPControl(implicit p: Parameters) extends CoreBundle()(p) { +import org.chipsalliance.rocket.util._ +//todo: remove util +class BPControl(xLen:Int, useBPWatch: Boolean) extends Bundle { val ttype = UInt(4.W) val dmode = Bool() val maskmax = UInt(6.W) - val reserved = UInt((xLen - (if (coreParams.useBPWatch) 26 else 24)).W) - val action = UInt((if (coreParams.useBPWatch) 3 else 1).W) + val reserved = UInt((xLen - (if (useBPWatch) 26 else 24)).W) + val action = UInt((if (useBPWatch) 3 else 1).W) val chain = Bool() val zero = UInt(2.W) val tmatch = UInt(2.W) @@ -30,9 +28,9 @@ class BPControl(implicit p: Parameters) extends CoreBundle()(p) { def enabled(mstatus: MStatus) = !mstatus.debug && Cat(m, h, s, u)(mstatus.prv) } -class TExtra(implicit p: Parameters) extends CoreBundle()(p) { - def mvalueBits: Int = if (xLen == 32) coreParams.mcontextWidth min 6 else coreParams.mcontextWidth min 13 - def svalueBits: Int = if (xLen == 32) coreParams.scontextWidth min 16 else coreParams.scontextWidth min 34 +class TExtra(xLen:Int, mcontextWidth:Int, scontextWidth:Int) extends Bundle { + def mvalueBits: Int = if (xLen == 32) mcontextWidth min 6 else mcontextWidth min 13 + def svalueBits: Int = if (xLen == 32) scontextWidth min 16 else scontextWidth min 34 def mselectPos: Int = if (xLen == 32) 25 else 50 def mvaluePos : Int = mselectPos + 1 def sselectPos: Int = 0 @@ -46,14 +44,14 @@ class TExtra(implicit p: Parameters) extends CoreBundle()(p) { val sselect = Bool() } -class BP(implicit p: Parameters) extends CoreBundle()(p) { - val control = new BPControl +class BP(xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Bundle { + val control = new BPControl(xLen,useBPWatch) val address = UInt(vaddrBits.W) - val textra = new TExtra + val textra = new TExtra(xLen, mcontextWidth, scontextWidth) def contextMatch(mcontext: UInt, scontext: UInt) = - (if (coreParams.mcontextWidth > 0) (!textra.mselect || (mcontext(textra.mvalueBits-1,0) === textra.mvalue)) else true.B) && - (if (coreParams.scontextWidth > 0) (!textra.sselect || (scontext(textra.svalueBits-1,0) === textra.svalue)) else true.B) + (if (mcontextWidth > 0) (!textra.mselect || (mcontext(textra.mvalueBits-1,0) === textra.mvalue)) else true.B) && + (if (scontextWidth > 0) (!textra.sselect || (scontext(textra.svalueBits-1,0) === textra.svalue)) else true.B) def mask(dummy: Int = 0) = (0 until control.maskMax-1).scanLeft(control.tmatch(0))((m, i) => m && address(i)).asUInt @@ -76,14 +74,14 @@ class BPWatch (val n: Int) extends Bundle() { val action = UInt(3.W) } -class BreakpointUnit(n: Int)(implicit val p: Parameters) extends Module with HasCoreParameters { +class BreakpointUnit(n: Int,xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Module { val io = IO(new Bundle { val status = Input(new MStatus()) - val bp = Input(Vec(n, new BP)) + val bp = Input(Vec(n, new BP(xLen, mcontextWidth, scontextWidth ,useBPWatch, vaddrBits))) val pc = Input(UInt(vaddrBits.W)) val ea = Input(UInt(vaddrBits.W)) - val mcontext = Input(UInt(coreParams.mcontextWidth.W)) - val scontext = Input(UInt(coreParams.scontextWidth.W)) + val mcontext = Input(UInt(mcontextWidth.W)) + val scontext = Input(UInt(scontextWidth.W)) val xcpt_if = Output(Bool()) val xcpt_ld = Output(Bool()) val xcpt_st = Output(Bool()) diff --git a/diplomatic/src/rocket/CSR.scala b/diplomatic/src/rocket/CSR.scala index 3cedca6d6..140a514d7 100644 --- a/diplomatic/src/rocket/CSR.scala +++ b/diplomatic/src/rocket/CSR.scala @@ -278,7 +278,7 @@ class CSRFileIO(implicit p: Parameters) extends CoreBundle val rocc_interrupt = Input(Bool()) val interrupt = Output(Bool()) val interrupt_cause = Output(UInt(xLen.W)) - val bp = Output(Vec(nBreakpoints, new BP)) + val bp = Output(Vec(nBreakpoints, new BP(p(XLen),coreParams.mcontextWidth, coreParams.scontextWidth,coreParams.useBPWatch, vaddrBits ))) val pmp = Output(Vec(nPMPs, new PMP)) val counters = Vec(nPerfCounters, new PerfCounterIO) val csrw_counter = Output(UInt(CSR.nCtr.W)) @@ -458,7 +458,7 @@ class CSRFile( val reg_scontext = (coreParams.scontextWidth > 0).option(RegInit(0.U(coreParams.scontextWidth.W))) val reg_tselect = Reg(UInt(log2Up(nBreakpoints).W)) - val reg_bp = Reg(Vec(1 << log2Up(nBreakpoints), new BP)) + val reg_bp = Reg(Vec(1 << log2Up(nBreakpoints), new BP(p(XLen),coreParams.mcontextWidth, coreParams.scontextWidth,coreParams.useBPWatch, vaddrBits ))) val reg_pmp = Reg(Vec(nPMPs, new PMPReg)) val reg_mie = Reg(UInt(xLen.W)) @@ -1512,7 +1512,7 @@ class CSRFile( if (coreParams.scontextWidth == 0) bpx.sselect := false.B } for (bp <- reg_bp drop nBreakpoints) - bp := 0.U.asTypeOf(new BP()) + bp := 0.U.asTypeOf(new BP(p(XLen),coreParams.mcontextWidth, coreParams.scontextWidth,coreParams.useBPWatch, vaddrBits )) for (pmp <- reg_pmp) { pmp.cfg.res := 0.U when (reset.asBool) { pmp.reset() } diff --git a/diplomatic/src/rocket/RocketCore.scala b/diplomatic/src/rocket/RocketCore.scala index 523819d94..b732f4993 100644 --- a/diplomatic/src/rocket/RocketCore.scala +++ b/diplomatic/src/rocket/RocketCore.scala @@ -349,7 +349,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val id_do_fence = WireDefault(id_rocc_busy && id_ctrl.fence || id_mem_busy && (id_ctrl.amo && id_amo_rl || id_ctrl.fence_i || id_reg_fence && (id_ctrl.mem || id_ctrl.rocc))) - val bpu = Module(new BreakpointUnit(nBreakpoints)) + val bpu = Module(new BreakpointUnit(nBreakpoints,p(XLen),coreParams.mcontextWidth, coreParams.scontextWidth,coreParams.useBPWatch, vaddrBits )) bpu.io.status := csr.io.status bpu.io.bp := csr.io.bp bpu.io.pc := ibuf.io.pc diff --git a/diplomatic/src/rocket/util.scala b/diplomatic/src/rocket/util.scala new file mode 100644 index 000000000..7cc7de147 --- /dev/null +++ b/diplomatic/src/rocket/util.scala @@ -0,0 +1,153 @@ +package org.chipsalliance.rocket + +import chisel3._ +import chisel3.util._ + +//todo: remove util +package object util { + 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) + } + } + + +} From 3b506c61afecd89248a9c7795fff041562027979 Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Mon, 8 May 2023 11:19:21 +0800 Subject: [PATCH 2/4] migrate to rocket --- rocket/src/Breakpoint.scala | 174 ++++++++++++++++++++++++++++++++++++ rocket/src/util.scala | 153 +++++++++++++++++++++++++++++++ 2 files changed, 327 insertions(+) create mode 100644 rocket/src/Breakpoint.scala create mode 100644 rocket/src/util.scala diff --git a/rocket/src/Breakpoint.scala b/rocket/src/Breakpoint.scala new file mode 100644 index 000000000..5fff47776 --- /dev/null +++ b/rocket/src/Breakpoint.scala @@ -0,0 +1,174 @@ +// See LICENSE.SiFive for license details. + +package org.chipsalliance.rocket + +import chisel3._ +import chisel3.util.{Cat} +import org.chipsalliance.rocket.util._ + +object PRV +{ + val SZ = 2 + val U = 0 + val S = 1 + val H = 2 + val M = 3 +} + +class MStatus extends Bundle { + // not truly part of mstatus, but convenient + val debug = Bool() + val cease = Bool() + val wfi = Bool() + val isa = UInt(32.W) + + val dprv = UInt(PRV.SZ.W) // effective prv for data accesses + val dv = Bool() // effective v for data accesses + val prv = UInt(PRV.SZ.W) + val v = Bool() + + val sd = Bool() + val zero2 = UInt(23.W) + val mpv = Bool() + val gva = Bool() + val mbe = Bool() + val sbe = Bool() + val sxl = UInt(2.W) + val uxl = UInt(2.W) + val sd_rv32 = Bool() + val zero1 = UInt(8.W) + val tsr = Bool() + val tw = Bool() + val tvm = Bool() + val mxr = Bool() + val sum = Bool() + val mprv = Bool() + val xs = UInt(2.W) + val fs = UInt(2.W) + val mpp = UInt(2.W) + val vs = UInt(2.W) + val spp = UInt(1.W) + val mpie = Bool() + val ube = Bool() + val spie = Bool() + val upie = Bool() + val mie = Bool() + val hie = Bool() + val sie = Bool() + val uie = Bool() +} +//todo: remove util +class BPControl(xLen:Int, useBPWatch: Boolean) extends Bundle { + val ttype = UInt(4.W) + val dmode = Bool() + val maskmax = UInt(6.W) + val reserved = UInt((xLen - (if (useBPWatch) 26 else 24)).W) + val action = UInt((if (useBPWatch) 3 else 1).W) + val chain = Bool() + val zero = UInt(2.W) + val tmatch = UInt(2.W) + val m = Bool() + val h = Bool() + val s = Bool() + val u = Bool() + val x = Bool() + val w = Bool() + val r = Bool() + + def tType = 2 + def maskMax = 4 + def enabled(mstatus: MStatus) = !mstatus.debug && Cat(m, h, s, u)(mstatus.prv) +} + +class TExtra(xLen:Int, mcontextWidth:Int, scontextWidth:Int) extends Bundle { + def mvalueBits: Int = if (xLen == 32) mcontextWidth min 6 else mcontextWidth min 13 + def svalueBits: Int = if (xLen == 32) scontextWidth min 16 else scontextWidth min 34 + def mselectPos: Int = if (xLen == 32) 25 else 50 + def mvaluePos : Int = mselectPos + 1 + def sselectPos: Int = 0 + def svaluePos : Int = 2 + + val mvalue = UInt(mvalueBits.W) + val mselect = Bool() + val pad2 = UInt((mselectPos - svalueBits - 2).W) + val svalue = UInt(svalueBits.W) + val pad1 = UInt(1.W) + val sselect = Bool() +} + +class BP(xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Bundle { + val control = new BPControl(xLen,useBPWatch) + val address = UInt(vaddrBits.W) + val textra = new TExtra(xLen, mcontextWidth, scontextWidth) + + def contextMatch(mcontext: UInt, scontext: UInt) = + (if (mcontextWidth > 0) (!textra.mselect || (mcontext(textra.mvalueBits-1,0) === textra.mvalue)) else true.B) && + (if (scontextWidth > 0) (!textra.sselect || (scontext(textra.svalueBits-1,0) === textra.svalue)) else true.B) + + def mask(dummy: Int = 0) = + (0 until control.maskMax-1).scanLeft(control.tmatch(0))((m, i) => m && address(i)).asUInt + + def pow2AddressMatch(x: UInt) = + (~x | mask()) === (~address | mask()) + + def rangeAddressMatch(x: UInt) = + (x >= address) ^ control.tmatch(0) + + def addressMatch(x: UInt) = + Mux(control.tmatch(1), rangeAddressMatch(x), pow2AddressMatch(x)) +} + +class BPWatch (val n: Int) extends Bundle() { + val valid = Vec(n, Bool()) + val rvalid = Vec(n, Bool()) + val wvalid = Vec(n, Bool()) + val ivalid = Vec(n, Bool()) + val action = UInt(3.W) +} + +class BreakpointUnit(n: Int,xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Module { + val io = IO(new Bundle { + val status = Input(new MStatus()) + val bp = Input(Vec(n, new BP(xLen, mcontextWidth, scontextWidth ,useBPWatch, vaddrBits))) + val pc = Input(UInt(vaddrBits.W)) + val ea = Input(UInt(vaddrBits.W)) + val mcontext = Input(UInt(mcontextWidth.W)) + val scontext = Input(UInt(scontextWidth.W)) + val xcpt_if = Output(Bool()) + val xcpt_ld = Output(Bool()) + val xcpt_st = Output(Bool()) + val debug_if = Output(Bool()) + val debug_ld = Output(Bool()) + val debug_st = Output(Bool()) + val bpwatch = Output(Vec(n, new BPWatch(1))) + }) + + io.xcpt_if := false.B + io.xcpt_ld := false.B + io.xcpt_st := false.B + io.debug_if := false.B + io.debug_ld := false.B + io.debug_st := false.B + + (io.bpwatch zip io.bp).foldLeft((true.B, true.B, true.B)) { case ((ri, wi, xi), (bpw, bp)) => + val en = bp.control.enabled(io.status) + val cx = bp.contextMatch(io.mcontext, io.scontext) + val r = en && bp.control.r && bp.addressMatch(io.ea) && cx + val w = en && bp.control.w && bp.addressMatch(io.ea) && cx + val x = en && bp.control.x && bp.addressMatch(io.pc) && cx + val end = !bp.control.chain + val action = bp.control.action + + bpw.action := action + bpw.valid(0) := false.B + bpw.rvalid(0) := false.B + bpw.wvalid(0) := false.B + bpw.ivalid(0) := false.B + + when (end && r && ri) { io.xcpt_ld := (action === 0.U); io.debug_ld := (action === 1.U); bpw.valid(0) := true.B; bpw.rvalid(0) := true.B } + when (end && w && wi) { io.xcpt_st := (action === 0.U); io.debug_st := (action === 1.U); bpw.valid(0) := true.B; bpw.wvalid(0) := true.B } + when (end && x && xi) { io.xcpt_if := (action === 0.U); io.debug_if := (action === 1.U); bpw.valid(0) := true.B; bpw.ivalid(0) := true.B } + + (end || r, end || w, end || x) + } +} diff --git a/rocket/src/util.scala b/rocket/src/util.scala new file mode 100644 index 000000000..7cc7de147 --- /dev/null +++ b/rocket/src/util.scala @@ -0,0 +1,153 @@ +package org.chipsalliance.rocket + +import chisel3._ +import chisel3.util._ + +//todo: remove util +package object util { + 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) + } + } + + +} From f3da5f6a8982e3d2251b0a4454f7ec719d544b9d Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Mon, 8 May 2023 11:52:23 +0800 Subject: [PATCH 3/4] remove --- diplomatic/src/rocket/Breakpoint.scala | 122 -------------------- diplomatic/src/rocket/util.scala | 153 ------------------------- rocket/src/Breakpoint.scala | 3 +- 3 files changed, 2 insertions(+), 276 deletions(-) delete mode 100644 diplomatic/src/rocket/Breakpoint.scala delete mode 100644 diplomatic/src/rocket/util.scala diff --git a/diplomatic/src/rocket/Breakpoint.scala b/diplomatic/src/rocket/Breakpoint.scala deleted file mode 100644 index 2ed76db6c..000000000 --- a/diplomatic/src/rocket/Breakpoint.scala +++ /dev/null @@ -1,122 +0,0 @@ -// See LICENSE.SiFive for license details. - -package org.chipsalliance.rocket - -import chisel3._ -import chisel3.util.{Cat} -import org.chipsalliance.rocket.util._ -//todo: remove util -class BPControl(xLen:Int, useBPWatch: Boolean) extends Bundle { - val ttype = UInt(4.W) - val dmode = Bool() - val maskmax = UInt(6.W) - val reserved = UInt((xLen - (if (useBPWatch) 26 else 24)).W) - val action = UInt((if (useBPWatch) 3 else 1).W) - val chain = Bool() - val zero = UInt(2.W) - val tmatch = UInt(2.W) - val m = Bool() - val h = Bool() - val s = Bool() - val u = Bool() - val x = Bool() - val w = Bool() - val r = Bool() - - def tType = 2 - def maskMax = 4 - def enabled(mstatus: MStatus) = !mstatus.debug && Cat(m, h, s, u)(mstatus.prv) -} - -class TExtra(xLen:Int, mcontextWidth:Int, scontextWidth:Int) extends Bundle { - def mvalueBits: Int = if (xLen == 32) mcontextWidth min 6 else mcontextWidth min 13 - def svalueBits: Int = if (xLen == 32) scontextWidth min 16 else scontextWidth min 34 - def mselectPos: Int = if (xLen == 32) 25 else 50 - def mvaluePos : Int = mselectPos + 1 - def sselectPos: Int = 0 - def svaluePos : Int = 2 - - val mvalue = UInt(mvalueBits.W) - val mselect = Bool() - val pad2 = UInt((mselectPos - svalueBits - 2).W) - val svalue = UInt(svalueBits.W) - val pad1 = UInt(1.W) - val sselect = Bool() -} - -class BP(xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Bundle { - val control = new BPControl(xLen,useBPWatch) - val address = UInt(vaddrBits.W) - val textra = new TExtra(xLen, mcontextWidth, scontextWidth) - - def contextMatch(mcontext: UInt, scontext: UInt) = - (if (mcontextWidth > 0) (!textra.mselect || (mcontext(textra.mvalueBits-1,0) === textra.mvalue)) else true.B) && - (if (scontextWidth > 0) (!textra.sselect || (scontext(textra.svalueBits-1,0) === textra.svalue)) else true.B) - - def mask(dummy: Int = 0) = - (0 until control.maskMax-1).scanLeft(control.tmatch(0))((m, i) => m && address(i)).asUInt - - def pow2AddressMatch(x: UInt) = - (~x | mask()) === (~address | mask()) - - def rangeAddressMatch(x: UInt) = - (x >= address) ^ control.tmatch(0) - - def addressMatch(x: UInt) = - Mux(control.tmatch(1), rangeAddressMatch(x), pow2AddressMatch(x)) -} - -class BPWatch (val n: Int) extends Bundle() { - val valid = Vec(n, Bool()) - val rvalid = Vec(n, Bool()) - val wvalid = Vec(n, Bool()) - val ivalid = Vec(n, Bool()) - val action = UInt(3.W) -} - -class BreakpointUnit(n: Int,xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Module { - val io = IO(new Bundle { - val status = Input(new MStatus()) - val bp = Input(Vec(n, new BP(xLen, mcontextWidth, scontextWidth ,useBPWatch, vaddrBits))) - val pc = Input(UInt(vaddrBits.W)) - val ea = Input(UInt(vaddrBits.W)) - val mcontext = Input(UInt(mcontextWidth.W)) - val scontext = Input(UInt(scontextWidth.W)) - val xcpt_if = Output(Bool()) - val xcpt_ld = Output(Bool()) - val xcpt_st = Output(Bool()) - val debug_if = Output(Bool()) - val debug_ld = Output(Bool()) - val debug_st = Output(Bool()) - val bpwatch = Output(Vec(n, new BPWatch(1))) - }) - - io.xcpt_if := false.B - io.xcpt_ld := false.B - io.xcpt_st := false.B - io.debug_if := false.B - io.debug_ld := false.B - io.debug_st := false.B - - (io.bpwatch zip io.bp).foldLeft((true.B, true.B, true.B)) { case ((ri, wi, xi), (bpw, bp)) => - val en = bp.control.enabled(io.status) - val cx = bp.contextMatch(io.mcontext, io.scontext) - val r = en && bp.control.r && bp.addressMatch(io.ea) && cx - val w = en && bp.control.w && bp.addressMatch(io.ea) && cx - val x = en && bp.control.x && bp.addressMatch(io.pc) && cx - val end = !bp.control.chain - val action = bp.control.action - - bpw.action := action - bpw.valid(0) := false.B - bpw.rvalid(0) := false.B - bpw.wvalid(0) := false.B - bpw.ivalid(0) := false.B - - when (end && r && ri) { io.xcpt_ld := (action === 0.U); io.debug_ld := (action === 1.U); bpw.valid(0) := true.B; bpw.rvalid(0) := true.B } - when (end && w && wi) { io.xcpt_st := (action === 0.U); io.debug_st := (action === 1.U); bpw.valid(0) := true.B; bpw.wvalid(0) := true.B } - when (end && x && xi) { io.xcpt_if := (action === 0.U); io.debug_if := (action === 1.U); bpw.valid(0) := true.B; bpw.ivalid(0) := true.B } - - (end || r, end || w, end || x) - } -} diff --git a/diplomatic/src/rocket/util.scala b/diplomatic/src/rocket/util.scala deleted file mode 100644 index 7cc7de147..000000000 --- a/diplomatic/src/rocket/util.scala +++ /dev/null @@ -1,153 +0,0 @@ -package org.chipsalliance.rocket - -import chisel3._ -import chisel3.util._ - -//todo: remove util -package object util { - 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) - } - } - - -} diff --git a/rocket/src/Breakpoint.scala b/rocket/src/Breakpoint.scala index 5fff47776..2370de87e 100644 --- a/rocket/src/Breakpoint.scala +++ b/rocket/src/Breakpoint.scala @@ -6,6 +6,7 @@ import chisel3._ import chisel3.util.{Cat} import org.chipsalliance.rocket.util._ +//todo: remove this object PRV { val SZ = 2 @@ -14,7 +15,7 @@ object PRV val H = 2 val M = 3 } - +//todo: remove this class MStatus extends Bundle { // not truly part of mstatus, but convenient val debug = Bool() From 2419538e4e45b322fc96c9b35158c92f598278ab Mon Sep 17 00:00:00 2001 From: Yanqi Yang Date: Mon, 8 May 2023 16:50:05 +0800 Subject: [PATCH 4/4] reformat and clean --- diplomatic/src/rocket/CSR.scala | 101 -------------------------------- rocket/src/Breakpoint.scala | 10 ++-- 2 files changed, 5 insertions(+), 106 deletions(-) diff --git a/diplomatic/src/rocket/CSR.scala b/diplomatic/src/rocket/CSR.scala index 140a514d7..ad47fb11c 100644 --- a/diplomatic/src/rocket/CSR.scala +++ b/diplomatic/src/rocket/CSR.scala @@ -15,49 +15,6 @@ import scala.collection.mutable.LinkedHashMap import Instructions._ import CustomInstructions._ -class MStatus extends Bundle { - // not truly part of mstatus, but convenient - val debug = Bool() - val cease = Bool() - val wfi = Bool() - val isa = UInt(32.W) - - val dprv = UInt(PRV.SZ.W) // effective prv for data accesses - val dv = Bool() // effective v for data accesses - val prv = UInt(PRV.SZ.W) - val v = Bool() - - val sd = Bool() - val zero2 = UInt(23.W) - val mpv = Bool() - val gva = Bool() - val mbe = Bool() - val sbe = Bool() - val sxl = UInt(2.W) - val uxl = UInt(2.W) - val sd_rv32 = Bool() - val zero1 = UInt(8.W) - val tsr = Bool() - val tw = Bool() - val tvm = Bool() - val mxr = Bool() - val sum = Bool() - val mprv = Bool() - val xs = UInt(2.W) - val fs = UInt(2.W) - val mpp = UInt(2.W) - val vs = UInt(2.W) - val spp = UInt(1.W) - val mpie = Bool() - val ube = Bool() - val spie = Bool() - val upie = Bool() - val mie = Bool() - val hie = Bool() - val sie = Bool() - val uie = Bool() -} - class MNStatus extends Bundle { val mpp = UInt(2.W) val zero3 = UInt(3.W) @@ -141,64 +98,6 @@ class PTBR(implicit p: Parameters) extends CoreBundle()(p) { val ppn = UInt((maxPAddrBits - pgIdxBits).W) } -object PRV -{ - val SZ = 2 - val U = 0 - val S = 1 - val H = 2 - val M = 3 -} - -object CSR -{ - // commands - val SZ = 3 - def X = BitPat.dontCare(SZ) - def N = 0.U(SZ.W) - def R = 2.U(SZ.W) - def I = 4.U(SZ.W) - def W = 5.U(SZ.W) - def S = 6.U(SZ.W) - def C = 7.U(SZ.W) - - // mask a CSR cmd with a valid bit - def maskCmd(valid: Bool, cmd: UInt): UInt = { - // all commands less than CSR.I are treated by CSRFile as NOPs - cmd & ~Mux(valid, 0.U, CSR.I) - } - - val ADDRSZ = 12 - - def modeLSB: Int = 8 - def mode(addr: Int): Int = (addr >> modeLSB) % (1 << PRV.SZ) - def mode(addr: UInt): UInt = addr(modeLSB + PRV.SZ - 1, modeLSB) - - def busErrorIntCause = 128 - def debugIntCause = 14 // keep in sync with MIP.debug - def debugTriggerCause = { - val res = debugIntCause - require(!(Causes.all contains res)) - res - } - def rnmiIntCause = 13 // NMI: Higher numbers = higher priority, must not reuse debugIntCause - def rnmiBEUCause = 12 - - val firstCtr = CSRs.cycle - val firstCtrH = CSRs.cycleh - val firstHPC = CSRs.hpmcounter3 - val firstHPCH = CSRs.hpmcounter3h - val firstHPE = CSRs.mhpmevent3 - val firstMHPC = CSRs.mhpmcounter3 - val firstMHPCH = CSRs.mhpmcounter3h - val firstHPM = 3 - val nCtr = 32 - val nHPM = nCtr - firstHPM - val hpmWidth = 40 - - val maxPMPs = 16 -} - class PerfCounterIO(implicit p: Parameters) extends CoreBundle with HasCoreParameters { val eventSel = Output(UInt(xLen.W)) diff --git a/rocket/src/Breakpoint.scala b/rocket/src/Breakpoint.scala index 2370de87e..2aeb978f9 100644 --- a/rocket/src/Breakpoint.scala +++ b/rocket/src/Breakpoint.scala @@ -97,10 +97,10 @@ class TExtra(xLen:Int, mcontextWidth:Int, scontextWidth:Int) extends Bundle { val sselect = Bool() } -class BP(xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Bundle { - val control = new BPControl(xLen,useBPWatch) +class BP(xLen: Int, mcontextWidth: Int, scontextWidth: Int, useBPWatch: Boolean, vaddrBits: Int) extends Bundle { + val control = new BPControl(xLen, useBPWatch) val address = UInt(vaddrBits.W) - val textra = new TExtra(xLen, mcontextWidth, scontextWidth) + val textra = new TExtra(xLen, mcontextWidth, scontextWidth) def contextMatch(mcontext: UInt, scontext: UInt) = (if (mcontextWidth > 0) (!textra.mselect || (mcontext(textra.mvalueBits-1,0) === textra.mvalue)) else true.B) && @@ -127,10 +127,10 @@ class BPWatch (val n: Int) extends Bundle() { val action = UInt(3.W) } -class BreakpointUnit(n: Int,xLen:Int, mcontextWidth:Int, scontextWidth:Int,useBPWatch: Boolean, vaddrBits:Int) extends Module { +class BreakpointUnit(n: Int, xLen: Int, mcontextWidth: Int, scontextWidth: Int, useBPWatch: Boolean, vaddrBits: Int) extends Module { val io = IO(new Bundle { val status = Input(new MStatus()) - val bp = Input(Vec(n, new BP(xLen, mcontextWidth, scontextWidth ,useBPWatch, vaddrBits))) + val bp = Input(Vec(n, new BP(xLen, mcontextWidth, scontextWidth, useBPWatch, vaddrBits))) val pc = Input(UInt(vaddrBits.W)) val ea = Input(UInt(vaddrBits.W)) val mcontext = Input(UInt(mcontextWidth.W))