IBusCachedPlugin with twoStage config is now compatible with syncronous regfile
This commit is contained in:
parent
9a4c35d7b6
commit
c83a157c64
|
@ -23,6 +23,11 @@ trait Pipeline {
|
|||
filtered.head.asInstanceOf[T]
|
||||
}
|
||||
|
||||
def serviceExist[T](clazz : Class[T]) = {
|
||||
val filtered = plugins.filter(o => clazz.isAssignableFrom(o.getClass))
|
||||
filtered.length != 0
|
||||
}
|
||||
|
||||
def build(): Unit ={
|
||||
plugins.foreach(_.setup(this.asInstanceOf[T]))
|
||||
|
||||
|
|
|
@ -20,10 +20,12 @@ case class InstructionCacheConfig( cacheSize : Int,
|
|||
|
||||
|
||||
|
||||
class IBusCachedPlugin(config : InstructionCacheConfig) extends Plugin[VexRiscv]{
|
||||
class IBusCachedPlugin(config : InstructionCacheConfig) extends Plugin[VexRiscv] {
|
||||
import config._
|
||||
var iBus : InstructionCacheMemBus = null
|
||||
|
||||
|
||||
|
||||
object IBUS_ACCESS_ERROR extends Stageable(Bool)
|
||||
var decodeExceptionPort : Flow[ExceptionCause] = null
|
||||
override def setup(pipeline: VexRiscv): Unit = {
|
||||
|
@ -55,8 +57,11 @@ class IBusCachedPlugin(config : InstructionCacheConfig) extends Plugin[VexRiscv]
|
|||
cache.io.cpu.fetch.isStuck := fetch.arbitration.isStuck
|
||||
if(!twoStageLogic) cache.io.cpu.fetch.isStuckByOthers := fetch.arbitration.isStuckByOthers
|
||||
cache.io.cpu.fetch.address := fetch.output(PC)
|
||||
if(!twoStageLogic) fetch.arbitration.haltIt setWhen(cache.io.cpu.fetch.haltIt)
|
||||
if(!twoStageLogic) fetch.insert(INSTRUCTION) := cache.io.cpu.fetch.data
|
||||
if(!twoStageLogic) {
|
||||
fetch.arbitration.haltIt setWhen (cache.io.cpu.fetch.haltIt)
|
||||
fetch.insert(INSTRUCTION) := cache.io.cpu.fetch.data
|
||||
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
|
||||
}
|
||||
|
||||
cache.io.flush.cmd.valid := False
|
||||
|
||||
|
@ -66,6 +71,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig) extends Plugin[VexRiscv]
|
|||
cache.io.cpu.decode.isStuck := decode.arbitration.isStuck
|
||||
cache.io.cpu.decode.address := decode.input(PC)
|
||||
decode.insert(INSTRUCTION) := cache.io.cpu.decode.data
|
||||
decode.insert(INSTRUCTION_ANTICIPATED) := cache.io.cpu.decode.dataAnticipated
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,7 +105,7 @@ case class InstructionCacheCpuFetch(p : InstructionCacheConfig) extends Bundle w
|
|||
val isStuck = Bool
|
||||
val isStuckByOthers = if(!p.twoStageLogic) Bool else null
|
||||
val address = UInt(p.addressWidth bit)
|
||||
val data = if(!p.twoStageLogic) Bits(32 bit) else null
|
||||
val data = Bits(32 bit) //If twoStageLogic == true, this signal is acurate only when there is the cache doesn't stall decode (Used for Sync regfile)
|
||||
val error = if(!p.twoStageLogic && p.catchAccessFault) Bool else null
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
|
@ -116,11 +122,12 @@ case class InstructionCacheCpuDecode(p : InstructionCacheConfig) extends Bundle
|
|||
val isStuck = Bool
|
||||
val address = UInt(p.addressWidth bit)
|
||||
val data = Bits(32 bit)
|
||||
val dataAnticipated = Bits(32 bits)
|
||||
val error = if(p.catchAccessFault) Bool else null
|
||||
|
||||
override def asMaster(): Unit = {
|
||||
out(isValid, isStuck, address)
|
||||
in(haltIt, data)
|
||||
in(haltIt, data, dataAnticipated)
|
||||
if(p.catchAccessFault) in(error)
|
||||
}
|
||||
}
|
||||
|
@ -398,24 +405,30 @@ class InstructionCache(p : InstructionCacheConfig) extends Component{
|
|||
fetchInstructionValidReg := False
|
||||
}
|
||||
|
||||
io.cpu.fetch.data := fetchInstructionValue
|
||||
|
||||
|
||||
val decodeInstructionValid = Reg(Bool)
|
||||
val decodeInstructionReg = Reg(Bits(32 bits))
|
||||
val decodeInstructionRegIn = (!io.cpu.decode.isStuck) ? fetchInstructionValue | loadedWord.data
|
||||
|
||||
io.cpu.decode.dataAnticipated := decodeInstructionReg
|
||||
when(!io.cpu.decode.isStuck){
|
||||
decodeInstructionValid := fetchInstructionValid
|
||||
decodeInstructionReg := fetchInstructionValue
|
||||
decodeInstructionReg := decodeInstructionRegIn
|
||||
io.cpu.decode.dataAnticipated := decodeInstructionRegIn
|
||||
}.elsewhen(loadedWord.valid && (loadedWord.address >> 2) === (io.cpu.decode.address >> 2)){
|
||||
decodeInstructionValid := True
|
||||
decodeInstructionReg := loadedWord.data
|
||||
decodeInstructionReg := decodeInstructionRegIn
|
||||
io.cpu.decode.dataAnticipated := decodeInstructionRegIn
|
||||
}
|
||||
|
||||
io.cpu.decode.haltIt := io.cpu.decode.isValid && !decodeInstructionValid
|
||||
io.cpu.decode.data := decodeInstructionReg
|
||||
|
||||
|
||||
lineLoader.requestIn.valid := io.cpu.decode.isValid && !decodeInstructionValid
|
||||
lineLoader.requestIn.addr := io.cpu.decode.address
|
||||
|
||||
}
|
||||
|
||||
io.flush.cmd.ready := !(lineLoader.request.valid || io.cpu.fetch.isValid)
|
||||
|
|
|
@ -60,6 +60,7 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean)
|
|||
fetch.insert(INSTRUCTION) := iBus.rsp.inst
|
||||
fetch.insert(IBUS_ACCESS_ERROR) := iBus.rsp.error
|
||||
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready)
|
||||
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
|
||||
|
||||
if(catchAccessFault){
|
||||
decodeExceptionPort.valid := decode.arbitration.isValid && decode.input(IBUS_ACCESS_ERROR)
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
package SpinalRiscv.Plugin
|
||||
|
||||
import SpinalRiscv.{Stageable, DecoderService, Riscv, VexRiscv}
|
||||
import SpinalRiscv._
|
||||
import spinal.core._
|
||||
import spinal.lib._
|
||||
|
||||
import scala.collection.mutable
|
||||
|
||||
|
||||
trait RegFileReadKind
|
||||
object ASYNC extends RegFileReadKind
|
||||
|
@ -41,7 +43,7 @@ class RegFilePlugin(regFileReadyKind : RegFileReadKind,zeroBoot : Boolean = fals
|
|||
//read register file
|
||||
val srcInstruction = regFileReadyKind match{
|
||||
case `ASYNC` => input(INSTRUCTION)
|
||||
case `SYNC` => Mux(arbitration.isStuck,input(INSTRUCTION),fetch.output(INSTRUCTION))
|
||||
case `SYNC` => input(INSTRUCTION_ANTICIPATED)
|
||||
}
|
||||
|
||||
val regFileReadAddress1 = srcInstruction(Riscv.rs1Range).asUInt
|
||||
|
|
|
@ -239,7 +239,7 @@ object TopLevel {
|
|||
catchIllegalInstruction = false
|
||||
),
|
||||
new RegFilePlugin(
|
||||
regFileReadyKind = Plugin.ASYNC,
|
||||
regFileReadyKind = Plugin.SYNC,
|
||||
zeroBoot = false
|
||||
),
|
||||
new IntAluPlugin,
|
||||
|
|
|
@ -19,6 +19,7 @@ case class VexRiscvConfig(pcWidth : Int){
|
|||
object PC extends Stageable(UInt(pcWidth bits))
|
||||
object PC_CALC_WITHOUT_JUMP extends Stageable(UInt(pcWidth bits))
|
||||
object INSTRUCTION extends Stageable(Bits(32 bits))
|
||||
object INSTRUCTION_ANTICIPATED extends Stageable(Bits(32 bits))
|
||||
object LEGAL_INSTRUCTION extends Stageable(Bool)
|
||||
object REGFILE_WRITE_VALID extends Stageable(Bool)
|
||||
object REGFILE_WRITE_DATA extends Stageable(Bits(32 bits))
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
[*]
|
||||
[*] GTKWave Analyzer v3.3.58 (w)1999-2014 BSI
|
||||
[*] Sat Apr 8 15:08:01 2017
|
||||
[*] Sun Apr 9 09:10:08 2017
|
||||
[*]
|
||||
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-simple.vcd"
|
||||
[dumpfile_mtime] "Sat Apr 8 15:02:54 2017"
|
||||
[dumpfile_size] 95378
|
||||
[dumpfile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/rv32ui-p-addi.vcd"
|
||||
[dumpfile_mtime] "Sun Apr 9 09:08:48 2017"
|
||||
[dumpfile_size] 136439
|
||||
[savefile] "/home/spinalvm/Spinal/VexRiscv/src/test/cpp/testA/fail.gtkw"
|
||||
[timestart] 211
|
||||
[timestart] 274
|
||||
[size] 1776 953
|
||||
[pos] -1 -1
|
||||
*-4.422177 320 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[pos] -775 -353
|
||||
*-2.774728 284 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1
|
||||
[treeopen] TOP.
|
||||
[treeopen] TOP.VexRiscv.
|
||||
[sst_width] 201
|
||||
[signals_width] 397
|
||||
[signals_width] 453
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 279
|
||||
@800200
|
||||
|
@ -31,19 +31,18 @@ TOP.VexRiscv.instructionCache_1.io_cpu_fetch_isValid
|
|||
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_isStuck
|
||||
@22
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_address[31:0]
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_data[31:0]
|
||||
@1000200
|
||||
-fetch
|
||||
@800200
|
||||
-decode
|
||||
@28
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_decode_isValid
|
||||
@29
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_decode_haltIt
|
||||
@28
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_decode_isStuck
|
||||
@22
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_decode_address[31:0]
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_decode_instruction[31:0]
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_decode_data[31:0]
|
||||
@1000200
|
||||
-decode
|
||||
@800200
|
||||
|
@ -61,5 +60,28 @@ TOP.VexRiscv.instructionCache_1.io_mem_rsp_valid
|
|||
-ibus
|
||||
@28
|
||||
TOP.VexRiscv.instructionCache_1.clk
|
||||
@22
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_fetch_data[31:0]
|
||||
TOP.VexRiscv.decode_RegFilePlugin_srcInstruction[31:0]
|
||||
TOP.VexRiscv.instructionCache_1.io_cpu_decode_data[31:0]
|
||||
@29
|
||||
TOP.VexRiscv.decode_arbitration_isValid
|
||||
@28
|
||||
TOP.VexRiscv.decode_arbitration_isStuck
|
||||
@22
|
||||
TOP.VexRiscv.decode_PC[31:0]
|
||||
TOP.VexRiscv.decode_REG1[31:0]
|
||||
TOP.VexRiscv.decode_REG2[31:0]
|
||||
@28
|
||||
TOP.VexRiscv.decode_REG1_USE
|
||||
TOP.VexRiscv.decode_REG2_USE
|
||||
TOP.VexRiscv.decode_arbitration_isValid
|
||||
TOP.VexRiscv.decode_arbitration_isStuck
|
||||
@22
|
||||
TOP.VexRiscv.decode_RegFilePlugin_regFileReadAddress1[4:0]
|
||||
TOP.VexRiscv.decode_RegFilePlugin_regFileReadAddress2[4:0]
|
||||
TOP.VexRiscv.decode_RegFilePlugin_rs1Data[31:0]
|
||||
TOP.VexRiscv.decode_RegFilePlugin_rs2Data[31:0]
|
||||
TOP.VexRiscv.decode_RegFilePlugin_srcInstruction[31:0]
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
||||
|
|
Loading…
Reference in New Issue