diff --git a/src/ieu/controller.sv b/src/ieu/controller.sv index be8ad4606..22cbaa9d5 100644 --- a/src/ieu/controller.sv +++ b/src/ieu/controller.sv @@ -458,12 +458,15 @@ module controller import cvw::*; #(parameter cvw_t P) ( assign MDUStallD = MDUE & MatchDE; // Int mult/div is at least two cycle latency, even when coming from the FDIV assign CSRRdStallD = CSRReadE & MatchDE; + logic StoreStallD; + // atomic operations are also detected as MemRWE[1] & MemRWE[0] assign AMOStallD = &MemRWE & MemRWD[1]; // Read after atomic operation causes structural hazard assign CMOStallD = (|CMOpE) & (|CMOpD); // *** CMO op after CMO op causes structural hazard. + assign StoreStallD = MemRWD[1] & MemRWE[0]; // CMO.inval, CMO.flush, and CMO.clean only update valid and dirty cache bits and never the tag or data arrays. There is no structual hazard. // CMO.zero always updates the tag and data arrays, but the cachefsm inserts the wait state if the next instruction reads the tag or data arrays. // Structural hazard causes stall if any of these events occur - assign StructuralStallD = LoadStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | AMOStallD | CMOStallD; + assign StructuralStallD = LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | AMOStallD | CMOStallD; endmodule diff --git a/src/lsu/dtim.sv b/src/lsu/dtim.sv index f896b506b..2817eafac 100644 --- a/src/lsu/dtim.sv +++ b/src/lsu/dtim.sv @@ -28,17 +28,15 @@ //////////////////////////////////////////////////////////////////////////////////////////////// module dtim import cvw::*; #(parameter cvw_t P) ( - input logic clk, reset, - input logic FlushW, - input logic ce, // Chip Enable. 0: Holds ReadDataWordM - input logic [1:0] MemRWM, // Read/Write control - input logic [1:0] MemRWE, // Read/Write control - input logic [P.PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address - input logic [P.LLEN-1:0] WriteDataM, // Write data from IEU - input logic [P.LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write - output logic [P.LLEN-1:0] ReadDataWordM, // Read data before subword selection - output logic DTIMStall, - output logic DTIMSelWrite + input logic clk, reset, + input logic FlushW, + input logic ce, // Chip Enable. 0: Holds ReadDataWordM + input logic [1:0] MemRWM, // Read/Write control + input logic [1:0] MemRWE, // Read/Write control + input logic [P.PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address + input logic [P.LLEN-1:0] WriteDataM, // Write data from IEU + input logic [P.LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write + output logic [P.LLEN-1:0] ReadDataWordM // Read data before subword selection ); logic we; @@ -50,16 +48,8 @@ module dtim import cvw::*; #(parameter cvw_t P) ( localparam ADDR_WDITH = $clog2(DEPTH); localparam OFFSET = $clog2(LLENBYTES); - logic DTIMStallHazard, DTIMStallHazardD; - - assign DTIMStallHazard = MemRWM[0] & MemRWE[1]; - flopr #(1) DTIMStallReg(clk, reset, DTIMStallHazard, DTIMStallHazardD); - assign DTIMStall = DTIMStallHazard & ~DTIMStallHazardD; - - assign DTIMSelWrite = MemRWM[0] & ~(DTIMStallHazard & ~DTIMStall); - - assign we = DTIMSelWrite & ~FlushW; // have to ignore write if Trap. + assign we = MemRWM[0] & ~FlushW; // have to ignore write if Trap. ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(DEPTH), .WIDTH(P.LLEN)) - ram(.clk, .ce(ce | DTIMSelWrite), .we, .bwe(ByteMaskM), .addr(DTIMAdr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM)); + ram(.clk, .ce, .we, .bwe(ByteMaskM), .addr(DTIMAdr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM)); endmodule diff --git a/src/lsu/lsu.sv b/src/lsu/lsu.sv index 840d03876..de10f68cd 100644 --- a/src/lsu/lsu.sv +++ b/src/lsu/lsu.sv @@ -150,7 +150,6 @@ module lsu import cvw::*; #(parameter cvw_t P) ( logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation logic SelDTIM; // Select DTIM rather than bus or D$ logic [P.XLEN-1:0] WriteDataZM; - logic DTIMStall; ///////////////////////////////////////////////////////////////////////////////////////////// // Pipeline for IEUAdr E to M @@ -220,7 +219,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( // the trap module. assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM; assign GatedStallW = StallW & ~SelHPTW; - assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall | DTIMStall; + assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall; assign LSUStallM = CacheBusHPWTStall | SpillStallM; ///////////////////////////////////////////////////////////////////////////////////////////// @@ -269,10 +268,9 @@ module lsu import cvw::*; #(parameter cvw_t P) ( if (P.DTIM_SUPPORTED) begin : dtim logic [P.PA_BITS-1:0] DTIMAdr; logic [1:0] DTIMMemRWM; - logic DTIMSelWrite; // The DTIM uses untranslated addresses, so it is not compatible with virtual memory. - mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], DTIMSelWrite, DTIMAdr); + mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], MemRWM[0], DTIMAdr); assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0; // **** fix ReadDataWordM to be LLEN. ByteMask is wrong length. // **** create config to support DTIM with floating point. @@ -280,9 +278,7 @@ module lsu import cvw::*; #(parameter cvw_t P) ( dtim #(P) dtim(.clk, .reset, .ce(~GatedStallW), .MemRWE(MemRWE), // *** update when you update the cache RWE .MemRWM(DTIMMemRWM), .DTIMAdr, .FlushW, .WriteDataM(LSUWriteDataM), - .ReadDataWordM(DTIMReadDataWordM[P.LLEN-1:0]), .ByteMaskM(ByteMaskM), .DTIMStall, .DTIMSelWrite); - end else begin - assign DTIMStall = '0; + .ReadDataWordM(DTIMReadDataWordM[P.LLEN-1:0]), .ByteMaskM(ByteMaskM)); end if (P.BUS_SUPPORTED) begin : bus if(P.DCACHE_SUPPORTED) begin : dcache