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_G16 G16
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[1] B4
set_io io_led[2] A2

View File

@ -6,6 +6,8 @@ module toplevel(
input io_G15,
output io_G16,
input io_F15,
output io_B12,
input io_B10,
output [7:0] io_led
);
@ -36,6 +38,8 @@ module toplevel(
.io_jtag_tms(io_F15),
.io_gpioA_read (io_gpioA_read),
.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

View File

@ -117,8 +117,8 @@ trait Pipeline {
}
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.isStuck := stage.arbitration.haltIt || stage.arbitration.isStuckByOthers
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.haltItself || stage.arbitration.isStuckByOthers
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 haltIt = False
val haltItByOther = False
val removeIt = False
val flushAll = False
val isValid = RegInit(False)
val isStuck = Bool
val isFlushed = Bool
val isStuckByOthers = Bool
val isFiring = Bool
val haltItself = False //user settable, stuck the instruction, should only be set by the instruction itself
val haltByOther = False //When settable, stuck the instruction, should only be set by something else than the stucked instruction
val removeIt = False //When settable, unschedule the instruction as if it was never executed (no side effect)
val flushAll = False //When settable, unschedule instructions in the current stage and all prior ones
val isValid = RegInit(False) //Inform if a instruction is in the current stage
val isStuck = Bool //Inform if the instruction is stuck (haltItself || haltByOther)
val isStuckByOthers = Bool //Inform if the instruction is stuck by sombody else
def isRemoved = removeIt //Inform if the instruction is going to be unschedule the current cycle
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(
new PcManagerSimplePlugin(
resetVector = 0x00000000l,
relaxedPcCalculation = true
relaxedPcCalculation = false
),
new IBusSimplePlugin(
interfaceKeepData = false,
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 IBusSimplePlugin(
// interfaceKeepData = false,
// catchAccessFault = true
// ),
new DBusSimplePlugin(
catchAddressMisaligned = true,
catchAccessFault = true,
earlyInjection = false
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 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 DBusSimplePlugin(
// catchAddressMisaligned = true,
// catchAccessFault = true,
// earlyInjection = false
// ),
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(
// ioRange = _(31 downto 28) === 0xF
// ),
// new MemoryTranslatorPlugin(
// tlbSize = 32,
// virtualRange = _(31 downto 28) === 0xC,
// ioRange = _(31 downto 28) === 0xF
// ),
new MemoryTranslatorPlugin(
tlbSize = 32,
virtualRange = _(31 downto 28) === 0xC,
ioRange = _(31 downto 28) === 0xF
),
new DecoderSimplePlugin(
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.PC).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.PC) 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.misc.SizeMapping
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.misc.{InterruptCtrl, Timer, Prescaler}
import spinal.lib.soc.pinsec.{PinsecTimerCtrlExternal, PinsecTimerCtrl}
@ -24,6 +24,7 @@ import vexriscv.{plugin, VexRiscvConfig, VexRiscv}
* - APB bus for peripherals
* - 32 GPIO pin
* - 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
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
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 apb = Apb3(
addressWidth = 8,
@ -380,6 +403,7 @@ case class Murax(config : MuraxConfig) extends Component{
master = apbBridge.apb,
slaves = List(
gpioACtrl.io.apb -> (0x00000, 4 kB),
uartCtrl.io.apb -> (0x10000, 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)
val pipelineLiberator = new Area{
val enable = False
prefetch.arbitration.haltItByOther setWhen(enable)
prefetch.arbitration.haltByOther setWhen(enable)
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
when(memory.input(ENV_CTRL) === EnvCtrlEnum.MRET) {
memory.arbitration.haltIt := writeBack.arbitration.isValid
memory.arbitration.haltItself := writeBack.arbitration.isValid
when(memory.arbitration.isFiring) {
jumpInterface.valid := True
jumpInterface.payload := mepc
@ -432,7 +432,7 @@ class CsrPlugin(config : CsrPluginConfig) extends Plugin[VexRiscv] with Exceptio
//Manage WFI instructions
if(wfiGen) when(execute.arbitration.isValid && execute.input(ENV_CTRL) === EnvCtrlEnum.WFI){
when(!interrupt){
execute.arbitration.haltIt := True
execute.arbitration.haltItself := 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)))
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
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.isStuck := arbitration.isStuck
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
}
@ -148,7 +148,7 @@ class DBusCachedPlugin(config : DataCacheConfig, memoryTranslatorPortConfig : An
exceptionBus.code := 13
}
}
arbitration.haltIt.setWhen(cache.io.cpu.writeBack.haltIt)
arbitration.haltItself.setWhen(cache.io.cpu.writeBack.haltIt)
val rspShifted = Bits(32 bits)
rspShifted := cache.io.cpu.writeBack.data

View File

@ -210,7 +210,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
default -> input(RS2)(31 downto 0)
)
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)
@ -222,7 +222,7 @@ class DBusSimplePlugin(catchAddressMisaligned : Boolean, catchAccessFault : Bool
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){

View File

@ -161,7 +161,7 @@ class DebugPlugin(val debugClockDomain : ClockDomain) extends Plugin[VexRiscv] {
when(io.bus.cmd.wr) {
insertDecodeInstruction := True
decode.arbitration.isValid setWhen (firstCycle)
decode.arbitration.haltIt setWhen (secondCycle)
decode.arbitration.haltItself setWhen (secondCycle)
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)) {
prefetch.arbitration.haltItByOther := True
prefetch.arbitration.haltByOther := True
decode.arbitration.flushAll := True
haltIt := True
haltedByBreak := True
}
when(haltIt) {
prefetch.arbitration.haltItByOther := True
prefetch.arbitration.haltByOther := True
}
when(stepIt && prefetch.arbitration.isFiring) {

View File

@ -47,7 +47,7 @@ class DivPlugin extends Plugin[VexRiscv]{
when(arbitration.isValid && input(IS_DIV)) {
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
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
}

View File

@ -12,6 +12,6 @@ class HazardPessimisticPlugin() extends Plugin[VexRiscv] {
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))
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)){
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.isFiring := prefetch.arbitration.isFiring
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
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
cache.io.cpu.fetch.address := fetch.output(PC)
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
decode.insert(INSTRUCTION_ANTICIPATED) := Mux(decode.arbitration.isStuck,decode.input(INSTRUCTION),fetch.output(INSTRUCTION))
decode.insert(INSTRUCTION_READY) := True
@ -100,7 +100,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B
if(twoStageLogic){
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.isUser := (if(privilegeService != null) privilegeService.isUser(writeBack) else False)
cache.io.cpu.decode.address := decode.input(PC)
@ -132,7 +132,7 @@ class IBusCachedPlugin(config : InstructionCacheConfig, askMemoryTranslation : B
cache.io.flush.cmd.valid := True
when(!cache.io.flush.cmd.ready){
arbitration.haltIt := True
arbitration.haltItself := True
} otherwise {
decode.arbitration.flushAll := True
}

View File

@ -117,7 +117,7 @@ class IBusSimplePlugin(interfaceKeepData : Boolean, catchAccessFault : Boolean)
//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.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
@ -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
if(interfaceKeepData)
fetch.arbitration.haltIt setWhen(fetch.arbitration.isValid && !iBus.rsp.ready)
fetch.arbitration.haltItself setWhen(fetch.arbitration.isValid && !iBus.rsp.ready)
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_READY) := True

View File

@ -108,7 +108,7 @@ class MemoryTranslatorPlugin(tlbSize : Int,
port.bus.rsp.allowWrite := cacheLine.allowWrite
port.bus.rsp.allowExecute := cacheLine.allowExecute
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 {
port.bus.rsp.physicalAddress := port.bus.cmd.virtualAddress
port.bus.rsp.allowRead := True

View File

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

View File

@ -10,6 +10,6 @@ class SingleInstructionLimiterPlugin() extends Plugin[VexRiscv] {
import pipeline._
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/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{
public:
@ -432,12 +377,12 @@ public:
ClockDomain *vgaClk = new ClockDomain(&top->io_vgaClk,NULL,40000,100000);
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);
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(vgaClk);
timeProcesses.push_back(asyncReset);
timeProcesses.push_back(jtag);
checkProcesses.push_back(uartRx);
timeProcesses.push_back(uartRx);
SdramConfig *sdramConfig = new SdramConfig(
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/jtag.h"
#include "../common/uart.h"
class MuraxWorkspace : public Workspace<VMurax>{
public:
MuraxWorkspace() : Workspace("Murax"){
ClockDomain *mainClk = new ClockDomain(&top->io_mainClk,NULL,83333,300000);
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(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);
timeProcesses.push_back(jtag);

View File

@ -421,7 +421,7 @@ public:
for(SimElement* simElement : simElements) simElement->preCycle();
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;
bool dummy;
iBusAccess(top->VexRiscv->decode_PC, &expectedData, &dummy);