forked from Github_Repos/cvw
Hmm. the icache and ifu didn't have a CommittedF signals going back to the privileged unit. They probably should. If an interrupt occurred during the middle of an instruction fetch icache miss I think it would corrupt the icache.
This commit is contained in:
parent
87485ed237
commit
638e506d0b
@ -53,14 +53,14 @@ module ahbinterface #(parameter LSU = 0) // **** modify to use LSU/ifu parameter
|
||||
input logic CPUBusy,
|
||||
output logic BusStall,
|
||||
output logic BusCommitted,
|
||||
output logic [(LSU ? `XLEN : 32)-1:0] ReadDataWord);
|
||||
output logic [(LSU ? `XLEN : 32)-1:0] FetchBuffer);
|
||||
|
||||
logic CaptureEn;
|
||||
|
||||
/// *** only 32 bit for IFU.
|
||||
localparam LEN = (LSU ? `XLEN : 32);
|
||||
|
||||
flopen #(LEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA[LEN-1:0]), .q(ReadDataWord));
|
||||
flopen #(LEN) fb(.clk(HCLK), .en(CaptureEn), .d(HRDATA[LEN-1:0]), .q(FetchBuffer));
|
||||
|
||||
if(LSU) begin
|
||||
// delay HWDATA by 1 cycle per spec; *** assumes AHBW = XLEN
|
||||
|
@ -53,6 +53,7 @@ module ifu (
|
||||
output logic BPPredWrongE,
|
||||
// Mem
|
||||
input logic RetM, TrapM,
|
||||
output logic CommittedF,
|
||||
input logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||
input logic InvalidateICacheM,
|
||||
output logic [31:0] InstrD, InstrM,
|
||||
@ -116,6 +117,8 @@ module ifu (
|
||||
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF;
|
||||
// branch predictor signal
|
||||
logic [`XLEN-1:0] PCNext1F, PCNext2F, PCNext0F;
|
||||
logic BusCommittedF, CacheCommittedF;
|
||||
|
||||
|
||||
assign PCFExt = {2'b00, PCFSpill};
|
||||
|
||||
@ -180,6 +183,12 @@ module ifu (
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Memory
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// CommittedM tells the CPU's privilege unit the current instruction
|
||||
// in the memory stage is a memory operaton and that memory operation is either completed
|
||||
// or is partially executed. Partially completed memory operations need to prevent an interrupts.
|
||||
// There is not a clean way to restore back to a partial executed instruction. CommiteedM will
|
||||
// delay the interrupt until the LSU is in a clean state.
|
||||
assign CommittedF = CacheCommittedF | BusCommittedF;
|
||||
|
||||
// logic [`XLEN-1:0] InstrRawF;
|
||||
// assign InstrRawF = InstrRawF[31:0];
|
||||
@ -221,7 +230,7 @@ module ifu (
|
||||
.Atomic('0), .FlushCache('0),
|
||||
.NextAdr(PCNextFSpill[11:0]),
|
||||
.PAdr(PCPF),
|
||||
.CacheCommitted(), .InvalidateCache(InvalidateICacheM));
|
||||
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM));
|
||||
ahbcacheinterface #(WORDSPERLINE, LINELEN, LOGBWPL, `ICACHE)
|
||||
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
|
||||
.HRDATA,
|
||||
@ -231,7 +240,7 @@ module ifu (
|
||||
.CacheBusAck(ICacheBusAck),
|
||||
.FetchBuffer, .PAdr(PCPF),
|
||||
.BusRW, .CPUBusy,
|
||||
.BusStall, .BusCommitted());
|
||||
.BusStall, .BusCommitted(BusCommittedF));
|
||||
|
||||
mux2 #(32) UnCachedDataMux(.d0(FinalInstrRawF), .d1(FetchBuffer[32-1:0]),
|
||||
.s(SelUncachedAdr), .y(InstrRawF[31:0]));
|
||||
@ -245,7 +254,7 @@ module ifu (
|
||||
ahbinterface #(0) ahbinterface(.HCLK(clk), .HRESETn(~reset), .HREADY(IFUHREADY),
|
||||
.HRDATA(HRDATA), .HTRANS(IFUHTRANS), .HWRITE(IFUHWRITE), .HWDATA(),
|
||||
.HWSTRB(), .BusRW, .ByteMask(), .WriteData('0),
|
||||
.CPUBusy, .BusStall, .BusCommitted(), .ReadDataWord(InstrRawF[31:0]));
|
||||
.CPUBusy, .BusStall, .BusCommitted(BusCommittedF), .FetchBuffer(InstrRawF[31:0]));
|
||||
|
||||
assign IFUHBURST = 3'b0;
|
||||
assign {ICacheFetchLine, ICacheStallF, FinalInstrRawF} = '0;
|
||||
|
@ -279,7 +279,7 @@ module lsu (
|
||||
ahbinterface #(1) ahbinterface(.HCLK(clk), .HRESETn(~reset), .HREADY(LSUHREADY),
|
||||
.HRDATA(HRDATA), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HWDATA(LSUHWDATA),
|
||||
.HWSTRB(LSUHWSTRB), .BusRW, .ByteMask(ByteMaskM), .WriteData(LSUWriteDataM),
|
||||
.CPUBusy, .BusStall, .BusCommitted(BusCommittedM), .ReadDataWord(ReadDataWordM));
|
||||
.CPUBusy, .BusStall, .BusCommitted(BusCommittedM), .FetchBuffer(ReadDataWordM));
|
||||
|
||||
assign ReadDataWordMuxM = ReadDataWordM; // from byte swapping
|
||||
assign LSUHBURST = 3'b0;
|
||||
|
@ -39,7 +39,7 @@ module privileged (
|
||||
output logic [`XLEN-1:0] PrivilegedNextPCM,
|
||||
output logic RetM, TrapM,
|
||||
output logic sfencevmaM,
|
||||
input logic InstrValidM, CommittedM,
|
||||
input logic InstrValidM, CommittedM, CommittedF,
|
||||
input logic FRegWriteM, LoadStallD,
|
||||
input logic BPPredDirWrongM,
|
||||
input logic BTBPredPCWrongM,
|
||||
@ -158,7 +158,7 @@ module privileged (
|
||||
.PrivilegeModeW,
|
||||
.MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MEDELEG_REGW,
|
||||
.STATUS_MIE, .STATUS_SIE,
|
||||
.InstrValidM, .CommittedM,
|
||||
.InstrValidM, .CommittedM, .CommittedF,
|
||||
.TrapM, .RetM,
|
||||
.InterruptM, .IntPendingM, .DelegateM,
|
||||
.CauseM);
|
||||
|
@ -42,7 +42,7 @@ module trap (
|
||||
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
|
||||
input logic [`XLEN-1:0] MEDELEG_REGW,
|
||||
input logic STATUS_MIE, STATUS_SIE,
|
||||
input logic InstrValidM, CommittedM,
|
||||
input logic InstrValidM, CommittedM, CommittedF,
|
||||
output logic TrapM, RetM,
|
||||
output logic InterruptM, IntPendingM, DelegateM,
|
||||
output logic [`LOG_XLEN-1:0] CauseM
|
||||
@ -63,7 +63,7 @@ module trap (
|
||||
assign PendingIntsM = MIP_REGW & MIE_REGW;
|
||||
assign IntPendingM = |PendingIntsM;
|
||||
assign ValidIntsM = {12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW;
|
||||
assign InterruptM = (|ValidIntsM) && InstrValidM && ~(CommittedM); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
|
||||
assign InterruptM = (|ValidIntsM) && InstrValidM && ~(CommittedM | CommittedF); // *** RT. CommittedM is a temporary hack to prevent integer division from having an interrupt during divide.
|
||||
assign DelegateM = `S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM]) &
|
||||
(PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE);
|
||||
|
||||
|
@ -165,7 +165,7 @@ module wallypipelinedcore (
|
||||
logic InstrDAPageFaultF;
|
||||
logic BigEndianM;
|
||||
logic FCvtIntE;
|
||||
|
||||
logic CommittedF;
|
||||
|
||||
ifu ifu(
|
||||
.clk, .reset,
|
||||
@ -182,7 +182,7 @@ module wallypipelinedcore (
|
||||
.BPPredWrongE,
|
||||
|
||||
// Mem
|
||||
.RetM, .TrapM, .PrivilegedNextPCM, .InvalidateICacheM,
|
||||
.RetM, .TrapM, .CommittedF, .PrivilegedNextPCM, .InvalidateICacheM,
|
||||
.InstrD, .InstrM, .PCM, .InstrClassM, .BPPredDirWrongM,
|
||||
.BTBPredPCWrongM, .RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
||||
|
||||
@ -336,7 +336,7 @@ module wallypipelinedcore (
|
||||
.InstrM, .CSRReadValW, .PrivilegedNextPCM,
|
||||
.RetM, .TrapM,
|
||||
.sfencevmaM,
|
||||
.InstrValidM, .CommittedM,
|
||||
.InstrValidM, .CommittedM, .CommittedF,
|
||||
.FRegWriteM, .LoadStallD,
|
||||
.BPPredDirWrongM, .BTBPredPCWrongM,
|
||||
.RASPredPCWrongM, .BPPredClassNonCFIWrongM,
|
||||
|
Loading…
Reference in New Issue
Block a user