修改mdu
This commit is contained in:
parent
1ab2644cba
commit
e6decd7c82
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue