From d74e4da0ae23ed403bdeacea5e9c8501439b3e6a Mon Sep 17 00:00:00 2001 From: Liphen Date: Mon, 20 Nov 2023 15:15:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9alu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/defines/isa/Instructions.scala | 2 +- .../playground/src/pipeline/execute/ALU.scala | 183 +++++------------- chisel/playground/test/src/TestMain.scala | 3 +- 3 files changed, 56 insertions(+), 132 deletions(-) diff --git a/chisel/playground/src/defines/isa/Instructions.scala b/chisel/playground/src/defines/isa/Instructions.scala index 88c7a55..1197822 100644 --- a/chisel/playground/src/defines/isa/Instructions.scala +++ b/chisel/playground/src/defines/isa/Instructions.scala @@ -86,7 +86,7 @@ object ALUOpType { def isAdd(func: UInt) = func(6) def pcPlus2(func: UInt) = func(5) def isBru(func: UInt) = func(4) - def isBranch(func: UInt) = !func(3) + def isBranch(func: UInt) = isBru(func) && !func(3) def isJump(func: UInt) = isBru(func) && !isBranch(func) def getBranchType(func: UInt) = func(2, 1) def isBranchInvert(func: UInt) = func(0) diff --git a/chisel/playground/src/pipeline/execute/ALU.scala b/chisel/playground/src/pipeline/execute/ALU.scala index 96aff58..a35e758 100644 --- a/chisel/playground/src/pipeline/execute/ALU.scala +++ b/chisel/playground/src/pipeline/execute/ALU.scala @@ -1,135 +1,58 @@ -// package cpu.pipeline.execute +package cpu.pipeline.execute -// import chisel3._ -// import chisel3.util._ -// import cpu.defines._ -// import cpu.defines.Const._ +import chisel3._ +import chisel3.util._ +import cpu.defines._ +import cpu.defines.Const._ -// class DivSignal extends Bundle { -// val ready = Input(Bool()) -// val result = Input(UInt(HILO_WID.W)) +class DivSignal extends Bundle { + val ready = Input(Bool()) + val result = Input(UInt(64.W)) -// val en = Output(Bool()) -// val signed = Output(Bool()) -// } -// class MultSignal extends Bundle { -// val ready = Input(Bool()) -// val result = Input(UInt(HILO_WID.W)) + val en = Output(Bool()) + val signed = Output(Bool()) +} +class MultSignal extends Bundle { + val ready = Input(Bool()) + val result = Input(UInt(64.W)) -// val en = Output(Bool()) -// val signed = Output(Bool()) -// } -// class Alu extends Module { -// val io = IO(new Bundle { -// val inst_info = Input(new InstInfo()) -// val src_info = Input(new SrcInfo()) -// val csr_rdata = Input(UInt(DATA_WID.W)) -// val llbit = Input(Bool()) -// val hilo = new Bundle { -// val rdata = Input(UInt(HILO_WID.W)) -// val wdata = Output(UInt(HILO_WID.W)) -// } -// val mul = new MultSignal() -// val div = new DivSignal() -// val result = Output(UInt(DATA_WID.W)) -// val overflow = Output(Bool()) -// val trap = Output(Bool()) -// }) -// val op = io.inst_info.op -// val src1 = io.src_info.src1_data -// val src2 = io.src_info.src2_data + val en = Output(Bool()) + val signed = Output(Bool()) +} +class Alu extends Module { + val io = IO(new Bundle { + val inst_info = Input(new InstInfo()) + val src_info = Input(new SrcInfo()) + val csr_rdata = Input(UInt(DATA_WID.W)) + val result = Output(UInt(DATA_WID.W)) + }) + val op = io.inst_info.op + val src1 = io.src_info.src1_data + val src2 = io.src_info.src2_data + val is_sub = !ALUOpType.isAdd(op) + val sum = (src1 +& (src2 ^ Fill(XLEN, is_sub))) + is_sub + val xor = src1 ^ src2 + val sltu = !sum(XLEN) + val slt = xor(XLEN - 1) ^ sltu -// val sum = src1 + src2 -// val diff = src1 - src2 -// val slt = src1.asSInt < src2.asSInt -// val sltu = src1 < src2 -// val clo = WireInit(32.U) -// val clz = WireInit(32.U) -// for (i <- 0 until 32) { -// when(!src1(i)) { -// clo := (31 - i).U -// }.otherwise { -// clz := (31 - i).U -// } -// } - -// val hilo = io.hilo.rdata - -// io.hilo.wdata := MuxLookup(op, 0.U)( -// Seq( -// EXE_MTHI -> Cat(src1, hilo(31, 0)), -// EXE_MTLO -> Cat(hilo(63, 32), src1), -// EXE_MULT -> Mux(io.mul.ready, io.mul.result, 0.U), -// EXE_MULTU -> Mux(io.mul.ready, io.mul.result, 0.U), -// EXE_MADD -> Mux(io.mul.ready, hilo + io.mul.result, 0.U), -// EXE_MADDU -> Mux(io.mul.ready, hilo + io.mul.result, 0.U), -// EXE_MSUB -> Mux(io.mul.ready, hilo - io.mul.result, 0.U), -// EXE_MSUBU -> Mux(io.mul.ready, hilo - io.mul.result, 0.U), -// EXE_DIV -> Mux(io.div.ready, io.div.result, 0.U), -// EXE_DIVU -> Mux(io.div.ready, io.div.result, 0.U) -// ) -// ) - -// io.mul.signed := VecInit(EXE_MULT, EXE_MUL, EXE_MADD, EXE_MSUB).contains(op) -// io.mul.en := Mux( -// VecInit(EXE_MUL, EXE_MULT, EXE_MULTU, EXE_MADD, EXE_MSUB, EXE_MADDU, EXE_MSUBU).contains(op), -// !io.mul.ready, -// false.B -// ) -// io.div.signed := VecInit(EXE_DIV).contains(op) -// io.div.en := Mux(VecInit(EXE_DIV, EXE_DIVU).contains(op), !io.div.ready, false.B) - -// io.result := MuxLookup(op, 0.U)( -// Seq( -// // 算数指令 -// EXE_ADD -> sum, -// EXE_ADDU -> sum, -// EXE_SUB -> diff, -// EXE_SUBU -> diff, -// EXE_SLT -> slt, -// EXE_SLTU -> sltu, -// // 逻辑指令 -// EXE_AND -> (src1 & src2), -// EXE_OR -> (src1 | src2), -// EXE_NOR -> (~(src1 | src2)), -// EXE_XOR -> (src1 ^ src2), -// // 移位指令 -// EXE_SLL -> (src2 << src1(4, 0)), -// EXE_SRL -> (src2 >> src1(4, 0)), -// EXE_SRA -> ((src2.asSInt >> src1(4, 0)).asUInt), -// // 数据移动指令 -// EXE_MFHI -> io.hilo.rdata(63, 32), -// EXE_MFLO -> io.hilo.rdata(31, 0), -// EXE_MFC0 -> io.csr_rdata, -// EXE_MOVN -> src1, -// EXE_MOVZ -> src1, -// // 前导记数指令 -// EXE_CLZ -> clz, -// EXE_CLO -> clo, -// // 特殊指令 -// EXE_SC -> io.llbit, -// // 乘除法 -// EXE_MUL -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U), -// EXE_MULT -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U), -// EXE_MULTU -> Mux(io.mul.ready, io.mul.result(31, 0), 0.U) -// ) -// ) - -// io.overflow := MuxLookup(op, false.B)( -// Seq( -// EXE_ADD -> ((src1(31) === src2(31)) & (src1(31) =/= sum(31))), -// EXE_SUB -> ((src1(31) =/= src2(31)) & (src1(31) =/= diff(31))) -// ) -// ) - -// io.trap := MuxLookup(op, false.B)( -// Seq( -// EXE_TEQ -> (src1 === src2), -// EXE_TNE -> (src1 =/= src2), -// EXE_TGE -> !slt, -// EXE_TGEU -> !sltu, -// EXE_TLT -> slt, -// EXE_TLTU -> sltu -// ) -// ) -// } + val shsrc1 = MuxLookup(op, src1(XLEN - 1, 0))( + List( + ALUOpType.srlw -> Util.zeroExtend(src1(31, 0), XLEN), + ALUOpType.sraw -> Util.signedExtend(src1(31, 0), XLEN) + ) + ) + val shamt = Mux(ALUOpType.isWordOp(op), src2(4, 0), if (XLEN == 64) src2(5, 0) else src2(4, 0)) + val res = MuxLookup(op(3, 0), sum)( + List( + ALUOpType.sll -> ((shsrc1 << shamt)(XLEN - 1, 0)), + ALUOpType.slt -> Util.zeroExtend(slt, XLEN), + ALUOpType.sltu -> Util.zeroExtend(sltu, XLEN), + ALUOpType.xor -> xor, + ALUOpType.srl -> (shsrc1 >> shamt), + ALUOpType.or -> (src1 | src2), + ALUOpType.and -> (src1 & src2), + ALUOpType.sra -> ((shsrc1.asSInt >> shamt).asUInt) + ) + ) + io.result := Mux(ALUOpType.isWordOp(op), Util.signedExtend(res(31, 0), 64), res) +} diff --git a/chisel/playground/test/src/TestMain.scala b/chisel/playground/test/src/TestMain.scala index c5423c6..afa831e 100644 --- a/chisel/playground/test/src/TestMain.scala +++ b/chisel/playground/test/src/TestMain.scala @@ -5,10 +5,11 @@ import cpu.pipeline.decoder.Decoder import cpu.pipeline.decoder.DecoderUnit import cache.ICache import cpu.pipeline.fetch.BranchPredictorUnit +import cpu.pipeline.execute.Alu object TestMain extends App { implicit val config = new CpuConfig() - def top = new BranchPredictorUnit() + def top = new Alu() val useMFC = false // use MLIR-based firrtl compiler val generator = Seq(chisel3.stage.ChiselGeneratorAnnotation(() => top)) if (useMFC) {