From 665c244ba1767834f98adea6839d97ae59ca94f9 Mon Sep 17 00:00:00 2001 From: Jarred Allen Date: Sat, 20 Mar 2021 17:54:40 -0400 Subject: [PATCH] Fix another bug in the icache (why so many of them?) --- wally-pipelined/src/ifu/icache.sv | 12 ++++++++---- wally-pipelined/testbench/testbench-imperas.sv | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index bef900088..29fef63d4 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -48,10 +48,14 @@ module icache( logic LastReadDataValidF; logic [`XLEN-1:0] LastReadDataF, LastReadAdrF, InDataF; + // This flop doesn't stall if StallF is high because we should output a nop + // when FlushD happens, even if the pipeline is also stalled. flopr #(1) flushDLastCycleFlop(clk, reset, FlushD | (FlushDLastCycle & StallF), FlushDLastCycle); - flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF, DelayD); + + flopenr #(1) delayDFlop(clk, reset, ~StallF, DelayF & ~CompressedF, DelayD); flopenr #(1) delaySideDFlop(clk, reset, ~StallF, DelaySideF, DelaySideD); flopenrc#(1) delayStateFlop(clk, reset, FlushD, ~StallF, DelayF & ~DelaySideF, DelaySideF); + // This flop stores the first half of a misaligned instruction while waiting for the other half flopenr #(16) halfInstrFlop(clk, reset, DelayF & ~StallF, MisalignedHalfInstrF, MisalignedHalfInstrD); // This flop is here to simulate pulling data out of the cache, which is edge-triggered @@ -68,7 +72,7 @@ module icache( // and then the upper word, in that order. generate if (`XLEN == 32) begin - assign InstrPAdrF = PCPF[1] ? ((DelaySideF & ~CompressedF) ? {PCPF[31:2]+1, 2'b00} : {PCPF[31:2], 2'b00}) : PCPF; + assign InstrPAdrF = PCPF[1] ? ((DelaySideF & ~CompressedF) ? {PCPF[31:2], 2'b00} : {PCPF[31:2], 2'b00}) : PCPF; end else begin assign InstrPAdrF = PCPF[2] ? (PCPF[1] ? ((DelaySideF & ~CompressedF) ? {PCPF[63:3]+1, 3'b000} : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000}) : {PCPF[63:3], 3'b000}; end @@ -101,7 +105,7 @@ module icache( assign ICacheStallF = 0; //DelayF & ~DelaySideF; // Detect if the instruction is compressed - assign CompressedF = (DelaySideF & DelayF) ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); + assign CompressedF = (DelayD) ? (MisalignedHalfInstrD[1:0] != 2'b11) : (InstrF[1:0] != 2'b11); // Pick the correct output, depending on whether we have to assemble this // instruction from two reads or not. @@ -113,7 +117,7 @@ module icache( end else if (DelayD & (MisalignedHalfInstrD[1:0] != 2'b11)) begin assign InstrDMuxChoice = 2'b11; end else begin - assign InstrDMuxChoice = {1'b0, DelaySideF}; + assign InstrDMuxChoice = {1'b0, DelayD}; end mux4 #(32) instrDMux (AlignedInstrD, {InstrInF[15:0], MisalignedHalfInstrD}, nop, {16'b0, MisalignedHalfInstrD}, InstrDMuxChoice, InstrRawD); endmodule diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 8b128b17a..1060d8cbc 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -349,7 +349,7 @@ string tests32i[] = { end else begin // RV32 // *** add the 32 bit bp tests tests = {tests32i}; - if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; + if (`C_SUPPORTED % 2 == 1) tests = {tests32ic, tests}; else tests = {tests, tests32iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; if (`A_SUPPORTED) tests = {tests, tests32a};