Splits multiplication in two cycles for 40MHz
This commit is contained in:
@@ -80,7 +80,21 @@ class Alu extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Multiplication
|
// 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 =
|
val multiplication_low =
|
||||||
Mux(io.word_mode, multiplication_res(31, 0), multiplication_res(63, 0))
|
Mux(io.word_mode, multiplication_res(31, 0), multiplication_res(63, 0))
|
||||||
val multiplication_high =
|
val multiplication_high =
|
||||||
@@ -123,54 +137,54 @@ class Alu extends Module {
|
|||||||
out := multiplication_high;
|
out := multiplication_high;
|
||||||
}
|
}
|
||||||
|
|
||||||
is(Div) {
|
is(Div) {
|
||||||
when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
div_by_zero()
|
div_by_zero()
|
||||||
}.elsewhen(op_a_sign ^ op_b_sign) {
|
}.elsewhen(op_a_sign ^ op_b_sign) {
|
||||||
out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
out := Utils.two_complement(divider.io.quotient, io.word_mode)
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
out := divider.io.quotient
|
out := divider.io.quotient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is(Divu) {
|
is(Divu) {
|
||||||
divider.io.dividend := op_a
|
divider.io.dividend := op_a
|
||||||
divider.io.divisor := op_b
|
divider.io.divisor := op_b
|
||||||
when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
div_by_zero()
|
div_by_zero()
|
||||||
}.otherwise { out := divider.io.quotient; }
|
}.otherwise { out := divider.io.quotient; }
|
||||||
}
|
}
|
||||||
|
|
||||||
is(Rem) {
|
is(Rem) {
|
||||||
when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
out := op_a
|
out := op_a
|
||||||
}.elsewhen(
|
}.elsewhen(
|
||||||
op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
op_a_sign && !op_b_sign && divider.io.remainder =/= 0.U
|
||||||
) {
|
) {
|
||||||
out := op_b - divider.io.remainder
|
out := op_b - divider.io.remainder
|
||||||
}.elsewhen(
|
}.elsewhen(
|
||||||
!op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
!op_a_sign && op_b_sign && divider.io.remainder =/= 0.U
|
||||||
) {
|
) {
|
||||||
out := Utils.two_complement(
|
out := Utils.two_complement(
|
||||||
Utils.two_complement(op_b) - divider.io.remainder,
|
Utils.two_complement(op_b) - divider.io.remainder,
|
||||||
io.word_mode
|
io.word_mode
|
||||||
)
|
)
|
||||||
}.elsewhen(op_a_sign && op_b_sign) {
|
}.elsewhen(op_a_sign && op_b_sign) {
|
||||||
out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
out := Utils.two_complement(divider.io.remainder, io.word_mode)
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
out := divider.io.remainder
|
out := divider.io.remainder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is(Remu) {
|
is(Remu) {
|
||||||
divider.io.dividend := op_a
|
divider.io.dividend := op_a
|
||||||
divider.io.divisor := op_b
|
divider.io.divisor := op_b
|
||||||
when(op_b === 0.U) {
|
when(op_b === 0.U) {
|
||||||
out := op_a
|
out := op_a
|
||||||
}.otherwise {
|
}.otherwise {
|
||||||
out := divider.io.remainder
|
out := divider.io.remainder
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is(And) {
|
is(And) {
|
||||||
out := op_a & op_b;
|
out := op_a & op_b;
|
||||||
@@ -231,18 +245,17 @@ class Alu extends Module {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(io.opcode) {
|
switch(io.opcode) {
|
||||||
is(Div, Divu, Rem, Remu) {
|
is(Div, Divu, Rem, Remu) {
|
||||||
when(!in_computation) {
|
when(!in_computation) {
|
||||||
divider.io.start := true.B
|
divider.io.start := true.B
|
||||||
in_computation := true.B
|
in_computation := true.B
|
||||||
}.elsewhen(divider.io.ready) {
|
}.elsewhen(divider.io.ready) {
|
||||||
io.should_stop_stall := true.B
|
io.should_stop_stall := true.B
|
||||||
in_computation := false.B
|
in_computation := false.B
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Special overflow cases for Div and Rem
|
// Special overflow cases for Div and Rem
|
||||||
when(
|
when(
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ object OpM {
|
|||||||
}
|
}
|
||||||
|
|
||||||
io.reg_file_we := true.B // Write to regfile
|
io.reg_file_we := true.B // Write to regfile
|
||||||
|
io.should_stall := true.B
|
||||||
switch(funct3) {
|
switch(funct3) {
|
||||||
is(Funct3.MUL) {
|
is(Funct3.MUL) {
|
||||||
io.alu_opcode := AluOpCode.Mul
|
io.alu_opcode := AluOpCode.Mul
|
||||||
@@ -38,19 +39,15 @@ object OpM {
|
|||||||
}
|
}
|
||||||
is(Funct3.DIV) {
|
is(Funct3.DIV) {
|
||||||
io.alu_opcode := AluOpCode.Div
|
io.alu_opcode := AluOpCode.Div
|
||||||
io.should_stall := true.B
|
|
||||||
}
|
}
|
||||||
is(Funct3.DIVU) {
|
is(Funct3.DIVU) {
|
||||||
io.alu_opcode := AluOpCode.Divu
|
io.alu_opcode := AluOpCode.Divu
|
||||||
io.should_stall := true.B
|
|
||||||
}
|
}
|
||||||
is(Funct3.REM) {
|
is(Funct3.REM) {
|
||||||
io.alu_opcode := AluOpCode.Rem
|
io.alu_opcode := AluOpCode.Rem
|
||||||
io.should_stall := true.B
|
|
||||||
}
|
}
|
||||||
is(Funct3.REMU) {
|
is(Funct3.REMU) {
|
||||||
io.alu_opcode := AluOpCode.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