mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Removed spill support from icache.
This commit is contained in:
parent
8c7638688b
commit
b045d84147
51
wally-pipelined/src/cache/icache.sv
vendored
51
wally-pipelined/src/cache/icache.sv
vendored
@ -77,18 +77,10 @@ module icache
|
|||||||
logic ICacheMemWriteEnable;
|
logic ICacheMemWriteEnable;
|
||||||
logic [`PA_BITS-1:0] FinalPCPF;
|
logic [`PA_BITS-1:0] FinalPCPF;
|
||||||
// Output signals from cache memory
|
// Output signals from cache memory
|
||||||
logic [31:0] ICacheMemReadData;
|
|
||||||
logic ICacheReadEn;
|
logic ICacheReadEn;
|
||||||
logic [BLOCKLEN-1:0] ReadLineF;
|
logic [BLOCKLEN-1:0] ReadLineF;
|
||||||
|
|
||||||
|
|
||||||
logic [15:0] SpillDataBlock0;
|
|
||||||
logic spill;
|
|
||||||
logic spillSave;
|
|
||||||
|
|
||||||
logic [1:1] SelAdr_q;
|
|
||||||
|
|
||||||
logic [`PA_BITS-1:0] PCPSpillF;
|
|
||||||
|
|
||||||
logic [1:0] SelAdr;
|
logic [1:0] SelAdr;
|
||||||
logic [INDEXLEN-1:0] RAdr;
|
logic [INDEXLEN-1:0] RAdr;
|
||||||
@ -109,16 +101,10 @@ module icache
|
|||||||
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
|
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
|
||||||
|
|
||||||
|
|
||||||
// on spill we want to get the first 2 bytes of the next cache block.
|
mux2 #(INDEXLEN)
|
||||||
// the spill only occurs if the PCPF mod BlockByteLength == -2. Therefore we can
|
|
||||||
// simply add 2 to land on the next cache block.
|
|
||||||
assign PCPSpillF = PCPF + {{{PA_WIDTH}{1'b0}}, 2'b10};
|
|
||||||
|
|
||||||
mux3 #(INDEXLEN)
|
|
||||||
AdrSelMux(.d0(PCNextF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
AdrSelMux(.d0(PCNextF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||||
.d1(PCF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
.d1(PCF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||||
.d2(PCPSpillF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
.s(SelAdr[0]),
|
||||||
.s(SelAdr),
|
|
||||||
.y(RAdr));
|
.y(RAdr));
|
||||||
|
|
||||||
|
|
||||||
@ -168,37 +154,10 @@ module icache
|
|||||||
assign ReadLineSetsF[BLOCKLEN/16-1] = {16'b0, ReadLineF[BLOCKLEN-1:BLOCKLEN-16]};
|
assign ReadLineSetsF[BLOCKLEN/16-1] = {16'b0, ReadLineF[BLOCKLEN-1:BLOCKLEN-16]};
|
||||||
endgenerate
|
endgenerate
|
||||||
|
|
||||||
assign ICacheMemReadData = ReadLineSetsF[FinalPCPF[$clog2(BLOCKLEN / 32) + 1 : 1]];
|
assign FinalInstrRawF = ReadLineSetsF[FinalPCPF[$clog2(BLOCKLEN / 32) + 1 : 1]];
|
||||||
|
|
||||||
// spills require storing the first cache block so it can merged
|
|
||||||
// with the second
|
|
||||||
// can optimize size, for now just make it the size of the data
|
|
||||||
// leaving the cache memory.
|
|
||||||
flopenr #(16) SpillInstrReg(.clk(clk),
|
|
||||||
.en(spillSave),
|
|
||||||
.reset(reset),
|
|
||||||
.d(ICacheMemReadData[15:0]),
|
|
||||||
.q(SpillDataBlock0));
|
|
||||||
|
|
||||||
assign FinalInstrRawF = spill ? {ICacheMemReadData[15:0], SpillDataBlock0} : ICacheMemReadData;
|
|
||||||
|
|
||||||
// Detect if the instruction is compressed
|
|
||||||
//assign CompressedF = FinalInstrRawF[1:0] != 2'b11;
|
|
||||||
//assign spill = &PCF[$clog2(BLOCKLEN/32)+1:1];
|
|
||||||
assign spill = 0;
|
|
||||||
|
|
||||||
|
|
||||||
|
assign FinalPCPF = PCPF;
|
||||||
// this mux needs to be delayed 1 cycle as it occurs 1 pipeline stage later.
|
|
||||||
// *** read enable may not be necessary.
|
|
||||||
flopenr #(1) SelAdrReg(.clk(clk),
|
|
||||||
.reset(reset),
|
|
||||||
.en(ICacheReadEn),
|
|
||||||
.d(SelAdr[1]),
|
|
||||||
.q(SelAdr_q[1]));
|
|
||||||
|
|
||||||
assign FinalPCPF = SelAdr_q[1] ? PCPSpillF : PCPF;
|
|
||||||
|
|
||||||
|
|
||||||
// *** CHANGE ME
|
// *** CHANGE ME
|
||||||
// if not cacheable the offset bits needs to be sent to the EBU.
|
// if not cacheable the offset bits needs to be sent to the EBU.
|
||||||
@ -228,8 +187,6 @@ module icache
|
|||||||
.ICacheFetchLine,
|
.ICacheFetchLine,
|
||||||
.CacheableF,
|
.CacheableF,
|
||||||
.hit,
|
.hit,
|
||||||
.spill,
|
|
||||||
.spillSave,
|
|
||||||
.SelAdr,
|
.SelAdr,
|
||||||
.LRUWriteEn);
|
.LRUWriteEn);
|
||||||
|
|
||||||
|
185
wally-pipelined/src/cache/icachefsm.sv
vendored
185
wally-pipelined/src/cache/icachefsm.sv
vendored
@ -43,7 +43,6 @@ module icachefsm
|
|||||||
|
|
||||||
// icache internal inputs
|
// icache internal inputs
|
||||||
input logic hit,
|
input logic hit,
|
||||||
input logic spill,
|
|
||||||
|
|
||||||
// icache internal outputs
|
// icache internal outputs
|
||||||
output logic ICacheReadEn,
|
output logic ICacheReadEn,
|
||||||
@ -57,54 +56,19 @@ module icachefsm
|
|||||||
output logic ICacheFetchLine,
|
output logic ICacheFetchLine,
|
||||||
|
|
||||||
// icache internal outputs
|
// icache internal outputs
|
||||||
output logic spillSave,
|
|
||||||
output logic [1:0] SelAdr,
|
output logic [1:0] SelAdr,
|
||||||
output logic LRUWriteEn
|
output logic LRUWriteEn
|
||||||
);
|
);
|
||||||
|
|
||||||
// FSM states
|
// FSM states
|
||||||
typedef enum {STATE_READY,
|
typedef enum {STATE_READY,
|
||||||
STATE_HIT_SPILL, // spill, block 0 hit
|
|
||||||
STATE_HIT_SPILL_MISS_FETCH_WDV, // block 1 miss, issue read to AHB and wait data.
|
|
||||||
STATE_HIT_SPILL_MISS_FETCH_DONE, // write data into SRAM/LUT
|
|
||||||
STATE_HIT_SPILL_MERGE, // Read block 0 of CPU access, should be able to optimize into STATE_HIT_SPILL.
|
|
||||||
|
|
||||||
// a challenge is the spill signal gets us out of the ready state and moves us to
|
|
||||||
// 1 of the 2 spill branches. However the original fsm design had us return to
|
|
||||||
// the ready state when the spill + hits/misses were fully resolved. The problem
|
|
||||||
// is the spill signal is based on PCPF so when we return to READY to check if the
|
|
||||||
// cache has a hit it still expresses spill. We can fix in 1 of two ways.
|
|
||||||
// 1. we can add 1 extra state at the end of each spill branch to returns the instruction
|
|
||||||
// to the CPU advancing the CPU and icache to the next instruction.
|
|
||||||
// 2. We can assert a signal which is delayed 1 cycle to suppress the spill when we get
|
|
||||||
// to the READY state.
|
|
||||||
// The first first option is more robust and increases the number of states by 2. The
|
|
||||||
// second option is seams like it should work, but I worry there is a hidden interaction
|
|
||||||
// between CPU stalling and that register.
|
|
||||||
// Picking option 1.
|
|
||||||
|
|
||||||
STATE_HIT_SPILL_FINAL, // this state replicates STATE_READY's replay of the
|
|
||||||
// spill access but does nto consider spill. It also does not do another operation.
|
|
||||||
|
|
||||||
STATE_MISS_FETCH_WDV, // aligned miss, issue read to AHB and wait for data.
|
STATE_MISS_FETCH_WDV, // aligned miss, issue read to AHB and wait for data.
|
||||||
STATE_MISS_FETCH_DONE, // write data into SRAM/LUT
|
STATE_MISS_FETCH_DONE, // write data into SRAM/LUT
|
||||||
STATE_MISS_READ, // read block 1 from SRAM/LUT
|
STATE_MISS_READ, // read block 1 from SRAM/LUT
|
||||||
STATE_MISS_READ_DELAY, // read block 1 from SRAM/LUT
|
STATE_MISS_READ_DELAY, // read block 1 from SRAM/LUT
|
||||||
|
|
||||||
STATE_MISS_SPILL_FETCH_WDV, // spill, miss on block 0, issue read to AHB and wait
|
STATE_CPU_BUSY
|
||||||
STATE_MISS_SPILL_FETCH_DONE, // write data into SRAM/LUT
|
|
||||||
STATE_MISS_SPILL_READ1, // read block 0 from SRAM/LUT
|
|
||||||
STATE_MISS_SPILL_2, // return to ready if hit or do second block update.
|
|
||||||
STATE_MISS_SPILL_2_START, // return to ready if hit or do second block update.
|
|
||||||
STATE_MISS_SPILL_MISS_FETCH_WDV, // miss on block 1, issue read to AHB and wait
|
|
||||||
STATE_MISS_SPILL_MISS_FETCH_DONE, // write data to SRAM/LUT
|
|
||||||
STATE_MISS_SPILL_MERGE, // read block 0 of CPU access,
|
|
||||||
|
|
||||||
STATE_MISS_SPILL_FINAL, // this state replicates STATE_READY's replay of the
|
|
||||||
// spill access but does nto consider spill. It also does not do another operation.
|
|
||||||
|
|
||||||
STATE_CPU_BUSY,
|
|
||||||
STATE_CPU_BUSY_SPILL
|
|
||||||
} statetype;
|
} statetype;
|
||||||
|
|
||||||
(* mark_debug = "true" *) statetype CurrState, NextState;
|
(* mark_debug = "true" *) statetype CurrState, NextState;
|
||||||
@ -119,7 +83,6 @@ module icachefsm
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
//IfuBusFetch = 1'b0;
|
//IfuBusFetch = 1'b0;
|
||||||
ICacheMemWriteEnable = 1'b0;
|
ICacheMemWriteEnable = 1'b0;
|
||||||
spillSave = 1'b0;
|
|
||||||
SelAdr = 2'b00;
|
SelAdr = 2'b00;
|
||||||
ICacheReadEn = 1'b0;
|
ICacheReadEn = 1'b0;
|
||||||
ICacheStallF = 1'b1;
|
ICacheStallF = 1'b1;
|
||||||
@ -137,7 +100,7 @@ module icachefsm
|
|||||||
SelAdr = 2'b01;
|
SelAdr = 2'b01;
|
||||||
ICacheStallF = 1'b0;
|
ICacheStallF = 1'b0;
|
||||||
end
|
end
|
||||||
else if (CacheableF & hit & ~spill) begin
|
else if (CacheableF & hit) begin
|
||||||
ICacheStallF = 1'b0;
|
ICacheStallF = 1'b0;
|
||||||
LRUWriteEn = 1'b1;
|
LRUWriteEn = 1'b1;
|
||||||
if(CPUBusy) begin
|
if(CPUBusy) begin
|
||||||
@ -146,17 +109,9 @@ module icachefsm
|
|||||||
end else begin
|
end else begin
|
||||||
NextState = STATE_READY;
|
NextState = STATE_READY;
|
||||||
end
|
end
|
||||||
end else if (CacheableF & hit & spill) begin
|
end else if (CacheableF & ~hit) begin
|
||||||
spillSave = 1'b1;
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
NextState = STATE_HIT_SPILL;
|
|
||||||
end else if (CacheableF & ~hit & ~spill) begin
|
|
||||||
SelAdr = 2'b01; /// *********(
|
SelAdr = 2'b01; /// *********(
|
||||||
NextState = STATE_MISS_FETCH_WDV;
|
NextState = STATE_MISS_FETCH_WDV;
|
||||||
end else if (CacheableF & ~hit & spill) begin
|
|
||||||
SelAdr = 2'b01;
|
|
||||||
NextState = STATE_MISS_SPILL_FETCH_WDV;
|
|
||||||
end else begin
|
end else begin
|
||||||
if(CPUBusy) begin
|
if(CPUBusy) begin
|
||||||
NextState = STATE_CPU_BUSY;
|
NextState = STATE_CPU_BUSY;
|
||||||
@ -166,49 +121,6 @@ module icachefsm
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
// branch 1, hit spill and 2, miss spill hit
|
|
||||||
STATE_HIT_SPILL: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
if (hit) begin
|
|
||||||
NextState = STATE_HIT_SPILL_FINAL;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_HIT_SPILL_MISS_FETCH_WDV;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_HIT_SPILL_MISS_FETCH_WDV: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
//IfuBusFetch = 1'b1;
|
|
||||||
if (ICacheBusAck) begin
|
|
||||||
NextState = STATE_HIT_SPILL_MISS_FETCH_DONE;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_HIT_SPILL_MISS_FETCH_WDV;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_HIT_SPILL_MISS_FETCH_DONE: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
ICacheMemWriteEnable = 1'b1;
|
|
||||||
NextState = STATE_HIT_SPILL_MERGE;
|
|
||||||
end
|
|
||||||
STATE_HIT_SPILL_MERGE: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
NextState = STATE_HIT_SPILL_FINAL;
|
|
||||||
end
|
|
||||||
STATE_HIT_SPILL_FINAL: begin
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
SelAdr = 2'b00;
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY_SPILL;
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
// branch 3 miss no spill
|
// branch 3 miss no spill
|
||||||
STATE_MISS_FETCH_WDV: begin
|
STATE_MISS_FETCH_WDV: begin
|
||||||
SelAdr = 2'b01;
|
SelAdr = 2'b01;
|
||||||
@ -242,80 +154,6 @@ module icachefsm
|
|||||||
NextState = STATE_READY;
|
NextState = STATE_READY;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
// branch 4 miss spill hit, and 5 miss spill miss
|
|
||||||
STATE_MISS_SPILL_FETCH_WDV: begin
|
|
||||||
SelAdr = 2'b01;
|
|
||||||
//IfuBusFetch = 1'b1;
|
|
||||||
if (ICacheBusAck) begin
|
|
||||||
NextState = STATE_MISS_SPILL_FETCH_DONE;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_MISS_SPILL_FETCH_WDV;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_FETCH_DONE: begin
|
|
||||||
SelAdr = 2'b01;
|
|
||||||
ICacheMemWriteEnable = 1'b1;
|
|
||||||
NextState = STATE_MISS_SPILL_READ1;
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_READ1: begin // always be a hit as we just wrote that cache block.
|
|
||||||
SelAdr = 2'b01; // there is a 1 cycle delay after setting the address before the date arrives.
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
NextState = STATE_MISS_SPILL_2;
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_2: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
spillSave = 1'b1; /// *** Could pipeline these to make it clearer in the fsm.
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
NextState = STATE_MISS_SPILL_2_START;
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_2_START: begin
|
|
||||||
if (~hit) begin
|
|
||||||
NextState = STATE_MISS_SPILL_MISS_FETCH_WDV;
|
|
||||||
end else begin
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
SelAdr = 2'b00;
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY_SPILL;
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_MISS_FETCH_WDV: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
//IfuBusFetch = 1'b1;
|
|
||||||
if (ICacheBusAck) begin
|
|
||||||
NextState = STATE_MISS_SPILL_MISS_FETCH_DONE;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_MISS_SPILL_MISS_FETCH_WDV;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_MISS_FETCH_DONE: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
ICacheMemWriteEnable = 1'b1;
|
|
||||||
NextState = STATE_MISS_SPILL_MERGE;
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_MERGE: begin
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
NextState = STATE_MISS_SPILL_FINAL;
|
|
||||||
end
|
|
||||||
STATE_MISS_SPILL_FINAL: begin
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
SelAdr = 2'b00;
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
LRUWriteEn = 1'b1;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY_SPILL;
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
end else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
STATE_CPU_BUSY: begin
|
STATE_CPU_BUSY: begin
|
||||||
ICacheStallF = 1'b0;
|
ICacheStallF = 1'b0;
|
||||||
if(CPUBusy) begin
|
if(CPUBusy) begin
|
||||||
@ -326,17 +164,6 @@ module icachefsm
|
|||||||
NextState = STATE_READY;
|
NextState = STATE_READY;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
STATE_CPU_BUSY_SPILL: begin
|
|
||||||
ICacheStallF = 1'b0;
|
|
||||||
ICacheReadEn = 1'b1;
|
|
||||||
if(CPUBusy) begin
|
|
||||||
NextState = STATE_CPU_BUSY_SPILL;
|
|
||||||
SelAdr = 2'b10;
|
|
||||||
end
|
|
||||||
else begin
|
|
||||||
NextState = STATE_READY;
|
|
||||||
end
|
|
||||||
end
|
|
||||||
default: begin
|
default: begin
|
||||||
SelAdr = 2'b01;
|
SelAdr = 2'b01;
|
||||||
NextState = STATE_READY;
|
NextState = STATE_READY;
|
||||||
@ -345,9 +172,7 @@ module icachefsm
|
|||||||
endcase
|
endcase
|
||||||
end
|
end
|
||||||
|
|
||||||
assign ICacheFetchLine = (CurrState == STATE_HIT_SPILL_MISS_FETCH_WDV) |
|
assign ICacheFetchLine = CurrState == STATE_MISS_FETCH_WDV;
|
||||||
(CurrState == STATE_MISS_FETCH_WDV) |
|
|
||||||
(CurrState == STATE_MISS_SPILL_FETCH_WDV) |
|
|
||||||
(CurrState == STATE_MISS_SPILL_MISS_FETCH_WDV);
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
Loading…
Reference in New Issue
Block a user