experimental iterative mul/div combo
This commit is contained in:
parent
5228a53293
commit
674ab2c594
|
@ -76,6 +76,19 @@ object Riscv{
|
||||||
def MULX = M"0000001----------0-------0110011"
|
def MULX = M"0000001----------0-------0110011"
|
||||||
def DIVX = M"0000001----------1-------0110011"
|
def DIVX = M"0000001----------1-------0110011"
|
||||||
|
|
||||||
|
def MUL = M"0000001----------000-----0110011"
|
||||||
|
def MULH = M"0000001----------001-----0110011"
|
||||||
|
def MULHSU = M"0000001----------010-----0110011"
|
||||||
|
def MULHU = M"0000001----------011-----0110011"
|
||||||
|
|
||||||
|
|
||||||
|
def DIV = M"0000001----------100-----0110011"
|
||||||
|
def DIVU = M"0000001----------101-----0110011"
|
||||||
|
def REM = M"0000001----------110-----0110011"
|
||||||
|
def REMU = M"0000001----------111-----0110011"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def CSRRW = M"-----------------001-----1110011"
|
def CSRRW = M"-----------------001-----1110011"
|
||||||
def CSRRS = M"-----------------010-----1110011"
|
def CSRRS = M"-----------------010-----1110011"
|
||||||
def CSRRC = M"-----------------011-----1110011"
|
def CSRRC = M"-----------------011-----1110011"
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
package vexriscv.plugin
|
||||||
|
|
||||||
|
import spinal.core._
|
||||||
|
import spinal.lib._
|
||||||
|
import vexriscv.{VexRiscv, _}
|
||||||
|
|
||||||
|
class MulDivIterativePlugin(mulUnroolFactor : Int = 1) extends Plugin[VexRiscv]{
|
||||||
|
object IS_MUL extends Stageable(Bool)
|
||||||
|
object IS_RS1_SIGNED extends Stageable(Bool)
|
||||||
|
object IS_RS2_SIGNED extends Stageable(Bool)
|
||||||
|
|
||||||
|
override def setup(pipeline: VexRiscv): Unit = {
|
||||||
|
import Riscv._
|
||||||
|
import pipeline.config._
|
||||||
|
|
||||||
|
|
||||||
|
val commonActions = List[(Stageable[_ <: BaseType],Any)](
|
||||||
|
SRC1_CTRL -> Src1CtrlEnum.RS,
|
||||||
|
SRC2_CTRL -> Src2CtrlEnum.RS,
|
||||||
|
REGFILE_WRITE_VALID -> True,
|
||||||
|
BYPASSABLE_EXECUTE_STAGE -> False,
|
||||||
|
BYPASSABLE_MEMORY_STAGE -> True,
|
||||||
|
RS1_USE -> True,
|
||||||
|
RS2_USE -> True
|
||||||
|
)
|
||||||
|
|
||||||
|
val mulActions = commonActions ++ List(IS_MUL -> True)
|
||||||
|
|
||||||
|
val decoderService = pipeline.service(classOf[DecoderService])
|
||||||
|
decoderService.addDefault(IS_MUL, False)
|
||||||
|
decoderService.add(List(
|
||||||
|
MUL -> (mulActions ++ List(IS_RS1_SIGNED -> False, IS_RS2_SIGNED -> False)),
|
||||||
|
MULH -> (mulActions ++ List(IS_RS1_SIGNED -> True, IS_RS2_SIGNED -> True)),
|
||||||
|
MULHSU -> (mulActions ++ List(IS_RS1_SIGNED -> True, IS_RS2_SIGNED -> False)),
|
||||||
|
MULHU -> (mulActions ++ List(IS_RS1_SIGNED -> False, IS_RS2_SIGNED -> False))
|
||||||
|
))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override def build(pipeline: VexRiscv): Unit = {
|
||||||
|
import pipeline._
|
||||||
|
import pipeline.config._
|
||||||
|
|
||||||
|
|
||||||
|
memory plug new Area {
|
||||||
|
import memory._
|
||||||
|
val rs1 = Reg(UInt(64 bits))
|
||||||
|
val rs2 = Reg(UInt(32 bits))
|
||||||
|
val accumulator = Reg(UInt(64 bits))
|
||||||
|
val mul = new Area{
|
||||||
|
val done = rs2 === 0
|
||||||
|
when(input(IS_MUL)){
|
||||||
|
arbitration.haltItself setWhen(!done)
|
||||||
|
rs1 := rs1 |<< mulUnroolFactor
|
||||||
|
rs2 := rs2 |>> mulUnroolFactor
|
||||||
|
accumulator := ((0 until mulUnroolFactor).map(i => rs2(i) ? (rs1 |<< i) | U(0)) :+ accumulator).reduceBalancedTree(_ + _)
|
||||||
|
output(REGFILE_WRITE_DATA) := ((input(INSTRUCTION)(13 downto 12) === B"00") ? accumulator(31 downto 0) | accumulator(63 downto 32)).asBits
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
when(!arbitration.isStuck){
|
||||||
|
accumulator := 0
|
||||||
|
def twoComplement(that : Bits, enable: Bool): UInt = (Mux(enable, ~that, that).asUInt + enable.asUInt)
|
||||||
|
val rs2NeedRevert = execute.input(RS2).msb && execute.input(IS_RS2_SIGNED)
|
||||||
|
val rs1Extended = B((63 downto 32) -> (execute.input(IS_RS1_SIGNED) && execute.input(RS1).msb), (31 downto 0) -> execute.input(RS1))
|
||||||
|
rs1 := twoComplement(rs1Extended, rs2NeedRevert)
|
||||||
|
rs2 := twoComplement(execute.input(RS2), rs2NeedRevert)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue