mirror of
https://github.com/openhwgroup/cvw
synced 2025-01-24 13:34:28 +00:00
Renamed PCMux (icache) to SelAdr to match dcache.
Removed unused cache files.
This commit is contained in:
parent
de9e234ffa
commit
2dff72d9e9
59
wally-pipelined/src/cache/ICacheMem.sv
vendored
59
wally-pipelined/src/cache/ICacheMem.sv
vendored
@ -1,59 +0,0 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module ICacheMem #(parameter NUMLINES=512, parameter BLOCKLEN = 256)
|
||||
(
|
||||
// Pipeline stuff
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
// If flush is high, invalidate the entire cache
|
||||
input logic flush,
|
||||
|
||||
input logic [`PA_BITS-1:0] PCTagF, // physical address
|
||||
input logic [`PA_BITS-1:0] PCNextIndexF, // virtual address
|
||||
input logic WriteEnable,
|
||||
input logic [BLOCKLEN-1:0] WriteLine,
|
||||
output logic [BLOCKLEN-1:0] ReadLineF,
|
||||
output logic HitF
|
||||
);
|
||||
|
||||
// divide the address bus into sections; tag, index, and offset
|
||||
localparam BLOCKBYTELEN = BLOCKLEN/8;
|
||||
localparam OFFSETLEN = $clog2(BLOCKBYTELEN);
|
||||
localparam INDEXLEN = $clog2(NUMLINES);
|
||||
// *** BUG. `XLEN needs to be replaced with the virtual address width, S32, S39, or S48
|
||||
localparam TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
|
||||
|
||||
logic [TAGLEN-1:0] LookupTag;
|
||||
logic [NUMLINES-1:0] ValidOut;
|
||||
logic DataValidBit;
|
||||
|
||||
// Depth is number of bits in one "word" of the memory, width is number of such words
|
||||
sram1rw #(.DEPTH(BLOCKLEN), .WIDTH(NUMLINES))
|
||||
cachemem (.*,
|
||||
.Addr(PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.ReadData(ReadLineF),
|
||||
.WriteData(WriteLine)
|
||||
);
|
||||
|
||||
sram1rw #(.DEPTH(TAGLEN), .WIDTH(NUMLINES))
|
||||
cachetags (.*,
|
||||
.Addr(PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.ReadData(LookupTag),
|
||||
.WriteData(PCTagF[`PA_BITS-1:INDEXLEN+OFFSETLEN])
|
||||
);
|
||||
|
||||
// Correctly handle the valid bits
|
||||
always_ff @(posedge clk, posedge reset) begin
|
||||
if (reset) begin
|
||||
ValidOut <= {NUMLINES{1'b0}};
|
||||
end else if (flush) begin
|
||||
ValidOut <= {NUMLINES{1'b0}};
|
||||
end else begin
|
||||
if (WriteEnable) begin
|
||||
ValidOut[PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= 1;
|
||||
end
|
||||
end
|
||||
DataValidBit <= ValidOut[PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]];
|
||||
end
|
||||
assign HitF = DataValidBit && (LookupTag == PCTagF[`PA_BITS-1:INDEXLEN+OFFSETLEN]);
|
||||
endmodule
|
22
wally-pipelined/src/cache/cache-sram.sv
vendored
22
wally-pipelined/src/cache/cache-sram.sv
vendored
@ -1,22 +0,0 @@
|
||||
// Depth is number of bits in one "word" of the memory, width is number of such words
|
||||
module Sram1Read1Write #(parameter DEPTH=128, WIDTH=256) (
|
||||
input logic clk,
|
||||
// port 1 is read only
|
||||
input logic [$clog2(WIDTH)-1:0] ReadAddr,
|
||||
output logic [DEPTH-1:0] ReadData,
|
||||
|
||||
// port 2 is write only
|
||||
input logic [$clog2(WIDTH)-1:0] WriteAddr,
|
||||
input logic [DEPTH-1:0] WriteData,
|
||||
input logic WriteEnable
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0][DEPTH-1:0] StoredData;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
ReadData <= StoredData[ReadAddr];
|
||||
if (WriteEnable) begin
|
||||
StoredData[WriteAddr] <= WriteData;
|
||||
end
|
||||
end
|
||||
endmodule
|
234
wally-pipelined/src/cache/dmapped.sv
vendored
234
wally-pipelined/src/cache/dmapped.sv
vendored
@ -1,234 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// dmapped.sv
|
||||
//
|
||||
// Written: jaallen@g.hmc.edu 2021-03-23
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: An implementation of a direct-mapped cache memory, with read-only and write-through versions
|
||||
//
|
||||
// A component of the Wally configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
|
||||
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
|
||||
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
|
||||
// is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
|
||||
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
|
||||
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
///////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
// Read-only direct-mapped memory
|
||||
module rodirectmappedmem #(parameter NUMLINES=512, parameter LINESIZE = 256, parameter WORDSIZE = `XLEN) (
|
||||
// Pipeline stuff
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic stall,
|
||||
// If flush is high, invalidate the entire cache
|
||||
input logic flush,
|
||||
// Select which address to read (broken for efficiency's sake)
|
||||
input logic [`XLEN-1:12] ReadUpperPAdr,
|
||||
input logic [11:0] ReadLowerAdr,
|
||||
// Write new data to the cache
|
||||
input logic WriteEnable,
|
||||
input logic [LINESIZE-1:0] WriteLine,
|
||||
input logic [`XLEN-1:0] WritePAdr,
|
||||
// Output the word, as well as if it is valid
|
||||
output logic [WORDSIZE-1:0] DataWord,
|
||||
output logic DataValid
|
||||
);
|
||||
|
||||
// Various compile-time constants
|
||||
localparam integer WORDWIDTH = $clog2(WORDSIZE/8);
|
||||
localparam integer OFFSETWIDTH = $clog2(LINESIZE/WORDSIZE);
|
||||
localparam integer SETWIDTH = $clog2(NUMLINES);
|
||||
localparam integer TAGWIDTH = `XLEN - OFFSETWIDTH - SETWIDTH - WORDWIDTH;
|
||||
|
||||
localparam integer OFFSETBEGIN = WORDWIDTH;
|
||||
localparam integer OFFSETEND = OFFSETBEGIN+OFFSETWIDTH-1;
|
||||
localparam integer SETBEGIN = OFFSETEND+1;
|
||||
localparam integer SETEND = SETBEGIN + SETWIDTH - 1;
|
||||
localparam integer TAGBEGIN = SETEND + 1;
|
||||
localparam integer TAGEND = TAGBEGIN + TAGWIDTH - 1;
|
||||
|
||||
// Machinery to read from and write to the correct addresses in memory
|
||||
logic [`XLEN-1:0] ReadPAdr;
|
||||
logic [`XLEN-1:0] OldReadPAdr;
|
||||
logic [OFFSETWIDTH-1:0] ReadOffset, WriteOffset;
|
||||
logic [SETWIDTH-1:0] ReadSet, WriteSet;
|
||||
logic [TAGWIDTH-1:0] ReadTag, WriteTag;
|
||||
logic [LINESIZE-1:0] ReadLine;
|
||||
logic [LINESIZE/WORDSIZE-1:0][WORDSIZE-1:0] ReadLineTransformed;
|
||||
|
||||
// Machinery to check if a given read is valid and is the desired value
|
||||
logic [TAGWIDTH-1:0] DataTag;
|
||||
logic [NUMLINES-1:0] ValidOut;
|
||||
logic DataValidBit;
|
||||
|
||||
flopenr #(`XLEN) ReadPAdrFlop(clk, reset, ~stall, ReadPAdr, OldReadPAdr);
|
||||
|
||||
// Assign the read and write addresses in cache memory
|
||||
always_comb begin
|
||||
ReadOffset = OldReadPAdr[OFFSETEND:OFFSETBEGIN];
|
||||
ReadPAdr = {ReadUpperPAdr, ReadLowerAdr};
|
||||
ReadSet = ReadPAdr[SETEND:SETBEGIN];
|
||||
ReadTag = OldReadPAdr[TAGEND:TAGBEGIN];
|
||||
|
||||
WriteOffset = WritePAdr[OFFSETEND:OFFSETBEGIN];
|
||||
WriteSet = WritePAdr[SETEND:SETBEGIN];
|
||||
WriteTag = WritePAdr[TAGEND:TAGBEGIN];
|
||||
end
|
||||
|
||||
// Depth is number of bits in one "word" of the memory, width is number of such words
|
||||
Sram1Read1Write #(.DEPTH(LINESIZE), .WIDTH(NUMLINES)) cachemem (
|
||||
.*,
|
||||
.ReadAddr(ReadSet),
|
||||
.ReadData(ReadLine),
|
||||
.WriteAddr(WriteSet),
|
||||
.WriteData(WriteLine)
|
||||
);
|
||||
Sram1Read1Write #(.DEPTH(TAGWIDTH), .WIDTH(NUMLINES)) cachetags (
|
||||
.*,
|
||||
.ReadAddr(ReadSet),
|
||||
.ReadData(DataTag),
|
||||
.WriteAddr(WriteSet),
|
||||
.WriteData(WriteTag)
|
||||
);
|
||||
|
||||
// Pick the right bits coming out the read line
|
||||
assign DataWord = ReadLineTransformed[ReadOffset];
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i < LINESIZE/WORDSIZE; i++) begin:readline
|
||||
assign ReadLineTransformed[i] = ReadLine[(i+1)*WORDSIZE-1:i*WORDSIZE];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Correctly handle the valid bits
|
||||
always_ff @(posedge clk, posedge reset) begin
|
||||
if (reset || flush) begin
|
||||
ValidOut <= {NUMLINES{1'b0}};
|
||||
end else begin
|
||||
if (WriteEnable) begin
|
||||
ValidOut[WriteSet] <= 1;
|
||||
end
|
||||
end
|
||||
DataValidBit <= ValidOut[ReadSet];
|
||||
end
|
||||
assign DataValid = DataValidBit && (DataTag == ReadTag);
|
||||
endmodule
|
||||
|
||||
|
||||
// Write-through direct-mapped memory
|
||||
module wtdirectmappedmem #(parameter NUMLINES=512, parameter LINESIZE = 256, parameter WORDSIZE = `XLEN) (
|
||||
// Pipeline stuff
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic stall,
|
||||
// If flush is high, invalidate the entire cache
|
||||
input logic flush,
|
||||
// Select which address to read (broken for efficiency's sake)
|
||||
input logic [`XLEN-1:12] ReadUpperPAdr,
|
||||
input logic [11:0] ReadLowerAdr,
|
||||
// Load new data into the cache (from main memory)
|
||||
input logic LoadEnable,
|
||||
input logic [LINESIZE-1:0] LoadLine,
|
||||
input logic [`XLEN-1:0] LoadPAdr,
|
||||
// Write data to the cache (like from a store instruction)
|
||||
input logic WriteEnable,
|
||||
input logic [WORDSIZE-1:0] WriteWord,
|
||||
input logic [`XLEN-1:0] WritePAdr,
|
||||
input logic [1:0] WriteSize, // Specify size of the write (non-written bits should be preserved)
|
||||
// Output the word, as well as if it is valid
|
||||
output logic [WORDSIZE-1:0] DataWord,
|
||||
output logic DataValid
|
||||
);
|
||||
|
||||
// Various compile-time constants
|
||||
localparam integer WORDWIDTH = $clog2(WORDSIZE/8);
|
||||
localparam integer OFFSETWIDTH = $clog2(LINESIZE/WORDSIZE);
|
||||
localparam integer SETWIDTH = $clog2(NUMLINES);
|
||||
localparam integer TAGWIDTH = `XLEN - OFFSETWIDTH - SETWIDTH - WORDWIDTH;
|
||||
|
||||
localparam integer OFFSETBEGIN = WORDWIDTH;
|
||||
localparam integer OFFSETEND = OFFSETBEGIN+OFFSETWIDTH-1;
|
||||
localparam integer SETBEGIN = OFFSETEND+1;
|
||||
localparam integer SETEND = SETBEGIN + SETWIDTH - 1;
|
||||
localparam integer TAGBEGIN = SETEND + 1;
|
||||
localparam integer TAGEND = TAGBEGIN + TAGWIDTH - 1;
|
||||
|
||||
// Machinery to read from and write to the correct addresses in memory
|
||||
logic [`XLEN-1:0] ReadPAdr;
|
||||
logic [`XLEN-1:0] OldReadPAdr;
|
||||
logic [OFFSETWIDTH-1:0] ReadOffset, LoadOffset;
|
||||
logic [SETWIDTH-1:0] ReadSet, LoadSet;
|
||||
logic [TAGWIDTH-1:0] ReadTag, LoadTag;
|
||||
logic [LINESIZE-1:0] ReadLine;
|
||||
logic [LINESIZE/WORDSIZE-1:0][WORDSIZE-1:0] ReadLineTransformed;
|
||||
|
||||
// Machinery to check if a given read is valid and is the desired value
|
||||
logic [TAGWIDTH-1:0] DataTag;
|
||||
logic [NUMLINES-1:0] ValidOut;
|
||||
logic DataValidBit;
|
||||
|
||||
flopenr #(`XLEN) ReadPAdrFlop(clk, reset, ~stall, ReadPAdr, OldReadPAdr);
|
||||
|
||||
// Assign the read and write addresses in cache memory
|
||||
always_comb begin
|
||||
ReadOffset = OldReadPAdr[OFFSETEND:OFFSETBEGIN];
|
||||
ReadPAdr = {ReadUpperPAdr, ReadLowerAdr};
|
||||
ReadSet = ReadPAdr[SETEND:SETBEGIN];
|
||||
ReadTag = OldReadPAdr[TAGEND:TAGBEGIN];
|
||||
|
||||
LoadOffset = LoadPAdr[OFFSETEND:OFFSETBEGIN];
|
||||
LoadSet = LoadPAdr[SETEND:SETBEGIN];
|
||||
LoadTag = LoadPAdr[TAGEND:TAGBEGIN];
|
||||
end
|
||||
|
||||
// Depth is number of bits in one "word" of the memory, width is number of such words
|
||||
Sram1Read1Write #(.DEPTH(LINESIZE), .WIDTH(NUMLINES)) cachemem (
|
||||
.*,
|
||||
.ReadAddr(ReadSet),
|
||||
.ReadData(ReadLine),
|
||||
.WriteAddr(LoadSet),
|
||||
.WriteData(LoadLine),
|
||||
.WriteEnable(LoadEnable)
|
||||
);
|
||||
Sram1Read1Write #(.DEPTH(TAGWIDTH), .WIDTH(NUMLINES)) cachetags (
|
||||
.*,
|
||||
.ReadAddr(ReadSet),
|
||||
.ReadData(DataTag),
|
||||
.WriteAddr(LoadSet),
|
||||
.WriteData(LoadTag),
|
||||
.WriteEnable(LoadEnable)
|
||||
);
|
||||
|
||||
// Pick the right bits coming out the read line
|
||||
assign DataWord = ReadLineTransformed[ReadOffset];
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i < LINESIZE/WORDSIZE; i++) begin:readline
|
||||
assign ReadLineTransformed[i] = ReadLine[(i+1)*WORDSIZE-1:i*WORDSIZE];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Correctly handle the valid bits
|
||||
always_ff @(posedge clk, posedge reset) begin
|
||||
if (reset || flush) begin
|
||||
ValidOut <= {NUMLINES{1'b0}};
|
||||
end else begin
|
||||
if (LoadEnable) begin
|
||||
ValidOut[LoadSet] <= 1;
|
||||
end
|
||||
end
|
||||
DataValidBit <= ValidOut[ReadSet];
|
||||
end
|
||||
assign DataValid = DataValidBit && (DataTag == ReadTag);
|
||||
endmodule
|
32
wally-pipelined/src/cache/icache.sv
vendored
32
wally-pipelined/src/cache/icache.sv
vendored
@ -90,7 +90,7 @@ module icache
|
||||
logic FetchCountFlag;
|
||||
logic CntEn;
|
||||
|
||||
logic [1:0] PCMux_q;
|
||||
logic [1:0] SelAdr_q;
|
||||
|
||||
|
||||
logic [LOGWPL-1:0] FetchCount, NextFetchCount;
|
||||
@ -99,8 +99,9 @@ module icache
|
||||
logic [`PA_BITS-1:OFFSETWIDTH] PCPTrunkF;
|
||||
|
||||
logic CntReset;
|
||||
logic [1:0] PCMux;
|
||||
logic [1:0] SelAdr;
|
||||
logic SavePC;
|
||||
logic [INDEXLEN-1:0] RAdr;
|
||||
|
||||
|
||||
// on spill we want to get the first 2 bytes of the next cache block.
|
||||
@ -108,19 +109,20 @@ module icache
|
||||
// simply add 2 to land on the next cache block.
|
||||
assign PCPSpillF = PCPF + {{{PA_WIDTH}{1'b0}}, 2'b10}; // *** modelsim does not allow the use of PA_BITS for literal width.
|
||||
|
||||
// now we have to select between these three PCs
|
||||
assign PCPreFinalF = PCMux[0] ? PCPF : PCNextF; // *** don't like the stallf, but it is necessary
|
||||
// for the data cache i used a cpu busy state which is triggered by StallW. In the case of the icache I
|
||||
// modified the select on this address mux. Both are not ideal; however the cpu_busy state is required for the
|
||||
// dcache as a write would repeatedly update the sram or worse for an uncached write multiple times.
|
||||
// I like reducing some complexity of the fsm; however I weight commonality between the i/d cache more.
|
||||
assign PCNextIndexF = PCMux[1] ? PCPSpillF : PCPreFinalF;
|
||||
mux3 #(INDEXLEN)
|
||||
AdrSelMux(.d0(PCNextF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.d1(PCPF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.d2(PCPSpillF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.s(SelAdr),
|
||||
.y(RAdr));
|
||||
|
||||
|
||||
|
||||
cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN), .OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN),
|
||||
.DIRTY_BITS(0))
|
||||
icachemem(.clk,
|
||||
.reset,
|
||||
.RAdr(PCNextIndexF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
|
||||
.RAdr(RAdr),
|
||||
.PAdr(PCTagF),
|
||||
.WriteEnable(ICacheMemWriteEnable),
|
||||
.WriteWordEnable('1),
|
||||
@ -228,13 +230,13 @@ module icache
|
||||
|
||||
// this mux needs to be delayed 1 cycle as it occurs 1 pipeline stage later.
|
||||
// *** read enable may not be necessary.
|
||||
flopenr #(2) PCMuxReg(.clk(clk),
|
||||
flopenr #(2) SelAdrReg(.clk(clk),
|
||||
.reset(reset),
|
||||
.en(ICacheReadEn),
|
||||
.d(PCMux),
|
||||
.q(PCMux_q));
|
||||
.d(SelAdr),
|
||||
.q(SelAdr_q));
|
||||
|
||||
assign PCTagF = PCMux_q[1] ? PCPSpillF : PCPF;
|
||||
assign PCTagF = SelAdr_q[1] ? PCPSpillF : PCPF;
|
||||
|
||||
// truncate the offset from PCPF for memory address generation
|
||||
assign PCPTrunkF = PCTagF[`PA_BITS-1:OFFSETWIDTH];
|
||||
@ -258,7 +260,7 @@ module icache
|
||||
.spillSave,
|
||||
.CntEn,
|
||||
.CntReset,
|
||||
.PCMux,
|
||||
.SelAdr,
|
||||
.SavePC
|
||||
);
|
||||
|
||||
|
68
wally-pipelined/src/cache/icachefsm.sv
vendored
68
wally-pipelined/src/cache/icachefsm.sv
vendored
@ -60,7 +60,7 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
output logic spillSave,
|
||||
output logic CntEn,
|
||||
output logic CntReset,
|
||||
output logic [1:0] PCMux,
|
||||
output logic [1:0] SelAdr,
|
||||
output logic SavePC
|
||||
);
|
||||
|
||||
@ -130,14 +130,14 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
//InstrReadF = 1'b0;
|
||||
ICacheMemWriteEnable = 1'b0;
|
||||
spillSave = 1'b0;
|
||||
PCMux = 2'b00;
|
||||
SelAdr = 2'b00;
|
||||
ICacheReadEn = 1'b0;
|
||||
SavePC = 1'b0;
|
||||
ICacheStallF = 1'b1;
|
||||
|
||||
case (CurrState)
|
||||
STATE_READY: begin
|
||||
PCMux = 2'b00;
|
||||
SelAdr = 2'b00;
|
||||
ICacheReadEn = 1'b1;
|
||||
if (ITLBMissF) begin
|
||||
NextState = STATE_TLB_MISS;
|
||||
@ -146,25 +146,25 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
ICacheStallF = 1'b0;
|
||||
if(StallF) begin
|
||||
NextState = STATE_CPU_BUSY;
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
end else if (hit & spill) begin
|
||||
spillSave = 1'b1;
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
NextState = STATE_HIT_SPILL;
|
||||
end else if (~hit & ~spill) begin
|
||||
CntReset = 1'b1;
|
||||
NextState = STATE_MISS_FETCH_WDV;
|
||||
end else if (~hit & spill) begin
|
||||
CntReset = 1'b1;
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
NextState = STATE_MISS_SPILL_FETCH_WDV;
|
||||
end else begin
|
||||
if(StallF) begin
|
||||
NextState = STATE_CPU_BUSY;
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
@ -172,7 +172,7 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
// branch 1, hit spill and 2, miss spill hit
|
||||
STATE_HIT_SPILL: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
UnalignedSelect = 1'b1;
|
||||
ICacheReadEn = 1'b1;
|
||||
if (hit) begin
|
||||
@ -183,7 +183,7 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
end
|
||||
STATE_HIT_SPILL_MISS_FETCH_WDV: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
//InstrReadF = 1'b1;
|
||||
PreCntEn = 1'b1;
|
||||
if (FetchCountFlag & InstrAckF) begin
|
||||
@ -193,25 +193,25 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
end
|
||||
STATE_HIT_SPILL_MISS_FETCH_DONE: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
ICacheMemWriteEnable = 1'b1;
|
||||
NextState = STATE_HIT_SPILL_MERGE;
|
||||
end
|
||||
STATE_HIT_SPILL_MERGE: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
UnalignedSelect = 1'b1;
|
||||
ICacheReadEn = 1'b1;
|
||||
NextState = STATE_HIT_SPILL_FINAL;
|
||||
end
|
||||
STATE_HIT_SPILL_FINAL: begin
|
||||
ICacheReadEn = 1'b1;
|
||||
PCMux = 2'b00;
|
||||
SelAdr = 2'b00;
|
||||
UnalignedSelect = 1'b1;
|
||||
SavePC = 1'b1;
|
||||
ICacheStallF = 1'b0;
|
||||
if(StallF) begin
|
||||
NextState = STATE_CPU_BUSY_SPILL;
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
@ -219,7 +219,7 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
// branch 3 miss no spill
|
||||
STATE_MISS_FETCH_WDV: begin
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
//InstrReadF = 1'b1;
|
||||
PreCntEn = 1'b1;
|
||||
if (FetchCountFlag & InstrAckF) begin
|
||||
@ -229,30 +229,30 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
end
|
||||
STATE_MISS_FETCH_DONE: begin
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
ICacheMemWriteEnable = 1'b1;
|
||||
NextState = STATE_MISS_READ;
|
||||
end
|
||||
STATE_MISS_READ: begin
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
ICacheReadEn = 1'b1;
|
||||
NextState = STATE_MISS_READ_DELAY;
|
||||
end
|
||||
STATE_MISS_READ_DELAY: begin
|
||||
//PCMux = 2'b01;
|
||||
//SelAdr = 2'b01;
|
||||
ICacheReadEn = 1'b1;
|
||||
ICacheStallF = 1'b0;
|
||||
if(StallF) begin
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
NextState = STATE_CPU_BUSY;
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
end
|
||||
// branch 4 miss spill hit, and 5 miss spill miss
|
||||
STATE_MISS_SPILL_FETCH_WDV: begin
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
PreCntEn = 1'b1;
|
||||
//InstrReadF = 1'b1;
|
||||
if (FetchCountFlag & InstrAckF) begin
|
||||
@ -262,17 +262,17 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
end
|
||||
STATE_MISS_SPILL_FETCH_DONE: begin
|
||||
PCMux = 2'b01;
|
||||
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.
|
||||
PCMux = 2'b01; // there is a 1 cycle delay after setting the address before the date arrives.
|
||||
SelAdr = 2'b01; // there is a 1 cycle delay after setting the address before the date arrives.
|
||||
ICacheReadEn = 1'b1;
|
||||
NextState = STATE_MISS_SPILL_2;
|
||||
end
|
||||
STATE_MISS_SPILL_2: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
UnalignedSelect = 1'b1;
|
||||
spillSave = 1'b1; /// *** Could pipeline these to make it clearer in the fsm.
|
||||
ICacheReadEn = 1'b1;
|
||||
@ -284,20 +284,20 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
NextState = STATE_MISS_SPILL_MISS_FETCH_WDV;
|
||||
end else begin
|
||||
ICacheReadEn = 1'b1;
|
||||
PCMux = 2'b00;
|
||||
SelAdr = 2'b00;
|
||||
UnalignedSelect = 1'b1;
|
||||
SavePC = 1'b1;
|
||||
ICacheStallF = 1'b0;
|
||||
if(StallF) begin
|
||||
NextState = STATE_CPU_BUSY;
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
end
|
||||
end
|
||||
STATE_MISS_SPILL_MISS_FETCH_WDV: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
PreCntEn = 1'b1;
|
||||
//InstrReadF = 1'b1;
|
||||
if (FetchCountFlag & InstrAckF) begin
|
||||
@ -307,25 +307,25 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
end
|
||||
STATE_MISS_SPILL_MISS_FETCH_DONE: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
ICacheMemWriteEnable = 1'b1;
|
||||
NextState = STATE_MISS_SPILL_MERGE;
|
||||
end
|
||||
STATE_MISS_SPILL_MERGE: begin
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
UnalignedSelect = 1'b1;
|
||||
ICacheReadEn = 1'b1;
|
||||
NextState = STATE_MISS_SPILL_FINAL;
|
||||
end
|
||||
STATE_MISS_SPILL_FINAL: begin
|
||||
ICacheReadEn = 1'b1;
|
||||
PCMux = 2'b00;
|
||||
SelAdr = 2'b00;
|
||||
UnalignedSelect = 1'b1;
|
||||
SavePC = 1'b1;
|
||||
ICacheStallF = 1'b0;
|
||||
if(StallF) begin
|
||||
NextState = STATE_CPU_BUSY;
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
@ -341,7 +341,7 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
end
|
||||
end
|
||||
STATE_TLB_MISS_DONE: begin
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
STATE_CPU_BUSY: begin
|
||||
@ -350,7 +350,7 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
NextState = STATE_TLB_MISS;
|
||||
end else if(StallF) begin
|
||||
NextState = STATE_CPU_BUSY;
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
end
|
||||
else begin
|
||||
NextState = STATE_READY;
|
||||
@ -363,14 +363,14 @@ module icachefsm #(parameter BLOCKLEN = 256)
|
||||
NextState = STATE_TLB_MISS;
|
||||
end else if(StallF) begin
|
||||
NextState = STATE_CPU_BUSY_SPILL;
|
||||
PCMux = 2'b10;
|
||||
SelAdr = 2'b10;
|
||||
end
|
||||
else begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
end
|
||||
default: begin
|
||||
PCMux = 2'b01;
|
||||
SelAdr = 2'b01;
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
// *** add in error handling and invalidate/evict
|
||||
|
Loading…
Reference in New Issue
Block a user