1. Modified the cache so it can handle the reset delay internally. This removes the mux from the IFU.

2. Removed the write address delay from simpleram.sv
3. Fixed rv32tim and rv32ic mode to handle missalignment correctly.
4. Added imperas32i and imperas32c to rv32tim mode.
This commit is contained in:
Ross Thompson 2022-01-26 17:37:04 -06:00
parent 2c982dca03
commit 23c4ba2777
6 changed files with 62 additions and 86 deletions

View File

@ -68,7 +68,7 @@ for test in tests32gc:
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
tests32ic = ["arch32i", "arch32c"] tests32ic = ["arch32i", "arch32c", "imperas32i", "imperas32c"]
for test in tests32ic: for test in tests32ic:
tc = TestCase( tc = TestCase(
name=test, name=test,
@ -77,7 +77,7 @@ for test in tests32ic:
grepstr="All tests ran without failures") grepstr="All tests ran without failures")
configs.append(tc) configs.append(tc)
tests32tim = ["arch32i", "arch32c"] tests32tim = ["arch32i", "arch32c", "imperas32i", "imperas32c"]
for test in tests32tim: for test in tests32tim:
tc = TestCase( tc = TestCase(
name=test, name=test,

View File

@ -79,6 +79,8 @@ module cachefsm
); );
logic AnyCPUReqM; logic AnyCPUReqM;
logic [1:0] PreSelAdr;
logic resetDelay;
typedef enum {STATE_READY, typedef enum {STATE_READY,
@ -107,6 +109,12 @@ module cachefsm
assign CacheAccess = AnyCPUReqM & CurrState == STATE_READY; assign CacheAccess = AnyCPUReqM & CurrState == STATE_READY;
assign CacheMiss = CacheAccess & ~CacheHit; assign CacheMiss = CacheAccess & ~CacheHit;
// special case on reset. When the fsm first exists reset the
// PCNextF will no longer be pointing to the correct address.
// But PCF will be the reset vector.
flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay));
assign SelAdr = resetDelay ? 2'b01 : PreSelAdr;
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset) CurrState <= #1 STATE_READY; if (reset) CurrState <= #1 STATE_READY;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
@ -114,7 +122,7 @@ module cachefsm
// next state logic and some state ouputs. // next state logic and some state ouputs.
always_comb begin always_comb begin
CacheStall = 1'b0; CacheStall = 1'b0;
SelAdr = 2'b00; PreSelAdr = 2'b00;
SetValid = 1'b0; SetValid = 1'b0;
ClearValid = 1'b0; ClearValid = 1'b0;
SetDirty = 1'b0; SetDirty = 1'b0;
@ -137,7 +145,7 @@ module cachefsm
STATE_READY: begin STATE_READY: begin
CacheStall = 1'b0; CacheStall = 1'b0;
SelAdr = 2'b00; PreSelAdr = 2'b00;
SRAMWordWriteEnable = 1'b0; SRAMWordWriteEnable = 1'b0;
SetDirty = 1'b0; SetDirty = 1'b0;
LRUWriteEn = 1'b0; LRUWriteEn = 1'b0;
@ -150,7 +158,7 @@ module cachefsm
// PTW ready the CPU will stall. // PTW ready the CPU will stall.
// The page table walker asserts it's control 1 cycle // The page table walker asserts it's control 1 cycle
// after the TLBs miss. // after the TLBs miss.
SelAdr = 2'b01; PreSelAdr = 2'b01;
NextState = STATE_READY; NextState = STATE_READY;
end end
@ -164,12 +172,12 @@ module cachefsm
// amo hit // amo hit
else if(Atomic[1] & (&RW) & CacheHit) begin else if(Atomic[1] & (&RW) & CacheHit) begin
SelAdr = 2'b01; PreSelAdr = 2'b01;
CacheStall = 1'b0; CacheStall = 1'b0;
if(CPUBusy) begin if(CPUBusy) begin
NextState = STATE_CPU_BUSY_FINISH_AMO; NextState = STATE_CPU_BUSY_FINISH_AMO;
SelAdr = 2'b01; PreSelAdr = 2'b01;
end end
else begin else begin
SRAMWordWriteEnable = 1'b1; SRAMWordWriteEnable = 1'b1;
@ -185,7 +193,7 @@ module cachefsm
if(CPUBusy) begin if(CPUBusy) begin
NextState = STATE_CPU_BUSY; NextState = STATE_CPU_BUSY;
SelAdr = 2'b01; PreSelAdr = 2'b01;
end end
else begin else begin
NextState = STATE_READY; NextState = STATE_READY;
@ -193,7 +201,7 @@ module cachefsm
end end
// write hit valid cached // write hit valid cached
else if (RW[0] & CacheHit) begin else if (RW[0] & CacheHit) begin
SelAdr = 2'b01; PreSelAdr = 2'b01;
CacheStall = 1'b0; CacheStall = 1'b0;
SRAMWordWriteEnable = 1'b1; SRAMWordWriteEnable = 1'b1;
SetDirty = 1'b1; SetDirty = 1'b1;
@ -201,7 +209,7 @@ module cachefsm
if(CPUBusy) begin if(CPUBusy) begin
NextState = STATE_CPU_BUSY; NextState = STATE_CPU_BUSY;
SelAdr = 2'b01; PreSelAdr = 2'b01;
end end
else begin else begin
NextState = STATE_READY; NextState = STATE_READY;
@ -218,7 +226,7 @@ module cachefsm
STATE_MISS_FETCH_WDV: begin STATE_MISS_FETCH_WDV: begin
CacheStall = 1'b1; CacheStall = 1'b1;
SelAdr = 2'b01; PreSelAdr = 2'b01;
if (CacheBusAck) begin if (CacheBusAck) begin
NextState = STATE_MISS_FETCH_DONE; NextState = STATE_MISS_FETCH_DONE;
@ -229,7 +237,7 @@ module cachefsm
STATE_MISS_FETCH_DONE: begin STATE_MISS_FETCH_DONE: begin
CacheStall = 1'b1; CacheStall = 1'b1;
SelAdr = 2'b01; PreSelAdr = 2'b01;
if(VictimDirty) begin if(VictimDirty) begin
NextState = STATE_MISS_EVICT_DIRTY; NextState = STATE_MISS_EVICT_DIRTY;
CacheWriteLine = 1'b1; CacheWriteLine = 1'b1;
@ -242,14 +250,14 @@ module cachefsm
SRAMLineWriteEnable = 1'b1; SRAMLineWriteEnable = 1'b1;
CacheStall = 1'b1; CacheStall = 1'b1;
NextState = STATE_MISS_READ_WORD; NextState = STATE_MISS_READ_WORD;
SelAdr = 2'b01; PreSelAdr = 2'b01;
SetValid = 1'b1; SetValid = 1'b1;
ClearDirty = 1'b1; ClearDirty = 1'b1;
//LRUWriteEn = 1'b1; // DO not update LRU on SRAM fetch update. Wait for subsequent read/write //LRUWriteEn = 1'b1; // DO not update LRU on SRAM fetch update. Wait for subsequent read/write
end end
STATE_MISS_READ_WORD: begin STATE_MISS_READ_WORD: begin
SelAdr = 2'b01; PreSelAdr = 2'b01;
CacheStall = 1'b1; CacheStall = 1'b1;
if (RW[0] & ~Atomic[1]) begin // handles stores and amo write. if (RW[0] & ~Atomic[1]) begin // handles stores and amo write.
NextState = STATE_MISS_WRITE_WORD; NextState = STATE_MISS_WRITE_WORD;
@ -261,12 +269,12 @@ module cachefsm
end end
STATE_MISS_READ_WORD_DELAY: begin STATE_MISS_READ_WORD_DELAY: begin
//SelAdr = 2'b01; //PreSelAdr = 2'b01;
SRAMWordWriteEnable = 1'b0; SRAMWordWriteEnable = 1'b0;
SetDirty = 1'b0; SetDirty = 1'b0;
LRUWriteEn = 1'b0; LRUWriteEn = 1'b0;
if(&RW & Atomic[1]) begin // amo write if(&RW & Atomic[1]) begin // amo write
SelAdr = 2'b01; PreSelAdr = 2'b01;
if(CPUBusy) begin if(CPUBusy) begin
NextState = STATE_CPU_BUSY_FINISH_AMO; NextState = STATE_CPU_BUSY_FINISH_AMO;
end end
@ -280,7 +288,7 @@ module cachefsm
LRUWriteEn = 1'b1; LRUWriteEn = 1'b1;
if(CPUBusy) begin if(CPUBusy) begin
NextState = STATE_CPU_BUSY; NextState = STATE_CPU_BUSY;
SelAdr = 2'b01; PreSelAdr = 2'b01;
end end
else begin else begin
NextState = STATE_READY; NextState = STATE_READY;
@ -291,11 +299,11 @@ module cachefsm
STATE_MISS_WRITE_WORD: begin STATE_MISS_WRITE_WORD: begin
SRAMWordWriteEnable = 1'b1; SRAMWordWriteEnable = 1'b1;
SetDirty = 1'b1; SetDirty = 1'b1;
SelAdr = 2'b01; PreSelAdr = 2'b01;
LRUWriteEn = 1'b1; LRUWriteEn = 1'b1;
if(CPUBusy) begin if(CPUBusy) begin
NextState = STATE_CPU_BUSY; NextState = STATE_CPU_BUSY;
SelAdr = 2'b01; PreSelAdr = 2'b01;
end end
else begin else begin
NextState = STATE_READY; NextState = STATE_READY;
@ -304,7 +312,7 @@ module cachefsm
STATE_MISS_EVICT_DIRTY: begin STATE_MISS_EVICT_DIRTY: begin
CacheStall = 1'b1; CacheStall = 1'b1;
SelAdr = 2'b01; PreSelAdr = 2'b01;
SelEvict = 1'b1; SelEvict = 1'b1;
if(CacheBusAck) begin if(CacheBusAck) begin
NextState = STATE_MISS_WRITE_CACHE_LINE; NextState = STATE_MISS_WRITE_CACHE_LINE;
@ -315,10 +323,10 @@ module cachefsm
STATE_CPU_BUSY: begin STATE_CPU_BUSY: begin
SelAdr = 2'b00; PreSelAdr = 2'b00;
if(CPUBusy) begin if(CPUBusy) begin
NextState = STATE_CPU_BUSY; NextState = STATE_CPU_BUSY;
SelAdr = 2'b01; PreSelAdr = 2'b01;
end end
else begin else begin
NextState = STATE_READY; NextState = STATE_READY;
@ -326,7 +334,7 @@ module cachefsm
end end
STATE_CPU_BUSY_FINISH_AMO: begin STATE_CPU_BUSY_FINISH_AMO: begin
SelAdr = 2'b01; PreSelAdr = 2'b01;
SRAMWordWriteEnable = 1'b0; SRAMWordWriteEnable = 1'b0;
SetDirty = 1'b0; SetDirty = 1'b0;
LRUWriteEn = 1'b0; LRUWriteEn = 1'b0;
@ -345,13 +353,13 @@ module cachefsm
// intialize flush counters // intialize flush counters
SelFlush = 1'b1; SelFlush = 1'b1;
CacheStall = 1'b1; CacheStall = 1'b1;
SelAdr = 2'b10; PreSelAdr = 2'b10;
NextState = STATE_FLUSH_CHECK; NextState = STATE_FLUSH_CHECK;
end end
STATE_FLUSH_CHECK: begin STATE_FLUSH_CHECK: begin
CacheStall = 1'b1; CacheStall = 1'b1;
SelAdr = 2'b10; PreSelAdr = 2'b10;
SelFlush = 1'b1; SelFlush = 1'b1;
if(VictimDirty) begin if(VictimDirty) begin
NextState = STATE_FLUSH_WRITE_BACK; NextState = STATE_FLUSH_WRITE_BACK;
@ -360,7 +368,7 @@ module cachefsm
end else if (FlushAdrFlag & FlushWayFlag) begin end else if (FlushAdrFlag & FlushWayFlag) begin
NextState = STATE_READY; NextState = STATE_READY;
CacheStall = 1'b0; CacheStall = 1'b0;
SelAdr = 2'b00; PreSelAdr = 2'b00;
FlushWayCntEn = 1'b0; FlushWayCntEn = 1'b0;
end else if(FlushWayFlag) begin end else if(FlushWayFlag) begin
NextState = STATE_FLUSH_INCR; NextState = STATE_FLUSH_INCR;
@ -375,7 +383,7 @@ module cachefsm
STATE_FLUSH_INCR: begin STATE_FLUSH_INCR: begin
CacheStall = 1'b1; CacheStall = 1'b1;
SelAdr = 2'b10; PreSelAdr = 2'b10;
SelFlush = 1'b1; SelFlush = 1'b1;
FlushWayCntRst = 1'b1; FlushWayCntRst = 1'b1;
NextState = STATE_FLUSH_CHECK; NextState = STATE_FLUSH_CHECK;
@ -383,7 +391,7 @@ module cachefsm
STATE_FLUSH_WRITE_BACK: begin STATE_FLUSH_WRITE_BACK: begin
CacheStall = 1'b1; CacheStall = 1'b1;
SelAdr = 2'b10; PreSelAdr = 2'b10;
SelFlush = 1'b1; SelFlush = 1'b1;
if(CacheBusAck) begin if(CacheBusAck) begin
NextState = STATE_FLUSH_CLEAR_DIRTY; NextState = STATE_FLUSH_CLEAR_DIRTY;
@ -397,12 +405,12 @@ module cachefsm
ClearDirty = 1'b1; ClearDirty = 1'b1;
VDWriteEnable = 1'b1; VDWriteEnable = 1'b1;
SelFlush = 1'b1; SelFlush = 1'b1;
SelAdr = 2'b10; PreSelAdr = 2'b10;
FlushWayCntEn = 1'b0; FlushWayCntEn = 1'b0;
if(FlushAdrFlag & FlushWayFlag) begin if(FlushAdrFlag & FlushWayFlag) begin
NextState = STATE_READY; NextState = STATE_READY;
CacheStall = 1'b0; CacheStall = 1'b0;
SelAdr = 2'b00; PreSelAdr = 2'b00;
end else if (FlushWayFlag) begin end else if (FlushWayFlag) begin
NextState = STATE_FLUSH_INCR; NextState = STATE_FLUSH_INCR;
FlushAdrCntEn = 1'b1; FlushAdrCntEn = 1'b1;

View File

@ -39,20 +39,17 @@ module simpleram #(parameter BASE=0, RANGE = 65535) (
); );
logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)]; logic [`XLEN-1:0] RAM[BASE>>(1+`XLEN/32):(RANGE+BASE)>>1+(`XLEN/32)];
logic [31:0] ad;
flop #(32) areg(clk, a, ad); // *** redesign external interface so this delay isn't needed
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
if (`XLEN == 64) begin:ramrw if (`XLEN == 64) begin:ramrw
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
rd <= RAM[a[31:3]]; rd <= RAM[a[31:3]];
if (we) RAM[ad[31:3]] <= #1 wd; if (we) RAM[a[31:3]] <= #1 wd;
end end
end else begin end else begin
always_ff @(posedge clk) begin:ramrw always_ff @(posedge clk) begin:ramrw
rd <= RAM[a[31:2]]; rd <= RAM[a[31:2]];
if (we) RAM[ad[31:2]] <= #1 wd; if (we) RAM[a[31:2]] <= #1 wd;
end end
end end
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */

View File

@ -232,12 +232,10 @@ module ifu (
if (`MEM_IROM) begin : irom if (`MEM_IROM) begin : irom
logic [`XLEN-1:0] FinalInstrRawF_FIXME; logic [`XLEN-1:0] FinalInstrRawF_FIXME;
// *** adjust interface so write address doesn't need delaying
// *** modify to be a ROM rather than RAM
simpleram #( simpleram #(
.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( .BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.clk, .clk,
.a(CPUBusy ? PCPF[31:0] : PCNextFMux[31:0]), // mux is also inside $, have to replay address if CPU is stalled. .a(CPUBusy | reset ? PCPF[31:0] : PCNextFMux[31:0]), // mux is also inside $, have to replay address if CPU is stalled.
.we(1'b0), .we(1'b0),
.wd(0), .rd(FinalInstrRawF_FIXME)); .wd(0), .rd(FinalInstrRawF_FIXME));
assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0]; assign FinalInstrRawF = FinalInstrRawF_FIXME[31:0];
@ -328,50 +326,23 @@ module ifu (
assign PrivilegedChangePCM = RetM | TrapM; assign PrivilegedChangePCM = RetM | TrapM;
mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F), mux2 #(`XLEN) pcmux0(.d0(PCPlus2or4F), .d1(BPPredPCF), .s(SelBPPredF), .y(PCNext0F));
.d1(BPPredPCF), mux2 #(`XLEN) pcmux1(.d0(PCNext0F), .d1(PCCorrectE), .s(BPPredWrongE), .y(PCNext1F));
.s(SelBPPredF), // The true correct target is IEUAdrE if PCSrcE is 1 else it is the fall through PCLinkE.
.y(PCNext0F)); mux2 #(`XLEN) pccorrectemux(.d0(PCLinkE), .d1(IEUAdrE), .s(PCSrcE), .y(PCCorrectE));
mux2 #(`XLEN) pcmux2(.d0(PCNext1F), .d1(PCBPWrongInvalidate), .s(InvalidateICacheM), .y(PCNext2F));
mux2 #(`XLEN) pcmux1(.d0(PCNext0F), // Mux only required on instruction class miss prediction.
.d1(PCCorrectE), mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF), .s(BPPredWrongM), .y(PCBPWrongInvalidate));
.s(BPPredWrongE), mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), .y(PCNext3F));
.y(PCNext1F));
// December 20, 2021 Ross Thompson, If instructions in ID and IF are already invalid we don't pick PCE on icache invalidate.
// this only happens because of branch class miss prediction. The Fence instruction was incorrectly predicted as a branch
// this means on the previous cycle the BPPredWrongE updated PCNextF to the correct fall through address.
// to fix we need to select the correct address PCF as the next PCNextF. Unforunately we must still flush the instruction in IF
// as we are deliberately invalidating the icache. This address has to be refetched by the icache.
mux2 #(`XLEN) pcmux2(.d0(PCNext1F),
.d1(PCBPWrongInvalidate),
.s(InvalidateICacheM),
.y(PCNext2F));
mux2 #(`XLEN) pcmux3(.d0(PCNext2F),
.d1(PrivilegedNextPCM),
.s(PrivilegedChangePCM),
//.y(UnalignedPCNextF));
.y(PCNext3F));
// This mux is required as PCNextF needs to be the valid reset vector during reset. // This mux is required as PCNextF needs to be the valid reset vector during reset.
// Reseting PCF does not accomplish this as PCNextF will be +2/4 more than PCF. // Reseting PCF does not accomplish this as PCNextF will be +2/4 more than PCF.
mux2 #(`XLEN) pcmux4(.d0(PCNext3F), //mux2 #(`XLEN) pcmux4(.d0(PCNext3F), .d1(`RESET_VECTOR), .s(`MEM_IROM ? reset : reset_q), .y(UnalignedPCNextF));
.d1(`RESET_VECTOR), // mux2 #(`XLEN) pcmux4(.d0(PCNext3F), .d1(`RESET_VECTOR), .s(reset), .y(UnalignedPCNextF)); // ******* probably can get rid of by making reset SelAdr = 01
.s(`MEM_IROM ? reset : reset_q), assign UnalignedPCNextF = PCNext3F;
.y(UnalignedPCNextF));
flop #(1) resetReg (.clk(clk), .d(reset),.q(reset_q)); // delay reset
flopenrc #(1) BPPredWrongMReg(.clk, .reset, .en(~StallM), .clear(FlushM),
.d(BPPredWrongE), .q(BPPredWrongM));
mux2 #(`XLEN) pcmuxBPWrongInvalidateFlush(.d0(PCE), .d1(PCF),
.s(BPPredWrongM), // & InvalidateICacheM *** check with linux.
.y(PCBPWrongInvalidate));
// The true correct target is IEUAdrE if PCSrcE is 1 else it is the fall through PCLinkE.
assign PCCorrectE = PCSrcE ? IEUAdrE : PCLinkE;
flopenrc #(1) BPPredWrongMReg(.clk, .reset, .en(~StallM), .clear(FlushM), .d(BPPredWrongE), .q(BPPredWrongM));
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF); flopenl #(`XLEN) pcreg(clk, reset, ~StallF, PCNextF, `RESET_VECTOR, PCF);
@ -404,7 +375,7 @@ module ifu (
end else begin : bpred end else begin : bpred
assign BPPredPCF = '0; assign BPPredPCF = '0;
assign BPPredWrongM = PCSrcE; assign BPPredWrongE = PCSrcE;
assign {SelBPPredF, BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM} = '0; assign {SelBPPredF, BPPredDirWrongM, BTBPredPCWrongM, RASPredPCWrongM, BPPredClassNonCFIWrongM} = '0;
end end
@ -428,7 +399,6 @@ module ifu (
// *** combine these with others in better way, including M, F // *** combine these with others in better way, including M, F
// Misaligned PC logic // Misaligned PC logic
// instruction address misalignment is generated by the target of control flow instructions, not // instruction address misalignment is generated by the target of control flow instructions, not
// the fetch itself. // the fetch itself.

View File

@ -127,11 +127,11 @@ module busfsm #(parameter integer WordCountThreshold,
(BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_FETCH) |
(BusCurrState == STATE_BUS_WRITE); (BusCurrState == STATE_BUS_WRITE);
assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE; assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE;
assign UnCachedLSUBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LSURWM[0])) | assign UnCachedLSUBusWrite = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (LSURWM[0] & ~IgnoreRequest)) |
(BusCurrState == STATE_BUS_UNCACHED_WRITE); (BusCurrState == STATE_BUS_UNCACHED_WRITE);
assign LSUBusWrite = UnCachedLSUBusWrite | (BusCurrState == STATE_BUS_WRITE); assign LSUBusWrite = UnCachedLSUBusWrite | (BusCurrState == STATE_BUS_WRITE);
assign UnCachedLSUBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (|LSURWM[1])) | assign UnCachedLSUBusRead = (BusCurrState == STATE_BUS_READY & UnCachedAccess & (|LSURWM[1] & IgnoreRequest)) |
(BusCurrState == STATE_BUS_UNCACHED_READ); (BusCurrState == STATE_BUS_UNCACHED_READ);
assign LSUBusRead = UnCachedLSUBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine); assign LSUBusRead = UnCachedLSUBusRead | (BusCurrState == STATE_BUS_FETCH) | (BusCurrState == STATE_BUS_READY & DCacheFetchLine);

View File

@ -153,7 +153,8 @@ module lsu (
assign DTLBStorePageFaultM = DTLBPageFaultM & PreLSURWM[0]; assign DTLBStorePageFaultM = DTLBPageFaultM & PreLSURWM[0];
end // if (`MEM_VIRTMEM) end // if (`MEM_VIRTMEM)
else begin else begin
assign {InterlockStall, SelHPTW, IgnoreRequest, PTE, PageType, DTLBWriteM, ITLBWriteF} = '0; assign {InterlockStall, SelHPTW, PTE, PageType, DTLBWriteM, ITLBWriteF} = '0;
assign IgnoreRequest = TrapM;
assign {DTLBLoadPageFaultM, DTLBStorePageFaultM} = '0; assign {DTLBLoadPageFaultM, DTLBStorePageFaultM} = '0;
assign CPUBusy = StallW; assign CPUBusy = StallW;
assign LSUAdrE = PreLSUAdrE; assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM; assign LSUAdrE = PreLSUAdrE; assign LSUFunct3M = Funct3M; assign LSUFunct7M = Funct7M; assign LSUAtomicM = AtomicM;
@ -248,8 +249,8 @@ module lsu (
// *** adjust interface so write address doesn't need delaying; switch to standard RAM? // *** adjust interface so write address doesn't need delaying; switch to standard RAM?
simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram ( simpleram #(.BASE(`RAM_BASE), .RANGE(`RAM_RANGE)) ram (
.clk, .clk,
.a(CPUBusy ? IEUAdrM[31:0] : IEUAdrE[31:0]), .a(CPUBusy | LSURWM[0] ? IEUAdrM[31:0] : IEUAdrE[31:0]),
.we(LSURWM[0]), .we(LSURWM[0] & ~TrapM), // have to ignore write if Trap.
.wd(FinalWriteDataM), .rd(ReadDataWordM)); .wd(FinalWriteDataM), .rd(ReadDataWordM));
// since we have a local memory the bus connections are all disabled. // since we have a local memory the bus connections are all disabled.