Refractoring of some arbitration signals

Add UART into Murax
This commit is contained in:
Charles Papon 2017-07-31 13:34:25 +02:00
parent 8708d2482f
commit c16a53c388
23 changed files with 239 additions and 149 deletions

View File

@ -5,6 +5,8 @@ set_io io_H16 H16
set_io io_G15 G15 set_io io_G15 G15
set_io io_G16 G16 set_io io_G16 G16
set_io io_F15 F15 set_io io_F15 F15
set_io io_B12 B12
set_io io_B10 B10
set_io io_led[0] B5 set_io io_led[0] B5
set_io io_led[1] B4 set_io io_led[1] B4
set_io io_led[2] A2 set_io io_led[2] A2

View File

@ -6,6 +6,8 @@ module toplevel(
input io_G15, input io_G15,
output io_G16, output io_G16,
input io_F15, input io_F15,
output io_B12,
input io_B10,
output [7:0] io_led output [7:0] io_led
); );
@ -36,6 +38,8 @@ module toplevel(
.io_jtag_tms(io_F15), .io_jtag_tms(io_F15),
.io_gpioA_read (io_gpioA_read), .io_gpioA_read (io_gpioA_read),
.io_gpioA_write (io_gpioA_write), .io_gpioA_write (io_gpioA_write),
.io_gpioA_writeEnable(io_gpioA_writeEnable) .io_gpioA_writeEnable(io_gpioA_writeEnable),
.io_uart_txd(io_B12),
.io_uart_rxd(io_B10)
); );
endmodule endmodule

View File

@ -117,8 +117,8 @@ trait Pipeline {
} }
for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){ for(stageIndex <- 0 until stages.length; stage = stages(stageIndex)){
stage.arbitration.isStuckByOthers := stage.arbitration.haltItByOther || stages.takeRight(stages.length - stageIndex - 1).map(s => s.arbitration.haltIt/* && !s.arbitration.removeIt*/).foldLeft(False)(_ || _) stage.arbitration.isStuckByOthers := stage.arbitration.haltByOther || stages.takeRight(stages.length - stageIndex - 1).map(s => s.arbitration.haltItself/* && !s.arbitration.removeIt*/).foldLeft(False)(_ || _)
stage.arbitration.isStuck := stage.arbitration.haltIt || stage.arbitration.isStuckByOthers stage.arbitration.isStuck := stage.arbitration.haltItself || stage.arbitration.isStuckByOthers
stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt stage.arbitration.isFiring := stage.arbitration.isValid && !stage.arbitration.isStuck && !stage.arbitration.removeIt
} }

View File

@ -45,15 +45,16 @@ class Stage() extends Area{
val arbitration = new Area{ val arbitration = new Area{
val haltIt = False val haltItself = False //user settable, stuck the instruction, should only be set by the instruction itself
val haltItByOther = False val haltByOther = False //When settable, stuck the instruction, should only be set by something else than the stucked instruction
val removeIt = False val removeIt = False //When settable, unschedule the instruction as if it was never executed (no side effect)
val flushAll = False val flushAll = False //When settable, unschedule instructions in the current stage and all prior ones
val isValid = RegInit(False) val isValid = RegInit(False) //Inform if a instruction is in the current stage
val isStuck = Bool val isStuck = Bool //Inform if the instruction is stuck (haltItself || haltByOther)
val isFlushed = Bool val isStuckByOthers = Bool //Inform if the instruction is stuck by sombody else
val isStuckByOthers = Bool def isRemoved = removeIt //Inform if the instruction is going to be unschedule the current cycle
val isFiring = Bool val isFlushed = Bool //Inform if the instruction is flushed (flushAll set in the current or subsequents stages)
val isFiring = Bool //Inform if the current instruction will go to the next stage the next cycle (isValid && !isStuck && !removeIt)
} }

View File

@ -33,63 +33,63 @@ object TestsWorkspace {
plugins = List( plugins = List(
new PcManagerSimplePlugin( new PcManagerSimplePlugin(
resetVector = 0x00000000l, resetVector = 0x00000000l,
relaxedPcCalculation = true relaxedPcCalculation = false
), ),
new IBusSimplePlugin( // new IBusSimplePlugin(
interfaceKeepData = false, // interfaceKeepData = false,
catchAccessFault = true // catchAccessFault = true
),
// new IBusCachedPlugin(
// config = InstructionCacheConfig(
// cacheSize = 4096,
// bytePerLine =32,
// wayCount = 1,
// wrappedMemAccess = true,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// catchIllegalAccess = true,
// catchAccessFault = true,
// catchMemoryTranslationMiss = true,
// asyncTagMemory = false,
// twoStageLogic = true
// ),
// askMemoryTranslation = true,
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 4
// )
// ), // ),
new DBusSimplePlugin( new IBusCachedPlugin(
catchAddressMisaligned = true, config = InstructionCacheConfig(
catchAccessFault = true, cacheSize = 4096,
earlyInjection = false bytePerLine =32,
wayCount = 1,
wrappedMemAccess = true,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchIllegalAccess = true,
catchAccessFault = true,
catchMemoryTranslationMiss = true,
asyncTagMemory = false,
twoStageLogic = true
),
askMemoryTranslation = true,
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
portTlbSize = 4
)
), ),
// new DBusCachedPlugin( // new DBusSimplePlugin(
// config = new DataCacheConfig( // catchAddressMisaligned = true,
// cacheSize = 4096, // catchAccessFault = true,
// bytePerLine = 32, // earlyInjection = false
// wayCount = 1,
// addressWidth = 32,
// cpuDataWidth = 32,
// memDataWidth = 32,
// catchAccessError = true,
// catchIllegal = true,
// catchUnaligned = true,
// catchMemoryTranslationMiss = true
// ),
//// memoryTranslatorPortConfig = null
// memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
// portTlbSize = 6
// )
// ), // ),
new DBusCachedPlugin(
config = new DataCacheConfig(
cacheSize = 4096,
bytePerLine = 32,
wayCount = 1,
addressWidth = 32,
cpuDataWidth = 32,
memDataWidth = 32,
catchAccessError = true,
catchIllegal = true,
catchUnaligned = true,
catchMemoryTranslationMiss = true
),
// memoryTranslatorPortConfig = null
memoryTranslatorPortConfig = MemoryTranslatorPortConfig(
portTlbSize = 6
)
),
// new StaticMemoryTranslatorPlugin( // new StaticMemoryTranslatorPlugin(
// ioRange = _(31 downto 28) === 0xF // ioRange = _(31 downto 28) === 0xF
// ), // ),
// new MemoryTranslatorPlugin( new MemoryTranslatorPlugin(
// tlbSize = 32, tlbSize = 32,
// virtualRange = _(31 downto 28) === 0xC, virtualRange = _(31 downto 28) === 0xC,
// ioRange = _(31 downto 28) === 0xF ioRange = _(31 downto 28) === 0xF
// ), ),
new DecoderSimplePlugin( new DecoderSimplePlugin(
catchIllegalInstruction = true catchIllegalInstruction = true
), ),

View File

@ -57,7 +57,7 @@ class VexRiscv(val config : VexRiscvConfig) extends Component with Pipeline{
decode.input(config.INSTRUCTION).addAttribute(Verilator.public) decode.input(config.INSTRUCTION).addAttribute(Verilator.public)
decode.input(config.PC).addAttribute(Verilator.public) decode.input(config.PC).addAttribute(Verilator.public)
decode.arbitration.isValid.addAttribute(Verilator.public) decode.arbitration.isValid.addAttribute(Verilator.public)
decode.arbitration.haltIt.addAttribute(Verilator.public) decode.arbitration.haltItself.addAttribute(Verilator.public)
writeBack.input(config.INSTRUCTION) keep() addAttribute(Verilator.public) writeBack.input(config.INSTRUCTION) keep() addAttribute(Verilator.public)
writeBack.input(config.PC) keep() addAttribute(Verilator.public) writeBack.input(config.PC) keep() addAttribute(Verilator.public)
writeBack.arbitration.isValid keep() addAttribute(Verilator.public) writeBack.arbitration.isValid keep() addAttribute(Verilator.public)

View File

@ -5,7 +5,7 @@ import spinal.lib._
import spinal.lib.bus.amba3.apb.{Apb3SlaveFactory, Apb3Decoder, Apb3Gpio, Apb3} import spinal.lib.bus.amba3.apb.{Apb3SlaveFactory, Apb3Decoder, Apb3Gpio, Apb3}
import spinal.lib.bus.misc.SizeMapping import spinal.lib.bus.misc.SizeMapping
import spinal.lib.com.jtag.Jtag import spinal.lib.com.jtag.Jtag
import spinal.lib.com.uart.Uart import spinal.lib.com.uart._
import spinal.lib.io.TriStateArray import spinal.lib.io.TriStateArray
import spinal.lib.misc.{InterruptCtrl, Timer, Prescaler} import spinal.lib.misc.{InterruptCtrl, Timer, Prescaler}
import spinal.lib.soc.pinsec.{PinsecTimerCtrlExternal, PinsecTimerCtrl} import spinal.lib.soc.pinsec.{PinsecTimerCtrlExternal, PinsecTimerCtrl}
@ -24,6 +24,7 @@ import vexriscv.{plugin, VexRiscvConfig, VexRiscv}
* - APB bus for peripherals * - APB bus for peripherals
* - 32 GPIO pin * - 32 GPIO pin
* - one 16 bits prescaler, two 16 bits timers * - one 16 bits prescaler, two 16 bits timers
* - one UART with tx/rx fifo
*/ */
@ -88,7 +89,7 @@ case class Murax(config : MuraxConfig) extends Component{
//Peripherals IO //Peripherals IO
val gpioA = master(TriStateArray(32 bits)) val gpioA = master(TriStateArray(32 bits))
// val uart = master(Uart()) val uart = master(Uart())
} }
@ -345,6 +346,28 @@ case class Murax(config : MuraxConfig) extends Component{
) )
io.gpioA <> gpioACtrl.io.gpio io.gpioA <> gpioACtrl.io.gpio
val uartCtrlConfig = UartCtrlMemoryMappedConfig(
uartCtrlConfig = UartCtrlGenerics(
dataWidthMax = 8,
clockDividerWidth = 20,
preSamplingSize = 1,
samplingSize = 3,
postSamplingSize = 1
),
initConfig = UartCtrlInitConfig(
baudrate = 115200,
dataLength = 7, //7 => 8 bits
parity = UartParityType.NONE,
stop = UartStopType.ONE
),
busCanWriteClockDividerConfig = false,
busCanWriteFrameConfig = false,
txFifoDepth = 16,
rxFifoDepth = 16
)
val uartCtrl = Apb3UartCtrl(uartCtrlConfig)
uartCtrl.io.uart <> io.uart
val timer = new Area{ val timer = new Area{
val apb = Apb3( val apb = Apb3(
addressWidth = 8, addressWidth = 8,
@ -380,6 +403,7 @@ case class Murax(config : MuraxConfig) extends Component{
master = apbBridge.apb, master = apbBridge.apb,
slaves = List( slaves = List(
gpioACtrl.io.apb -> (0x00000, 4 kB), gpioACtrl.io.apb -> (0x00000, 4 kB),
uartCtrl.io.apb -> (0x10000, 4 kB),
timer.apb -> (0x20000, 4 kB) timer.apb -> (0x20000, 4 kB)
) )
) )

View File

@ -325,7 +325,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Used to make the pipeline empty softly (for interrupts) //Used to make the pipeline empty softly (for interrupts)
val pipelineLiberator = new Area{ val pipelineLiberator = new Area{
val enable = False val enable = False
prefetch.arbitration.haltItByOther setWhen(enable) prefetch.arbitration.haltByOther setWhen(enable)
val done = ! List(fetch, decode, execute, memory).map(_.arbitration.isValid).orR val done = ! List(fetch, decode, execute, memory).map(_.arbitration.isValid).orR
} }
@ -413,7 +413,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Manage MRET instructions //Manage MRET instructions
when(memory.input(ENV_CTRL) === EnvCtrlEnum.MRET) { when(memory.input(ENV_CTRL) === EnvCtrlEnum.MRET) {
memory.arbitration.haltIt := writeBack.arbitration.isValid memory.arbitration.haltItself := writeBack.arbitration.isValid
when(memory.arbitration.isFiring) { when(memory.arbitration.isFiring) {
jumpInterface.valid := True jumpInterface.valid := True
jumpInterface.payload := mepc jumpInterface.payload := mepc
@ -432,7 +432,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Manage WFI instructions //Manage WFI instructions
if(wfiGen) when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.WFI){ if(wfiGen) when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.WFI){
when(!interrupt){ when(!interrupt){
execute.arbitration.haltIt := True execute.arbitration.haltItself := True
decode.arbitration.flushAll := True decode.arbitration.flushAll := True
} }
} }
@ -461,7 +461,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
|| (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0))) || (input(INSTRUCTION)(14 downto 13) === "11" && imm.z === 0)))
val writeInstruction = arbitration.isValid && input(IS_CSR) && writeOpcode val writeInstruction = arbitration.isValid && input(IS_CSR) && writeOpcode
arbitration.haltIt setWhen(writeInstruction && !readDataRegValid) arbitration.haltItself setWhen(writeInstruction && !readDataRegValid)
val writeEnable = writeInstruction && !arbitration.isStuckByOthers && !arbitration.removeIt && readDataRegValid val writeEnable = writeInstruction && !arbitration.isStuckByOthers && !arbitration.removeIt && readDataRegValid
when(arbitration.isValid && input(IS_CSR)) { when(arbitration.isValid && input(IS_CSR)) {

View File

@ -123,7 +123,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE) cache.io.cpu.memory.isValid := arbitration.isValid && input(MEMORY_ENABLE)
cache.io.cpu.memory.isStuck := arbitration.isStuck cache.io.cpu.memory.isStuck := arbitration.isStuck
cache.io.cpu.memory.isRemoved := arbitration.removeIt cache.io.cpu.memory.isRemoved := arbitration.removeIt
arbitration.haltIt setWhen(cache.io.cpu.memory.haltIt) arbitration.haltItself setWhen(cache.io.cpu.memory.haltIt)
cache.io.cpu.memory.mmuBus <> mmuBus cache.io.cpu.memory.mmuBus <> mmuBus
} }
@ -148,7 +148,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
exceptionBus.code := 13 exceptionBus.code := 13
} }
} }
arbitration.haltIt.setWhen(cache.io.cpu.writeBack.haltIt) arbitration.haltItself.setWhen(cache.io.cpu.writeBack.haltIt)
val rspShifted = Bits(32 bits) val rspShifted = Bits(32 bits)
rspShifted := cache.io.cpu.writeBack.data rspShifted := cache.io.cpu.writeBack.data

View File

@ -210,7 +210,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
default -> input(RS2)(31 downto 0) default -> input(RS2)(31 downto 0)
) )
when(arbitration.isValid && input(MEMORY_ENABLE) && !dBus.cmd.ready && !input(ALIGNEMENT_FAULT)){ when(arbitration.isValid && input(MEMORY_ENABLE) && !dBus.cmd.ready && !input(ALIGNEMENT_FAULT)){
arbitration.haltIt := True arbitration.haltItself := True
} }
insert(MEMORY_ADDRESS_LOW) := dBus.cmd.address(1 downto 0) insert(MEMORY_ADDRESS_LOW) := dBus.cmd.address(1 downto 0)
@ -222,7 +222,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
insert(MEMORY_READ_DATA) := dBus.rsp.data insert(MEMORY_READ_DATA) := dBus.rsp.data
arbitration.haltIt setWhen(arbitration.isValid && input(MEMORY_ENABLE) && input(REGFILE_WRITE_VALID) && !dBus.rsp.ready) arbitration.haltItself setWhen(arbitration.isValid && input(MEMORY_ENABLE) && input(REGFILE_WRITE_VALID) && !dBus.rsp.ready)
if(catchAccessFault || catchAddressMisaligned){ if(catchAccessFault || catchAddressMisaligned){
if(!catchAccessFault){ if(!catchAccessFault){

View File

@ -161,7 +161,7 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] {
when(io.bus.cmd.wr) { when(io.bus.cmd.wr) {
insertDecodeInstruction := True insertDecodeInstruction := True
decode.arbitration.isValid setWhen (firstCycle) decode.arbitration.isValid setWhen (firstCycle)
decode.arbitration.haltIt setWhen (secondCycle) decode.arbitration.haltItself setWhen (secondCycle)
io.bus.cmd.ready := !(firstCycle || secondCycle || decode.arbitration.isValid) io.bus.cmd.ready := !(firstCycle || secondCycle || decode.arbitration.isValid)
} }
} }
@ -180,14 +180,14 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] {
when(execute.arbitration.isFiring && execute.input(IS_EBREAK)) { when(execute.arbitration.isFiring && execute.input(IS_EBREAK)) {
prefetch.arbitration.haltItByOther := True prefetch.arbitration.haltByOther := True
decode.arbitration.flushAll := True decode.arbitration.flushAll := True
haltIt := True haltIt := True
haltedByBreak := True haltedByBreak := True
} }
when(haltIt) { when(haltIt) {
prefetch.arbitration.haltItByOther := True prefetch.arbitration.haltByOther := True
} }
when(stepIt && prefetch.arbitration.isFiring) { when(stepIt && prefetch.arbitration.isFiring) {

View File

@ -47,7 +47,7 @@ class DivPlugin extends Plugin[VexRiscv]{
when(arbitration.isValid && input(IS_DIV)) { when(arbitration.isValid && input(IS_DIV)) {
divider.io.cmd.valid := !arbitration.isStuckByOthers && !arbitration.removeIt divider.io.cmd.valid := !arbitration.isStuckByOthers && !arbitration.removeIt
arbitration.haltIt := memory.arbitration.isValid && memory.input(IS_DIV) arbitration.haltItself := memory.arbitration.isValid && memory.input(IS_DIV)
} }
} }
@ -59,7 +59,7 @@ class DivPlugin extends Plugin[VexRiscv]{
divider.io.rsp.ready := !arbitration.isStuckByOthers divider.io.rsp.ready := !arbitration.isStuckByOthers
when(arbitration.isValid && input(IS_DIV)) { when(arbitration.isValid && input(IS_DIV)) {
arbitration.haltIt := !divider.io.rsp.valid arbitration.haltItself := !divider.io.rsp.valid
input(REGFILE_WRITE_DATA) := Mux(input(INSTRUCTION)(13), divider.io.rsp.remainder, divider.io.rsp.quotient).asBits input(REGFILE_WRITE_DATA) := Mux(input(INSTRUCTION)(13), divider.io.rsp.remainder, divider.io.rsp.quotient).asBits
} }

View File

@ -12,6 +12,6 @@ class HazardPessimisticPlugin() extends Plugin[VexRiscv] {
import pipeline.config._ import pipeline.config._
val writesInPipeline = List(execute,memory,writeBack).map(s => s.arbitration.isValid && s.input(REGFILE_WRITE_VALID)) :+ RegNext(writeBack.arbitration.isValid && writeBack.input(REGFILE_WRITE_VALID)) val writesInPipeline = List(execute,memory,writeBack).map(s => s.arbitration.isValid && s.input(REGFILE_WRITE_VALID)) :+ RegNext(writeBack.arbitration.isValid && writeBack.input(REGFILE_WRITE_VALID))
decode.arbitration.haltIt.setWhen(decode.arbitration.isValid && writesInPipeline.orR) decode.arbitration.haltItself.setWhen(decode.arbitration.isValid && writesInPipeline.orR)
} }
} }

View File

@ -92,7 +92,7 @@ class HazardSimplePlugin(bypassExecute : Boolean,
} }
when(decode.arbitration.isValid && (src0Hazard || src1Hazard)){ when(decode.arbitration.isValid && (src0Hazard || src1Hazard)){
decode.arbitration.haltIt := True decode.arbitration.haltItself := True
} }
} }
} }

View File

@ -70,7 +70,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B
cache.io.cpu.prefetch.isValid := prefetch.arbitration.isValid cache.io.cpu.prefetch.isValid := prefetch.arbitration.isValid
cache.io.cpu.prefetch.isFiring := prefetch.arbitration.isFiring cache.io.cpu.prefetch.isFiring := prefetch.arbitration.isFiring
cache.io.cpu.prefetch.address := prefetch.output(PC) cache.io.cpu.prefetch.address := prefetch.output(PC)
prefetch.arbitration.haltIt setWhen(cache.io.cpu.prefetch.haltIt) prefetch.arbitration.haltItself setWhen(cache.io.cpu.prefetch.haltIt)
//Connect fetch cache side //Connect fetch cache side
cache.io.cpu.fetch.isValid := fetch.arbitration.isValid cache.io.cpu.fetch.isValid := fetch.arbitration.isValid
@ -78,7 +78,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B
if(!twoStageLogic) cache.io.cpu.fetch.isStuckByOthers := fetch.arbitration.isStuckByOthers if(!twoStageLogic) cache.io.cpu.fetch.isStuckByOthers := fetch.arbitration.isStuckByOthers
cache.io.cpu.fetch.address := fetch.output(PC) cache.io.cpu.fetch.address := fetch.output(PC)
if(!twoStageLogic) { if(!twoStageLogic) {
fetch.arbitration.haltIt setWhen (cache.io.cpu.fetch.haltIt) fetch.arbitration.haltItself setWhen (cache.io.cpu.fetch.haltIt)
fetch.insert(INSTRUCTION) := cache.io.cpu.fetch.data fetch.insert(INSTRUCTION) := cache.io.cpu.fetch.data
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION)) decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
decode.insert(INSTRUCTION_READY) := True decode.insert(INSTRUCTION_READY) := True
@ -100,7 +100,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B
if(twoStageLogic){ if(twoStageLogic){
cache.io.cpu.decode.isValid := decode.arbitration.isValid && RegNextWhen(fetch.arbitration.isValid, !decode.arbitration.isStuck) //avoid inserted instruction from debug module cache.io.cpu.decode.isValid := decode.arbitration.isValid && RegNextWhen(fetch.arbitration.isValid, !decode.arbitration.isStuck) //avoid inserted instruction from debug module
decode.arbitration.haltIt.setWhen(cache.io.cpu.decode.haltIt) decode.arbitration.haltItself.setWhen(cache.io.cpu.decode.haltIt)
cache.io.cpu.decode.isStuck := decode.arbitration.isStuck cache.io.cpu.decode.isStuck := decode.arbitration.isStuck
cache.io.cpu.decode.isUser := (if(privilegeService != null) privilegeService.isUser(writeBack) else False) cache.io.cpu.decode.isUser := (if(privilegeService != null) privilegeService.isUser(writeBack) else False)
cache.io.cpu.decode.address := decode.input(PC) cache.io.cpu.decode.address := decode.input(PC)
@ -132,7 +132,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B
cache.io.flush.cmd.valid := True cache.io.flush.cmd.valid := True
when(!cache.io.flush.cmd.ready){ when(!cache.io.flush.cmd.ready){
arbitration.haltIt := True arbitration.haltItself := True
} otherwise { } otherwise {
decode.arbitration.flushAll := True decode.arbitration.flushAll := True
} }

View File

@ -117,7 +117,7 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean)
//Emit iBus.cmd request //Emit iBus.cmd request
iBus.cmd.valid := prefetch.arbitration.isValid && !prefetch.arbitration.removeIt && !prefetch.arbitration.isStuckByOthers && !(pendingCmd && !iBus.rsp.ready) //prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers iBus.cmd.valid := prefetch.arbitration.isValid && !prefetch.arbitration.removeIt && !prefetch.arbitration.isStuckByOthers && !(pendingCmd && !iBus.rsp.ready) //prefetch.arbitration.isValid && !prefetch.arbitration.isStuckByOthers
iBus.cmd.pc := prefetch.output(PC) iBus.cmd.pc := prefetch.output(PC)
prefetch.arbitration.haltIt setWhen (!iBus.cmd.ready || (pendingCmd && !iBus.rsp.ready)) prefetch.arbitration.haltItself setWhen (!iBus.cmd.ready || (pendingCmd && !iBus.rsp.ready))
} }
//Bus rsp buffer //Bus rsp buffer
@ -144,9 +144,9 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean)
fetch.insert(IBUS_ACCESS_ERROR) clearWhen(!fetch.arbitration.isValid) //Avoid interference with instruction injection from the debug plugin fetch.insert(IBUS_ACCESS_ERROR) clearWhen(!fetch.arbitration.isValid) //Avoid interference with instruction injection from the debug plugin
if(interfaceKeepData) if(interfaceKeepData)
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready) fetch.arbitration.haltItself setWhen(fetch.arbitration.isValid && !iBus.rsp.ready)
else else
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready && !rspBuffer.valid) fetch.arbitration.haltItself setWhen(fetch.arbitration.isValid && !iBus.rsp.ready && !rspBuffer.valid)
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION)) decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
decode.insert(INSTRUCTION_READY) := True decode.insert(INSTRUCTION_READY) := True

View File

@ -108,7 +108,7 @@ class MemoryTranslatorPlugin(tlbSize : Int,
port.bus.rsp.allowWrite := cacheLine.allowWrite port.bus.rsp.allowWrite := cacheLine.allowWrite
port.bus.rsp.allowExecute := cacheLine.allowExecute port.bus.rsp.allowExecute := cacheLine.allowExecute
port.bus.rsp.allowUser := cacheLine.allowUser port.bus.rsp.allowUser := cacheLine.allowUser
port.stage.arbitration.haltIt setWhen (port.bus.cmd.isValid && !cacheHit && !sharedMiss) port.stage.arbitration.haltItself setWhen (port.bus.cmd.isValid && !cacheHit && !sharedMiss)
} otherwise { } otherwise {
port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress
port.bus.rsp.allowRead := True port.bus.rsp.allowRead := True

View File

@ -168,7 +168,7 @@ class LightShifterPlugin extends Plugin[VexRiscv]{
when(done){ when(done){
isActive := False isActive := False
} otherwise{ } otherwise{
arbitration.haltIt := True arbitration.haltItself := True
} }
} }
} }

View File

@ -10,6 +10,6 @@ class SingleInstructionLimiterPlugin() extends Plugin[VexRiscv] {
import pipeline._ import pipeline._
import pipeline.config._ import pipeline.config._
prefetch.arbitration.haltItByOther.setWhen(List(fetch,decode,execute,memory,writeBack).map(_.arbitration.isValid).orR) prefetch.arbitration.haltByOther.setWhen(List(fetch,decode,execute,memory,writeBack).map(_.arbitration.isValid).orR)
} }
} }

View File

@ -25,6 +25,7 @@
#include "../common/framework.h" #include "../common/framework.h"
#include "../common/jtag.h" #include "../common/jtag.h"
#include "../common/uart.h"
@ -214,62 +215,6 @@ public:
} }
}; };
class UartRx : public SensitiveProcess{
public:
CData *rx;
uint32_t uartTimeRate;
UartRx(CData *rx, uint32_t uartTimeRate){
this->rx = rx;
this->uartTimeRate = uartTimeRate;
}
enum State {START, DATA, STOP,START_SUCCESS};
State state = START;
uint64_t holdTime = 0;
CData holdValue;
char data;
uint32_t counter;
virtual void tick(uint64_t time){
if(time < holdTime){
if(*rx != holdValue && time + (uartTimeRate>>7) < holdTime){
cout << "UART RX FRAME ERROR at " << time << endl;
holdTime = time;
state = START;
}
}else{
switch(state){
case START:
case START_SUCCESS:
if(state == START_SUCCESS){
cout << data << flush;
state = START;
}
if(*rx == 0 && time > uartTimeRate){
holdTime = time + uartTimeRate;
holdValue = *rx;
state = DATA;
counter = 0;
data = 0;
}
break;
case DATA:
data |= (*rx) << counter++;
if(counter == 8){
state = STOP;
}
holdValue = *rx;
holdTime = time + uartTimeRate;
break;
case STOP:
holdTime = time + uartTimeRate;
holdValue = 1;
state = START_SUCCESS;
break;
}
}
}
};
class VexRiscvTracer : public SimElement{ class VexRiscvTracer : public SimElement{
public: public:
@ -432,12 +377,12 @@ public:
ClockDomain *vgaClk = new ClockDomain(&top->io_vgaClk,NULL,40000,100000); ClockDomain *vgaClk = new ClockDomain(&top->io_vgaClk,NULL,40000,100000);
AsyncReset *asyncReset = new AsyncReset(&top->io_asyncReset,50000); AsyncReset *asyncReset = new AsyncReset(&top->io_asyncReset,50000);
Jtag *jtag = new Jtag(&top->io_jtag_tms,&top->io_jtag_tdi,&top->io_jtag_tdo,&top->io_jtag_tck,80000); Jtag *jtag = new Jtag(&top->io_jtag_tms,&top->io_jtag_tdi,&top->io_jtag_tdo,&top->io_jtag_tck,80000);
UartRx *uartRx = new UartRx(&top->io_uart_txd,(50000000/8/115200)*8*axiClk->tooglePeriod*2); UartRx *uartRx = new UartRx(&top->io_uart_txd,1.0e12/115200);
timeProcesses.push_back(axiClk); timeProcesses.push_back(axiClk);
timeProcesses.push_back(vgaClk); timeProcesses.push_back(vgaClk);
timeProcesses.push_back(asyncReset); timeProcesses.push_back(asyncReset);
timeProcesses.push_back(jtag); timeProcesses.push_back(jtag);
checkProcesses.push_back(uartRx); timeProcesses.push_back(uartRx);
SdramConfig *sdramConfig = new SdramConfig( SdramConfig *sdramConfig = new SdramConfig(
2, //byteCount 2, //byteCount

111
src/test/cpp/common/uart.h Normal file
View File

@ -0,0 +1,111 @@
class UartRx : public TimeProcess{
public:
CData *rx;
uint32_t uartTimeRate;
UartRx(CData *rx, uint32_t uartTimeRate){
this->rx = rx;
this->uartTimeRate = uartTimeRate;
schedule(uartTimeRate);
}
enum State {START, DATA, STOP,START_SUCCESS};
State state = START;
char data;
uint32_t counter;
virtual void tick(){
switch(state){
case START:
if(*rx == 0){
state = DATA;
counter = 0;
data = 0;
schedule(uartTimeRate*5/4);
} else {
schedule(uartTimeRate/4);
}
break;
case DATA:
data |= (*rx) << counter++;
if(counter == 8){
state = STOP;
}
schedule(uartTimeRate);
break;
case STOP:
if(*rx){
cout << data << flush;
} else {
cout << "UART RX FRAME ERROR at " << time << endl;
}
schedule(uartTimeRate/4);
state = START;
break;
}
}
};
/*
class UartRx : public SensitiveProcess{
public:
CData *rx;
uint32_t uartTimeRate;
UartRx(CData *rx, uint32_t uartTimeRate){
this->rx = rx;
this->uartTimeRate = uartTimeRate;
}
enum State {START, DATA, STOP,START_SUCCESS};
State state = START;
uint64_t holdTime = 0;
CData holdValue;
char data;
uint32_t counter;
virtual void tick(uint64_t time){
if(time < holdTime){
if(*rx != holdValue && time + (uartTimeRate>>7) < holdTime){
cout << "UART RX FRAME ERROR at " << time << endl;
holdTime = time;
state = START;
}
}else{
switch(state){
case START:
case START_SUCCESS:
if(state == START_SUCCESS){
cout << data << flush;
state = START;
}
if(*rx == 0 && time > uartTimeRate){
holdTime = time + uartTimeRate;
holdValue = *rx;
state = DATA;
counter = 0;
data = 0;
}
break;
case DATA:
data |= (*rx) << counter++;
if(counter == 8){
state = STOP;
}
holdValue = *rx;
holdTime = time + uartTimeRate;
break;
case STOP:
holdTime = time + uartTimeRate;
holdValue = 1;
state = START_SUCCESS;
break;
}
}
}
};*/

View File

@ -5,15 +5,18 @@
#include "../common/framework.h" #include "../common/framework.h"
#include "../common/jtag.h" #include "../common/jtag.h"
#include "../common/uart.h"
class MuraxWorkspace : public Workspace<VMurax>{ class MuraxWorkspace : public Workspace<VMurax>{
public: public:
MuraxWorkspace() : Workspace("Murax"){ MuraxWorkspace() : Workspace("Murax"){
ClockDomain *mainClk = new ClockDomain(&top->io_mainClk,NULL,83333,300000); ClockDomain *mainClk = new ClockDomain(&top->io_mainClk,NULL,83333,300000);
AsyncReset *asyncReset = new AsyncReset(&top->io_asyncReset,50000); AsyncReset *asyncReset = new AsyncReset(&top->io_asyncReset,50000);
UartRx *uartRx = new UartRx(&top->io_uart_txd,1.0e12/115200);
timeProcesses.push_back(mainClk); timeProcesses.push_back(mainClk);
timeProcesses.push_back(asyncReset); timeProcesses.push_back(asyncReset);
timeProcesses.push_back(uartRx);
Jtag *jtag = new Jtag(&top->io_jtag_tms,&top->io_jtag_tdi,&top->io_jtag_tdo,&top->io_jtag_tck,83333*4); Jtag *jtag = new Jtag(&top->io_jtag_tms,&top->io_jtag_tdi,&top->io_jtag_tdo,&top->io_jtag_tck,83333*4);
timeProcesses.push_back(jtag); timeProcesses.push_back(jtag);

View File

@ -421,7 +421,7 @@ public:
for(SimElement* simElement : simElements) simElement->preCycle(); for(SimElement* simElement : simElements) simElement->preCycle();
if(withInstructionReadCheck){ if(withInstructionReadCheck){
if(top->VexRiscv->decode_arbitration_isValid && !top->VexRiscv->decode_arbitration_haltIt){ if(top->VexRiscv->decode_arbitration_isValid && !top->VexRiscv->decode_arbitration_haltItself){
uint32_t expectedData; uint32_t expectedData;
bool dummy; bool dummy;
iBusAccess(top->VexRiscv->decode_PC, &expectedData, &dummy); iBusAccess(top->VexRiscv->decode_PC, &expectedData, &dummy);