MulPlugin.outputBuffer feature added

This commit is contained in:
Dolu1990 2021-02-16 14:16:57 +01:00
parent 3b99090879
commit fe690528f7
2 changed files with 56 additions and 23 deletions

View File

@ -5,7 +5,8 @@ import spinal.core._
import spinal.lib.KeepAttribute
//Input buffer generaly avoid the FPGA synthesis to duplicate reg inside the DSP cell, which could stress timings quite much.
class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{
class MulPlugin(var inputBuffer : Boolean = false,
var outputBuffer : Boolean = false) extends Plugin[VexRiscv]{
object MUL_LL extends Stageable(UInt(32 bits))
object MUL_LH extends Stageable(SInt(34 bits))
object MUL_HL extends Stageable(SInt(34 bits))
@ -53,16 +54,26 @@ class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{
// a := input(SRC1)
// b := input(SRC2)
val delay = (if(inputBuffer) 1 else 0) + (if(outputBuffer) 1 else 0)
val delayLogic = (delay != 0) generate new Area{
val counter = Reg(UInt(log2Up(delay+1) bits))
when(arbitration.isValid && input(IS_MUL) && counter =/= delay){
arbitration.haltItself := True
}
when(!arbitration.isStuckByOthers){
counter := counter + 1
}
when(!arbitration.isStuck){
counter := 0
}
}
val withInputBuffer = inputBuffer generate new Area{
val rs1 = RegNext(input(RS1))
val rs2 = RegNext(input(RS2))
a := rs1
b := rs2
val delay = RegNext(arbitration.isStuck)
when(arbitration.isValid && input(IS_MUL) && !delay){
arbitration.haltItself := True
}
}
val noInputBuffer = (!inputBuffer) generate new Area{
@ -91,10 +102,25 @@ class MulPlugin(inputBuffer : Boolean = false) extends Plugin[VexRiscv]{
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 withOuputBuffer = outputBuffer generate new Area{
val mul_ll = RegNext(aULow * bULow)
val mul_lh = RegNext(aSLow * bHigh)
val mul_hl = RegNext(aHigh * bSLow)
val mul_hh = RegNext(aHigh * bHigh)
insert(MUL_LL) := mul_ll
insert(MUL_LH) := mul_lh
insert(MUL_HL) := mul_hl
insert(MUL_HH) := mul_hh
}
val noOutputBuffer = (!outputBuffer) generate new Area{
insert(MUL_LL) := aULow * bULow
insert(MUL_LH) := aSLow * bHigh
insert(MUL_HL) := aHigh * bSLow
insert(MUL_HH) := aHigh * bHigh
}
Component.current.afterElaboration{
//Avoid synthesis tools to retime RS1 RS2 from execute stage to decode stage leading to bad timings (ex : Vivado, even if retiming is disabled)

View File

@ -173,11 +173,17 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") {
} :: l
if(!noMemory && !noWriteBack) l =
new VexRiscvPosition("MulDivFpga") {
if(!noMemory && !noWriteBack) {
val inputBuffer = r.nextBoolean()
val outputBuffer = r.nextBoolean()
l = new VexRiscvPosition(s"MulDivFpga$inputBuffer$outputBuffer") {
override def testParam = "MUL=yes DIV=yes"
override def applyOn(config: VexRiscvConfig): Unit = {
config.plugins += new MulPlugin
config.plugins += new MulPlugin(
inputBuffer = inputBuffer,
outputBuffer = outputBuffer
)
config.plugins += new MulDivIterativePlugin(
genMul = false,
genDiv = true,
@ -186,6 +192,7 @@ class MulDivDimension extends VexRiscvDimension("MulDiv") {
)
}
} :: l
}
random(r, l)
}