From 96afb0a7f540fe0e1f948af83cd105dc92417227 Mon Sep 17 00:00:00 2001 From: jon Date: Thu, 13 Aug 2020 17:33:46 +0100 Subject: [PATCH] FIFO optimisation both for build time (and possibly condition complexity?) and for throughput. --- .../RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv | 5 ++- src_Core/RISCY_OOO/procs/lib/Fifos.bsv | 37 +++++++++++++++++-- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv index b6a476e..0fdb0ed 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv @@ -343,8 +343,9 @@ module mkFetchStage(FetchStage); // Pipeline Stage FIFOs Fifo#(2, Tuple2#(Bit#(TLog#(SupSizeX2)),Fetch1ToFetch2)) f12f2 <- mkCFFifo; Fifo#(4, Tuple2#(Bit#(TLog#(SupSizeX2)),Fetch2ToFetch3)) f22f3 <- mkCFFifo; // FIFO should match I$ latency - SupFifo#(SupSizeX2, 3, Fetch3ToDecode) f32d <- mkSupFifo; // This fifo needs a capacity of 3 for full throughput. Unknown why. - SupFifo#(SupSize, 2, FromFetchStage) out_fifo <- mkSupFifo; + // These two fifos needs a capacity of 3 for full throughput if we fire only when we can enq on on channels. + SupFifo#(SupSizeX2, 3, Fetch3ToDecode) f32d <- mkUGSupFifo; // Unguarded to prevent the static analyser from exploding. + SupFifo#(SupSize, 3, FromFetchStage) out_fifo <- mkSupFifo; // Can the fifo size be smaller? // Branch Predictors diff --git a/src_Core/RISCY_OOO/procs/lib/Fifos.bsv b/src_Core/RISCY_OOO/procs/lib/Fifos.bsv index 393b5c2..5ce065a 100644 --- a/src_Core/RISCY_OOO/procs/lib/Fifos.bsv +++ b/src_Core/RISCY_OOO/procs/lib/Fifos.bsv @@ -160,7 +160,7 @@ endinstance // endfunction // endinstance -module mkSupFifo(SupFifo#(k,n,t)) provisos ( +module mkUGSupFifo(SupFifo#(k,n,t)) provisos ( Bits#(t,tSz), FShow#(t), Add#(TExp#(TLog#(k)), 0, k) // k must be power of 2 @@ -177,7 +177,7 @@ module mkSupFifo(SupFifo#(k,n,t)) provisos ( Bool can_enq = internalFifos[fifoIdx].notFull; return (interface SupFifoEnq; method Bool canEnq = can_enq; - method Action enq(t x) if(can_enq); + method Action enq(t x); enqueueElement[i][0] <= tagged Valid x; endmethod endinterface); @@ -188,10 +188,10 @@ module mkSupFifo(SupFifo#(k,n,t)) provisos ( Bool can_deq = internalFifos[fifoIdx].notEmpty; return (interface SupFifoDeq; method Bool canDeq = can_deq; - method t first if(can_deq); + method t first; return internalFifos[fifoIdx].first; endmethod - method Action deq if(can_deq); + method Action deq; willDequeue[i][0] <= True; endmethod endinterface); @@ -231,6 +231,35 @@ module mkSupFifo(SupFifo#(k,n,t)) provisos ( endmethod endmodule +module mkSupFifo(SupFifo#(k,n,t)) provisos ( + Bits#(t,tSz), + FShow#(t), + Add#(TExp#(TLog#(k)), 0, k) // k must be power of 2 +); + SupFifo#(k,n,t) ugf <- mkUGSupFifo; + + function SupFifoEnq#(t) getEnqIfc(Integer i); + return (interface SupFifoEnq; + method Bool canEnq = ugf.enqS[i].canEnq; + method Action enq(t x) if(ugf.enqS[i].canEnq) = ugf.enqS[i].enq(x); + endinterface); + endfunction + + function SupFifoDeq#(t) getDeqIfc(Integer i); + return (interface SupFifoDeq; + method Bool canDeq = ugf.deqS[i].canDeq; + method t first if(ugf.deqS[i].canDeq) = ugf.deqS[i].first; + method Action deq if(ugf.deqS[i].canDeq) = ugf.deqS[i].deq; + endinterface); + endfunction + + Vector#(k,Integer) indexes = genVector; + interface Vector enqS = map(getEnqIfc, indexes); + interface Vector deqS = map(getDeqIfc, indexes); + + method Bool internalEmpty = ugf.internalEmpty; +endmodule + // A Conflict free implementation of n element FIFO