修改mdu
This commit is contained in:
parent
1ab2644cba
commit
e6decd7c82
|
@ -6,160 +6,38 @@ import cpu.defines._
|
||||||
import cpu.defines.Const._
|
import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
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 {
|
class Div(implicit cpuConfig: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val src1 = Input(UInt(XLEN.W))
|
val src1 = Input(UInt(XLEN.W))
|
||||||
val src2 = Input(UInt(XLEN.W))
|
val src2 = Input(UInt(XLEN.W))
|
||||||
val signed = Input(Bool())
|
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))
|
val result = Output(UInt((2 * XLEN).W))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (cpuConfig.build) {
|
val div_signed = io.signed
|
||||||
// TODO:未经测试
|
|
||||||
val signedDiv = Module(new SignedDiv()).io
|
|
||||||
val unsignedDiv = Module(new UnsignedDiv()).io
|
|
||||||
|
|
||||||
signedDiv.aclk := clock
|
val dividend_signed = io.src1(XLEN - 1) & div_signed
|
||||||
unsignedDiv.aclk := clock
|
val divisor_signed = io.src2(XLEN - 1) & div_signed
|
||||||
|
|
||||||
// 0为被除数,1为除数
|
val dividend_abs = Mux(dividend_signed, (-io.src1).asUInt, io.src1.asUInt)
|
||||||
val unsignedDiv_sent = Seq.fill(2)(RegInit(false.B))
|
val divisor_abs = Mux(divisor_signed, (-io.src2).asUInt, io.src2.asUInt)
|
||||||
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) {
|
val quotient_signed = (io.src1(XLEN - 1) ^ io.src2(XLEN - 1)) & div_signed
|
||||||
unsignedDiv_sent(0) := true.B
|
val remainder_signed = io.src1(XLEN - 1) & div_signed
|
||||||
}.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) {
|
val quotient_abs = dividend_abs / divisor_abs
|
||||||
signedDiv_sent(0) := true.B
|
val remainder_abs = dividend_abs - quotient_abs * divisor_abs
|
||||||
}.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) {
|
val quotient = WireInit(0.S(XLEN.W))
|
||||||
signedDiv_done := true.B
|
val remainder = WireInit(0.S(XLEN.W))
|
||||||
}.elsewhen(io.allow_to_go) {
|
|
||||||
signedDiv_done := false.B
|
|
||||||
}
|
|
||||||
|
|
||||||
when(unsignedDiv.m_axis_dout_tvalid && !io.allow_to_go) {
|
quotient := Mux(quotient_signed, (-quotient_abs).asSInt, quotient_abs.asSInt)
|
||||||
unsignedDiv_done := true.B
|
remainder := Mux(remainder_signed, (-remainder_abs).asSInt, remainder_abs.asSInt)
|
||||||
}.elsewhen(io.allow_to_go) {
|
when(io.src2 === 0.U) {
|
||||||
unsignedDiv_done := false.B
|
quotient := (~0.U).asSInt
|
||||||
}
|
remainder := io.src1.asSInt
|
||||||
// 被除数和除数的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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
io.result := Cat(remainder, quotient)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,9 @@ import cpu.CpuConfig
|
||||||
|
|
||||||
class Mdu(implicit cpuConfig: CpuConfig) extends Module {
|
class Mdu(implicit cpuConfig: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val info = Input(new Info())
|
val info = Input(new Info())
|
||||||
val src_info = Input(new SrcInfo())
|
val src_info = Input(new SrcInfo())
|
||||||
val allow_to_go = Input(Bool())
|
|
||||||
|
|
||||||
val ready = Output(Bool())
|
|
||||||
val result = Output(UInt(XLEN.W))
|
val result = Output(UInt(XLEN.W))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -36,23 +34,18 @@ class Mdu(implicit cpuConfig: CpuConfig) extends Module {
|
||||||
MDUOpType.mulhu -> (zeroExtend, zeroExtend)
|
MDUOpType.mulhu -> (zeroExtend, zeroExtend)
|
||||||
)
|
)
|
||||||
|
|
||||||
mul.src1 := LookupTree(op(1, 0), srcMulConvertTable.map(p => (p._1, p._2._1(src1))))
|
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.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) =>
|
val srcDivConvertFunc = (x: UInt) =>
|
||||||
Mux(is_w, Mux(MDUOpType.isDivSign(op), SignedExtend(x(31, 0), XLEN), ZeroExtend(x(31, 0), XLEN)), x)
|
Mux(is_w, Mux(MDUOpType.isDivSign(op), SignedExtend(x(31, 0), XLEN), ZeroExtend(x(31, 0), XLEN)), x)
|
||||||
div.src1 := srcDivConvertFunc(src1)
|
div.src1 := srcDivConvertFunc(src1)
|
||||||
div.src2 := srcDivConvertFunc(src2)
|
div.src2 := srcDivConvertFunc(src2)
|
||||||
div.signed := MDUOpType.isDivSign(op)
|
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 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 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)
|
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)
|
io.result := Mux(is_w, SignedExtend(result(31, 0), XLEN), result)
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,63 +6,15 @@ import cpu.defines._
|
||||||
import cpu.defines.Const._
|
import cpu.defines.Const._
|
||||||
import cpu.CpuConfig
|
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 {
|
class Mul(implicit val cpuConfig: CpuConfig) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
val src1 = Input(UInt((XLEN + 1).W))
|
val src1 = Input(UInt((XLEN + 1).W))
|
||||||
val src2 = 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))
|
val result = Output(UInt((2 * XLEN).W))
|
||||||
})
|
})
|
||||||
|
|
||||||
if (cpuConfig.build) {
|
val signed = WireInit(0.U((2 * XLEN).W))
|
||||||
// TODO:未经测试
|
signed := (io.src1.asSInt * io.src2.asSInt).asUInt
|
||||||
val signedMul = Module(new SignedMul()).io
|
io.result := signed
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue