From e6decd7c823d5344db0e24c5d8ee1087d6e55a9a Mon Sep 17 00:00:00 2001 From: Liphen Date: Fri, 22 Mar 2024 14:26:21 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9mdu?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/pipeline/execute/fu/Div.scala | 164 +++--------------- .../src/pipeline/execute/fu/Mdu.scala | 21 +-- .../src/pipeline/execute/fu/Mul.scala | 58 +------ 3 files changed, 33 insertions(+), 210 deletions(-) diff --git a/chisel/playground/src/pipeline/execute/fu/Div.scala b/chisel/playground/src/pipeline/execute/fu/Div.scala index 7641d77..5af6ef2 100644 --- a/chisel/playground/src/pipeline/execute/fu/Div.scala +++ b/chisel/playground/src/pipeline/execute/fu/Div.scala @@ -6,160 +6,38 @@ import cpu.defines._ import cpu.defines.Const._ import cpu.CpuConfig -class SignedDiv extends BlackBox with HasBlackBoxResource { - val io = IO(new Bundle { - val aclk = Input(Clock()) - // 除数 - val s_axis_divisor_tvalid = Input(Bool()) - val s_axis_divisor_tready = Output(Bool()) - val s_axis_divisor_tdata = Input(UInt(XLEN.W)) - // 被除数 - val s_axis_dividend_tvalid = Input(Bool()) - val s_axis_dividend_tready = Output(Bool()) - val s_axis_dividend_tdata = Input(UInt(XLEN.W)) - // 结果 - val m_axis_dout_tvalid = Output(Bool()) - val m_axis_dout_tdata = Output(UInt((2 * XLEN).W)) - }) -} - -class UnsignedDiv extends BlackBox with HasBlackBoxResource { - val io = IO(new Bundle { - val aclk = Input(Clock()) - // 除数 - val s_axis_divisor_tvalid = Input(Bool()) - val s_axis_divisor_tready = Output(Bool()) - val s_axis_divisor_tdata = Input(UInt(XLEN.W)) - // 被除数 - val s_axis_dividend_tvalid = Input(Bool()) - val s_axis_dividend_tready = Output(Bool()) - val s_axis_dividend_tdata = Input(UInt(XLEN.W)) - // 结果 - val m_axis_dout_tvalid = Output(Bool()) - val m_axis_dout_tdata = Output(UInt((2 * XLEN).W)) - }) -} - class Div(implicit cpuConfig: CpuConfig) extends Module { val io = IO(new Bundle { - val src1 = Input(UInt(XLEN.W)) - val src2 = Input(UInt(XLEN.W)) - val signed = Input(Bool()) - val en = Input(Bool()) - val allow_to_go = Input(Bool()) + val src1 = Input(UInt(XLEN.W)) + val src2 = Input(UInt(XLEN.W)) + val signed = Input(Bool()) - val ready = Output(Bool()) val result = Output(UInt((2 * XLEN).W)) }) - if (cpuConfig.build) { - // TODO:未经测试 - val signedDiv = Module(new SignedDiv()).io - val unsignedDiv = Module(new UnsignedDiv()).io + val div_signed = io.signed - signedDiv.aclk := clock - unsignedDiv.aclk := clock + val dividend_signed = io.src1(XLEN - 1) & div_signed + val divisor_signed = io.src2(XLEN - 1) & div_signed - // 0为被除数,1为除数 - val unsignedDiv_sent = Seq.fill(2)(RegInit(false.B)) - val unsignedDiv_done = RegInit(false.B) - val signedDiv_sent = Seq.fill(2)(RegInit(false.B)) - val signedDiv_done = RegInit(false.B) + val dividend_abs = Mux(dividend_signed, (-io.src1).asUInt, io.src1.asUInt) + val divisor_abs = Mux(divisor_signed, (-io.src2).asUInt, io.src2.asUInt) - when(unsignedDiv.s_axis_dividend_tready && unsignedDiv.s_axis_dividend_tvalid) { - unsignedDiv_sent(0) := true.B - }.elsewhen(io.ready && io.allow_to_go) { - unsignedDiv_sent(0) := false.B - } - when(unsignedDiv.s_axis_divisor_tready && unsignedDiv.s_axis_divisor_tvalid) { - unsignedDiv_sent(1) := true.B - }.elsewhen(io.ready && io.allow_to_go) { - unsignedDiv_sent(1) := false.B - } + val quotient_signed = (io.src1(XLEN - 1) ^ io.src2(XLEN - 1)) & div_signed + val remainder_signed = io.src1(XLEN - 1) & div_signed - when(signedDiv.s_axis_dividend_tready && signedDiv.s_axis_dividend_tvalid) { - signedDiv_sent(0) := true.B - }.elsewhen(io.ready && io.allow_to_go) { - signedDiv_sent(0) := false.B - } - when(signedDiv.s_axis_divisor_tready && signedDiv.s_axis_divisor_tvalid) { - signedDiv_sent(1) := true.B - }.elsewhen(io.ready && io.allow_to_go) { - signedDiv_sent(1) := false.B - } + val quotient_abs = dividend_abs / divisor_abs + val remainder_abs = dividend_abs - quotient_abs * divisor_abs - when(signedDiv.m_axis_dout_tvalid && !io.allow_to_go) { - signedDiv_done := true.B - }.elsewhen(io.allow_to_go) { - signedDiv_done := false.B - } + val quotient = WireInit(0.S(XLEN.W)) + val remainder = WireInit(0.S(XLEN.W)) - when(unsignedDiv.m_axis_dout_tvalid && !io.allow_to_go) { - unsignedDiv_done := true.B - }.elsewhen(io.allow_to_go) { - unsignedDiv_done := false.B - } - // 被除数和除数的valid信号 - signedDiv.s_axis_dividend_tvalid := io.en && !signedDiv_sent(0) && io.signed - signedDiv.s_axis_divisor_tvalid := io.en && !signedDiv_sent(1) && io.signed - - unsignedDiv.s_axis_dividend_tvalid := io.en && !unsignedDiv_sent(0) && !io.signed - unsignedDiv.s_axis_divisor_tvalid := io.en && !unsignedDiv_sent(1) && !io.signed - - // 被除数和除数的值 - signedDiv.s_axis_dividend_tdata := io.src1 - signedDiv.s_axis_divisor_tdata := io.src2 - - unsignedDiv.s_axis_dividend_tdata := io.src1 - unsignedDiv.s_axis_divisor_tdata := io.src2 - - io.ready := Mux( - io.signed, - signedDiv.m_axis_dout_tvalid || signedDiv_done, - unsignedDiv.m_axis_dout_tvalid || unsignedDiv_done - ) - val signedRes = - Cat(signedDiv.m_axis_dout_tdata(XLEN - 1, 0), signedDiv.m_axis_dout_tdata((2 * XLEN) - 1, XLEN)) - val unsignedRes = - Cat(unsignedDiv.m_axis_dout_tdata(XLEN - 1, 0), unsignedDiv.m_axis_dout_tdata((2 * XLEN) - 1, XLEN)) - io.result := Mux(io.signed, signedRes, unsignedRes) - } else { - val cnt = RegInit(0.U(log2Ceil(cpuConfig.divClockNum + 1).W)) - cnt := MuxCase( - cnt, - Seq( - (io.en && !io.ready) -> (cnt + 1.U), - io.allow_to_go -> 0.U - ) - ) - - val div_signed = io.signed - - val dividend_signed = io.src1(XLEN - 1) & div_signed - val divisor_signed = io.src2(XLEN - 1) & div_signed - - val dividend_abs = Mux(dividend_signed, (-io.src1).asUInt, io.src1.asUInt) - val divisor_abs = Mux(divisor_signed, (-io.src2).asUInt, io.src2.asUInt) - - val quotient_signed = (io.src1(XLEN - 1) ^ io.src2(XLEN - 1)) & div_signed - val remainder_signed = io.src1(XLEN - 1) & div_signed - - val quotient_abs = dividend_abs / divisor_abs - val remainder_abs = dividend_abs - quotient_abs * divisor_abs - - val quotient = RegInit(0.S(XLEN.W)) - val remainder = RegInit(0.S(XLEN.W)) - - when(io.en) { - quotient := Mux(quotient_signed, (-quotient_abs).asSInt, quotient_abs.asSInt) - remainder := Mux(remainder_signed, (-remainder_abs).asSInt, remainder_abs.asSInt) - when(io.src2 === 0.U) { - quotient := (~0.U).asSInt - remainder := io.src1.asSInt - } - } - - io.ready := cnt >= cpuConfig.divClockNum.U - io.result := Cat(remainder, quotient) + quotient := Mux(quotient_signed, (-quotient_abs).asSInt, quotient_abs.asSInt) + remainder := Mux(remainder_signed, (-remainder_abs).asSInt, remainder_abs.asSInt) + when(io.src2 === 0.U) { + quotient := (~0.U).asSInt + remainder := io.src1.asSInt } + + io.result := Cat(remainder, quotient) } diff --git a/chisel/playground/src/pipeline/execute/fu/Mdu.scala b/chisel/playground/src/pipeline/execute/fu/Mdu.scala index 62b2dd8..d74cfcf 100644 --- a/chisel/playground/src/pipeline/execute/fu/Mdu.scala +++ b/chisel/playground/src/pipeline/execute/fu/Mdu.scala @@ -8,11 +8,9 @@ import cpu.CpuConfig class Mdu(implicit cpuConfig: CpuConfig) extends Module { val io = IO(new Bundle { - val info = Input(new Info()) - val src_info = Input(new SrcInfo()) - val allow_to_go = Input(Bool()) + val info = Input(new Info()) + val src_info = Input(new SrcInfo()) - val ready = Output(Bool()) val result = Output(UInt(XLEN.W)) }) @@ -36,23 +34,18 @@ class Mdu(implicit cpuConfig: CpuConfig) extends Module { MDUOpType.mulhu -> (zeroExtend, zeroExtend) ) - mul.src1 := LookupTree(op(1, 0), srcMulConvertTable.map(p => (p._1, p._2._1(src1)))) - mul.src2 := LookupTree(op(1, 0), srcMulConvertTable.map(p => (p._1, p._2._2(src2)))) - mul.en := valid && !is_div - mul.allow_to_go := io.allow_to_go + mul.src1 := LookupTree(op(1, 0), srcMulConvertTable.map(p => (p._1, p._2._1(src1)))) + mul.src2 := LookupTree(op(1, 0), srcMulConvertTable.map(p => (p._1, p._2._2(src2)))) val srcDivConvertFunc = (x: UInt) => Mux(is_w, Mux(MDUOpType.isDivSign(op), SignedExtend(x(31, 0), XLEN), ZeroExtend(x(31, 0), XLEN)), x) - div.src1 := srcDivConvertFunc(src1) - div.src2 := srcDivConvertFunc(src2) - div.signed := MDUOpType.isDivSign(op) - div.en := valid && is_div - div.allow_to_go := io.allow_to_go + div.src1 := srcDivConvertFunc(src1) + div.src2 := srcDivConvertFunc(src2) + div.signed := MDUOpType.isDivSign(op) val mul_result = Mux(op(1, 0) === MDUOpType.mul, mul.result(XLEN - 1, 0), mul.result(2 * XLEN - 1, XLEN)) val div_result = Mux(op(1), div.result(2 * XLEN - 1, XLEN), div.result(XLEN - 1, 0)) val result = Mux(is_div, div_result, mul_result) - io.ready := Mux(is_div, div.ready, mul.ready) io.result := Mux(is_w, SignedExtend(result(31, 0), XLEN), result) } diff --git a/chisel/playground/src/pipeline/execute/fu/Mul.scala b/chisel/playground/src/pipeline/execute/fu/Mul.scala index 6ae744e..fa525fd 100644 --- a/chisel/playground/src/pipeline/execute/fu/Mul.scala +++ b/chisel/playground/src/pipeline/execute/fu/Mul.scala @@ -6,63 +6,15 @@ import cpu.defines._ import cpu.defines.Const._ import cpu.CpuConfig -class SignedMul extends BlackBox with HasBlackBoxResource { - val io = IO(new Bundle { - val CLK = Input(Clock()) - val CE = Input(Bool()) - val A = Input(UInt((XLEN + 1).W)) - val B = Input(UInt((XLEN + 1).W)) - - val P = Output(UInt(((2 * XLEN) + 2).W)) - }) -} - class Mul(implicit val cpuConfig: CpuConfig) extends Module { val io = IO(new Bundle { - val src1 = Input(UInt((XLEN + 1).W)) - val src2 = Input(UInt((XLEN + 1).W)) - val en = Input(Bool()) - val allow_to_go = Input(Bool()) + val src1 = Input(UInt((XLEN + 1).W)) + val src2 = Input(UInt((XLEN + 1).W)) - val ready = Output(Bool()) val result = Output(UInt((2 * XLEN).W)) }) - if (cpuConfig.build) { - // TODO:未经测试 - val signedMul = Module(new SignedMul()).io - val cnt = RegInit(0.U(log2Ceil(cpuConfig.mulClockNum + 1).W)) - - cnt := MuxCase( - cnt, - Seq( - (io.en && !io.ready) -> (cnt + 1.U), - io.allow_to_go -> 0.U - ) - ) - - signedMul.CLK := clock - signedMul.CE := io.en - - signedMul.A := io.src1 - signedMul.B := io.src2 - io.ready := cnt >= cpuConfig.mulClockNum.U - io.result := signedMul.P((2 * XLEN) - 1, 0) - } else { - val cnt = RegInit(0.U(log2Ceil(cpuConfig.mulClockNum + 1).W)) - cnt := MuxCase( - cnt, - Seq( - (io.en && !io.ready) -> (cnt + 1.U), - io.allow_to_go -> 0.U - ) - ) - - val signed = RegInit(0.U((2 * XLEN).W)) - when(io.en) { - signed := (io.src1.asSInt * io.src2.asSInt).asUInt - } - io.result := signed - io.ready := cnt >= cpuConfig.mulClockNum.U - } + val signed = WireInit(0.U((2 * XLEN).W)) + signed := (io.src1.asSInt * io.src2.asSInt).asUInt + io.result := signed }