Splits multiplication in two cycles for 40MHz
This commit is contained in:
@@ -80,7 +80,21 @@ class Alu extends Module {
|
||||
}
|
||||
|
||||
// Multiplication
|
||||
val multiplication_res = op_a * op_b // Mul non signée
|
||||
|
||||
// Pipeline multiplication to trim critical path
|
||||
val multiplication_res = RegNext(op_a * op_b) // Mul non signée
|
||||
|
||||
switch(io.opcode) {
|
||||
is(Mul, Mulhsu, Mulh, Mulhu) {
|
||||
when(!in_computation) {
|
||||
in_computation := true.B
|
||||
}.elsewhen(in_computation) {
|
||||
in_computation := false.B
|
||||
io.should_stop_stall := true.B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val multiplication_low =
|
||||
Mux(io.word_mode, multiplication_res(31, 0), multiplication_res(63, 0))
|
||||
val multiplication_high =
|
||||
@@ -123,54 +137,54 @@ class Alu extends Module {
|
||||
out := multiplication_high;
|
||||
}
|
||||
|
||||
is(Div) {
|
||||
when(op_b === 0.U) {
|
||||
div_by_zero()
|
||||
}.elsewhen(op_a_sign ^ op_b_sign) {
|
||||
out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
||||
}.otherwise {
|
||||
out := divider.io.quotient
|
||||
}
|
||||
}
|
||||
|
||||
is(Divu) {
|
||||
divider.io.dividend := op_a
|
||||
divider.io.divisor := op_b
|
||||
when(op_b === 0.U) {
|
||||
div_by_zero()
|
||||
}.otherwise { out := divider.io.quotient; }
|
||||
}
|
||||
|
||||
is(Rem) {
|
||||
when(op_b === 0.U) {
|
||||
out := op_a
|
||||
}.elsewhen(
|
||||
op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
||||
) {
|
||||
out := op_b - divider.io.remainder
|
||||
}.elsewhen(
|
||||
!op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
||||
) {
|
||||
out := Utils.two_complement(
|
||||
Utils.two_complement(op_b) - divider.io.remainder,
|
||||
io.word_mode
|
||||
)
|
||||
}.elsewhen(op_a_sign && op_b_sign) {
|
||||
out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
||||
}.otherwise {
|
||||
out := divider.io.remainder
|
||||
}
|
||||
}
|
||||
|
||||
is(Remu) {
|
||||
divider.io.dividend := op_a
|
||||
divider.io.divisor := op_b
|
||||
when(op_b === 0.U) {
|
||||
out := op_a
|
||||
}.otherwise {
|
||||
out := divider.io.remainder
|
||||
}
|
||||
}
|
||||
is(Div) {
|
||||
when(op_b === 0.U) {
|
||||
div_by_zero()
|
||||
}.elsewhen(op_a_sign ^ op_b_sign) {
|
||||
out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
||||
}.otherwise {
|
||||
out := divider.io.quotient
|
||||
}
|
||||
}
|
||||
|
||||
is(Divu) {
|
||||
divider.io.dividend := op_a
|
||||
divider.io.divisor := op_b
|
||||
when(op_b === 0.U) {
|
||||
div_by_zero()
|
||||
}.otherwise { out := divider.io.quotient; }
|
||||
}
|
||||
|
||||
is(Rem) {
|
||||
when(op_b === 0.U) {
|
||||
out := op_a
|
||||
}.elsewhen(
|
||||
op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
||||
) {
|
||||
out := op_b - divider.io.remainder
|
||||
}.elsewhen(
|
||||
!op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
||||
) {
|
||||
out := Utils.two_complement(
|
||||
Utils.two_complement(op_b) - divider.io.remainder,
|
||||
io.word_mode
|
||||
)
|
||||
}.elsewhen(op_a_sign && op_b_sign) {
|
||||
out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
||||
}.otherwise {
|
||||
out := divider.io.remainder
|
||||
}
|
||||
}
|
||||
|
||||
is(Remu) {
|
||||
divider.io.dividend := op_a
|
||||
divider.io.divisor := op_b
|
||||
when(op_b === 0.U) {
|
||||
out := op_a
|
||||
}.otherwise {
|
||||
out := divider.io.remainder
|
||||
}
|
||||
}
|
||||
|
||||
is(And) {
|
||||
out := op_a & op_b;
|
||||
@@ -231,18 +245,17 @@ class Alu extends Module {
|
||||
}
|
||||
}
|
||||
|
||||
switch(io.opcode) {
|
||||
is(Div, Divu, Rem, Remu) {
|
||||
when(!in_computation) {
|
||||
divider.io.start := true.B
|
||||
in_computation := true.B
|
||||
}.elsewhen(divider.io.ready) {
|
||||
io.should_stop_stall := true.B
|
||||
in_computation := false.B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch(io.opcode) {
|
||||
is(Div, Divu, Rem, Remu) {
|
||||
when(!in_computation) {
|
||||
divider.io.start := true.B
|
||||
in_computation := true.B
|
||||
}.elsewhen(divider.io.ready) {
|
||||
io.should_stop_stall := true.B
|
||||
in_computation := false.B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Special overflow cases for Div and Rem
|
||||
when(
|
||||
|
||||
@@ -23,6 +23,7 @@ object OpM {
|
||||
}
|
||||
|
||||
io.reg_file_we := true.B // Write to regfile
|
||||
io.should_stall := true.B
|
||||
switch(funct3) {
|
||||
is(Funct3.MUL) {
|
||||
io.alu_opcode := AluOpCode.Mul
|
||||
@@ -38,19 +39,15 @@ object OpM {
|
||||
}
|
||||
is(Funct3.DIV) {
|
||||
io.alu_opcode := AluOpCode.Div
|
||||
io.should_stall := true.B
|
||||
}
|
||||
is(Funct3.DIVU) {
|
||||
io.alu_opcode := AluOpCode.Divu
|
||||
io.should_stall := true.B
|
||||
}
|
||||
is(Funct3.REM) {
|
||||
io.alu_opcode := AluOpCode.Rem
|
||||
io.should_stall := true.B
|
||||
}
|
||||
is(Funct3.REMU) {
|
||||
io.alu_opcode := AluOpCode.Remu
|
||||
io.should_stall := true.B
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
+====================+====================+==============================+
|
||||
| Launch Setup Clock | Launch Hold Clock | Pin |
|
||||
+====================+====================+==============================+
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[58]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[52]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[32]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[61]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[54]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[17]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[42]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[11]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[12]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[56]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[8]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[36]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[19]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[60]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[48]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[51]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[24]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[41]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[53]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[50]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[57]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[37]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[1]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[62]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[29]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[46]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[38]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[10]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[14]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[63]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[28]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[9]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | clnt/clintRegValue_reg[49]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[58]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[61]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[60]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[57]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[56]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[52]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[53]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[49]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[48]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[45]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[44]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[41]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[40]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[37]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[36]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[33]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[32]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[29]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[28]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[25]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[24]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[21]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[20]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[17]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[16]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[13]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[12]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[9]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[8]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[5]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[4]/D |
|
||||
| clk_out1_clk_wiz_0 | clk_out1_clk_wiz_0 | core/reg_pc_reg[1]/D |
|
||||
+--------------------+--------------------+------------------------------+
|
||||
Reference in New Issue
Block a user