
spinal.lib.cpu.riscv.impl.extension.MulExtension.scala Maven / Gradle / Ivy
package spinal.lib.cpu.riscv.impl.extension
import spinal.core._
import spinal.lib._
import spinal.lib.bus.avalon.AvalonMM
import spinal.lib.cpu.riscv.impl._
import spinal.lib.cpu.riscv.impl.Utils._
/**
* Created by PIC32F_USER on 12/03/2016.
*/
class MulExtension extends CoreExtension{
override def needTag: Boolean = true
override def getName: String = "MulExtension"
override def applyIt(core: RiscvCore): Area = new Area{
import core._
var sample : Bool = null
def RegPip [T<:Data] (that : T) = spinal.core.RegNextWhen(that,sample)
val s1 = new Area {
val aSigned,bSigned = Bool()
val a,b = Bits(32 bit)
a := execute0.inInst.alu_op0
b := execute0.inInst.alu_op1
switch(execute0.inInst.instruction(13 downto 12)) {
is(B"01") {
aSigned := True
bSigned := True
}
is(B"10") {
aSigned := True
bSigned := False
}
default {
aSigned := False
bSigned := False
}
}
val aULow = a(15 downto 0).asUInt
val bULow = b(15 downto 0).asUInt
val aSLow = (False ## a(15 downto 0)).asSInt
val bSLow = (False ## b(15 downto 0)).asSInt
val aHigh = (((aSigned && a.msb) ## a(31 downto 16))).asSInt
val bHigh = (((bSigned && b.msb) ## b(31 downto 16))).asSInt
val mul_ll = aULow * bULow
val mul_lh = aSLow * bHigh
val mul_hl = aHigh * bSLow
val mul_hh = aHigh * bHigh
}
val s2 = new Area {
sample = execute0.outInst.ready
val mul_ll = RegPip(s1.mul_ll)
val mul_lh = RegPip(s1.mul_lh)
val mul_hl = RegPip(s1.mul_hl)
val mul_hh = RegPip(s1.mul_hh)
val low = S(0, mul_hl.getWidth + 2 bit) + (False ## mul_ll).asSInt + (mul_lh << 16) + (mul_hl << 16)
}
val s3 = new Area {
sample = execute1.outInst.ready
val low = RegPip(s2.low)
val mul_hh = RegPip(s2.mul_hh)
val result = low + (mul_hh << 32)
}
//pipeline insertion logic
when(isMyTag(writeBack.inInst.ctrl)){
switch(writeBack.inInst.instruction(13 downto 12)){
is(B"00"){
writeBack.inInst.result := s3.low(31 downto 0).asBits
}
is(B"01",B"10",B"11"){
writeBack.inInst.result := s3.result(63 downto 32).asBits
}
}
}
sample = null
}
def MULX = M"0000001----------0-------0110011"
override def instructionCtrlExtension(instruction: Bits, ctrl: InstructionCtrl): Unit = {
when(instruction === MULX){
applyTag(ctrl)
ctrl.instVal := True
ctrl.op0 := OP0.RS
ctrl.op1 := OP1.RS
ctrl.wb := WB.ALU
ctrl.rfen := True
ctrl.execute0AluBypass := False
ctrl.execute1AluBypass := False //instruction(14 downto 12) === B"000"
ctrl.useSrc0 := True
ctrl.useSrc1 := True
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy