Add shadow regfile

various cleaning
This commit is contained in:
Dolu1990 2018-11-16 17:06:11 +01:00
parent cc48fc7403
commit 75d4d049d7
7 changed files with 96 additions and 26 deletions

View File

@ -6,6 +6,7 @@ import spinal.lib._
import spinal.lib.bus.amba4.axi.{Axi4Config, Axi4ReadOnly}
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
import vexriscv.demo.{SimpleBus, SimpleBusConfig}
case class InstructionCacheConfig( cacheSize : Int,
@ -45,6 +46,11 @@ case class InstructionCacheConfig( cacheSize : Int,
constantBurstBehavior = true
)
def getSimpleBusConfig() = SimpleBusConfig(
addressWidth = 32,
dataWidth = 32
)
def getWishboneConfig() = WishboneConfig(
addressWidth = 30,
dataWidth = 32,
@ -178,6 +184,24 @@ case class InstructionCacheMemBus(p : InstructionCacheConfig) extends Bundle wit
mm
}
def toSimpleBus(): SimpleBus = {
val simpleBusConfig = p.getSimpleBusConfig()
val bus = SimpleBus(simpleBusConfig)
val counter = Counter(p.burstSize, bus.cmd.fire)
bus.cmd.valid := cmd.valid
bus.cmd.address := cmd.address(31 downto widthOf(counter.value) + 2) @@ counter @@ U"00"
bus.cmd.wr := False
bus.cmd.mask.assignDontCare()
bus.cmd.data.assignDontCare()
cmd.ready := counter.willOverflow
rsp.valid := bus.rsp.valid
rsp.data := bus.rsp.payload.data
rsp.error := False
bus
}
def toWishbone(): Wishbone = {
val wishboneConfig = p.getWishboneConfig()
val bus = Wishbone(wishboneConfig)

View File

@ -200,7 +200,8 @@ trait CsrInterface{
}
def rw(csrAddress : Int, thats : (Int, Data)*) : Unit = for(that <- thats) rw(csrAddress,that._1, that._2)
def r [T <: Data](csrAddress : Int, thats : (Int, Data)*) : Unit = for(that <- thats) r(csrAddress,that._1, that._2)
def w(csrAddress : Int, thats : (Int, Data)*) : Unit = for(that <- thats) w(csrAddress,that._1, that._2)
def r(csrAddress : Int, thats : (Int, Data)*) : Unit = for(that <- thats) r(csrAddress,that._1, that._2)
def rw[T <: Data](csrAddress : Int, that : T): Unit = rw(csrAddress,0,that)
def w[T <: Data](csrAddress : Int, that : T): Unit = w(csrAddress,0,that)
def r [T <: Data](csrAddress : Int, that : T): Unit = r(csrAddress,0,that)

View File

@ -6,6 +6,7 @@ import spinal.lib._
import spinal.lib.bus.amba4.axi._
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
import vexriscv.demo.SimpleBus
import vexriscv.ip.DataCacheMemCmd
@ -131,11 +132,7 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
mm.read := cmdStage.valid && !cmdStage.wr
mm.write := cmdStage.valid && cmdStage.wr
mm.address := (cmdStage.address >> 2) @@ U"00"
mm.writeData := cmdStage.size.mux (
U(0) -> cmdStage.data(7 downto 0) ## cmdStage.data(7 downto 0) ## cmdStage.data(7 downto 0) ## cmdStage.data(7 downto 0),
U(1) -> cmdStage.data(15 downto 0) ## cmdStage.data(15 downto 0),
default -> cmdStage.data(31 downto 0)
)
mm.writeData := cmdStage.data(31 downto 0)
mm.byteEnable := (cmdStage.size.mux (
U(0) -> B"0001",
U(1) -> B"0011",
@ -179,6 +176,25 @@ case class DBusSimpleBus() extends Bundle with IMasterSlave{
rsp.error := False //TODO
bus
}
def toSimpleBus() : SimpleBus = {
val bus = SimpleBus(32,32)
bus.cmd.valid := cmd.valid
bus.cmd.wr := cmd.wr
bus.cmd.address := cmd.address.resized
bus.cmd.data := cmd.data
bus.cmd.mask := cmd.size.mux(
0 -> B"0001",
1 -> B"0011",
default -> B"1111"
) |<< cmd.address(1 downto 0)
cmd.ready := bus.cmd.ready
rsp.ready := bus.rsp.valid
rsp.data := bus.rsp.data
bus
}
}
@ -311,9 +327,10 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean = false,
memoryExceptionPort.valid := True
}
}
when(!(arbitration.isValid && input(MEMORY_ENABLE))){
when(!(arbitration.isValid && input(MEMORY_ENABLE) && (if(cmdStage == rspStage) !arbitration.isStuckByOthers else True))){
memoryExceptionPort.valid := False
}
memoryExceptionPort.badAddr := input(REGFILE_WRITE_DATA).asUInt //Drived by IntAluPlugin
}

View File

@ -6,6 +6,7 @@ import spinal.lib._
import spinal.lib.bus.amba4.axi._
import spinal.lib.bus.avalon.{AvalonMM, AvalonMMConfig}
import spinal.lib.bus.wishbone.{Wishbone, WishboneConfig}
import vexriscv.demo.SimpleBus
@ -135,6 +136,18 @@ case class IBusSimpleBus(interfaceKeepData : Boolean = false) extends Bundle wit
bus
}
def toSimpleBus(): SimpleBus = {
val bus = SimpleBus(32,32)
bus.cmd.arbitrationFrom(cmd)
bus.cmd.address := cmd.pc.resized
bus.cmd.wr := False
bus.cmd.mask.assignDontCare()
bus.cmd.data.assignDontCare()
rsp.valid := bus.rsp.valid
rsp.inst := bus.rsp.payload.data
rsp.error := False
bus
}
}
@ -202,8 +215,9 @@ class IBusSimplePlugin(resetVector : BigInt,
cmd.valid := stage.input.valid && pendingCmd =/= pendingMax && !stages.map(_.arbitration.isValid).orR
assert(injectorStage == false)
assert(iBusRsp.stages.dropWhile(_ != stage).length <= 2)
}else
}else {
cmd.valid := stage.input.valid && stage.output.ready && pendingCmd =/= pendingMax
}
cmd.pc := stage.input.payload(31 downto 2) @@ "00"
} else new Area{
//This implementation keep the cmd on the bus until it's executed, even if the pipeline is flushed

View File

@ -84,10 +84,10 @@ class IntAluPlugin extends Plugin[VexRiscv]{
import execute._
val bitwise = input(ALU_BITWISE_CTRL).mux(
AluBitwiseCtrlEnum.AND -> (input(SRC1) & input(SRC2)),
AluBitwiseCtrlEnum.OR -> (input(SRC1) | input(SRC2)),
AluBitwiseCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)),
AluBitwiseCtrlEnum.SRC1 -> input(SRC1)
AluBitwiseCtrlEnum.AND -> (input(SRC1) & input(SRC2)),
AluBitwiseCtrlEnum.OR -> (input(SRC1) | input(SRC2)),
AluBitwiseCtrlEnum.XOR -> (input(SRC1) ^ input(SRC2)),
AluBitwiseCtrlEnum.SRC1 -> input(SRC1)
)
// mux results

View File

@ -11,17 +11,17 @@ trait RegFileReadKind
object ASYNC extends RegFileReadKind
object SYNC extends RegFileReadKind
class RegFilePlugin(regFileReadyKind : RegFileReadKind,
zeroBoot : Boolean = false,
x0Init : Boolean = true,
writeRfInMemoryStage : Boolean = false,
readInExecute : Boolean = false,
syncUpdateOnStall : Boolean = true) extends Plugin[VexRiscv] with RegFileService{
syncUpdateOnStall : Boolean = true,
withShadow : Boolean = false //shadow registers aren't transition hazard free
) extends Plugin[VexRiscv] with RegFileService{
import Riscv._
// assert(!writeRfInMemoryStage)
override def readStage(): Stage = if(readInExecute) pipeline.execute else pipeline.decode
override def setup(pipeline: VexRiscv): Unit = {
@ -36,9 +36,23 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,
import pipeline._
import pipeline.config._
val readStage = if(readInExecute) execute else decode
val writeStage = if(writeRfInMemoryStage) memory else stages.last
val global = pipeline plug new Area{
val regFile = Mem(Bits(32 bits),32) addAttribute(Verilator.public)
if(zeroBoot) regFile.init(List.fill(32)(B(0, 32 bits)))
val regFileSize = if(withShadow) 64 else 32
val regFile = Mem(Bits(32 bits),regFileSize) addAttribute(Verilator.public)
if(zeroBoot) regFile.init(List.fill(regFileSize)(B(0, 32 bits)))
val shadow = ifGen(withShadow)(new Area{
val write, read, clear = RegInit(False)
read clearWhen(clear && !readStage.arbitration.isStuck)
write clearWhen(clear && !writeStage.arbitration.isStuck)
val csrService = pipeline.service(classOf[CsrInterface])
csrService.w(0x7C0,2 -> clear, 1 -> read, 0 -> write)
})
}
//Disable rd0 write in decoding stage
@ -47,7 +61,6 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,
}
//Read register file
val readStage = if(readInExecute) execute else decode
readStage plug new Area{
import readStage._
@ -58,8 +71,9 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,
case `SYNC` if readInExecute => if(syncUpdateOnStall) Mux(execute.arbitration.isStuck, execute.input(INSTRUCTION), decode.input(INSTRUCTION)) else decode.input(INSTRUCTION)
}
val regFileReadAddress1 = srcInstruction(Riscv.rs1Range).asUInt
val regFileReadAddress2 = srcInstruction(Riscv.rs2Range).asUInt
def shadowPrefix(that : Bits) = if(withShadow) global.shadow.read ## that else that
val regFileReadAddress1 = U(shadowPrefix(srcInstruction(Riscv.rs1Range)))
val regFileReadAddress2 = U(shadowPrefix(srcInstruction(Riscv.rs2Range)))
val (rs1Data,rs2Data) = regFileReadyKind match{
case `ASYNC` => (global.regFile.readAsync(regFileReadAddress1),global.regFile.readAsync(regFileReadAddress2))
@ -73,13 +87,13 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,
}
//Write register file
val writeStage = if(writeRfInMemoryStage) memory else stages.last
writeStage plug new Area {
import writeStage._
def shadowPrefix(that : Bits) = if(withShadow) global.shadow.write ## that else that
val regFileWrite = global.regFile.writePort.addAttribute(Verilator.public)
regFileWrite.valid := output(REGFILE_WRITE_VALID) && arbitration.isFiring
regFileWrite.address := output(INSTRUCTION)(rdRange).asUInt
regFileWrite.address := U(shadowPrefix(output(INSTRUCTION)(rdRange)))
regFileWrite.data := output(REGFILE_WRITE_DATA)
//CPU will initialise constant register zero in the first cycle

View File

@ -26,7 +26,7 @@ class FullBarrelShifterPlugin(earlyInjection : Boolean = false) extends Plugin[V
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> Bool(earlyInjection),
BYPASSABLE_MEMORY_STAGE -> True,
RS1_USE -> True
RS1_USE -> True
)
val nonImmediateActions = List[(Stageable[_ <: BaseType],Any)](
@ -35,8 +35,8 @@ class FullBarrelShifterPlugin(earlyInjection : Boolean = false) extends Plugin[V
REGFILE_WRITE_VALID -> True,
BYPASSABLE_EXECUTE_STAGE -> Bool(earlyInjection),
BYPASSABLE_MEMORY_STAGE -> True,
RS1_USE -> True,
RS2_USE -> True
RS1_USE -> True,
RS2_USE -> True
)
val decoderService = pipeline.service(classOf[DecoderService])