修改mdu

This commit is contained in:
Liphen 2024-03-22 14:26:21 +08:00
parent 1ab2644cba
commit e6decd7c82
3 changed files with 33 additions and 210 deletions

View File

@ -6,133 +6,15 @@ 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 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
signedDiv.aclk := clock
unsignedDiv.aclk := clock
// 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)
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
}
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
}
when(signedDiv.m_axis_dout_tvalid && !io.allow_to_go) {
signedDiv_done := true.B
}.elsewhen(io.allow_to_go) {
signedDiv_done := false.B
}
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
@ -147,19 +29,15 @@ class Div(implicit cpuConfig: CpuConfig) extends Module {
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))
val quotient = WireInit(0.S(XLEN.W))
val remainder = WireInit(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)
}
}

View File

@ -10,9 +10,7 @@ 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 ready = Output(Bool())
val result = Output(UInt(XLEN.W))
})
@ -38,21 +36,16 @@ class Mdu(implicit cpuConfig: CpuConfig) extends Module {
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
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
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)
}

View File

@ -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 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) {
val signed = WireInit(0.U((2 * XLEN).W))
signed := (io.src1.asSInt * io.src2.asSInt).asUInt
}
io.result := signed
io.ready := cnt >= cpuConfig.mulClockNum.U
}
}