Lint passes, but I only hope to have loads working. Stores, lr/sc, atomic, are not fully implemented.

Also faults and the dcache ptw interlock are not implemented.
This commit is contained in:
Ross Thompson 2021-07-09 15:16:38 -05:00
parent 94c3fde724
commit ec80cc1820
9 changed files with 322 additions and 294 deletions

View File

@ -46,6 +46,9 @@ module DCacheMem #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26
output logic Dirty output logic Dirty
); );
logic [NUMLINES-1:0] ValidBits, DirtyBits;
genvar words; genvar words;
generate generate
@ -69,22 +72,6 @@ module DCacheMem #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26
.WriteEnable(WriteEnable)); .WriteEnable(WriteEnable));
sram1rw #(.DEPTH(BLOCKLEN),
.WIDTH(NUMLINES))
CacheDataMem(.clk(clk),
.Addr(Adr),
.ReadData(ReadData),
.WriteData(WriteData),
.WriteEnable(WriteEnable));
sram1rw #(.DEPTH(TAGLEN),
.WIDTH(NUMLINES))
CacheTagMem(.clk(clk),
.Addr(Adr),
.ReadData(ReadTag),
.WriteData(WriteTag),
.WriteEnable(WriteEnable));
always_ff @(posedge clk, posedge reset) begin always_ff @(posedge clk, posedge reset) begin
if (reset) if (reset)
ValidBits <= {NUMLINES{1'b0}}; ValidBits <= {NUMLINES{1'b0}};

View File

@ -196,6 +196,7 @@ module ICacheCntrl #(parameter BLOCKLEN = 256)
assign spill = PCPF[4:1] == 4'b1111 ? 1'b1 : 1'b0; assign spill = PCPF[4:1] == 4'b1111 ? 1'b1 : 1'b0;
assign hit = ICacheMemReadValid; // note ICacheMemReadValid is hit. assign hit = ICacheMemReadValid; // note ICacheMemReadValid is hit.
// verilator lint_off WIDTH // verilator lint_off WIDTH
// *** Bug width is wrong.
assign FetchCountFlag = (FetchCount == FetchCountThreshold); assign FetchCountFlag = (FetchCount == FetchCountThreshold);
// verilator lint_on WIDTH // verilator lint_on WIDTH

View File

@ -36,8 +36,9 @@ module dcache
// cpu side // cpu side
input logic [1:0] MemRWM, input logic [1:0] MemRWM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [6:0] Funct7M,
input logic [1:0] AtomicM, input logic [1:0] AtomicM,
input logic [`PA_BITS-1:0] MemAdrE, // virtual address, but we only use the lower 12 bits. input logic [`XLEN-1:0] MemAdrE, // virtual address, but we only use the lower 12 bits.
input logic [`PA_BITS-1:0] MemPAdrM, // physical address input logic [`PA_BITS-1:0] MemPAdrM, // physical address
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
@ -54,8 +55,7 @@ module dcache
output logic AHBWrite, output logic AHBWrite,
input logic AHBAck, // from ahb input logic AHBAck, // from ahb
input logic [`XLEN-1:0] HRDATA, // from ahb input logic [`XLEN-1:0] HRDATA, // from ahb
output logic [`XLEN-1:0] HWDATA, // to ahb output logic [`XLEN-1:0] HWDATA // to ahb
output logic [2:0] AHBSize
); );
localparam integer BLOCKLEN = 256; localparam integer BLOCKLEN = 256;
@ -78,21 +78,23 @@ module dcache
logic [NUMWAYS-1:0] WriteEnable; logic [NUMWAYS-1:0] WriteEnable;
logic [NUMWAYS-1:0] WriteWordEnable; logic [NUMWAYS-1:0] WriteWordEnable;
logic [BLOCKLEN-1:0] SRAMWriteData; logic [BLOCKLEN-1:0] SRAMWriteData;
logic [BLOCKLEN-1:0] DCacheMemWriteData;
logic SetValidM, ClearValidM, SetValidW, ClearValidW; logic SetValidM, ClearValidM, SetValidW, ClearValidW;
logic SetDirtyM, ClearDirtyM, SetDirtyW, ClearDirtyW; logic SetDirtyM, ClearDirtyM, SetDirtyW, ClearDirtyW;
logic [BLOCKLEN-1:0] ReadDataM, ReadDataMaskedM [NUMWAYS-1:0]; logic [BLOCKLEN-1:0] ReadDataBlockWayM [NUMWAYS-1:0];
logic [BLOCKLEN-1:0] VictimReadDataMaskedM [NUMWAYS-1:0]; logic [BLOCKLEN-1:0] ReadDataBlockWayMaskedM [NUMWAYS-1:0];
logic [TAGLEN-1:0] TagData [NUMWAYS-1:0]; logic [BLOCKLEN-1:0] VictimReadDataBLockWayMaskedM [NUMWAYS-1:0];
logic [TAGLEN-1:0] ReadTag [NUMWAYS-1:0];
logic [NUMWAYS-1:0] Valid, Dirty, WayHit; logic [NUMWAYS-1:0] Valid, Dirty, WayHit;
logic CacheHit; logic CacheHit;
logic [NUMREPL_BITS-1:0] ReplacementBits, NewReplacement; logic [NUMREPL_BITS-1:0] ReplacementBits [NUMLINES-1:0];
logic [BLOCKLEN-1:0] ReadDataSelectWayM; logic [NUMREPL_BITS-1:0] NewReplacement [NUMLINES-1:0];
logic [`XLEN-1:0] ReadDataSelectWayXLEN [(WORDSPERLINE)-1:0]; logic [BLOCKLEN-1:0] ReadDataBlockM;
logic [`XLEN-1:0] WordReadDataM, FinalReadDataM; logic [`XLEN-1:0] ReadDataBlockSetsM [(WORDSPERLINE)-1:0];
logic [`XLEN-1:0] ReadDataWordM, FinalReadDataWordM;
logic [`XLEN-1:0] WriteDataW, FinalWriteDataW, FinalAMOWriteDataW; logic [`XLEN-1:0] WriteDataW, FinalWriteDataW, FinalAMOWriteDataW;
logic [BLOCKLEN-1:0] FinalWriteDataWordsW; logic [BLOCKLEN-1:0] FinalWriteDataWordsW;
logic [LOGWPL:0] FetchCount, NextFetchCount; logic [LOGWPL:0] FetchCount, NextFetchCount;
logic [NUMWAYS-1:0] SRAMWordWriteEnableM, SRAMWordWriteEnableW;
logic [WORDSPERLINE-1:0] SRAMWordEnable [NUMWAYS-1:0]; logic [WORDSPERLINE-1:0] SRAMWordEnable [NUMWAYS-1:0];
logic SelMemWriteDataM, SelMemWriteDataW; logic SelMemWriteDataM, SelMemWriteDataW;
logic [2:0] Funct3W; logic [2:0] Funct3W;
@ -100,16 +102,27 @@ module dcache
logic SRAMWordWriteEnableM, SRAMWordWriteEnableW; logic SRAMWordWriteEnableM, SRAMWordWriteEnableW;
logic SRAMBlockWriteEnableM; logic SRAMBlockWriteEnableM;
logic SRAMWriteEnable; logic SRAMWriteEnable;
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
logic SaveSRAMRead; logic SaveSRAMRead;
logic [1:0] AtomicW; logic [1:0] AtomicW;
logic [NUMWAYS-1:0] VictimWay; logic [NUMWAYS-1:0] VictimWay;
logic [NUMWAYS-1:0] VictimDirtyWay; logic [NUMWAYS-1:0] VictimDirtyWay;
logic [BLOCKLEN-1:0] VictimReadDataSelectWayM; logic [BLOCKLEN-1:0] VictimReadDataBlockM;
logic VictimDirty; logic VictimDirty;
logic SelAMOWrite;
logic [6:0] Funct7W;
logic [INDEXLEN-1:0] AdrMuxOut;
flopenr #(7) Funct7WReg(.clk(clk),
.reset(reset),
.en(~StallW),
.d(Funct7M),
.q(Funct7W));
// data path // data path
@ -120,15 +133,15 @@ module dcache
.q(MemPAdrW)); .q(MemPAdrW));
mux2 #(INDEXLEN) mux2 #(INDEXLEN)
AdrSelMux(.d0(MemAdrE[INDEXLEN+OFFSET-1:OFFSET]), AdrSelMux(.d0(MemAdrE[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d1(MemPAdrM[INDEXLEN+OFFSET-1:OFFSET]), .d1(MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.s(SelAdrM), .s(SelAdrM),
.y(AdrMuxOut)); .y(AdrMuxOut));
mux2 #(INDEXLEN) mux2 #(INDEXLEN)
SelAdrlMux2(.d0(AdrMuxOut), SelAdrlMux2(.d0(AdrMuxOut),
.d1(MemPAdrW[INDEXLEN+OFFSET-1:OFFSET]), .d1(MemPAdrW[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.s(SRAMWordWriteEnableW), .s(SRAMWordWriteEnableW),
.y(SRAMAdr)); .y(SRAMAdr));
@ -140,68 +153,89 @@ module dcache
MemWay(.clk(clk), MemWay(.clk(clk),
.reset(reset), .reset(reset),
.Adr(SRAMAdr), .Adr(SRAMAdr),
.WAdr(MemPAdrW[INDEXLEN+OFFSET-1:OFFSET]), .WAdr(MemPAdrW[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.WriteEnable(SRAMWriteEnable[way]), .WriteEnable(SRAMWayWriteEnable[way]),
.WriteWordEnable(SRAMWordEnable[way]), .WriteWordEnable(SRAMWordEnable[way]),
.WriteData(SRAMWriteData), .WriteData(SRAMWriteData),
.WriteTag(MemPAdrW[`PA_BITS-1:OFFSET+INDEXLEN]), .WriteTag(MemPAdrW[`PA_BITS-1:OFFSETLEN+INDEXLEN]),
.SetValid(SetValidW), .SetValid(SetValidW),
.ClearValid(ClearValidW), .ClearValid(ClearValidW),
.SetDirty(SetDirtyW), .SetDirty(SetDirtyW),
.ClearDirty(ClearDirtyW), .ClearDirty(ClearDirtyW),
.ReadData(ReadDataM[way]), .ReadData(ReadDataBlockWayM[way]),
.ReadTag(ReadTag[way]), .ReadTag(ReadTag[way]),
.Valid(Valid[way]), .Valid(Valid[way]),
.Dirty(Dirty[way])); .Dirty(Dirty[way]));
assign WayHit = Valid & (ReadTag[way] == MemAdrM); assign WayHit[way] = Valid[way] & (ReadTag[way] == MemPAdrM[`PA_BITS-1:OFFSETLEN+INDEXLEN]);
assign ReadDataMaskedM[way] = Valid[way] ? ReadDataM[way] : '0; // first part of AO mux. assign ReadDataBlockWayMaskedM[way] = Valid[way] ? ReadDataBlockWayM[way] : '0; // first part of AO mux.
// the cache block candiate for eviction // the cache block candiate for eviction
assign VictimReadDataMaskedM[way] = VictimWay[way] & ReadDataM[way]; assign VictimReadDataBLockWayMaskedM[way] = VictimWay[way] ? ReadDataBlockWayM[way] : '0;
assign VictimDirtyWay[way] = VictimWay[way] & Dirty[way] & Valid[way]; assign VictimDirtyWay[way] = VictimWay[way] & Dirty[way] & Valid[way];
end end
endgenerate endgenerate
always_ff @(posedge clk, posedge reset) begin always_ff @(posedge clk, posedge reset) begin
if (reset) ReplacementBits <= '0; if (reset) begin
else if (SRAMWriteEnable) ReplacementBits[MemPAdrW[INDEXLEN+OFFSET-1:OFFSET]] <= NewReplacement; for(int index = 0; index < NUMLINES-1; index++)
ReplacementBits[index] <= '0;
end
else if (SRAMWriteEnable) ReplacementBits[MemPAdrW[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacement;
end end
// *** TODO add replacement policy // *** TODO add replacement policy
assign NewReplacement = '0; genvar index;
generate
for(index = 0; index < NUMLINES-1; index++)
assign NewReplacement[index] = '0;
endgenerate
assign VictimWay = 4'b0001; assign VictimWay = 4'b0001;
assign SRAMWriteEnable = SRAMBlockWriteEnableM ? VictimWay : '0; mux2 #(NUMWAYS) WriteEnableMux(.d0(SRAMWordWriteEnableW ? WayHit : '0),
.d1(SRAMBlockWriteEnableM ? VictimWay : '0),
.s(SRAMBlockWriteEnableM),
.y(SRAMWayWriteEnable));
assign CacheHit = |WayHit; assign CacheHit = |WayHit;
assign ReadDataSelectWayM = |ReadDataMaskedM; // second part of AO mux. // ReadDataBlockWayMaskedM is a 2d array of cache block len by number of ways.
assign VictimReadDataSelectWayM = | VictimReadDataMaskedM; // Need to OR together each way in a bitwise manner.
// Final part of the AO Mux.
always_comb begin
ReadDataBlockM = '0;
VictimReadDataBlockM = '0;
for(int index = 0; index < NUMWAYS; index++) begin
ReadDataBlockM = ReadDataBlockM | ReadDataBlockWayMaskedM;
VictimReadDataBlockM = VictimReadDataBlockM | VictimReadDataBLockWayMaskedM;
end
end
assign VictimDirty = | VictimDirtyWay; assign VictimDirty = | VictimDirtyWay;
// Convert the Read data bus ReadDataSelectWay into sets of XLEN so we can // Convert the Read data bus ReadDataSelectWay into sets of XLEN so we can
// easily build a variable input mux. // easily build a variable input mux.
genvar index;
generate generate
for (index = 0; index < WORDSPERLINE; index++) begin for (index = 0; index < WORDSPERLINE; index++) begin
assign ReadDataSelectWayM[index] = ReadDataSelectM[((index+1)*`XLEN)-1: (index*`XLEN)]; assign ReadDataBlockSetsM[index] = ReadDataBlockM[((index+1)*`XLEN)-1: (index*`XLEN)];
end end
endgenerate endgenerate
// variable input mux // variable input mux
assign WordReadDataM = ReadDataSelectWayM[MemPAdrM[WORDSPERLINE+$clog2(`XLEN/8) : $clog2(`XLEN/8)]]; assign ReadDataWordM = ReadDataBlockSetsM[MemPAdrM[$clog2(WORDSPERLINE+`XLEN/8) : $clog2(`XLEN/8)]];
// finally swr // finally swr
subwordread subwordread(.HRDATA(WordReadDataM), // *** BUG fix HSIZED? why was it this way?
.HADDRD(MemPAdrM[`XLEN/8-1:0]), subwordread subwordread(.HRDATA(ReadDataWordM),
.HSIZED(Funct3M), .HADDRD(MemPAdrM[2:0]),
.HRDATAMasked(FinalReadDataM)); .HSIZED({Funct3M[2], 1'b0, Funct3M[1:0]}),
.HRDATAMasked(FinalReadDataWordM));
flopen #(XLEN) ReadDataWReg(.clk(clk), flopen #(`XLEN) ReadDataWReg(.clk(clk),
.en(~StallW), .en(~StallW),
.d(FinalReadDataM), .d(FinalReadDataWordM),
.q(ReadDataW)); .q(ReadDataW));
// write path // write path
flopen #(XLEN) WriteDataWReg(.clk(clk), flopen #(`XLEN) WriteDataWReg(.clk(clk),
.en(~StallW), .en(~StallW),
.d(WriteDataM), .d(WriteDataM),
.q(WriteDataW)); .q(WriteDataW));
@ -212,15 +246,15 @@ module dcache
.q(Funct3W)); .q(Funct3W));
subwordwrite subwordwrite(.HRDATA(ReadDataW), subwordwrite subwordwrite(.HRDATA(ReadDataW),
.HADDRD(MemPAdrM[`XLEN/8-1:0]), .HADDRD(MemPAdrM[2:0]),
.HSIZED(Funct3W), .HSIZED({Funct3W[2], 1'b0, Funct3W[1:0]}),
.HWDATAIN(WriteDataW), .HWDATAIN(WriteDataW),
.HWDATA(FinalWriteDataW)); .HWDATA(FinalWriteDataW));
generate generate
if (`A_SUPPORTED) begin if (`A_SUPPORTED) begin
logic [`XLEN-1:0] AMOResult; logic [`XLEN-1:0] AMOResult;
amoalu amoalu(.srca(ReadDataW), .srcb(WriteDataW), .funct(Funct7W), .width(Funct3W), amoalu amoalu(.srca(ReadDataW), .srcb(WriteDataW), .funct(Funct7W), .width(Funct3W[1:0]),
.result(AMOResult)); .result(AMOResult));
mux2 #(`XLEN) wdmux(FinalWriteDataW, AMOResult, SelAMOWrite & AtomicW[1], FinalAMOWriteDataW); mux2 #(`XLEN) wdmux(FinalWriteDataW, AMOResult, SelAMOWrite & AtomicW[1], FinalAMOWriteDataW);
end else end else
@ -238,18 +272,15 @@ module dcache
end end
endgenerate endgenerate
flopenr #(LOGWPL+1) // *** Coding style. this is just awful. The purpose is to align FetchCount to the
FetchCountReg(.clk(clk), // size of XLEN so we can fetch XLEN bits. FetchCount needs to be padded to PA_BITS length.
.reset(reset | CntReset), generate
.en(CntEn), if (`XLEN == 32) begin
.d(NextFetchCount), assign AHBPAdr = ({ {`PA_BITS-4{1'b0}}, FetchCount} << 2) + MemPAdrM;
.q(FetchCount)); end else begin
assign AHBPAdr = ({ {`PA_BITS-3{1'b0}}, FetchCount} << 3) + MemPAdrM;
assign NextFetchCount = FetchCount + 1'b1; end
endgenerate
assign AHBPAdr = (FetchCount << (`XLEN/8)) + MemPAdrM;
// remove later
assign AHBSize = 3'b000;
// mux between the CPU's write and the cache fetch. // mux between the CPU's write and the cache fetch.
@ -315,7 +346,7 @@ module dcache
assign AnyCPUReqM = |MemRWM | (|AtomicM); assign AnyCPUReqM = |MemRWM | (|AtomicM);
assign FetchCountFlag = (FetchCount == FetchCountThreshold); assign FetchCountFlag = (FetchCount == FetchCountThreshold[LOGWPL:0]);
flopenr #(LOGWPL+1) flopenr #(LOGWPL+1)
FetchCountReg(.clk(clk), FetchCountReg(.clk(clk),
@ -331,8 +362,8 @@ module dcache
flopr #(1+4+2) flopr #(1+4+2)
SRAMWritePipeReg(.clk(clk), SRAMWritePipeReg(.clk(clk),
.reset(reset), .reset(reset),
.d({SRAMWordWriteEnableM, SetValidM, ClearValidM, SetDiryM, ClearDirtyM, AtomicM}), .d({SRAMWordWriteEnableM, SetValidM, ClearValidM, SetDirtyM, ClearDirtyM, AtomicM}),
.q({SRAMWordWriteEnableW, SetValidW, ClearValidM, SetDiryM, ClearDirtyM, AtomicW})); .q({SRAMWordWriteEnableW, SetValidW, ClearValidM, SetDirtyM, ClearDirtyM, AtomicW}));
// fsm state regs // fsm state regs
@ -347,7 +378,7 @@ module dcache
// next state logic and some state ouputs. // next state logic and some state ouputs.
always_comb begin always_comb begin
DCacheStall = 1'b0; DCacheStall = 1'b0;
SelAdrM = 2'b00; SelAdrM = 1'b0;
PreCntEn = 1'b0; PreCntEn = 1'b0;
SetValidM = 1'b0; SetValidM = 1'b0;
ClearValidM = 1'b0; ClearValidM = 1'b0;
@ -360,12 +391,13 @@ module dcache
CntReset = 1'b0; CntReset = 1'b0;
AHBRead = 1'b0; AHBRead = 1'b0;
AHBWrite = 1'b0; AHBWrite = 1'b0;
SelAMOWrite = 1'b0;
case (CurrState) case (CurrState)
STATE_READY: begin STATE_READY: begin
// sram busy // sram busy
if (AnyCPUReqM & SRAMWordWriteEnableW) begin if (AnyCPUReqM & SRAMWordWriteEnableW) begin
NextState = STATE_BUSY; NextState = STATE_SRAM_BUSY;
DCacheStall = 1'b1; DCacheStall = 1'b1;
end end
// TLB Miss // TLB Miss
@ -373,7 +405,7 @@ module dcache
NextState = STATE_PTW_MISS_FETCH_WDV; NextState = STATE_PTW_MISS_FETCH_WDV;
end end
// amo hit // amo hit
else if(|AtomicM & ~UncachedM & ~FSMReg & CacheHit & ~DTLBMissM) begin else if(|AtomicM & ~UncachedM & ~FaultM & CacheHit & ~DTLBMissM) begin
NextState = STATE_AMO_UPDATE; NextState = STATE_AMO_UPDATE;
DCacheStall = 1'b1; DCacheStall = 1'b1;
end end
@ -423,7 +455,7 @@ module dcache
STATE_READ_MISS_FETCH_DONE: begin STATE_READ_MISS_FETCH_DONE: begin
DCacheStall = 1'b1; DCacheStall = 1'b1;
if(VictimDirt) begin if(VictimDirty) begin
NextState = STATE_READ_MISS_CHECK_EVICTED_DIRTY; NextState = STATE_READ_MISS_CHECK_EVICTED_DIRTY;
end else begin end else begin
NextState = STATE_READ_MISS_WRITE_CACHE_BLOCK; NextState = STATE_READ_MISS_WRITE_CACHE_BLOCK;
@ -445,7 +477,7 @@ module dcache
STATE_PTW_MISS_FETCH_WDV: begin STATE_PTW_MISS_FETCH_WDV: begin
DCacheStall = 1'b1; DCacheStall = 1'b1;
AdrSel = 2'b01; SelAdrM = 1'b1;
if (FetchCountFlag & AHBAck) begin if (FetchCountFlag & AHBAck) begin
NextState = STATE_PTW_MISS_FETCH_DONE; NextState = STATE_PTW_MISS_FETCH_DONE;
end else begin end else begin

View File

@ -36,7 +36,7 @@ endpackage
module ahblite ( module ahblite (
input logic clk, reset, input logic clk, reset,
input logic StallW, FlushW, input logic StallW,
// Load control // Load control
input logic UnsignedLoadM, input logic UnsignedLoadM,
input logic [1:0] AtomicMaskedM, input logic [1:0] AtomicMaskedM,
@ -47,15 +47,13 @@ module ahblite (
output logic [`XLEN-1:0] InstrRData, output logic [`XLEN-1:0] InstrRData,
output logic InstrAckF, output logic InstrAckF,
// Signals from Data Cache // Signals from Data Cache
input logic [`PA_BITS-1:0] MemPAdrM, input logic [`PA_BITS-1:0] DCtoAHBPAdrM,
input logic MemReadM, MemWriteM, input logic DCtoAHBReadM,
input logic [`XLEN-1:0] WriteDataM, input logic DCtoAHBWriteM,
input logic [1:0] MemSizeM, input logic [`XLEN-1:0] DCtoAHBWriteData,
//output logic DataStall, output logic [`XLEN-1:0] DCfromAHBReadData,
// Signals from MMU input logic [1:0] MemSizeM, // *** remove
// Signals from PMA checker output logic DCfromAHBAck,
input logic DSquashBusAccessM, ISquashBusAccessF,
// Signals to PMA checker (metadata of proposed access)
// Return from bus // Return from bus
output logic [`XLEN-1:0] HRDATAW, output logic [`XLEN-1:0] HRDATAW,
// AHB-Lite external signals // AHB-Lite external signals
@ -75,13 +73,13 @@ module ahblite (
output logic [3:0] HSIZED, output logic [3:0] HSIZED,
output logic HWRITED, output logic HWRITED,
// Stalls // Stalls
output logic CommitM, MemAckW output logic CommitM
); );
logic GrantData; logic GrantData;
logic [31:0] AccessAddress; logic [31:0] AccessAddress;
logic [2:0] AccessSize, PTESize, ISize; logic [2:0] AccessSize, PTESize, ISize;
logic [`AHBW-1:0] HRDATAMasked, ReadDataM, CapturedHRDATAMasked, HRDATANext, WriteData; logic [`AHBW-1:0] HRDATAMasked, ReadDataM, HRDATANext, CapturedHRDATAMasked, WriteData;
logic IReady, DReady; logic IReady, DReady;
logic CaptureDataM,CapturedDataAvailable; logic CaptureDataM,CapturedDataAvailable;
@ -95,7 +93,7 @@ module ahblite (
// while an instruction read is occuring, the instruction read finishes before // while an instruction read is occuring, the instruction read finishes before
// the data access can take place. // the data access can take place.
import ahbliteState::*; import ahbliteState::*;
statetype BusState, ProposedNextBusState, NextBusState; statetype BusState, NextBusState;
flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState); flopenl #(.TYPE(statetype)) busreg(HCLK, ~HRESETn, 1'b1, NextBusState, IDLE, BusState);
@ -109,49 +107,32 @@ module ahblite (
// interface that might be used in place of the ahblite. // interface that might be used in place of the ahblite.
always_comb always_comb
case (BusState) case (BusState)
IDLE: if (AtomicMaskedM[1]) ProposedNextBusState = ATOMICREAD; IDLE: if (AtomicMaskedM[1]) NextBusState = ATOMICREAD;
else if (MemReadM) ProposedNextBusState = MEMREAD; // Memory has priority over instructions else if (DCtoAHBReadM) NextBusState = MEMREAD; // Memory has priority over instructions
else if (MemWriteM) ProposedNextBusState = MEMWRITE; else if (DCtoAHBWriteM) NextBusState = MEMWRITE;
else if (InstrReadF) ProposedNextBusState = INSTRREAD; else if (InstrReadF) NextBusState = INSTRREAD;
else ProposedNextBusState = IDLE; else NextBusState = IDLE;
ATOMICREAD: if (~HREADY) ProposedNextBusState = ATOMICREAD; ATOMICREAD: if (~HREADY) NextBusState = ATOMICREAD;
else ProposedNextBusState = ATOMICWRITE; else NextBusState = ATOMICWRITE;
ATOMICWRITE: if (~HREADY) ProposedNextBusState = ATOMICWRITE; ATOMICWRITE: if (~HREADY) NextBusState = ATOMICWRITE;
else if (InstrReadF) ProposedNextBusState = INSTRREAD; else if (InstrReadF) NextBusState = INSTRREAD;
else ProposedNextBusState = IDLE; else NextBusState = IDLE;
MEMREAD: if (~HREADY) ProposedNextBusState = MEMREAD; MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (InstrReadF) ProposedNextBusState = INSTRREAD; else if (InstrReadF) NextBusState = INSTRREAD;
else ProposedNextBusState = IDLE; else NextBusState = IDLE;
MEMWRITE: if (~HREADY) ProposedNextBusState = MEMWRITE; MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
else if (InstrReadF) ProposedNextBusState = INSTRREAD; else if (InstrReadF) NextBusState = INSTRREAD;
else ProposedNextBusState = IDLE; else NextBusState = IDLE;
INSTRREAD: if (~HREADY) ProposedNextBusState = INSTRREAD; INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
else ProposedNextBusState = IDLE; // if (InstrReadF still high) else NextBusState = IDLE; // if (InstrReadF still high)
default: ProposedNextBusState = IDLE; default: NextBusState = IDLE;
endcase endcase
// Determine access type (important for determining whether to fault)
// (ProposedNextBusState == MMUTRANSLATE);
// The PMA and PMP checkers can decide to squash the access
// *** this probably needs to be controlled by the caches rather than EBU dh 7/2/11
assign NextBusState = (DSquashBusAccessM || ISquashBusAccessF) ? IDLE : ProposedNextBusState;
// stall signals
// Note that we need to extend both stalls when MMUTRANSLATE goes to idle,
// since translation might not be complete.
// *** Ross Thompson remove this datastall
/* -----\/----- EXCLUDED -----\/-----
assign #2 DataStall = ((NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE));
-----/\----- EXCLUDED -----/\----- */
// bus outputs // bus outputs
assign #1 GrantData = (ProposedNextBusState == MEMREAD) || (ProposedNextBusState == MEMWRITE) || assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE) ||
(ProposedNextBusState == ATOMICREAD) || (ProposedNextBusState == ATOMICWRITE); (NextBusState == ATOMICREAD) || (NextBusState == ATOMICWRITE);
assign #1 AccessAddress = (GrantData) ? MemPAdrM[31:0] : InstrPAdrF[31:0]; assign #1 AccessAddress = (GrantData) ? DCtoAHBPAdrM[31:0] : InstrPAdrF[31:0];
//assign #1 HADDR = (MMUTranslate) ? MMUPAdr[31:0] : AccessAddress; //assign #1 HADDR = (MMUTranslate) ? MMUPAdr[31:0] : AccessAddress;
assign #1 HADDR = AccessAddress; assign #1 HADDR = AccessAddress;
generate generate
@ -180,11 +161,11 @@ module ahblite (
//assign MMUReady = (BusState == MMUTRANSLATE && HREADY); //assign MMUReady = (BusState == MMUTRANSLATE && HREADY);
assign InstrRData = HRDATA; assign InstrRData = HRDATA;
assign DCfromAHBReadData = HRDATA;
assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD); assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD);
assign CommitM = (BusState == MEMREAD) || (BusState == MEMWRITE) || (BusState == ATOMICREAD) || (BusState == ATOMICWRITE); assign CommitM = (BusState == MEMREAD) || (BusState == MEMWRITE) || (BusState == ATOMICREAD) || (BusState == ATOMICWRITE);
// *** Bracker 6/5/21: why is this W stage? // *** Bracker 6/5/21: why is this W stage?
assign MemAckW = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE) || assign DCfromAHBAck = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE);
((BusState == ATOMICREAD) && (NextBusState != ATOMICREAD)) || ((BusState == ATOMICWRITE) && (NextBusState != ATOMICWRITE));
//assign MMUReadPTE = HRDATA; //assign MMUReadPTE = HRDATA;
// Carefully decide when to update ReadDataW // Carefully decide when to update ReadDataW
// ReadDataMstored holds the most recent memory read. // ReadDataMstored holds the most recent memory read.
@ -208,17 +189,20 @@ module ahblite (
flopr #(`XLEN) ReadDataOldWReg(clk, reset, HRDATANext, HRDATAW); flopr #(`XLEN) ReadDataOldWReg(clk, reset, HRDATANext, HRDATAW);
// Extract and sign-extend subwords if necessary // Extract and sign-extend subwords if necessary
subwordread swr(.*); subwordread swr(.HRDATA(HRDATA),
.HADDRD(HADDRD),
.HSIZED(HSIZED),
.HRDATAMasked(HRDATAMasked));
// Handle AMO instructions if applicable // Handle AMO instructions if applicable
generate generate
if (`A_SUPPORTED) begin if (`A_SUPPORTED) begin
logic [`XLEN-1:0] AMOResult; logic [`XLEN-1:0] AMOResult;
amoalu amoalu(.srca(HRDATAW), .srcb(WriteDataM), .funct(Funct7M), .width(MemSizeM), amoalu amoalu(.srca(HRDATAW), .srcb(DCtoAHBWriteData), .funct(Funct7M), .width(MemSizeM),
.result(AMOResult)); .result(AMOResult));
mux2 #(`XLEN) wdmux(WriteDataM, AMOResult, AtomicMaskedM[1], WriteData); mux2 #(`XLEN) wdmux(DCtoAHBWriteData, AMOResult, AtomicMaskedM[1], WriteData);
end else end else
assign WriteData = WriteDataM; assign WriteData = DCtoAHBWriteData;
endgenerate endgenerate
endmodule endmodule

View File

@ -50,7 +50,7 @@ module datapath (
input logic FWriteIntM, input logic FWriteIntM,
input logic [`XLEN-1:0] FIntResM, input logic [`XLEN-1:0] FIntResM,
output logic [`XLEN-1:0] SrcAM, output logic [`XLEN-1:0] SrcAM,
output logic [`XLEN-1:0] WriteDataM, MemAdrM, output logic [`XLEN-1:0] WriteDataM, MemAdrM, MemAdrE,
// Writeback stage signals // Writeback stage signals
input logic StallW, FlushW, input logic StallW, FlushW,
input logic FWriteIntW, input logic FWriteIntW,
@ -120,6 +120,7 @@ module datapath (
flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
flopenrc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ~StallM, ALUResultE, ALUResultM); flopenrc #(`XLEN) ALUResultMReg(clk, reset, FlushM, ~StallM, ALUResultE, ALUResultM);
assign MemAdrM = ALUResultM; assign MemAdrM = ALUResultM;
assign MemAdrE = ALUResultE;
flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM); flopenrc #(`XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, WriteDataE, WriteDataM);
flopenrc #(5) RdMEg(clk, reset, FlushM, ~StallM, RdE, RdM); flopenrc #(5) RdMEg(clk, reset, FlushM, ~StallM, RdE, RdM);
mux2 #(`XLEN) resultmuxM(ALUResultM, FIntResM, FWriteIntM, ResultM); mux2 #(`XLEN) resultmuxM(ALUResultM, FIntResM, FWriteIntM, ResultM);

View File

@ -49,7 +49,7 @@ module ieu (
input logic SquashSCW, // from LSU input logic SquashSCW, // from LSU
output logic [1:0] MemRWM, // read/write control goes to LSU output logic [1:0] MemRWM, // read/write control goes to LSU
output logic [1:0] AtomicM, // atomic control goes to LSU output logic [1:0] AtomicM, // atomic control goes to LSU
output logic [`XLEN-1:0] MemAdrM, WriteDataM, // Address and write data to LSU output logic [`XLEN-1:0] MemAdrM, MemAdrE, WriteDataM, // Address and write data to LSU
output logic [2:0] Funct3M, // size and signedness to LSU output logic [2:0] Funct3M, // size and signedness to LSU
output logic [`XLEN-1:0] SrcAM, // to privilege and fpu output logic [`XLEN-1:0] SrcAM, // to privilege and fpu

View File

@ -32,12 +32,13 @@ module lsu
( (
input logic clk, reset, input logic clk, reset,
input logic StallM, FlushM, StallW, FlushW, input logic StallM, FlushM, StallW, FlushW,
output logic DCacheStall, output logic LSUStall,
// Memory Stage // Memory Stage
// connected to cpu (controls) // connected to cpu (controls)
input logic [1:0] MemRWM, input logic [1:0] MemRWM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [6:0] Funct7M,
input logic [1:0] AtomicM, input logic [1:0] AtomicM,
output logic CommittedM, output logic CommittedM,
output logic SquashSCW, output logic SquashSCW,
@ -45,6 +46,7 @@ module lsu
// address and write data // address and write data
input logic [`XLEN-1:0] MemAdrM, input logic [`XLEN-1:0] MemAdrM,
input logic [`XLEN-1:0] MemAdrE,
input logic [`XLEN-1:0] WriteDataM, input logic [`XLEN-1:0] WriteDataM,
output logic [`XLEN-1:0] ReadDataW, output logic [`XLEN-1:0] ReadDataW,
@ -60,14 +62,12 @@ module lsu
// connect to ahb // connect to ahb
input logic CommitM, // should this be generated in the abh interface? input logic CommitM, // should this be generated in the abh interface?
output logic [`PA_BITS-1:0] MemPAdrM, // to ahb output logic [`PA_BITS-1:0] DCtoAHBPAdrM, // to ahb
output logic MemReadM, MemWriteM, output logic DCtoAHBReadM,
output logic [1:0] AtomicMaskedM, output logic DCtoAHBWriteM,
input logic MemAckW, // from ahb input logic DCfromAHBAck, // from ahb
input logic [`XLEN-1:0] HRDATAW, // from ahb input logic [`XLEN-1:0] DCfromAHBReadData, // from ahb
output logic [2:0] SizeFromLSU, output logic [`XLEN-1:0] DCtoAHBWriteData, // to ahb
output logic StallWfromLSU,
// mmu management // mmu management
@ -87,14 +87,9 @@ module lsu
output logic DTLBHitM, // not connected output logic DTLBHitM, // not connected
// PMA/PMP (inside mmu) signals
input logic [31:0] HADDR, // *** replace all of these H inputs with physical adress once pma checkers have been edited to use paddr as well.
input logic [2:0] HSIZE, HBURST,
input logic HWRITE,
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // *** this one especially has a large note attached to it in pmpchecker. input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0] // *** this one especially has a large note attached to it in pmpchecker.
output logic DSquashBusAccessM
// output logic [5:0] DHSELRegionsM // output logic [5:0] DHSELRegionsM
); );
@ -119,6 +114,9 @@ module lsu
logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem logic PMPInstrAccessFaultF, PMAInstrAccessFaultF; // *** these are just so that the mmu has somewhere to put these outputs since they aren't used in dmem
// *** if you're allowed to parameterize outputs/ inputs existence, these are an easy delete. // *** if you're allowed to parameterize outputs/ inputs existence, these are an easy delete.
logic [`PA_BITS-1:0] MemPAdrM; // from mmu to dcache
logic DTLBMissM; logic DTLBMissM;
logic [`XLEN-1:0] PageTableEntryM; logic [`XLEN-1:0] PageTableEntryM;
logic [1:0] PageTypeM; logic [1:0] PageTypeM;
@ -130,27 +128,21 @@ module lsu
logic HPTWTranslate; logic HPTWTranslate;
logic HPTWRead; logic HPTWRead;
logic [1:0] MemRWMtoDCache; logic [1:0] MemRWMtoDCache;
logic [2:0] SizetoDCache; logic [2:0] Funct3MtoDCache;
logic [1:0] AtomicMtoDCache; logic [1:0] AtomicMtoDCache;
logic [`XLEN-1:0] MemAdrMtoDCache; logic [`XLEN-1:0] MemAdrMtoDCache;
logic [`XLEN-1:0] WriteDataMtoDCache; logic [`XLEN-1:0] MemAdrEtoDCache;
logic [`XLEN-1:0] ReadDataWfromDCache; logic [`XLEN-1:0] ReadDataWfromDCache;
logic StallWtoDCache; logic StallWtoDCache;
logic CommittedMfromDCache; logic CommittedMfromDCache;
logic SquashSCWfromDCache; logic SquashSCWfromDCache;
logic DataMisalignedMfromDCache; logic DataMisalignedMfromDCache;
logic HPTWReady; logic HPTWReady;
logic LSUStall;
logic DisableTranslation; // used to stop intermediate PTE physical addresses being saved to TLB. logic DisableTranslation; // used to stop intermediate PTE physical addresses being saved to TLB.
logic DCacheStall;
// for time being until we have a dcache the AHB Lite read bus HRDATAW will be connected to the
// CPU's read data input ReadDataW.
assign ReadDataWfromDCache = HRDATAW;
pagetablewalker pagetablewalker( pagetablewalker pagetablewalker(
.clk(clk), .clk(clk),
.reset(reset), .reset(reset),
@ -192,32 +184,29 @@ module lsu
.Funct3M(Funct3M), .Funct3M(Funct3M),
.AtomicM(AtomicM), .AtomicM(AtomicM),
.MemAdrM(MemAdrM), .MemAdrM(MemAdrM),
.WriteDataM(WriteDataM), // *** Need to remove this.
.StallW(StallW), .StallW(StallW),
.ReadDataW(ReadDataW), .ReadDataW(ReadDataW),
.CommittedM(CommittedM), .CommittedM(CommittedM),
.SquashSCW(SquashSCW), .SquashSCW(SquashSCW),
.DataMisalignedM(DataMisalignedM), .DataMisalignedM(DataMisalignedM),
.DCacheStall(DCacheStall), .LSUStall(LSUStall),
// LSU // DCACHE
.DisableTranslation(DisableTranslation), .DisableTranslation(DisableTranslation),
.MemRWMtoDCache(MemRWMtoDCache), .MemRWMtoDCache(MemRWMtoDCache),
.SizetoDCache(SizetoDCache), .Funct3MtoDCache(Funct3MtoDCache),
.AtomicMtoDCache(AtomicMtoDCache), .AtomicMtoDCache(AtomicMtoDCache),
.MemAdrMtoDCache(MemAdrMtoDCache), .MemAdrMtoDCache(MemAdrMtoDCache),
.WriteDataMtoDCache(WriteDataMtoDCache), // *** ??????????????
.StallWtoDCache(StallWtoDCache), .StallWtoDCache(StallWtoDCache),
.CommittedMfromDCache(CommittedMfromDCache), .CommittedMfromDCache(CommittedMfromDCache),
.SquashSCWfromDCache(SquashSCWfromDCache), .SquashSCWfromDCache(SquashSCWfromDCache),
.DataMisalignedMfromDCache(DataMisalignedMfromDCache), .DataMisalignedMfromDCache(DataMisalignedMfromDCache),
.ReadDataWfromDCache(ReadDataWfromDCache), .ReadDataWfromDCache(ReadDataWfromDCache),
.DataStall(LSUStall)); .DCacheStall(DCacheStall));
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0)) mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
dmmu(.VirtualAddress(MemAdrMtoDCache), dmmu(.VirtualAddress(MemAdrMtoDCache),
.Size(SizetoDCache[1:0]), .Size(Funct3MtoDCache[1:0]),
.PTE(PageTableEntryM), .PTE(PageTableEntryM),
.PageTypeWriteVal(PageTypeM), .PageTypeWriteVal(PageTypeM),
.TLBWrite(DTLBWriteM), .TLBWrite(DTLBWriteM),
@ -227,10 +216,11 @@ module lsu
.TLBHit(DTLBHitM), .TLBHit(DTLBHitM),
.TLBPageFault(DTLBPageFaultM), .TLBPageFault(DTLBPageFaultM),
.ExecuteAccessF(1'b0), .ExecuteAccessF(1'b0),
.AtomicAccessM(AtomicMaskedM[1]), //.AtomicAccessM(AtomicMaskedM[1]),
.AtomicAccessM(1'b0),
.WriteAccessM(MemRWMtoDCache[0]), .WriteAccessM(MemRWMtoDCache[0]),
.ReadAccessM(MemRWMtoDCache[1]), .ReadAccessM(MemRWMtoDCache[1]),
.SquashBusAccess(DSquashBusAccessM), .SquashBusAccess(),
.DisableTranslation(DisableTranslation), .DisableTranslation(DisableTranslation),
.InstrAccessFaultF(), .InstrAccessFaultF(),
// .SelRegions(DHSELRegionsM), // .SelRegions(DHSELRegionsM),
@ -242,7 +232,7 @@ module lsu
// Determine if an Unaligned access is taking place // Determine if an Unaligned access is taking place
always_comb always_comb
case(SizetoDCache[1:0]) case(Funct3MtoDCache[1:0])
2'b00: DataMisalignedMfromDCache = 0; // lb, sb, lbu 2'b00: DataMisalignedMfromDCache = 0; // lb, sb, lbu
2'b01: DataMisalignedMfromDCache = MemAdrMtoDCache[0]; // lh, sh, lhu 2'b01: DataMisalignedMfromDCache = MemAdrMtoDCache[0]; // lh, sh, lhu
2'b10: DataMisalignedMfromDCache = MemAdrMtoDCache[1] | MemAdrMtoDCache[0]; // lw, sw, flw, fsw, lwu 2'b10: DataMisalignedMfromDCache = MemAdrMtoDCache[1] | MemAdrMtoDCache[0]; // lw, sw, flw, fsw, lwu
@ -254,6 +244,10 @@ module lsu
// Changed DataMisalignedMfromDCache to a larger combination of trap sources // Changed DataMisalignedMfromDCache to a larger combination of trap sources
// NonBusTrapM is anything that the bus doesn't contribute to producing // NonBusTrapM is anything that the bus doesn't contribute to producing
// By contrast, using TrapM results in circular logic errors // By contrast, using TrapM results in circular logic errors
/* -----\/----- EXCLUDED -----\/-----
// *** BUG for now leave this out. come back later after the d cache is working. July 09, 2021
assign MemReadM = MemRWMtoDCache[1] & ~NonBusTrapM & ~DTLBMissM & CurrState != STATE_STALLED; assign MemReadM = MemRWMtoDCache[1] & ~NonBusTrapM & ~DTLBMissM & CurrState != STATE_STALLED;
assign MemWriteM = MemRWMtoDCache[0] & ~NonBusTrapM & ~DTLBMissM & ~SquashSCM & CurrState != STATE_STALLED; assign MemWriteM = MemRWMtoDCache[0] & ~NonBusTrapM & ~DTLBMissM & ~SquashSCM & CurrState != STATE_STALLED;
assign AtomicMaskedM = CurrState != STATE_STALLED ? AtomicMtoDCache : 2'b00 ; assign AtomicMaskedM = CurrState != STATE_STALLED ? AtomicMtoDCache : 2'b00 ;
@ -292,16 +286,56 @@ module lsu
assign SquashSCWfromDCache = 0; assign SquashSCWfromDCache = 0;
end end
endgenerate endgenerate
-----/\----- EXCLUDED -----/\----- */
// *** BUG
assign MemAdrEtoDCache = MemAdrE; // needs to be muxed in lsuarb.
dcache dcache(.clk(clk),
.reset(reset),
.StallM(StallM),
.StallW(StallW),
.FlushM(FlushM),
.FlushW(FlushW),
.MemRWM(MemRWMtoDCache),
.Funct3M(Funct3MtoDCache),
.Funct7M(Funct7M),
.AtomicM(AtomicMtoDCache),
.MemAdrE(MemAdrEtoDCache), // *** add to arb
.MemPAdrM(MemPAdrM),
.WriteDataM(WriteDataM),
.ReadDataW(ReadDataWfromDCache),
.DCacheStall(DCacheStall),
.FaultM(LoadMisalignedFaultM | StoreMisalignedFaultM), // this is wrong needs to be all faults.
.DTLBMissM(DTLBMissM),
.UncachedM(1'b0), // ***connect to PMA
// AHB connection
.AHBPAdr(DCtoAHBPAdrM),
.AHBRead(DCtoAHBReadM),
.AHBWrite(DCtoAHBWriteM),
.AHBAck(DCfromAHBAck),
.HWDATA(DCtoAHBWriteData),
.HRDATA(DCfromAHBReadData)
);
// assign AtomicMaskedM = 2'b00; // *** Remove from AHB
// Data stall // Data stall
//assign LSUStall = (NextState == STATE_FETCH) || (NextState == STATE_FETCH_AMO_1) || (NextState == STATE_FETCH_AMO_2); //assign LSUStall = (NextState == STATE_FETCH) || (NextState == STATE_FETCH_AMO_1) || (NextState == STATE_FETCH_AMO_2);
assign HPTWReady = (CurrState == STATE_READY); // BUG *** July 09, 2021
//assign HPTWReady = (CurrState == STATE_READY);
// Ross Thompson April 22, 2021 // Ross Thompson April 22, 2021
// for now we need to handle the issue where the data memory interface repeately // for now we need to handle the issue where the data memory interface repeately
// requests data from memory rather than issuing a single request. // requests data from memory rather than issuing a single request.
/* -----\/----- EXCLUDED -----\/-----
// *** BUG will need to modify this so we can handle the ptw. July 09, 2021
flopenl #(.TYPE(statetype)) stateReg(.clk(clk), flopenl #(.TYPE(statetype)) stateReg(.clk(clk),
.load(reset), .load(reset),
@ -331,7 +365,7 @@ module lsu
end end
STATE_FETCH_AMO_1: begin STATE_FETCH_AMO_1: begin
LSUStall = 1'b1; LSUStall = 1'b1;
if (MemAckW) begin if (DCfromAHBAck) begin
NextState = STATE_FETCH_AMO_2; NextState = STATE_FETCH_AMO_2;
end else begin end else begin
NextState = STATE_FETCH_AMO_1; NextState = STATE_FETCH_AMO_1;
@ -339,9 +373,9 @@ module lsu
end end
STATE_FETCH_AMO_2: begin STATE_FETCH_AMO_2: begin
LSUStall = 1'b1; LSUStall = 1'b1;
if (MemAckW & ~StallWtoDCache) begin if (DCfromAHBAck & ~StallWtoDCache) begin
NextState = STATE_FETCH_AMO_2; NextState = STATE_FETCH_AMO_2;
end else if (MemAckW & StallWtoDCache) begin end else if (DCfromAHBAck & StallWtoDCache) begin
NextState = STATE_STALLED; NextState = STATE_STALLED;
end else begin end else begin
NextState = STATE_FETCH_AMO_2; NextState = STATE_FETCH_AMO_2;
@ -349,9 +383,9 @@ module lsu
end end
STATE_FETCH: begin STATE_FETCH: begin
LSUStall = 1'b1; LSUStall = 1'b1;
if (MemAckW & ~StallWtoDCache) begin if (DCfromAHBAck & ~StallWtoDCache) begin
NextState = STATE_READY; NextState = STATE_READY;
end else if (MemAckW & StallWtoDCache) begin end else if (DCfromAHBAck & StallWtoDCache) begin
NextState = STATE_STALLED; NextState = STATE_STALLED;
end else begin end else begin
NextState = STATE_FETCH; NextState = STATE_FETCH;
@ -378,9 +412,9 @@ module lsu
end end
STATE_PTW_FETCH : begin STATE_PTW_FETCH : begin
LSUStall = 1'b1; LSUStall = 1'b1;
if (MemAckW & ~DTLBWriteM) begin if (DCfromAHBAck & ~DTLBWriteM) begin
NextState = STATE_PTW_READY; NextState = STATE_PTW_READY;
end else if (MemAckW & DTLBWriteM) begin end else if (DCfromAHBAck & DTLBWriteM) begin
NextState = STATE_READY; NextState = STATE_READY;
end else begin end else begin
NextState = STATE_PTW_FETCH; NextState = STATE_PTW_FETCH;
@ -395,10 +429,7 @@ module lsu
end end
endcase endcase
end // always_comb end // always_comb
-----/\----- EXCLUDED -----/\----- */
// *** for now just pass through size
assign SizeFromLSU = SizetoDCache;
assign StallWfromLSU = StallWtoDCache;
endmodule endmodule

View File

@ -42,29 +42,27 @@ module lsuArb
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [1:0] AtomicM, input logic [1:0] AtomicM,
input logic [`XLEN-1:0] MemAdrM, input logic [`XLEN-1:0] MemAdrM,
input logic [`XLEN-1:0] WriteDataM,
input logic StallW, input logic StallW,
// to CPU // to CPU
output logic [`XLEN-1:0] ReadDataW, output logic [`XLEN-1:0] ReadDataW,
output logic CommittedM, output logic CommittedM,
output logic SquashSCW, output logic SquashSCW,
output logic DataMisalignedM, output logic DataMisalignedM,
output logic DCacheStall, output logic LSUStall,
// to LSU // to LSU
output logic DisableTranslation, output logic DisableTranslation,
output logic [1:0] MemRWMtoDCache, output logic [1:0] MemRWMtoDCache,
output logic [2:0] SizetoDCache, output logic [2:0] Funct3MtoDCache,
output logic [1:0] AtomicMtoDCache, output logic [1:0] AtomicMtoDCache,
output logic [`XLEN-1:0] MemAdrMtoDCache, output logic [`XLEN-1:0] MemAdrMtoDCache,
output logic [`XLEN-1:0] WriteDataMtoDCache,
output logic StallWtoDCache, output logic StallWtoDCache,
// from LSU // from LSU
input logic CommittedMfromDCache, input logic CommittedMfromDCache,
input logic SquashSCWfromDCache, input logic SquashSCWfromDCache,
input logic DataMisalignedMfromDCache, input logic DataMisalignedMfromDCache,
input logic [`XLEN-1:0] ReadDataWfromDCache, input logic [`XLEN-1:0] ReadDataWfromDCache,
input logic DataStall input logic DCacheStall
); );
@ -141,11 +139,10 @@ module lsuArb
generate generate
assign PTWSize = (`XLEN==32 ? 3'b010 : 3'b011); // 32 or 64-bit access from htpw assign PTWSize = (`XLEN==32 ? 3'b010 : 3'b011); // 32 or 64-bit access from htpw
endgenerate endgenerate
mux2 #(3) sizemux(Funct3M, PTWSize, SelPTW, SizetoDCache); mux2 #(3) sizemux(Funct3M, PTWSize, SelPTW, Funct3MtoDCache);
assign AtomicMtoDCache = SelPTW ? 2'b00 : AtomicM; assign AtomicMtoDCache = SelPTW ? 2'b00 : AtomicM;
assign MemAdrMtoDCache = SelPTW ? HPTWPAdr : MemAdrM; assign MemAdrMtoDCache = SelPTW ? HPTWPAdr : MemAdrM;
assign WriteDataMtoDCache = SelPTW ? `XLEN'b0 : WriteDataM;
assign StallWtoDCache = SelPTW ? 1'b0 : StallW; assign StallWtoDCache = SelPTW ? 1'b0 : StallW;
// demux the inputs from LSU to walker or cpu's data port. // demux the inputs from LSU to walker or cpu's data port.
@ -158,7 +155,7 @@ module lsuArb
// *** need to rename DcacheStall and Datastall. // *** need to rename DcacheStall and Datastall.
// not clear at all. I think it should be LSUStall from the LSU, // not clear at all. I think it should be LSUStall from the LSU,
// which is demuxed to HPTWStall and CPUDataStall? (not sure on this last one). // which is demuxed to HPTWStall and CPUDataStall? (not sure on this last one).
assign HPTWStall = SelPTW ? DataStall : 1'b1; assign HPTWStall = SelPTW ? DCacheStall : 1'b1;
//assign HPTWStallD = SelPTW ? DataStall : 1'b1; //assign HPTWStallD = SelPTW ? DataStall : 1'b1;
/* -----\/----- EXCLUDED -----\/----- /* -----\/----- EXCLUDED -----\/-----
assign HPTWStallD = SelPTW ? DataStall : 1'b1; assign HPTWStallD = SelPTW ? DataStall : 1'b1;
@ -168,6 +165,6 @@ module lsuArb
.q(HPTWStall)); .q(HPTWStall));
-----/\----- EXCLUDED -----/\----- */ -----/\----- EXCLUDED -----/\----- */
assign DCacheStall = SelPTW ? 1'b1 : DataStall; // *** this is probably going to change. assign LSUStall = SelPTW ? 1'b1 : DCacheStall; // *** this is probably going to change.
endmodule endmodule

View File

@ -128,45 +128,36 @@ module wallypipelinedhart
// bus interface to dmem // cpu lsu interface
logic MemReadM, MemWriteM;
logic [1:0] AtomicMaskedM;
logic [2:0] Funct3M; logic [2:0] Funct3M;
logic [`XLEN-1:0] MemAdrM, WriteDataM; logic [`XLEN-1:0] MemAdrM, MemAdrE, WriteDataM;
logic [`PA_BITS-1:0] MemPAdrM;
logic [`XLEN-1:0] ReadDataW; logic [`XLEN-1:0] ReadDataW;
logic CommittedM;
// AHB ifu interface
logic [`PA_BITS-1:0] InstrPAdrF; logic [`PA_BITS-1:0] InstrPAdrF;
logic [`XLEN-1:0] InstrRData; logic [`XLEN-1:0] InstrRData;
logic InstrReadF; logic InstrReadF;
logic InstrAckF, MemAckW; logic InstrAckF;
logic CommitM, CommittedM;
// AHB LSU interface
logic [`PA_BITS-1:0] DCtoAHBPAdrM;
logic DCtoAHBReadM;
logic DCtoAHBWriteM;
logic DCfromAHBAck;
logic [`XLEN-1:0] DCfromAHBReadData;
logic [`XLEN-1:0] DCtoAHBWriteData;
logic CommitM;
logic BPPredWrongE; logic BPPredWrongE;
logic BPPredDirWrongM; logic BPPredDirWrongM;
logic BTBPredPCWrongM; logic BTBPredPCWrongM;
logic RASPredPCWrongM; logic RASPredPCWrongM;
logic BPPredClassNonCFIWrongM; logic BPPredClassNonCFIWrongM;
logic [`XLEN-1:0] WriteDatatmpM;
logic [4:0] InstrClassM; logic [4:0] InstrClassM;
logic [`XLEN-1:0] HRDATAW;
// IEU vs HPTW arbitration signals to send to LSU
logic [1:0] MemRWMtoLSU;
logic [2:0] SizeToLSU;
logic [1:0] AtomicMtoLSU;
logic [`XLEN-1:0] MemAdrMtoLSU;
logic [`XLEN-1:0] WriteDataMtoLSU;
logic [`XLEN-1:0] ReadDataWFromLSU;
logic CommittedMfromLSU;
logic SquashSCWfromLSU;
logic DataMisalignedMfromLSU;
logic StallWtoLSU;
logic StallWfromLSU;
logic [2:0] SizeFromLSU;
logic InstrAccessFaultF; logic InstrAccessFaultF;
logic [2:0] DCtoAHBSizeM;
@ -176,43 +167,33 @@ module wallypipelinedhart
ieu ieu(.*); // integer execution unit: integer register file, datapath and controller ieu ieu(.*); // integer execution unit: integer register file, datapath and controller
// mux2 #(`XLEN) OutputInput2mux(WriteDataM, FWriteDataM, FMemRWM[0], WriteDatatmpM);
lsu lsu(.clk(clk), lsu lsu(.clk(clk),
.reset(reset), .reset(reset),
.StallM(StallM), .StallM(StallM),
.FlushM(FlushM), .FlushM(FlushM),
.StallW(StallW), .StallW(StallW),
.FlushW(FlushW), .FlushW(FlushW),
// connected to arbiter (reconnect to CPU) // CPU interface
.MemRWM(MemRWM), .MemRWM(MemRWM),
.Funct3M(Funct3M), .Funct3M(Funct3M),
.Funct7M(InstrM[31:25]),
.AtomicM(AtomicM), .AtomicM(AtomicM),
.CommittedM(CommittedM), .CommittedM(CommittedM),
.SquashSCW(SquashSCW), .SquashSCW(SquashSCW),
.DataMisalignedM(DataMisalignedM), .DataMisalignedM(DataMisalignedM),
.MemAdrE(MemAdrE),
.MemAdrM(MemAdrM), .MemAdrM(MemAdrM),
.WriteDataM(WriteDataM), .WriteDataM(WriteDataM),
.ReadDataW(ReadDataW), .ReadDataW(ReadDataW),
// connected to ahb (all stay the same) // connected to ahb (all stay the same)
.CommitM(CommitM), .CommitM(CommitM),
.MemPAdrM(MemPAdrM), .DCtoAHBPAdrM(DCtoAHBPAdrM),
.MemReadM(MemReadM), .DCtoAHBReadM(DCtoAHBReadM),
.MemWriteM(MemWriteM), .DCtoAHBWriteM(DCtoAHBWriteM),
.AtomicMaskedM(AtomicMaskedM), .DCfromAHBAck(DCfromAHBAck),
.MemAckW(MemAckW), .DCfromAHBReadData(DCfromAHBReadData),
.HRDATAW(HRDATAW), .DCtoAHBWriteData(DCtoAHBWriteData),
.SizeFromLSU(SizeFromLSU), // stays the same
.StallWfromLSU(StallWfromLSU), // stays the same
.DSquashBusAccessM(DSquashBusAccessM), // probalby removed after dcache implemenation?
// currently not connected (but will need to be used for lsu talking to ahb.
.HADDR(HADDR),
.HSIZE(HSIZE),
.HBURST(HBURST),
.HWRITE(HWRITE),
// connect to csr or privilege and stay the same. // connect to csr or privilege and stay the same.
.PrivilegeModeW(PrivilegeModeW), // connects to csr .PrivilegeModeW(PrivilegeModeW), // connects to csr
@ -234,7 +215,6 @@ module wallypipelinedhart
.StoreMisalignedFaultM(StoreMisalignedFaultM), // connects to privilege .StoreMisalignedFaultM(StoreMisalignedFaultM), // connects to privilege
.StoreAccessFaultM(StoreAccessFaultM), // connects to privilege .StoreAccessFaultM(StoreAccessFaultM), // connects to privilege
// connected to hptw. Move to internal.
.PCF(PCF), .PCF(PCF),
.ITLBMissF(ITLBMissF), .ITLBMissF(ITLBMissF),
.PageTableEntryF(PageTableEntryF), .PageTableEntryF(PageTableEntryF),
@ -246,19 +226,34 @@ module wallypipelinedhart
.DTLBHitM(DTLBHitM), // not connected remove .DTLBHitM(DTLBHitM), // not connected remove
.DCacheStall(DCacheStall)) // change to DCacheStall .LSUStall(DCacheStall)); // change to DCacheStall
;
ahblite ebu( generate
//.InstrReadF(1'b0), if (`XLEN == 32) assign DCtoAHBSizeM = 3'b010;
//.InstrRData(InstrF), // hook up InstrF later else assign DCtoAHBSizeM = 3'b011;
.ISquashBusAccessF(1'b0), // *** temporary hack to disable PMP instruction fetch checking endgenerate;
.WriteDataM(WriteDataM),
.MemSizeM(SizeFromLSU[1:0]), .UnsignedLoadM(SizeFromLSU[2]),
.Funct7M(InstrM[31:25]), ahblite ebu(// IFU connections
.HRDATAW(HRDATAW), .InstrPAdrF(InstrPAdrF),
.StallW(StallWfromLSU), .InstrReadF(InstrReadF),
.InstrRData(InstrRData),
.InstrAckF(InstrAckF),
// LSU connections
.DCtoAHBPAdrM(DCtoAHBPAdrM), // rename to DCtoAHBPAdrM
.DCtoAHBReadM(DCtoAHBReadM), // rename to DCtoAHBReadM
.DCtoAHBWriteM(DCtoAHBWriteM), // rename to DCtoAHBWriteM
.DCtoAHBWriteData(DCtoAHBWriteData),
.DCfromAHBReadData(DCfromAHBReadData),
.DCfromAHBAck(DCfromAHBAck),
// remove these
.MemSizeM(DCtoAHBSizeM[1:0]), // *** depends on XLEN should be removed
.UnsignedLoadM(1'b0),
.Funct7M(7'b0),
.HRDATAW(),
.StallW(1'b0),
.AtomicMaskedM(2'b00),
.*); .*);