diff --git a/chisel/playground/src/defines/Util.scala b/chisel/playground/src/defines/Util.scala index 697e9a1..e791c8c 100644 --- a/chisel/playground/src/defines/Util.scala +++ b/chisel/playground/src/defines/Util.scala @@ -3,13 +3,13 @@ package cpu.defines import chisel3._ import chisel3.util._ -object Util { - def subwordModify(source: UInt, start: Int, md: UInt): UInt = { +object SubwordModify { + def apply(source: UInt, start: Int, md: UInt): UInt = { val ms = md.getWidth - subwordModify(source, (start, start - ms + 1), md) + apply(source, (start, start - ms + 1), md) } - def subwordModify(source: UInt, tuple: (Int, Int), md: UInt): UInt = { + def apply(source: UInt, tuple: (Int, Int), md: UInt): UInt = { val ws = source.getWidth val ms = md.getWidth val start = tuple._1 @@ -23,42 +23,107 @@ object Util { else if (start == ws - 1) Cat(md, source(end - 1, 0)) else Cat(source(ws - 1, start + 1), md, source(end - 1, 0)) } +} - def listHasElement(list: Seq[UInt], element: UInt): Bool = { - list.foldLeft(false.B)((r, e) => r || (e === element)) - } - - def MAXnBIT(m: Int): BigInt = BigInt(1) << m - - def unsignedToSigned(s: BigInt, width: Int = 32): BigInt = { - val m = MAXnBIT(width - 1) - if (s >= m) s - 2 * m - else s - } - - def signedExtend(a: UInt, len: Int) = { +object SignedExtend { + def apply(a: UInt, len: Int) = { val aLen = a.getWidth val signBit = a(aLen - 1) if (aLen >= len) a(len - 1, 0) else Cat(Fill(len - aLen, signBit), a) } - - def zeroExtend(raw: UInt, to: Int = 32): UInt = { - zeroExtend(raw, raw.getWidth, to) - } - - def zeroExtend(raw: UInt, from: Int, to: Int): UInt = { - require(to > from && from >= 1) - Cat(Fill(to - from, 0.U), raw) - } - - object LookupTree { - def apply[T <: Data](key: UInt, mapping: Iterable[(UInt, T)]): T = - Mux1H(mapping.map(p => (p._1 === key, p._2))) - } - - object LookupTreeDefault { - def apply[T <: Data](key: UInt, default: T, mapping: Iterable[(UInt, T)]): T = - MuxLookup(key, default)(mapping.toSeq) - } - +} + +object ZeroExtend { + def apply(a: UInt, len: Int) = { + val aLen = a.getWidth + if (aLen >= len) a(len - 1, 0) else Cat(0.U((len - aLen).W), a) + } +} +object LookupTree { + def apply[T <: Data](key: UInt, mapping: Iterable[(UInt, T)]): T = + Mux1H(mapping.map(p => (p._1 === key, p._2))) +} + +object LookupTreeDefault { + def apply[T <: Data](key: UInt, default: T, mapping: Iterable[(UInt, T)]): T = + MuxLookup(key, default)(mapping.toSeq) +} + +object MaskData { + def apply(oldData: UInt, newData: UInt, fullmask: UInt) = { + require(oldData.getWidth == newData.getWidth) + require(oldData.getWidth == fullmask.getWidth) + (newData & fullmask) | (oldData & ~fullmask) + } +} + +object RegMap { + def Unwritable = null + def apply(addr: Int, reg: UInt, wfn: UInt => UInt = (x => x)) = (addr, (reg, wfn)) + def generate( + mapping: Map[Int, (UInt, UInt => UInt)], + raddr: UInt, + rdata: UInt, + waddr: UInt, + wen: Bool, + wdata: UInt, + wmask: UInt + ): Unit = { + val chiselMapping = mapping.map { case (a, (r, w)) => (a.U, r, w) } + rdata := LookupTree(raddr, chiselMapping.map { case (a, r, w) => (a, r) }) + chiselMapping.map { + case (a, r, w) => + if (w != null) when(wen && waddr === a) { r := w(MaskData(r, wdata, wmask)) } + } + } + def generate( + mapping: Map[Int, (UInt, UInt => UInt)], + addr: UInt, + rdata: UInt, + wen: Bool, + wdata: UInt, + wmask: UInt + ): Unit = generate(mapping, addr, rdata, addr, wen, wdata, wmask) +} + +object MaskedRegMap extends CoreParameter { + def Unwritable = null + def NoSideEffect: UInt => UInt = (x => x) + def WritableMask = Fill(XLEN, true.B) + def UnwritableMask = 0.U(XLEN.W) + def apply( + addr: Int, + reg: UInt, + wmask: UInt = WritableMask, + wfn: UInt => UInt = (x => x), + rmask: UInt = WritableMask + ) = (addr, (reg, wmask, wfn, rmask)) + def generate( + mapping: Map[Int, (UInt, UInt, UInt => UInt, UInt)], + raddr: UInt, + rdata: UInt, + waddr: UInt, + wen: Bool, + wdata: UInt + ): Unit = { + val chiselMapping = mapping.map { case (a, (r, wm, w, rm)) => (a.U, r, wm, w, rm) } + rdata := LookupTree(raddr, chiselMapping.map { case (a, r, wm, w, rm) => (a, r & rm) }) + chiselMapping.map { + case (a, r, wm, w, rm) => + if (w != null && wm != UnwritableMask) when(wen && waddr === a) { r := w(MaskData(r, wdata, wm)) } + } + } + def isIllegalAddr(mapping: Map[Int, (UInt, UInt, UInt => UInt, UInt)], addr: UInt): Bool = { + val illegalAddr = Wire(Bool()) + val chiselMapping = mapping.map { case (a, (r, wm, w, rm)) => (a.U, r, wm, w, rm) } + illegalAddr := LookupTreeDefault(addr, true.B, chiselMapping.map { case (a, r, wm, w, rm) => (a, false.B) }) + illegalAddr + } + def generate( + mapping: Map[Int, (UInt, UInt, UInt => UInt, UInt)], + addr: UInt, + rdata: UInt, + wen: Bool, + wdata: UInt + ): Unit = generate(mapping, addr, rdata, addr, wen, wdata) } diff --git a/chisel/playground/src/pipeline/decoder/DecoderUnit.scala b/chisel/playground/src/pipeline/decoder/DecoderUnit.scala index 5294ca9..870fe22 100644 --- a/chisel/playground/src/pipeline/decoder/DecoderUnit.scala +++ b/chisel/playground/src/pipeline/decoder/DecoderUnit.scala @@ -8,6 +8,7 @@ import cpu.defines.Const._ import cpu.{BranchPredictorConfig, CpuConfig} import cpu.pipeline.execute.DecoderUnitExecuteUnit import cpu.pipeline.fetch.BufferUnit +import cpu.pipeline.execute class InstFifoDecoderUnit(implicit val config: CpuConfig) extends Bundle { val allow_to_go = Output(Vec(config.decoderNum, Bool())) @@ -24,21 +25,13 @@ class DataForwardToDecoderUnit extends Bundle { val mem = new RegWrite() } -class CsrDecoderUnit extends Bundle { - val access_allowed = Bool() - val kernel_mode = Bool() - val intterupt_allowed = Bool() - val cause_ip = UInt(8.W) - val status_im = UInt(8.W) -} - class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExceptionNO { val io = IO(new Bundle { // 输入 val instFifo = new InstFifoDecoderUnit() val regfile = Vec(config.decoderNum, new Src12Read()) val forward = Input(Vec(config.fuNum, new DataForwardToDecoderUnit())) - val csr = Input(new CsrDecoderUnit()) + val csr = Input(new execute.CsrDecoderUnit()) // 输出 val fetchUnit = new Bundle { val branch = Output(Bool()) @@ -121,12 +114,13 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti io.executeStage.inst0.ex.int.zip(int.asBools).map { case (x, y) => x := y } val hasInt = int.orR + io.executeStage.inst0.valid := !io.instFifo.info.empty io.executeStage.inst0.pc := pc(0) io.executeStage.inst0.inst_info := inst_info(0) io.executeStage.inst0.src_info.src1_data := Mux( inst_info(0).reg1_ren, forwardCtrl.out.inst(0).src1.rdata, - Util.signedExtend(pc(0), INST_ADDR_WID) + SignedExtend(pc(0), INST_ADDR_WID) ) io.executeStage.inst0.src_info.src2_data := Mux( inst_info(0).reg2_ren, @@ -145,12 +139,13 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti io.executeStage.inst0.jb_info.branch_target := io.bpu.branch_target io.executeStage.inst0.jb_info.update_pht_index := io.bpu.update_pht_index if (config.decoderNum == 2) { + io.executeStage.inst1.valid := !io.instFifo.info.almost_empty io.executeStage.inst1.pc := pc(1) io.executeStage.inst1.inst_info := inst_info(1) io.executeStage.inst1.src_info.src1_data := Mux( inst_info(1).reg1_ren, forwardCtrl.out.inst(1).src1.rdata, - Util.signedExtend(pc(1), INST_ADDR_WID) + SignedExtend(pc(1), INST_ADDR_WID) ) io.executeStage.inst1.src_info.src2_data := Mux( inst_info(1).reg2_ren, @@ -161,8 +156,7 @@ class DecoderUnit(implicit val config: CpuConfig) extends Module with HasExcepti io.executeStage.inst1.ex.excode(illegalInstr) := !decoder(1).io.out.inst_info.inst_valid && !hasInt && !io.instFifo.info.almost_empty io.executeStage.inst1.ex.excode(instrAccessFault) := io.instFifo.inst(1).acc_err - } - else { + } else { io.executeStage.inst1 := DontCare } } diff --git a/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala b/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala index 8d70100..47118d7 100644 --- a/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala +++ b/chisel/playground/src/pipeline/memory/DataMemoryAccess.scala @@ -44,7 +44,7 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module { (io.memoryUnit.in.mem_sel(0) && !io.memoryUnit.in.ex(0).flush_req || io.memoryUnit.in.mem_sel(1) && !io.memoryUnit.in.ex(0).flush_req && !io.memoryUnit.in.ex(1).flush_req) io.dataMemory.out.addr := mem_addr - val rdata = Util.LookupTree( + val rdata = LookupTree( mem_addr(2, 0), List( "b000".U -> mem_rdata(63, 0), @@ -57,19 +57,19 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module { "b111".U -> mem_rdata(63, 56) ) ) - io.memoryUnit.out.rdata := Util.LookupTree( + io.memoryUnit.out.rdata := LookupTree( op, List( - LSUOpType.lb -> Util.signedExtend(rdata(7, 0), XLEN), - LSUOpType.lh -> Util.signedExtend(rdata(15, 0), XLEN), - LSUOpType.lw -> Util.signedExtend(rdata(31, 0), XLEN), - LSUOpType.lbu -> Util.zeroExtend(rdata(7, 0), XLEN), - LSUOpType.lhu -> Util.zeroExtend(rdata(15, 0), XLEN), - LSUOpType.lwu -> Util.zeroExtend(rdata(31, 0), XLEN) + LSUOpType.lb -> SignedExtend(rdata(7, 0), XLEN), + LSUOpType.lh -> SignedExtend(rdata(15, 0), XLEN), + LSUOpType.lw -> SignedExtend(rdata(31, 0), XLEN), + LSUOpType.lbu -> ZeroExtend(rdata(7, 0), XLEN), + LSUOpType.lhu -> ZeroExtend(rdata(15, 0), XLEN), + LSUOpType.lwu -> ZeroExtend(rdata(31, 0), XLEN) ) ) def genWdata(data: UInt, sizeEncode: UInt): UInt = { - Util.LookupTree( + LookupTree( sizeEncode, List( "b00".U -> Fill(8, data(7, 0)), @@ -81,7 +81,7 @@ class DataMemoryAccess(implicit val config: CpuConfig) extends Module { } io.dataMemory.out.wdata := genWdata(mem_wdata, op(1, 0)) def genWmask(addr: UInt, sizeEncode: UInt): UInt = { - Util.LookupTree( + LookupTree( sizeEncode, List( "b00".U -> 0x1.U, //0001 << addr(2:0)