Skip to content

Commit

Permalink
Add VectorFIFOF module
Browse files Browse the repository at this point in the history
The VectorFIFOF module has a FIFOF interface for enqueuing and dequeuing
data.  It also provides a method, which returns a Vector of Maybe entries,
to access all entries in the queue simultaneously.
  • Loading branch information
darius-bluespec committed Jan 3, 2025
1 parent 154d564 commit 001feaf
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 0 deletions.
1 change: 1 addition & 0 deletions Libraries/Misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ build:
$(BSC) -u $(BSCFLAGS) EdgeFIFOFs.bsv
$(BSC) -u $(BSCFLAGS) GetPut_Aux.bsv
$(BSC) -u $(BSCFLAGS) Semi_FIFOF.bsv
$(BSC) -u $(BSCFLAGS) VectorFIFOF.bsv

.PHONY: clean full_clean
clean full_clean:
90 changes: 90 additions & 0 deletions Libraries/Misc/VectorFIFOF.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@

package VectorFIFOF;

// This package implements a fifo like module with a parameterized
// depth and standard FIFOF interface. The module also provides
// parallel access to all items in the fifo, for example, to allow
// searching for hazards before enqueueing new items.

import FIFOF ::*;
import Vector ::*;

interface VectorFIFOF#(numeric type depth, type t);
interface FIFOF#(t) fifo;
interface Vector#(depth, Maybe#(t)) vector;
endinterface

module mkVectorFIFOF(VectorFIFOF#(depth, t))
provisos(
Bits#(t, a__)
);

Vector#(depth, Reg#(t)) vr_data <- replicateM(mkRegU);
Array#(Reg#(UInt#(TLog#(TAdd#(depth,1))))) r_count <- mkCReg(3, 0);

Wire#(t) w_enq <- mkWire;
PulseWire pw_deq <- mkPulseWire;
PulseWire pw_clear <- mkPulseWire;

function Bool notFull;
return r_count[0] < fromInteger(valueOf(depth));
endfunction

function Bool notEmpty;
return r_count[0] != 0;
endfunction

rule rl_enq;
vr_data[r_count[1]] <= w_enq;
r_count[1] <= r_count[1] + 1;
endrule

rule rl_deq(pw_deq);
for (Integer i = 0; i < fromInteger(valueOf(depth)) - 1; i = i + 1)
vr_data[i] <= vr_data[i + 1];

r_count[0] <= r_count[0] - 1;
endrule

rule rl_clear(pw_clear);
r_count[2] <= 0;
endrule

function Maybe#(t) valid(Integer x, t a);
if (fromInteger(x) < r_count[0])
return tagged Valid a;
else
return tagged Invalid;
endfunction

interface FIFOF fifo;
method Action enq(t x) if (notFull);
w_enq <= x;
endmethod

method Action deq if (notEmpty);
pw_deq.send;
endmethod

method t first if (r_count[0] > 0);
return vr_data[0];
endmethod

method Action clear;
pw_clear.send;
endmethod

method Bool notFull;
return notFull;
endmethod

method Bool notEmpty;
return notEmpty;
endmethod
endinterface

interface Vector vector = zipWith(valid, genVector, readVReg(vr_data));

endmodule

endpackage

0 comments on commit 001feaf

Please sign in to comment.