I've tightly coupled the cache to the processer, so cache considerations show up in state machine states.
I'm using write-through with no write allocate.
The following Verilog code shows how the cache impacts things.
wadr = cache write address
radr = cache read address
wdat = data to write to cache
rdat = data read from cache
Code: Select all
// Stores always write through to memory, then optionally update the cache if
// there was a write hit.
STORE1:
begin
cyc_o <= 1'b1;
stb_o <= 1'b1;
we_o <= 1'b1;
sel_o <= 4'hf; // select all byte lanes
adr_o <= {wadr,2'b00};
dat_o <= wdat;
radr <= wadr; // Do a cache read to test the hit
state <= STORE2;
end
// Terminal state for stores. Update the data cache if there was a cache hit.
// Clear any previously set lock status
STORE2:
if (ack_i) begin
lock_o <= 1'b0;
cyc_o <= 1'b0;
stb_o <= 1'b0;
we_o <= 1'b0;
sel_o <= 4'h0;
adr_o <= 34'h0;
dat_o <= 32'h0;
if (dhit) begin // we would set dmiss = `TRUE in the else for a write-allocate cache
wr <= 1'b1;
end
state <= IFETCH;
end
// Handle the following address modes: zp : zp,Rn : abs : abs,Rn
LOAD1:
if (unCachedData) begin
if (isRMW)
lock_o <= 1'b1;
cyc_o <= 1'b1;
stb_o <= 1'b1;
sel_o <= 4'hf;
adr_o <= {radr,2'b00};
state <= LOAD2;
end
else if (dhit) begin
b <= rdat;
state <= CALC;
end
else
dmiss <= `TRUE;
LOAD2:
if (ack_i) begin
cyc_o <= 1'b0;
stb_o <= 1'b0;
sel_o <= 4'h0;
b <= dat_i;
state <= CALC;
end