experimental iterative mul/div combo

This commit is contained in:
Dolu1990 2018-03-09 19:07:26 +01:00
parent 5228a53293
commit 674ab2c594
2 changed files with 84 additions and 0 deletions

View File

@ -76,6 +76,19 @@ object Riscv{
def MULX = M"0000001----------0-------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 CSRRS = M"-----------------010-----1110011"
def CSRRC = M"-----------------011-----1110011"

View File

@ -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)
}
}
}
}