diff --git a/chisel/playground/src/pipeline/execute/fu/Bru.scala b/chisel/playground/src/pipeline/execute/fu/Bru.scala new file mode 100644 index 0000000..6301918 --- /dev/null +++ b/chisel/playground/src/pipeline/execute/fu/Bru.scala @@ -0,0 +1,44 @@ +package cpu.pipeline.execute + +import chisel3._ +import chisel3.util._ +import cpu.defines._ +import cpu.defines.Const._ + +class Bru extends Module { + val io = IO(new Bundle { + val in = new Bundle { + val pc = Input(UInt(XLEN.W)) + val info = Input(new Info()) + val src_info = Input(new SrcInfo()) + } + val out = new Bundle { + val branch = Output(Bool()) + val target = Output(UInt(XLEN.W)) + } + }) + val valid = + io.in.info.fusel === FuType.bru && io.in.info.valid + val src1 = io.in.src_info.src1_data + val src2 = io.in.src_info.src2_data + val op = io.in.info.op + val is_sub = !BRUOpType.isAdd(op) + val adder = (src1 +& (src2 ^ Fill(XLEN, is_sub))) + is_sub + val xor = src1 ^ src2 + val sltu = !adder(XLEN) + val slt = xor(XLEN - 1) ^ sltu + val table = List( + BRUOpType.getBranchType(BRUOpType.beq) -> !xor.orR, + BRUOpType.getBranchType(BRUOpType.blt) -> slt, + BRUOpType.getBranchType(BRUOpType.bltu) -> sltu + ) + io.out.branch := valid & + (LookupTree(BRUOpType.getBranchType(op), table) ^ BRUOpType.isBranchInvert(op) | + BRUOpType.isJump(op)) + io.out.target := Mux1H( + Seq( + (io.out.branch) -> (io.in.pc + io.in.info.imm), + (op === BRUOpType.jalr) -> ((src1 + src2) & ~1.U(XLEN.W)) + ) + ) +}