mirror of
https://github.com/SpinalHDL/VexRiscv.git
synced 2025-01-03 03:43:39 -05:00
Fix DataCache bug (interaction between the victim buffer and the memory read request in execute/memory stages)
freeRTOS pass
This commit is contained in:
parent
9fe4e1d54d
commit
6d117f5c81
4 changed files with 2435 additions and 2351 deletions
|
@ -277,7 +277,7 @@ object TestsWorkspace {
|
|||
}*/
|
||||
// toplevel.writeBack.input(config.PC).addAttribute(Verilator.public)
|
||||
// toplevel.service(classOf[DecoderSimplePlugin]).bench(toplevel)
|
||||
|
||||
// toplevel.children.find(_.isInstanceOf[DataCache]).get.asInstanceOf[DataCache].io.cpu.execute.addAttribute(Verilator.public)
|
||||
toplevel
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ object Bypasser{
|
|||
}
|
||||
|
||||
|
||||
//shot readValid path
|
||||
//short readValid path
|
||||
def writeFirstMemWrap(readValid : Bool, readLastAddress : UInt, readLastData : Bits,writeValid : Bool, writeAddress : UInt, writeData : Bits,writeMask : Bits) : Bits = {
|
||||
val writeHit = writeValid && writeAddress === readLastAddress
|
||||
val writeSample = readValid || writeHit
|
||||
|
@ -412,6 +412,8 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
}
|
||||
|
||||
|
||||
val cpuMemoryStageNeedReadData = Bool()
|
||||
|
||||
val victim = new Area{
|
||||
val requestIn = Stream(cloneable(new Bundle{
|
||||
// val way = UInt(log2Up(wayCount) bits)
|
||||
|
@ -438,7 +440,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
dataReadCmd.payload := request.address(lineRange) @@ readLineCmdCounter(readLineCmdCounter.high - 1 downto 0)
|
||||
way.dataReadRspOneKeepAddress := True
|
||||
} otherwise {
|
||||
when(!dataReadRestored) {
|
||||
when(!dataReadRestored && cpuMemoryStageNeedReadData) {
|
||||
dataReadCmd.valid := True
|
||||
dataReadCmd.payload := way.dataReadRspOneAddress //Restore stage one readed value
|
||||
}
|
||||
|
@ -447,6 +449,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
}
|
||||
|
||||
dataReadRestored clearWhen(request.ready)
|
||||
io.cpu.memory.haltIt := cpuMemoryStageNeedReadData && request.valid && !dataReadRestored
|
||||
|
||||
//Fill the buffer with line read responses
|
||||
val readLineRspCounter = Reg(UInt(log2Up(memTransactionPerLine + 1) bits)) init(0)
|
||||
|
@ -503,8 +506,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
io.cpu.memory.mmuBus.cmd.isValid := io.cpu.memory.isValid && request.kind === MEMORY //TODO filter request kind
|
||||
io.cpu.memory.mmuBus.cmd.virtualAddress := request.address
|
||||
io.cpu.memory.mmuBus.cmd.bypassTranslation := request.way
|
||||
|
||||
io.cpu.memory.haltIt := io.cpu.memory.isValid && request.kind === MEMORY && !request.wr && victim.request.valid && !victim.dataReadRestored
|
||||
cpuMemoryStageNeedReadData := io.cpu.memory.isValid && request.kind === MEMORY && !request.wr
|
||||
}
|
||||
|
||||
val stageB = new Area {
|
||||
|
@ -567,7 +569,7 @@ class DataCache(p : DataCacheConfig) extends Component{
|
|||
when(delayedIsStuck && !mmuRsp.miss) {
|
||||
when(delayedWaysHitValid || (request.way && way.tagReadRspTwo.used)) {
|
||||
io.cpu.writeBack.haltIt.clearWhen(!(victim.requestIn.valid && !victim.requestIn.ready))
|
||||
victim.requestIn.valid := request.clean && way.tagReadRspTwo.dirty
|
||||
victim.requestIn.valid := request.clean && way.tagReadRspTwo.dirty
|
||||
tagsWriteCmd.valid := victim.requestIn.ready
|
||||
} otherwise{
|
||||
io.cpu.writeBack.haltIt := False
|
||||
|
|
|
@ -746,6 +746,9 @@ public:
|
|||
|
||||
|
||||
#ifdef DBUS_CACHED
|
||||
|
||||
//#include "VVexRiscv_DataCache.h"
|
||||
|
||||
class DBusCached : public SimElement{
|
||||
public:
|
||||
uint32_t address;
|
||||
|
@ -766,6 +769,23 @@ public:
|
|||
}
|
||||
|
||||
virtual void preCycle(){
|
||||
VL_IN8(io_cpu_execute_isValid,0,0);
|
||||
VL_IN8(io_cpu_execute_isStuck,0,0);
|
||||
VL_IN8(io_cpu_execute_args_kind,0,0);
|
||||
VL_IN8(io_cpu_execute_args_wr,0,0);
|
||||
VL_IN8(io_cpu_execute_args_size,1,0);
|
||||
VL_IN8(io_cpu_execute_args_forceUncachedAccess,0,0);
|
||||
VL_IN8(io_cpu_execute_args_clean,0,0);
|
||||
VL_IN8(io_cpu_execute_args_invalidate,0,0);
|
||||
VL_IN8(io_cpu_execute_args_way,0,0);
|
||||
|
||||
// if(top->VexRiscv->dataCache_1->io_cpu_execute_isValid && !top->VexRiscv->dataCache_1->io_cpu_execute_isStuck
|
||||
// && top->VexRiscv->dataCache_1->io_cpu_execute_args_wr){
|
||||
// if(top->VexRiscv->dataCache_1->io_cpu_execute_args_address == 0x80025978)
|
||||
// cout << "WR 0x80025978 = " << hex << setw(8) << top->VexRiscv->dataCache_1->io_cpu_execute_args_data << endl;
|
||||
// if(top->VexRiscv->dataCache_1->io_cpu_execute_args_address == 0x8002596c)
|
||||
// cout << "WR 0x8002596c = " << hex << setw(8) << top->VexRiscv->dataCache_1->io_cpu_execute_args_data << endl;
|
||||
// }
|
||||
if (top->dBus_cmd_valid && top->dBus_cmd_ready) {
|
||||
if(pendingCount == 0){
|
||||
pendingCount = top->dBus_cmd_payload_length+1;
|
||||
|
@ -1583,6 +1603,9 @@ int main(int argc, char **argv, char **env) {
|
|||
Workspace w("debugPluginExternal");
|
||||
w.loadHex("../../resources/hex/debugPluginExternal.hex");
|
||||
w.noInstructionReadCheck();
|
||||
//w.setIStall(false);
|
||||
//w.setDStall(false);
|
||||
|
||||
#if defined(TRACE) || defined(TRACE_ACCESS)
|
||||
//w.setCyclesPerSecond(5e3);
|
||||
//printf("Speed reduced 5Khz\n");
|
||||
|
@ -1593,7 +1616,7 @@ int main(int argc, char **argv, char **env) {
|
|||
|
||||
|
||||
|
||||
TestA().run();
|
||||
redo(REDO,TestA().run();)
|
||||
|
||||
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue