Add GenMicro experiment to reduce ice40 area usage.
IBusSimplePlugin now require cmdFork parameters to be set (no default)
This commit is contained in:
parent
48bff80653
commit
0662cc2797
|
@ -33,14 +33,14 @@ object TestsWorkspace {
|
|||
plugins = List(
|
||||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = true,
|
||||
cmdForkPersistence = true,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = NONE,
|
||||
historyRamSizeLog2 = 10,
|
||||
catchAccessFault = true,
|
||||
compressedGen = false,
|
||||
busLatencyMin = 1,
|
||||
injectorStage = true
|
||||
injectorStage = false
|
||||
),
|
||||
// new IBusCachedPlugin(
|
||||
// resetVector = 0x80000000l,
|
||||
|
|
|
@ -16,6 +16,7 @@ object FormalSimple extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x00000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = DYNAMIC_TARGET,
|
||||
catchAccessFault = false,
|
||||
compressedGen = true
|
||||
|
|
|
@ -19,6 +19,7 @@ object GenCustomCsr extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x00000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = NONE,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -15,6 +15,7 @@ object GenCustomSimdAdd extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x00000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = NONE,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -14,6 +14,7 @@ object GenDeterministicVex extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = STATIC,
|
||||
catchAccessFault = true,
|
||||
compressedGen = false
|
||||
|
|
|
@ -15,6 +15,7 @@ object GenFullNoMmuNoCache extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = STATIC,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -15,6 +15,7 @@ object GenNoCacheNoMmuMaxPerf extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = DYNAMIC_TARGET,
|
||||
historyRamSizeLog2 = 8,
|
||||
catchAccessFault = true,
|
||||
|
|
|
@ -14,6 +14,7 @@ object GenSmallAndProductive extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = NONE,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -14,6 +14,7 @@ object GenSmallest extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = NONE,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -19,6 +19,7 @@ object GenSmallestNoCsr extends App{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = NONE,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -498,6 +498,7 @@ object MuraxDhrystoneReadyMulDivStatic{
|
|||
config.cpuPlugins += new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = true,
|
||||
cmdForkPersistence = false,
|
||||
prediction = STATIC,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -29,6 +29,7 @@ object VexRiscvAvalonForSim{
|
|||
new IBusSimplePlugin(
|
||||
resetVector = 0x00000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = STATIC,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false
|
||||
|
|
|
@ -182,7 +182,10 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
|
|||
}
|
||||
|
||||
|
||||
class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, catchAccessFault : Boolean = false, earlyInjection : Boolean = false/*, idempotentRegions : (UInt) => Bool = (x) => False*/) extends Plugin[VexRiscv]{
|
||||
class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
|
||||
catchAccessFault : Boolean = false,
|
||||
earlyInjection : Boolean = false,/*, idempotentRegions : (UInt) => Bool = (x) => False*/
|
||||
onlyLoadWords : Boolean = false) extends Plugin[VexRiscv]{
|
||||
|
||||
var dBus : DBusSimpleBus = null
|
||||
|
||||
|
@ -220,7 +223,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, catchAccessFaul
|
|||
|
||||
decoderService.addDefault(MEMORY_ENABLE, False)
|
||||
decoderService.add(
|
||||
List(LB, LH, LW, LBU, LHU, LWU).map(_ -> loadActions) ++
|
||||
(if(onlyLoadWords) List(LW) else List(LB, LH, LW, LBU, LHU, LWU)).map(_ -> loadActions) ++
|
||||
List(SB, SH, SW).map(_ -> storeActions)
|
||||
)
|
||||
|
||||
|
@ -329,7 +332,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false, catchAccessFaul
|
|||
)
|
||||
|
||||
when(arbitration.isValid && input(MEMORY_ENABLE)) {
|
||||
output(REGFILE_WRITE_DATA) := rspFormated
|
||||
output(REGFILE_WRITE_DATA) := (if(!onlyLoadWords) rspFormated else input(MEMORY_READ_DATA))
|
||||
}
|
||||
|
||||
if(!earlyInjection)
|
||||
|
|
|
@ -28,7 +28,7 @@ abstract class IBusFetcherImpl(val catchAccessFault : Boolean,
|
|||
var dynamicTargetFailureCorrection : Flow[UInt] = null
|
||||
var externalResetVector : UInt = null
|
||||
assert(cmdToRspStageCount >= 1)
|
||||
assert(!(cmdToRspStageCount == 1 && !injectorStage))
|
||||
// assert(!(cmdToRspStageCount == 1 && !injectorStage))
|
||||
assert(!(compressedGen && !decodePcGen))
|
||||
var fetcherHalt : Bool = null
|
||||
var fetcherflushIt : Bool = null
|
||||
|
|
|
@ -7,6 +7,13 @@ import spinal.lib._
|
|||
|
||||
class HazardPessimisticPlugin() extends Plugin[VexRiscv] {
|
||||
import Riscv._
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
val decoderService = pipeline.service(classOf[DecoderService])
|
||||
decoderService.addDefault(HAS_SIDE_EFFECT, False)
|
||||
}
|
||||
|
||||
override def build(pipeline: VexRiscv): Unit = {
|
||||
import pipeline._
|
||||
import pipeline.config._
|
||||
|
|
|
@ -143,16 +143,17 @@ case class IBusSimpleBus(interfaceKeepData : Boolean) extends Bundle with IMaste
|
|||
|
||||
|
||||
class IBusSimplePlugin(resetVector : BigInt,
|
||||
cmdForkOnSecondStage : Boolean,
|
||||
cmdForkPersistence : Boolean,
|
||||
catchAccessFault : Boolean = false,
|
||||
cmdForkOnSecondStage : Boolean = false,
|
||||
cmdForkPersistence : Boolean = false,
|
||||
prediction : BranchPrediction = NONE,
|
||||
historyRamSizeLog2 : Int = 10,
|
||||
keepPcPlus4 : Boolean = false,
|
||||
compressedGen : Boolean = false,
|
||||
busLatencyMin : Int = 1,
|
||||
pendingMax : Int = 7,
|
||||
injectorStage : Boolean = true
|
||||
injectorStage : Boolean = true,
|
||||
rspHoldValue : Boolean = false
|
||||
) extends IBusFetcherImpl(
|
||||
catchAccessFault = catchAccessFault,
|
||||
resetVector = resetVector,
|
||||
|
@ -168,6 +169,7 @@ class IBusSimplePlugin(resetVector : BigInt,
|
|||
|
||||
var iBus : IBusSimpleBus = null
|
||||
var decodeExceptionPort : Flow[ExceptionCause] = null
|
||||
if(rspHoldValue) assert(busLatencyMin == 1)
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
super.setup(pipeline)
|
||||
|
@ -221,22 +223,29 @@ class IBusSimplePlugin(resetVector : BigInt,
|
|||
discardCounter := (if(cmdForkOnSecondStage) pendingCmdNext else pendingCmd - iBus.rsp.fire.asUInt)
|
||||
}
|
||||
|
||||
val rspBuffer = StreamFifoLowLatency(IBusSimpleRsp(), busLatencyMin + (if(cmdForkOnSecondStage && cmdForkPersistence) 1 else 0))
|
||||
rspBuffer.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream
|
||||
rspBuffer.io.flush := flush
|
||||
val rspBufferOutput = Stream(IBusSimpleRsp())
|
||||
|
||||
val rspBuffer = if(!rspHoldValue) new Area{
|
||||
val c = StreamFifoLowLatency(IBusSimpleRsp(), busLatencyMin + (if(cmdForkOnSecondStage && cmdForkPersistence) 1 else 0))
|
||||
c.io.push << iBus.rsp.throwWhen(discardCounter =/= 0).toStream
|
||||
c.io.flush := flush
|
||||
rspBufferOutput << c.io.pop
|
||||
} else new Area{
|
||||
rspBufferOutput << iBus.rsp.throwWhen(discardCounter =/= 0).toStream
|
||||
}
|
||||
|
||||
val fetchRsp = FetchRsp()
|
||||
fetchRsp.pc := stages.last.output.payload
|
||||
fetchRsp.rsp := rspBuffer.io.pop.payload
|
||||
fetchRsp.rsp.error.clearWhen(!rspBuffer.io.pop.valid) //Avoid interference with instruction injection from the debug plugin
|
||||
fetchRsp.rsp := rspBufferOutput.payload
|
||||
fetchRsp.rsp.error.clearWhen(!rspBufferOutput.valid) //Avoid interference with instruction injection from the debug plugin
|
||||
|
||||
|
||||
var issueDetected = False
|
||||
val join = Stream(FetchRsp())
|
||||
join.valid := stages.last.output.valid && rspBuffer.io.pop.valid
|
||||
join.valid := stages.last.output.valid && rspBufferOutput.valid
|
||||
join.payload := fetchRsp
|
||||
stages.last.output.ready := stages.last.output.valid ? join.fire | join.ready
|
||||
rspBuffer.io.pop.ready := join.fire
|
||||
rspBufferOutput.ready := join.fire
|
||||
output << join.haltWhen(issueDetected)
|
||||
|
||||
if(catchAccessFault){
|
||||
|
|
|
@ -11,10 +11,14 @@ trait RegFileReadKind
|
|||
object ASYNC extends RegFileReadKind
|
||||
object SYNC extends RegFileReadKind
|
||||
|
||||
class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = false, writeRfInMemoryStage : Boolean = false) extends Plugin[VexRiscv]{
|
||||
class RegFilePlugin(regFileReadyKind : RegFileReadKind,
|
||||
zeroBoot : Boolean = false,
|
||||
writeRfInMemoryStage : Boolean = false,
|
||||
readInExecute : Boolean = false) extends Plugin[VexRiscv]{
|
||||
import Riscv._
|
||||
|
||||
assert(!writeRfInMemoryStage)
|
||||
// assert(!writeRfInMemoryStage)
|
||||
|
||||
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
import pipeline.config._
|
||||
|
@ -33,19 +37,21 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals
|
|||
if(zeroBoot) regFile.init(List.fill(32)(B(0, 32 bits)))
|
||||
}
|
||||
|
||||
//Read register file
|
||||
decode plug new Area{
|
||||
import decode._
|
||||
|
||||
//Disable rd0 write in decoding stage
|
||||
when(decode.input(INSTRUCTION)(rdRange) === 0) {
|
||||
decode.input(REGFILE_WRITE_VALID) := False
|
||||
}
|
||||
|
||||
//Read register file
|
||||
val readStage = if(readInExecute) execute else decode
|
||||
readStage plug new Area{
|
||||
import readStage._
|
||||
|
||||
//read register file
|
||||
val srcInstruction = regFileReadyKind match{
|
||||
case `ASYNC` => input(INSTRUCTION)
|
||||
case `SYNC` => input(INSTRUCTION_ANTICIPATED)
|
||||
case `SYNC` if !readInExecute => input(INSTRUCTION_ANTICIPATED)
|
||||
case `SYNC` if readInExecute => Mux(execute.arbitration.isStuck, execute.input(INSTRUCTION), decode.input(INSTRUCTION))
|
||||
}
|
||||
|
||||
val regFileReadAddress1 = srcInstruction(Riscv.rs1Range).asUInt
|
||||
|
@ -61,8 +67,9 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals
|
|||
}
|
||||
|
||||
//Write register file
|
||||
(if(writeRfInMemoryStage) memory else writeBack) plug new Area {
|
||||
import writeBack._
|
||||
val writeStage = if(writeRfInMemoryStage) memory else writeBack
|
||||
writeStage plug new Area {
|
||||
import writeStage._
|
||||
|
||||
val regFileWrite = global.regFile.writePort.addAttribute(Verilator.public)
|
||||
regFileWrite.valid := output(REGFILE_WRITE_VALID) && arbitration.isFiring
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package vexriscv.experimental
|
||||
|
||||
import spinal.core._
|
||||
import spinal.lib.eda.bench.{AlteraStdTargets, Bench, Rtl, XilinxStdTargets}
|
||||
import spinal.lib.eda.icestorm.IcestormStdTargets
|
||||
import vexriscv.demo.{GenSmallestNoCsr, Murax, MuraxConfig}
|
||||
import vexriscv.plugin._
|
||||
import vexriscv.{VexRiscv, VexRiscvConfig, plugin}
|
||||
|
||||
/**
|
||||
* Created by spinalvm on 15.06.17.
|
||||
*/
|
||||
object GenMicro extends App{
|
||||
def cpu() = {
|
||||
val removeOneFetchStage = true
|
||||
val writeBackOpt = true
|
||||
val onlyLoadWords = true
|
||||
val rspHoldValue = true
|
||||
val earlyBranch = false
|
||||
val noShifter = true
|
||||
val pessimisticHazard = true
|
||||
new VexRiscv(
|
||||
config = VexRiscvConfig(
|
||||
plugins = List(
|
||||
// new PcManagerSimplePlugin(
|
||||
// resetVector = 0x00000000l,
|
||||
// relaxedPcCalculation = false
|
||||
// ),
|
||||
|
||||
new IBusSimplePlugin(
|
||||
resetVector = 0x80000000l,
|
||||
cmdForkOnSecondStage = false,
|
||||
cmdForkPersistence = false,
|
||||
prediction = NONE,
|
||||
catchAccessFault = false,
|
||||
compressedGen = false,
|
||||
injectorStage = !removeOneFetchStage,
|
||||
rspHoldValue = rspHoldValue
|
||||
),
|
||||
new DBusSimplePlugin(
|
||||
catchAddressMisaligned = false,
|
||||
catchAccessFault = false,
|
||||
earlyInjection = writeBackOpt,
|
||||
onlyLoadWords = onlyLoadWords
|
||||
),
|
||||
new DecoderSimplePlugin(
|
||||
catchIllegalInstruction = false
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = plugin.SYNC,
|
||||
zeroBoot = false,
|
||||
readInExecute = removeOneFetchStage,
|
||||
writeRfInMemoryStage = writeBackOpt
|
||||
),
|
||||
new IntAluPlugin,
|
||||
new SrcPlugin(
|
||||
separatedAddSub = false,
|
||||
executeInsertion = removeOneFetchStage
|
||||
),
|
||||
if(!pessimisticHazard)
|
||||
new HazardSimplePlugin(
|
||||
bypassExecute = false,
|
||||
bypassMemory = false,
|
||||
bypassWriteBack = false,
|
||||
bypassWriteBackBuffer = false,
|
||||
pessimisticUseSrc = false,
|
||||
pessimisticWriteRegFile = false,
|
||||
pessimisticAddressMatch = false
|
||||
)
|
||||
else
|
||||
new HazardPessimisticPlugin(),
|
||||
new BranchPlugin(
|
||||
earlyBranch = earlyBranch,
|
||||
catchAddressMisaligned = false
|
||||
),
|
||||
new YamlPlugin("cpu0.yaml")
|
||||
) ++ (if(noShifter) Nil else List(new LightShifterPlugin))
|
||||
)
|
||||
)
|
||||
}
|
||||
SpinalConfig(mergeAsyncProcess = false).generateVerilog(cpu())
|
||||
}
|
||||
|
||||
|
||||
|
||||
object GenMicroSynthesis {
|
||||
def main(args: Array[String]) {
|
||||
val microNoCsr = new Rtl {
|
||||
override def getName(): String = "MicroNoCsr"
|
||||
override def getRtlPath(): String = "MicroNoCsr.v"
|
||||
SpinalVerilog(GenMicro.cpu().setDefinitionName(getRtlPath().split("\\.").head))
|
||||
}
|
||||
|
||||
val smallestNoCsr = new Rtl {
|
||||
override def getName(): String = "SmallestNoCsr"
|
||||
override def getRtlPath(): String = "SmallestNoCsr.v"
|
||||
SpinalVerilog(GenSmallestNoCsr.cpu().setDefinitionName(getRtlPath().split("\\.").head))
|
||||
}
|
||||
|
||||
val rtls = List(microNoCsr)
|
||||
// val rtls = List(smallestNoCsr)
|
||||
|
||||
val targets = IcestormStdTargets().take(1) ++ XilinxStdTargets(
|
||||
vivadoArtix7Path = "/eda/Xilinx/Vivado/2017.2/bin"
|
||||
) ++ AlteraStdTargets(
|
||||
quartusCycloneIVPath = "/eda/intelFPGA_lite/17.0/quartus/bin/",
|
||||
quartusCycloneVPath = "/eda/intelFPGA_lite/17.0/quartus/bin/"
|
||||
)
|
||||
|
||||
|
||||
Bench(rtls, targets, "/eda/tmp/")
|
||||
}
|
||||
}
|
|
@ -12,7 +12,7 @@ object Presentation extends App{
|
|||
val config = VexRiscvConfig()
|
||||
|
||||
config.plugins ++= List(
|
||||
new IBusSimplePlugin(resetVector = 0x80000000l),
|
||||
// new IBusSimplePlugin(resetVector = 0x80000000l),
|
||||
new DBusSimplePlugin,
|
||||
new CsrPlugin(CsrPluginConfig.smallest),
|
||||
new DecoderSimplePlugin,
|
||||
|
|
Loading…
Reference in New Issue