This commit is contained in:
Rose Thompson 2023-12-29 15:13:18 -06:00
commit f59fa5089d
22 changed files with 164 additions and 199 deletions

View File

@ -124,7 +124,7 @@ git clone https://github.com/verilator/verilator # Only first time
unset VERILATOR_ROOT # For bash unset VERILATOR_ROOT # For bash
cd verilator cd verilator
git pull # Make sure git repository is up-to-date git pull # Make sure git repository is up-to-date
git checkout master # Use development branch (e.g. recent bug fixes) git checkout master
autoconf # Create ./configure script autoconf # Create ./configure script
./configure # Configure and create Makefile ./configure # Configure and create Makefile
make -j ${NUM_THREADS} # Build Verilator itself (if error, try just 'make') make -j ${NUM_THREADS} # Build Verilator itself (if error, try just 'make')

View File

@ -78,7 +78,8 @@ for test in tests64i:
configs.append(tc) configs.append(tc)
tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused
tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zi", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "wally32a", "wally32priv", "wally32periph"] tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "wally32a", "wally32priv", "wally32periph"]
#tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zicboz", "arch32zcb", "wally32a", "wally32priv", "wally32periph"]
for test in tests32gc: for test in tests32gc:
tc = TestCase( tc = TestCase(
name=test, name=test,
@ -126,15 +127,19 @@ for test in ahbTests:
configs.append(tc) configs.append(tc)
tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
"arch64priv", "arch64c", "arch64m", "arch64a", "arch64zi", "wally64a", "wally64periph", "wally64priv"] "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv"]
#tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
# "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"]
if (coverage): # delete all but 64gc tests when running coverage if (coverage): # delete all but 64gc tests when running coverage
configs = [] configs = []
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
"arch64zi", "wally64a", "wally64periph", "wally64priv", "arch64zifencei", "wally64a", "wally64periph", "wally64priv",
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # add when working: "arch64zicboz", "arch64zcb",
if (fp): if (fp):
tests64gc.append("arch64f") tests64gc.append("arch64f")
tests64gc.append("arch64d") tests64gc.append("arch64d")
tests64gc.append("arch64f_fma")
tests64gc.append("arch64d_fma")
coverStr = '-coverage' coverStr = '-coverage'
else: else:
coverStr = '' coverStr = ''

6
src/cache/cache.sv vendored
View File

@ -38,7 +38,7 @@ module cache import cvw::*; #(parameter cvw_t P,
input logic [1:0] CacheRW, // [1] Read, [0] Write input logic [1:0] CacheRW, // [1] Read, [0] Write
input logic FlushCache, // Flush all dirty lines back to memory input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, // Clear all valid bits input logic InvalidateCache, // Clear all valid bits
input logic [3:0] CMOp, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero input logic [3:0] CMOpM, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits. input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits.
input logic [PA_BITS-1:0] PAdr, // Physical address input logic [PA_BITS-1:0] PAdr, // Physical address
input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only) input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only)
@ -186,7 +186,7 @@ module cache import cvw::*; #(parameter cvw_t P,
// Merge write data into fetched cache line for store miss // Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
.d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOp[3]), .y(LineWriteData[8*index+7:8*index])); .d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOpM[3]), .y(LineWriteData[8*index+7:8*index]));
end end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
end end
@ -231,5 +231,5 @@ module cache import cvw::*; #(parameter cvw_t P,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush, .ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn); .InvalidateCache, .CMOpM, .CacheEn, .LRUWriteEn);
endmodule endmodule

32
src/cache/cachefsm.sv vendored
View File

@ -41,7 +41,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
input logic [1:0] CacheRWNext, // [1] Read, [0] Write input logic [1:0] CacheRWNext, // [1] Read, [0] Write
input logic FlushCache, // Flush all dirty lines back to memory input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, // Clear all valid bits input logic InvalidateCache, // Clear all valid bits
input logic [3:0] CMOp, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero input logic [3:0] CMOpM, // 0001: cbo.inval; 0010: cbo.flush; 0100: cbo.clean; 1000: cbo.zero
// Bus controls // Bus controls
input logic CacheBusAck, // Bus operation completed input logic CacheBusAck, // Bus operation completed
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback) output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
@ -97,8 +97,8 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign AnyUpdateHit = (CacheRW[0]) & CacheHit; // exclusion-tag: icache storeAMO1 assign AnyUpdateHit = (CacheRW[0]) & CacheHit; // exclusion-tag: icache storeAMO1
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
assign CMOZeroNoEviction = CMOp[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now assign CMOZeroNoEviction = CMOpM[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now
assign CMOWriteback = ((CMOp[1] | CMOp[2]) & CacheHit & HitLineDirty) | CMOp[3] & LineDirty; assign CMOWriteback = ((CMOpM[1] | CMOpM[2]) & CacheHit & HitLineDirty) | CMOpM[3] & LineDirty;
assign FlushFlag = FlushAdrFlag & FlushWayFlag; assign FlushFlag = FlushAdrFlag & FlushWayFlag;
@ -133,7 +133,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY; else NextState = STATE_READY;
// exclusion-tag-start: icache case // exclusion-tag-start: icache case
STATE_WRITEBACK: if(CacheBusAck & ~(|CMOp[3:1])) NextState = STATE_FETCH; STATE_WRITEBACK: if(CacheBusAck & ~(|CMOpM[3:1])) NextState = STATE_FETCH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; // Read_hold lowers CacheStall else if(CacheBusAck) NextState = STATE_READ_HOLD; // Read_hold lowers CacheStall
else NextState = STATE_WRITEBACK; else NextState = STATE_WRITEBACK;
// eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack. // eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack.
@ -160,25 +160,25 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
// write enables internal to cache // write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE | assign SetValid = CurrState == STATE_WRITE_LINE |
(CurrState == STATE_READY & CMOZeroNoEviction) | (CurrState == STATE_READY & CMOZeroNoEviction) |
(CurrState == STATE_WRITEBACK & CacheBusAck & CMOp[3]); (CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]);
assign ClearValid = (CurrState == STATE_READY & CMOp[0]) | assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) |
(CurrState == STATE_WRITEBACK & CMOp[2] & CacheBusAck); (CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck);
// coverage off -item e 1 -fecexprrow 8 // coverage off -item e 1 -fecexprrow 8
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) | assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) | (CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
(CurrState == STATE_WRITEBACK & CMOp[3] & CacheBusAck); (CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
// exclusion-tag-start: icache flushdirtycontrols // exclusion-tag-start: icache flushdirtycontrols
assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) | (CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
(CurrState == STATE_WRITEBACK & (CMOp[3] & CacheBusAck)); (CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set. (CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
// Flush and eviction controls // Flush and eviction controls
CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck; CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOp[1] | CMOp[2])) | (CacheBusAck & CMOp[3]))) | assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
(CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) | (CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) |
(CurrState == STATE_WRITE_LINE); (CurrState == STATE_WRITE_LINE);
assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | ~CacheBusAck)) | assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2] | ~CacheBusAck)) |
(CurrState == STATE_READY & AnyMiss & LineDirty); (CurrState == STATE_READY & AnyMiss & LineDirty);
/* -----\/----- EXCLUDED -----\/----- /* -----\/----- EXCLUDED -----\/-----
assign SelFlush = (CurrState == STATE_READY & FlushCache) | assign SelFlush = (CurrState == STATE_READY & FlushCache) |
@ -198,7 +198,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
// Bus interface controls // Bus interface controls
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
(CurrState == STATE_FETCH & ~CacheBusAck) | (CurrState == STATE_FETCH & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOp)); (CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM));
logic LoadMiss; logic LoadMiss;
@ -208,14 +208,14 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW
(CurrState == STATE_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]) & ~CacheBusAck); (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & ~CacheBusAck);
assign SelAdrData = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOp))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed assign SelAdrData = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) |
resetDelay; resetDelay;
assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOp))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) |

View File

@ -28,9 +28,9 @@
module hazard import cvw::*; #(parameter cvw_t P) ( module hazard import cvw::*; #(parameter cvw_t P) (
input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic BPWrongE, CSRWriteFenceM, RetM, TrapM,
input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, input logic StructuralStallD,
input logic LSUStallM, IFUStallF, input logic LSUStallM, IFUStallF,
input logic FCvtIntStallD, FPUStallD, input logic FPUStallD,
input logic DivBusyE, FDivBusyE, input logic DivBusyE, FDivBusyE,
input logic wfiM, IntPendingM, input logic wfiM, IntPendingM,
// Stall & flush outputs // Stall & flush outputs
@ -82,7 +82,7 @@ module hazard import cvw::*; #(parameter cvw_t P) (
// The IFU stalls the entire pipeline rather than just Fetch to avoid complications with instructions later in the pipeline causing Exceptions // The IFU stalls the entire pipeline rather than just Fetch to avoid complications with instructions later in the pipeline causing Exceptions
// A trap could be asserted at the start of a IFU/LSU stall, and should flush the memory operation // A trap could be asserted at the start of a IFU/LSU stall, and should flush the memory operation
assign StallFCause = '0; assign StallFCause = '0;
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallDCause = (StructuralStallD | FPUStallD) & ~FlushDCause;
assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause;
assign StallMCause = WFIStallM & ~FlushMCause; assign StallMCause = WFIStallM & ~FlushMCause;
// Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1.

View File

@ -27,8 +27,8 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) ( module alu import cvw::*; #(parameter cvw_t P) (
input logic [WIDTH-1:0] A, B, // Operands input logic [P.XLEN-1:0] A, B, // Operands
input logic W64, // W64-type instruction input logic W64, // W64-type instruction
input logic SubArith, // Subtraction or arithmetic shift input logic SubArith, // Subtraction or arithmetic shift
input logic [2:0] ALUSelect, // ALU mux select signal input logic [2:0] ALUSelect, // ALU mux select signal
@ -37,14 +37,14 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
input logic [2:0] Funct3, // For BMU decoding input logic [2:0] Funct3, // For BMU decoding
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
input logic BMUActiveE, // Bit manipulation instruction being executed input logic BMUActiveE, // Bit manipulation instruction being executed
output logic [WIDTH-1:0] ALUResult, // ALU result output logic [P.XLEN-1:0] ALUResult, // ALU result
output logic [WIDTH-1:0] Sum); // Sum of operands output logic [P.XLEN-1:0] Sum); // Sum of operands
// CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction. // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction.
// FullResult = ALU result before adjusting for a RV64 w-suffix instruction. // FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult, PreALUResult; // Intermediate Signals logic [P.XLEN-1:0] CondMaskInvB, Shift, FullResult, PreALUResult; // Intermediate Signals
logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux logic [P.XLEN-1:0] CondMaskB; // Result of B mask select mux
logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux logic [P.XLEN-1:0] CondShiftA; // Result of A shifted select mux
logic Carry, Neg; // Flags: carry out, negative logic Carry, Neg; // Flags: carry out, negative
logic LT, LTU; // Less than, Less than unsigned logic LT, LTU; // Less than, Less than unsigned
logic Asign, Bsign; // Sign bits of A, B logic Asign, Bsign; // Sign bits of A, B
@ -53,7 +53,7 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
// CondMaskB is B for add/sub, or a masked version of B for certain bit manipulation instructions // CondMaskB is B for add/sub, or a masked version of B for certain bit manipulation instructions
// CondShiftA is A for add/sub or a shifted version of A for shift-and-add BMU instructions // CondShiftA is A for add/sub or a shifted version of A for shift-and-add BMU instructions
assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB; assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB;
assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(P.XLEN-1){1'b0}}, SubArith};
// Shifts (configurable for rotation) // Shifts (configurable for rotation)
shifter #(P) sh(.A, .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2])); shifter #(P) sh(.A, .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2]));
@ -62,9 +62,9 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
// Overflow occurs when the numbers being subtracted have the opposite sign // Overflow occurs when the numbers being subtracted have the opposite sign
// and the result has the opposite sign of A. // and the result has the opposite sign of A.
// LT is simplified from Overflow = Asign & Bsign & Asign & Neg; LT = Neg ^ Overflow // LT is simplified from Overflow = Asign & Bsign & Asign & Neg; LT = Neg ^ Overflow
assign Neg = Sum[WIDTH-1]; assign Neg = Sum[P.XLEN-1];
assign Asign = A[WIDTH-1]; assign Asign = A[P.XLEN-1];
assign Bsign = B[WIDTH-1]; assign Bsign = B[P.XLEN-1];
assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg; assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg;
assign LTU = ~Carry; assign LTU = ~Carry;
@ -73,21 +73,22 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
case (ALUSelect) case (ALUSelect)
3'b000: FullResult = Sum; // add or sub (including address generation) 3'b000: FullResult = Sum; // add or sub (including address generation)
3'b001: FullResult = Shift; // sll, sra, or srl 3'b001: FullResult = Shift; // sll, sra, or srl
3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt 3'b010: FullResult = {{(P.XLEN-1){1'b0}}, LT}; // slt
3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu 3'b011: FullResult = {{(P.XLEN-1){1'b0}}, LTU}; // sltu
3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv 3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv
3'b101: FullResult = (P.ZBS_SUPPORTED | P.ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported) 3'b101: FullResult = (P.ZBS_SUPPORTED | P.ZBB_SUPPORTED) ? {{(P.XLEN-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported)
3'b110: FullResult = A | CondMaskInvB; // or, orn, bset 3'b110: FullResult = A | CondMaskInvB; // or, orn, bset
3'b111: FullResult = A & CondMaskInvB; // and, bclr 3'b111: FullResult = A & CondMaskInvB; // and, bclr
endcase endcase
// Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits
if (WIDTH == 64) assign PreALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; if (P.XLEN == 64) assign PreALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign PreALUResult = FullResult; else assign PreALUResult = FullResult;
// Final Result B instruction select mux // Final Result B instruction select mux
if (P.ZBC_SUPPORTED | P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED) begin : bitmanipalu if (P.ZBC_SUPPORTED | P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED) begin : bitmanipalu
bitmanipalu #(P, WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, .BMUActiveE, bitmanipalu #(P) balu(
.A, .B, .W64, .BSelect, .ZBBSelect, .BMUActiveE,
.Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult, .Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult,
.CondMaskB, .CondShiftA, .ALUResult); .CondMaskB, .CondShiftA, .ALUResult);
end else begin end else begin

View File

@ -27,9 +27,8 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module bitmanipalu import cvw::*; #(parameter cvw_t P, module bitmanipalu import cvw::*; #(parameter cvw_t P) (
parameter WIDTH=32) ( input logic [P.XLEN-1:0] A, B, // Operands
input logic [WIDTH-1:0] A, B, // Operands
input logic W64, // W64-type instruction input logic W64, // W64-type instruction
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] ZBBSelect, // ZBB mux select signal
@ -38,37 +37,37 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P,
input logic LTU, // less than unsigned flag input logic LTU, // less than unsigned flag
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
input logic BMUActiveE, // Bit manipulation instruction being executed input logic BMUActiveE, // Bit manipulation instruction being executed
input logic [WIDTH-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals input logic [P.XLEN-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals
output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions output logic [P.XLEN-1:0] CondMaskB, // B is conditionally masked for ZBS instructions
output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions output logic [P.XLEN-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions
output logic [WIDTH-1:0] ALUResult); // Result output logic [P.XLEN-1:0] ALUResult); // Result
logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result logic [P.XLEN-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result
logic [WIDTH-1:0] MaskB; // BitMask of B logic [P.XLEN-1:0] MaskB; // BitMask of B
logic [WIDTH-1:0] RevA; // Bit-reversed A logic [P.XLEN-1:0] RevA; // Bit-reversed A
logic Rotate; // Indicates if it is Rotate instruction logic Rotate; // Indicates if it is Rotate instruction
logic Mask; // Indicates if it is ZBS instruction logic Mask; // Indicates if it is ZBS instruction
logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
logic [WIDTH-1:0] CondZextA; // A Conditional Extend Intermediary Signal logic [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal
logic [WIDTH-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity logic [P.XLEN-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity
// gate data inputs to BMU to only operate when BMU is active // gate data inputs to BMU to only operate when BMU is active
assign ABMU = A & {WIDTH{BMUActiveE}}; assign ABMU = A & {P.XLEN{BMUActiveE}};
assign BBMU = B & {WIDTH{BMUActiveE}}; assign BBMU = B & {P.XLEN{BMUActiveE}};
// Extract control signals from bitmanip ALUControl. // Extract control signals from bitmanip ALUControl.
assign {Mask, PreShift} = BALUControl[1:0]; assign {Mask, PreShift} = BALUControl[1:0];
// Mask Generation Mux // Mask Generation Mux
if (P.ZBS_SUPPORTED) begin: zbsdec if (P.ZBS_SUPPORTED) begin: zbsdec
decoder #($clog2(WIDTH)) maskgen(BBMU[$clog2(WIDTH)-1:0], MaskB); decoder #($clog2(P.XLEN)) maskgen(BBMU[$clog2(P.XLEN)-1:0], MaskB);
mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); mux2 #(P.XLEN) maskmux(B, MaskB, Mask, CondMaskB);
end else assign CondMaskB = B; end else assign CondMaskB = B;
// 0-3 bit Pre-Shift Mux // 0-3 bit Pre-Shift Mux
if (P.ZBA_SUPPORTED) begin: zbapreshift if (P.ZBA_SUPPORTED) begin: zbapreshift
if (WIDTH == 64) begin if (P.XLEN == 64) begin
mux2 #(64) zextmux(A, {{32{1'b0}}, A[31:0]}, W64, CondZextA); mux2 #(64) zextmux(A, {{32{1'b0}}, A[31:0]}, W64, CondZextA);
end else assign CondZextA = A; end else assign CondZextA = A;
assign PreShiftAmt = Funct3[2:1] & {2{PreShift}}; assign PreShiftAmt = Funct3[2:1] & {2{PreShift}};
@ -80,17 +79,17 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P,
// Bit reverse needed for some ZBB, ZBC instructions // Bit reverse needed for some ZBB, ZBC instructions
if (P.ZBC_SUPPORTED | P.ZBB_SUPPORTED) begin: bitreverse if (P.ZBC_SUPPORTED | P.ZBB_SUPPORTED) begin: bitreverse
bitreverse #(WIDTH) brA(.A(ABMU), .RevA); bitreverse #(P.XLEN) brA(.A(ABMU), .RevA);
end end
// ZBC Unit // ZBC Unit
if (P.ZBC_SUPPORTED) begin: zbc if (P.ZBC_SUPPORTED) begin: zbc
zbc #(WIDTH) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult); zbc #(P.XLEN) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult);
end else assign ZBCResult = 0; end else assign ZBCResult = 0;
// ZBB Unit // ZBB Unit
if (P.ZBB_SUPPORTED) begin: zbb if (P.ZBB_SUPPORTED) begin: zbb
zbb #(WIDTH) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult); zbb #(P.XLEN) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult);
end else assign ZBBResult = 0; end else assign ZBBResult = 0;
// Result Select Mux // Result Select Mux

View File

@ -39,10 +39,14 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
output logic JumpD, // Jump instruction output logic JumpD, // Jump instruction
output logic BranchD, // Branch instruction output logic BranchD, // Branch instruction
// Execute stage control signals output logic StructuralStallD, // Structural stalls detected by controller
output logic LoadStallD, // Structural stalls for load, sent to performance counters
output logic [4:0] Rs1D, Rs2D, // Register sources to read in Decode or Execute stage
// Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] FlagsE, // Comparison flags ({eq, lt}) input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
input logic FWriteIntE, // Write integer register, coming from FPU controller input logic FWriteIntE, // Write integer register, coming from FPU controller
input logic FCvtIntE, // FPU convert float to int
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit) output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
output logic ALUSrcAE, ALUSrcBE, // ALU operands output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, // Selects result to pass on to Memory stage output logic ALUResultSrcE, // Selects result to pass on to Memory stage
@ -65,7 +69,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic [3:0] CMOpM, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero output logic [3:0] CMOpM, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
output logic IFUPrefetchE, // instruction prefetch output logic IFUPrefetchE, // instruction prefetch
output logic LSUPrefetchM, // data prefetch output logic LSUPrefetchM, // data prefetch
output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers
// Memory stage control signals // Memory stage control signals
input logic StallM, FlushM, // Stall, flush Memory stage input logic StallM, FlushM, // Stall, flush Memory stage
output logic [1:0] MemRWE, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write output logic [1:0] MemRWE, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write
@ -83,14 +87,16 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic [2:0] ResultSrcW, // Select source of result to write back to register file output logic [2:0] ResultSrcW, // Select source of result to write back to register file
// Stall during CSRs // Stall during CSRs
output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions
output logic StoreStallD // Store (memory write) causes stall output logic [4:0] RdE, RdM, // Pipelined destination registers
// Forwarding controls
output logic [4:0] RdW // Register destinations in Execute, Memory, or Writeback stage
); );
logic [4:0] Rs1E, Rs2E; // pipelined register sources
logic [6:0] OpD; // Opcode in Decode stage logic [6:0] OpD; // Opcode in Decode stage
logic [2:0] Funct3D; // Funct3 field in Decode stage logic [2:0] Funct3D; // Funct3 field in Decode stage
logic [6:0] Funct7D; // Funct7 field in Decode stage logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs1D, Rs2D, RdD; // Rs1/2 source register / dest reg in Decode stage logic [4:0] RdD; // Rs1/2 source register / dest reg in Decode stage
`define CTRLW 24 `define CTRLW 24
@ -146,6 +152,9 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic [3:0] CMOpD, CMOpE; // which CMO instruction 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero logic [3:0] CMOpD, CMOpE; // which CMO instruction 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
logic IFUPrefetchD; // instruction prefetch logic IFUPrefetchD; // instruction prefetch
logic LSUPrefetchD, LSUPrefetchE; // data prefetch logic LSUPrefetchD, LSUPrefetchE; // data prefetch
logic AMOStallD, CMOStallD; // Structural hazards from atomic and cache management ops
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; assign OpD = InstrD[6:0];
@ -394,6 +403,9 @@ module controller import cvw::*; #(parameter cvw_t P) (
flopenrc #(35) controlregE(clk, reset, FlushE, ~StallE, flopenrc #(35) controlregE(clk, reset, FlushE, ~StallE,
{ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, InstrValidD}, {ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, InstrValidD},
{ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, InstrValidE}); {ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, InstrValidE});
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
// Branch Logic // Branch Logic
// The comparator handles both signed and unsigned branches using BranchSignedE // The comparator handles both signed and unsigned branches using BranchSignedE
@ -415,22 +427,45 @@ module controller import cvw::*; #(parameter cvw_t P) (
flopenrc #(25) controlregM(clk, reset, FlushM, ~StallM, flopenrc #(25) controlregM(clk, reset, FlushM, ~StallM,
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE, CMOpE, LSUPrefetchE}, {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE, CMOpE, LSUPrefetchE},
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM, CMOpM, LSUPrefetchM}); {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM, CMOpM, LSUPrefetchM});
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
// Writeback stage pipeline control register // Writeback stage pipeline control register
flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW, flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
{RegWriteM, ResultSrcM, IntDivM}, {RegWriteM, ResultSrcM, IntDivM},
{RegWriteW, ResultSrcW, IntDivW}); {RegWriteW, ResultSrcW, IntDivW});
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
// Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA // Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
assign CSRWriteFenceM = CSRWriteM | FenceM; assign CSRWriteFenceM = CSRWriteM | FenceM;
// Forwarding logic
always_comb begin
ForwardAE = 2'b00;
ForwardBE = 2'b00;
if (Rs1E != 5'b0)
if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01;
if (Rs2E != 5'b0)
if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time
assign MatchDE = ((Rs1D == RdE) | (Rs2D == RdE)) & (RdE != 5'b0); // Decode-stage instruction source depends on result from execute stage instruction
assign FCvtIntStallD = FCvtIntE & MatchDE; // FPU to Integer transfers have single-cycle latency except fcvt
assign LoadStallD = (MemReadE|SCE) & MatchDE;
assign MDUStallD = MDUE & MatchDE; // Int mult/div is at least two cycle latency, even when coming from the FDIV
assign CSRRdStallD = CSRReadE & MatchDE;
// the synchronous DTIM cannot read immediately after write // the synchronous DTIM cannot read immediately after write
// a cache cannot read or write immediately after a write // a cache cannot read or write immediately after a write
// atomic operations are also detected as MemRWD[1] // atomic operations are also detected as MemRWD[1] ***check; seems like & MemRWE
// *** RT: Remove this after updating the cache. // *** RT: Remove this after updating the cache.
// *** RT: Check that atomic after atomic works correctly. // *** RT: Check that atomic after atomic works correctly.
//assign StoreStallD = ((|CMOpE)) & ((|CMOpD)); assign AMOStallD = &MemRWE & MemRWD[1]; // Read after atomic operation causes structural hazard
logic AMOHazard; assign CMOStallD = (|CMOpE) & (|CMOpD); // CMO op after CMO op causes structural hazard ***explain, why doesn't interact with read/write
assign AMOHazard = &MemRWE & MemRWD[1];
assign StoreStallD = ((|CMOpE) & (|CMOpD)) | AMOHazard; // Structural hazard causes stall if any of these events occur
assign StructuralStallD = LoadStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | AMOStallD | CMOStallD;
endmodule endmodule

View File

@ -32,6 +32,7 @@ module datapath import cvw::*; #(parameter cvw_t P) (
// Decode stage signals // Decode stage signals
input logic [2:0] ImmSrcD, // Selects type of immediate extension input logic [2:0] ImmSrcD, // Selects type of immediate extension
input logic [31:0] InstrD, // Instruction in Decode stage input logic [31:0] InstrD, // Instruction in Decode stage
input logic [4:0] Rs1D, Rs2D, // Source registers
// Execute stage signals // Execute stage signals
input logic [P.XLEN-1:0] PCE, // PC in Execute stage input logic [P.XLEN-1:0] PCE, // PC in Execute stage
input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage) input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage)
@ -68,9 +69,8 @@ module datapath import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] CSRReadValW, // CSR read result input logic [P.XLEN-1:0] CSRReadValW, // CSR read result
input logic [P.XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result input logic [P.XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result
input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result
input logic [4:0] RdW // Destination register
// Hazard Unit signals // Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage
output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage
); );
// Fetch stage signals // Fetch stage signals
@ -94,9 +94,6 @@ module datapath import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division) logic [P.XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division)
// Decode stage // Decode stage
assign Rs1D = InstrD[19:15];
assign Rs2D = InstrD[24:20];
assign RdD = InstrD[11:7];
regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D); regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D);
extend #(P) ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD); extend #(P) ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD);
@ -104,28 +101,23 @@ module datapath import cvw::*; #(parameter cvw_t P) (
flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E); flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E);
flopenrc #(P.XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E); flopenrc #(P.XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E);
flopenrc #(P.XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE); flopenrc #(P.XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE);
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
mux3 #(P.XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE); mux3 #(P.XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE);
mux3 #(P.XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE); mux3 #(P.XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE);
comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(P, P.XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, BMUActiveE, ALUResultE, IEUAdrE); alu #(P) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, BMUActiveE, ALUResultE, IEUAdrE);
mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);
// Memory stage pipeline register // Memory stage pipeline register
flopenrc #(P.XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); flopenrc #(P.XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
flopenrc #(P.XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); flopenrc #(P.XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM);
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM); flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM);
// Writeback stage pipeline register and logic // Writeback stage pipeline register and logic
flopenrc #(P.XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW); flopenrc #(P.XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
// floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt // floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt
if (P.F_SUPPORTED) begin:fpmux if (P.F_SUPPORTED) begin:fpmux

View File

@ -1,62 +0,0 @@
///////////////////////////////////////////
// forward.sv
//
// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified:
//
// Purpose: Determine datapath forwarding
//
// Documentation: RISC-V System on Chip Design Chapter 4 (Section 4.2.2.3)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module forward(
// Detect hazards
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers
input logic MemReadE, MDUE, CSRReadE, // Execute stage instruction is a load (MemReadE), divide (MDUE), or CSR read (CSRReadE)
input logic RegWriteM, RegWriteW, // Instruction in Memory or Writeback stage writes register file
input logic FCvtIntE, // FPU convert float to int
input logic SCE, // Store Conditional instruction
// Forwarding controls
output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers
output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD // Stall due to conversion, load, multiply/divide, CSR read
);
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
always_comb begin
ForwardAE = 2'b00;
ForwardBE = 2'b00;
if (Rs1E != 5'b0)
if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01;
if (Rs2E != 5'b0)
if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time
assign MatchDE = ((Rs1D == RdE) | (Rs2D == RdE)) & (RdE != 5'b0); // Decode-stage instruction source depends on result from execute stage instruction
assign FCvtIntStallD = FCvtIntE & MatchDE; // FPU to Integer transfers have single-cycle latency except fcvt
assign LoadStallD = (MemReadE|SCE) & MatchDE;
assign MDUStallD = MDUE & MatchDE; // Int mult/div is at least two cycle latency, even when coming from the FDIV
assign CSRRdStallD = CSRReadE & MatchDE;
endmodule

View File

@ -73,8 +73,8 @@ module ieu import cvw::*; #(parameter cvw_t P) (
// Hazard unit signals // Hazard unit signals
input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit output logic StructuralStallD, // IEU detects structural hazard in Decode stage
output logic MDUStallD, CSRRdStallD, StoreStallD, output logic LoadStallD, // Structural stalls for load, sent to performance counters
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
); );
@ -94,7 +94,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
logic SubArithE; // Subtraction or arithmetic shift logic SubArithE; // Subtraction or arithmetic shift
// Forwarding signals // Forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers logic [4:0] Rs1D, Rs2D; // Source registers
logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers
logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages
logic MemReadE, CSRReadE; // Load, CSRRead instruction logic MemReadE, CSRReadE; // Load, CSRRead instruction
@ -104,25 +104,23 @@ module ieu import cvw::*; #(parameter cvw_t P) (
controller #(P) c( controller #(P) c(
.clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD, .clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD,
.IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .IllegalIEUFPUInstrD, .IllegalBaseInstrD,
.StructuralStallD, .LoadStallD, .Rs1D, .Rs2D,
.StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE,
.BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .MDUActiveE, .CMOpM, .IFUPrefetchE, .LSUPrefetchM, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .MDUActiveE,
.FCvtIntE, .ForwardAE, .ForwardBE, .CMOpM, .IFUPrefetchE, .LSUPrefetchM,
.StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM,
.RdW, .RdE, .RdM);
datapath #(P) dp( datapath #(P) dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, .clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE,
.Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
.CSRReadValW, .MDUResultW, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); .CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW);
forward fw(
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
.MemReadE, .MDUE, .CSRReadE, .RegWriteM, .RegWriteW,
.FCvtIntE, .SCE, .ForwardAE, .ForwardBE,
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD);
endmodule endmodule

View File

@ -185,7 +185,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(), .InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(), .InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(), .LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
.UpdateDA(InstrUpdateDAF), .CMOp(4'b0), .UpdateDA(InstrUpdateDAF), .CMOpM(4'b0),
.AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0), .AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -234,7 +234,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0; assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
// *** RT: Fix CMOp. Should be CMOpM. Also PAdr and NextSet are replaced with mux between PCPF/IEUAdrM and PCSpillNextF/IEUAdrE. // *** RT: PAdr and NextSet are replaced with mux between PCPF/IEUAdrM and PCSpillNextF/IEUAdrE.
cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS), cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS),
.NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS), .NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS),
.NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) .NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1))
@ -251,7 +251,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.FlushCache('0), .FlushCache('0),
.NextSet(PCSpillNextF[11:0]), .NextSet(PCSpillNextF[11:0]),
.PAdr(PCPF), .PAdr(PCPF),
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM), .CMOp('0)); .CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM), .CMOpM('0));
ahbcacheinterface #(P.AHBW, P.LLEN, P.PA_BITS, WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1) ahbcacheinterface #(P.AHBW, P.LLEN, P.PA_BITS, WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1)
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset), ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),

View File

@ -240,7 +240,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM, .StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM,
.StoreAmoPageFaultM, .StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw. .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw.
.UpdateDA(DataUpdateDAM), .CMOp(CMOpM), .UpdateDA(DataUpdateDAM), .CMOpM(CMOpM),
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), .AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0),
.WriteAccessM, .ReadAccessM(PreLSURWM[1]), .WriteAccessM, .ReadAccessM(PreLSURWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -335,7 +335,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.CacheCommitted(DCacheCommittedM), .CacheCommitted(DCacheCommittedM),
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM), .CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM),
.FetchBuffer, .CacheBusRW(CacheBusRWTemp), .FetchBuffer, .CacheBusRW(CacheBusRWTemp),
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0), .CMOp(CacheCMOpM)); .CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0), .CMOpM(CacheCMOpM));
assign DCacheStallM = CacheStall & ~IgnoreRequestTLB; assign DCacheStallM = CacheStall & ~IgnoreRequestTLB;
assign CacheBusRW = CacheBusRWTemp; assign CacheBusRW = CacheBusRWTemp;

View File

@ -55,7 +55,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
output logic UpdateDA, // page fault due to setting dirty or access bit output logic UpdateDA, // page fault due to setting dirty or access bit
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources
// PMA checker signals // PMA checker signals
input logic [3:0] CMOp, // Cache management instructions input logic [3:0] CMOpM, // Cache management instructions
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses
@ -85,7 +85,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]), .SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]),
.SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]), .SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]),
.VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOp, .PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM,
.DisableTranslation, .PTE, .PageTypeWriteVal, .DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
.Translate, .TLBPageFault, .UpdateDA, .PBMemoryType); .Translate, .TLBPageFault, .UpdateDA, .PBMemoryType);
@ -107,7 +107,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
// Check physical memory accesses // Check physical memory accesses
/////////////////////////////////////////// ///////////////////////////////////////////
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOp, pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOpM,
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType, .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
.Cacheable, .Idempotent, .SelTIM, .Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
@ -115,7 +115,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
if (P.PMP_ENTRIES > 0) begin : pmp if (P.PMP_ENTRIES > 0) begin : pmp
pmpchecker #(P) pmpchecker(.PhysicalAddress, .PrivilegeModeW, pmpchecker #(P) pmpchecker(.PhysicalAddress, .PrivilegeModeW,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.ExecuteAccessF, .WriteAccessM, .ReadAccessM, .CMOp, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .CMOpM,
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
end else begin end else begin
assign PMPInstrAccessFaultF = 0; assign PMPInstrAccessFaultF = 0;

View File

@ -31,7 +31,7 @@
module pmachecker import cvw::*; #(parameter cvw_t P) ( module pmachecker import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size, input logic [1:0] Size,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
input logic AtomicAccessM, // Atomic access input logic AtomicAccessM, // Atomic access
input logic ExecuteAccessF, // Execute access input logic ExecuteAccessF, // Execute access
input logic WriteAccessM, // Write access input logic WriteAccessM, // Write access
@ -51,7 +51,7 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
// Determine what type of access is being made // Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM; assign AccessRW = ReadAccessM | WriteAccessM;
assign AccessRWXC = ReadAccessM | WriteAccessM | ExecuteAccessF | (|CMOp); assign AccessRWXC = ReadAccessM | WriteAccessM | ExecuteAccessF | (|CMOpM);
assign AccessRX = ReadAccessM | ExecuteAccessF; assign AccessRX = ReadAccessM | ExecuteAccessF;
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
@ -75,5 +75,5 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
assign PMAAccessFault = (SelRegions[0]) & AccessRWXC | AtomicAccessM & ~AtomicAllowed; assign PMAAccessFault = (SelRegions[0]) & AccessRWXC | AtomicAccessM & ~AtomicAllowed;
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault; assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
assign PMAStoreAmoAccessFaultM = (WriteAccessM | (|CMOp)) & PMAAccessFault; assign PMAStoreAmoAccessFaultM = (WriteAccessM | (|CMOpM)) & PMAAccessFault;
endmodule endmodule

View File

@ -42,7 +42,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0],
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0],
input logic ExecuteAccessF, WriteAccessM, ReadAccessM, input logic ExecuteAccessF, WriteAccessM, ReadAccessM,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
output logic PMPInstrAccessFaultF, output logic PMPInstrAccessFaultF,
output logic PMPLoadAccessFaultM, output logic PMPLoadAccessFaultM,
output logic PMPStoreAmoAccessFaultM output logic PMPStoreAmoAccessFaultM
@ -72,8 +72,8 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
// Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region // Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | (|(L & FirstMatch)); // *** switch to this logic when PMP is initialized for non-machine mode assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | (|(L & FirstMatch)); // *** switch to this logic when PMP is initialized for non-machine mode
assign PMPCBOMAccessFault = EnforcePMP & (|CMOp[2:0]) & ~|((R|W) & FirstMatch) ; assign PMPCBOMAccessFault = EnforcePMP & (|CMOpM[2:0]) & ~|((R|W) & FirstMatch) ;
assign PMPCBOZAccessFault = EnforcePMP & CMOp[3] & ~|(W & FirstMatch) ; assign PMPCBOZAccessFault = EnforcePMP & CMOpM[3] & ~|(W & FirstMatch) ;
assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault; assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault;
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;

View File

@ -62,7 +62,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic ReadAccess, input logic ReadAccess,
input logic WriteAccess, input logic WriteAccess,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
input logic DisableTranslation, input logic DisableTranslation,
input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual) input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual)
input logic [P.XLEN-1:0] PTE, // page table entry to write input logic [P.XLEN-1:0] PTE, // page table entry to write
@ -109,7 +109,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
assign NAPOT4 = (PPN[3:0] == 4'b1000); // 64 KiB contiguous region with pte.napot_bits = 4 assign NAPOT4 = (PPN[3:0] == 4'b1000); // 64 KiB contiguous region with pte.napot_bits = 4
tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOp, .DisableTranslation, .TLBFlush, .PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM, .DisableTranslation, .TLBFlush,
.PTEAccessBits, .CAMHit, .Misaligned, .NAPOT4, .PTEAccessBits, .CAMHit, .Misaligned, .NAPOT4,
.TLBMiss, .TLBHit, .TLBPageFault, .TLBMiss, .TLBHit, .TLBPageFault,
.UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType); .UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType);

View File

@ -35,7 +35,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
input logic ENVCFG_ADUE, // HPTW A/D Update enable input logic ENVCFG_ADUE, // HPTW A/D Update enable
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic ReadAccess, WriteAccess, input logic ReadAccess, WriteAccess,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
input logic DisableTranslation, input logic DisableTranslation,
input logic TLBFlush, // Invalidate all TLB entries input logic TLBFlush, // Invalidate all TLB entries
input logic [11:0] PTEAccessBits, input logic [11:0] PTEAccessBits,
@ -69,7 +69,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
assign Translate = (SATP_MODE != P.NO_TRANSLATE[P.SVMODE_BITS-1:0]) & (EffectivePrivilegeMode != P.M_MODE) & ~DisableTranslation; assign Translate = (SATP_MODE != P.NO_TRANSLATE[P.SVMODE_BITS-1:0]) & (EffectivePrivilegeMode != P.M_MODE) & ~DisableTranslation;
// Determine whether TLB is being used // Determine whether TLB is being used
assign TLBAccess = ReadAccess | WriteAccess | (|CMOp); assign TLBAccess = ReadAccess | WriteAccess | (|CMOpM);
// Check that upper bits are legal (all 0s or all 1s) // Check that upper bits are legal (all 0s or all 1s)
vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal); vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal);
@ -113,8 +113,8 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
// Check for write error. Writes are invalid when the page's write bit is // Check for write error. Writes are invalid when the page's write bit is
// low. // low.
assign InvalidWrite = WriteAccess & ~PTE_W; assign InvalidWrite = WriteAccess & ~PTE_W;
assign InvalidCBOM = (|CMOp[2:0]) & (~PTE_W | (~PTE_R & (~STATUS_MXR | ~PTE_X))); assign InvalidCBOM = (|CMOpM[2:0]) & (~PTE_W | (~PTE_R & (~STATUS_MXR | ~PTE_X)));
assign InvalidCBOZ = CMOp[3] & ~PTE_W; assign InvalidCBOZ = CMOpM[3] & ~PTE_W;
assign InvalidAccess = InvalidRead | InvalidWrite | InvalidCBOM | InvalidCBOZ; assign InvalidAccess = InvalidRead | InvalidWrite | InvalidCBOM | InvalidCBOZ;
assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D; assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D;
end end

View File

@ -54,7 +54,6 @@ module csr import cvw::*; #(parameter cvw_t P) (
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
// inputs for performance counters // inputs for performance counters
input logic LoadStallD, input logic LoadStallD,
input logic StoreStallD,
input logic ICacheStallF, input logic ICacheStallF,
input logic DCacheStallM, input logic DCacheStallM,
input logic BPDirPredWrongM, input logic BPDirPredWrongM,
@ -275,7 +274,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
if (P.ZICNTR_SUPPORTED) begin:counters if (P.ZICNTR_SUPPORTED) begin:counters
csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM, csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM,
.InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM, .InstrValidNotFlushedM, .LoadStallD, .CSRWriteM, .CSRMWriteM,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
.InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,

View File

@ -32,7 +32,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic StallE, StallM, input logic StallE, StallM,
input logic FlushM, input logic FlushM,
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD, input logic InstrValidNotFlushedM, LoadStallD,
input logic CSRMWriteM, CSRWriteM, input logic CSRMWriteM, CSRWriteM,
input logic BPDirPredWrongM, input logic BPDirPredWrongM,
input logic BTAWrongM, input logic BTAWrongM,
@ -75,7 +75,6 @@ module csrc import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] HPMCOUNTER_REGW[P.COUNTERS-1:0]; logic [P.XLEN-1:0] HPMCOUNTER_REGW[P.COUNTERS-1:0];
logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0]; logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0];
logic LoadStallE, LoadStallM; logic LoadStallE, LoadStallM;
logic StoreStallE, StoreStallM;
logic [P.COUNTERS-1:0] WriteHPMCOUNTERM; logic [P.COUNTERS-1:0] WriteHPMCOUNTERM;
logic [P.COUNTERS-1:0] CounterEvent; logic [P.COUNTERS-1:0] CounterEvent;
logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0]; logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0];
@ -83,8 +82,8 @@ module csrc import cvw::*; #(parameter cvw_t P) (
genvar i; genvar i;
// Interface signals // Interface signals
flopenrc #(2) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d({StoreStallD, LoadStallD}), .q({StoreStallE, LoadStallE})); // don't flush the load stall during a load stall. flopenrc #(1) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d(LoadStallD), .q(LoadStallE)); // don't flush the load stall during a load stall.
flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, LoadStallM})); flopenrc #(1) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(LoadStallE), .q(LoadStallM));
// Determine when to increment each counter // Determine when to increment each counter
assign CounterEvent[0] = 1'b1; // MCYCLE always increments assign CounterEvent[0] = 1'b1; // MCYCLE always increments
@ -100,7 +99,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
assign CounterEvent[12] = StoreStallM; // Store Stall assign CounterEvent[12] = 0; // depricated Store Stall
assign CounterEvent[13] = DCacheAccess; // data cache access assign CounterEvent[13] = DCacheAccess; // data cache access
assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[15] = DCacheStallM; // d cache miss cycles assign CounterEvent[15] = DCacheStallM; // d cache miss cycles

View File

@ -45,7 +45,6 @@ module privileged import cvw::*; #(parameter cvw_t P) (
// processor events for performance counter logging // processor events for performance counter logging
input logic FRegWriteM, // instruction will write floating-point registers input logic FRegWriteM, // instruction will write floating-point registers
input logic LoadStallD, // load instruction is stalling input logic LoadStallD, // load instruction is stalling
input logic StoreStallD, // store instruction is stalling
input logic ICacheStallF, // I cache stalled input logic ICacheStallF, // I cache stalled
input logic DCacheStallM, // D cache stalled input logic DCacheStallM, // D cache stalled
input logic BPDirPredWrongM, // branch predictor guessed wrong direction input logic BPDirPredWrongM, // branch predictor guessed wrong direction
@ -133,7 +132,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
.InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM,
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM,
.sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
.IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,

View File

@ -75,7 +75,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic PCSrcE; logic PCSrcE;
logic CSRWriteFenceM; logic CSRWriteFenceM;
logic DivBusyE; logic DivBusyE;
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD; logic StructuralStallD;
logic LoadStallD;
logic SquashSCW; logic SquashSCW;
logic MDUActiveE; // Mul/Div instruction being executed logic MDUActiveE; // Mul/Div instruction being executed
logic ENVCFG_ADUE; // HPTW A/D Update enable logic ENVCFG_ADUE; // HPTW A/D Update enable
@ -95,7 +96,6 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic FCvtIntW; logic FCvtIntW;
logic FDivBusyE; logic FDivBusyE;
logic FRegWriteM; logic FRegWriteM;
logic FCvtIntStallD;
logic FpLoadStoreM; logic FpLoadStoreM;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
logic [P.XLEN-1:0] FIntDivResultW; logic [P.XLEN-1:0] FIntDivResultW;
@ -211,8 +211,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW, .InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW,
// hazards // hazards
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE, .StructuralStallD, .LoadStallD, .PCSrcE,
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM);
lsu #(P) lsu( lsu #(P) lsu(
.clk, .reset, .StallM, .FlushM, .StallW, .FlushW, .clk, .reset, .StallM, .FlushM, .StallW, .FlushW,
@ -266,9 +266,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
// global stall and flush control // global stall and flush control
hazard #(P) hzu( hazard #(P) hzu(
.BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM,
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .StructuralStallD,
.LSUStallM, .IFUStallF, .LSUStallM, .IFUStallF,
.FCvtIntStallD, .FPUStallD, .FPUStallD,
.DivBusyE, .FDivBusyE, .DivBusyE, .FDivBusyE,
.wfiM, .IntPendingM, .wfiM, .IntPendingM,
// Stall & flush outputs // Stall & flush outputs
@ -284,7 +284,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM, .InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM,
.RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF, .RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF,
.InstrValidM, .CommittedM, .CommittedF, .InstrValidM, .CommittedM, .CommittedF,
.FRegWriteM, .LoadStallD, .StoreStallD, .FRegWriteM, .LoadStallD,
.BPDirPredWrongM, .BTAWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .BPWrongM,
.RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE, .RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,