Skip to content

Commit 28d3ce5

Browse files
Add VectorFIFOF module
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. Co-authored-by: Julie Schwartz <quark@bluespec.com>
1 parent 154d564 commit 28d3ce5

File tree

8 files changed

+409
-0
lines changed

8 files changed

+409
-0
lines changed

Libraries/Misc/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ build:
1515
$(BSC) -u $(BSCFLAGS) EdgeFIFOFs.bsv
1616
$(BSC) -u $(BSCFLAGS) GetPut_Aux.bsv
1717
$(BSC) -u $(BSCFLAGS) Semi_FIFOF.bsv
18+
$(BSC) -u $(BSCFLAGS) VectorFIFOF.bsv
1819

1920
.PHONY: clean full_clean
2021
clean full_clean:

Libraries/Misc/VectorFIFOF.bsv

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
// Copyright (c) 2025 Bluespec, Inc.
2+
//
3+
// SPDX-License-Identifier: BSD-3-Clause
4+
5+
package VectorFIFOF;
6+
7+
// This package implements a fifo like module with a parameterized
8+
// depth and standard FIFOF interface. The module also provides
9+
// parallel access to all items in the fifo, for example, to allow
10+
// searching for hazards before enqueueing new items.
11+
//
12+
// The enq, deq, and clear methods may be called in any order. enq
13+
// and deq may not occur in the same cycle if the fifo is empty or
14+
// full.
15+
16+
import FIFOF ::*;
17+
import RevertingVirtualReg ::*;
18+
import Vector ::*;
19+
20+
interface VectorFIFOF#(numeric type depth, type t);
21+
interface FIFOF#(t) fifo;
22+
method Vector#(depth, Maybe#(t)) vector();
23+
endinterface
24+
25+
module mkVectorFIFOF(VectorFIFOF#(depth, t))
26+
provisos(
27+
Bits#(t, tsz)
28+
);
29+
30+
Vector#(depth, Reg#(t)) vr_data <- replicateM(mkRegU);
31+
Reg#(UInt#(TLog#(TAdd#(depth,1)))) r_count <- mkReg(0);
32+
33+
RWire#(t) w_enq <- mkRWire;
34+
PulseWire pw_deq <- mkPulseWire;
35+
PulseWire pw_clear <- mkPulseWire;
36+
37+
(* fire_when_enabled, no_implicit_conditions *)
38+
rule rl_magic;
39+
if (pw_clear)
40+
r_count <= 0;
41+
else if (isValid(w_enq.wget) && !pw_deq)
42+
r_count <= r_count + 1;
43+
else if (!isValid(w_enq.wget) && pw_deq)
44+
r_count <= r_count - 1;
45+
46+
Vector#(depth, t) newdata = readVReg(vr_data);
47+
48+
if (pw_deq)
49+
for (Integer i = 0; i < fromInteger(valueOf(depth)) - 1; i = i + 1)
50+
newdata[i] = newdata[i + 1];
51+
52+
if (w_enq.wget matches tagged Valid .x)
53+
newdata[pw_deq ? r_count - 1 : r_count] = x;
54+
55+
writeVReg(vr_data, newdata);
56+
endrule
57+
58+
function Bool notFull;
59+
return r_count < fromInteger(valueOf(depth));
60+
endfunction
61+
62+
function Bool notEmpty;
63+
return r_count != 0;
64+
endfunction
65+
66+
function Maybe#(t) valid(Integer x, t a);
67+
if (fromInteger(x) < r_count)
68+
return tagged Valid a;
69+
else
70+
return tagged Invalid;
71+
endfunction
72+
73+
Reg#(Bool) beforeEnq <- mkRevertingVirtualReg(True);
74+
Reg#(Bool) beforeDeq <- mkRevertingVirtualReg(True);
75+
Reg#(Bool) beforeClear <- mkRevertingVirtualReg(True);
76+
77+
Bool beforeActions = beforeEnq && beforeDeq && beforeClear;
78+
79+
interface FIFOF fifo;
80+
method Action enq(t x) if (notFull && beforeClear);
81+
w_enq.wset(x);
82+
beforeEnq <= False;
83+
endmethod
84+
method Action deq if (notEmpty && beforeClear);
85+
pw_deq.send;
86+
beforeDeq <= False;
87+
endmethod
88+
method t first if (beforeDeq && beforeClear && (r_count > 0)) = vr_data[0];
89+
method Action clear();
90+
pw_clear.send;
91+
beforeClear <= False;
92+
endmethod
93+
method Bool notFull() if (beforeActions) = notFull;
94+
method Bool notEmpty() if (beforeActions) = notEmpty;
95+
endinterface
96+
97+
method vector() if (beforeActions) = zipWith(valid, genVector, readVReg(vr_data));
98+
99+
endmodule
100+
101+
endpackage

testing/bsc.contrib/Misc/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# for "make clean" to work everywhere
2+
3+
CONFDIR = $(realpath ../..)
4+
5+
include $(CONFDIR)/clean.mk
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import FIFOF ::*;
2+
import VectorFIFOF ::*;
3+
4+
(* synthesize *)
5+
module mkVectorFIFOF_4_Bool(VectorFIFOF#(4,Bool));
6+
(* hide *)
7+
VectorFIFOF#(4,Bool) __i <- mkVectorFIFOF;
8+
return __i;
9+
endmodule
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
checking package dependencies
2+
compiling TestSched_VectorFIFOF.bsv
3+
code generation for mkVectorFIFOF_4_Bool starts
4+
=== schedule:
5+
parallel: [esposito: [fifo_enq -> [],
6+
fifo_deq -> [],
7+
fifo_first -> [],
8+
fifo_notFull -> [],
9+
fifo_notEmpty -> [],
10+
fifo_clear -> [],
11+
vector -> [],
12+
RL_rl_magic -> []]]
13+
order: [fifo_first,
14+
fifo_notFull,
15+
fifo_notEmpty,
16+
vector,
17+
fifo_enq,
18+
fifo_deq,
19+
fifo_clear,
20+
RL_rl_magic]
21+
22+
-----
23+
24+
=== resources:
25+
[(beforeClear.read, [(beforeClear.read, 1)]),
26+
(beforeClear.write, [(beforeClear.write 1'd1, 1)]),
27+
(beforeDeq.read, [(beforeDeq.read, 1)]),
28+
(beforeDeq.write, [(beforeDeq.write 1'd1, 1)]),
29+
(beforeEnq.read, [(beforeEnq.read, 1)]),
30+
(beforeEnq.write, [(beforeEnq.write 1'd1, 1)]),
31+
(pw_clear.whas, [(pw_clear.whas, 1)]),
32+
(pw_clear.wset, [(pw_clear.wset, 1)]),
33+
(pw_deq.whas, [(pw_deq.whas, 1)]),
34+
(pw_deq.wset, [(pw_deq.wset, 1)]),
35+
(r_count.read, [(r_count.read, 1)]),
36+
(r_count.write,
37+
[(if pw_clear_whas_OR_w_enq_whas_AND_NOT_pw_deq_wha_ETC___d9 then
38+
r_count.write IF_pw_clear_whas_THEN_0_ELSE_IF_w_enq_whas_AND_ETC___d14,
39+
1)]),
40+
(vr_data_0.read, [(vr_data_0.read, 1)]),
41+
(vr_data_0.write, [(vr_data_0.write IF_w_enq_whas_THEN_IF_IF_pw_deq_whas_THEN_r_co_ETC___d22, 1)]),
42+
(vr_data_1.read, [(vr_data_1.read, 1)]),
43+
(vr_data_1.write, [(vr_data_1.write IF_w_enq_whas_THEN_IF_IF_pw_deq_whas_THEN_r_co_ETC___d27, 1)]),
44+
(vr_data_2.read, [(vr_data_2.read, 1)]),
45+
(vr_data_2.write, [(vr_data_2.write IF_w_enq_whas_THEN_IF_IF_pw_deq_whas_THEN_r_co_ETC___d32, 1)]),
46+
(vr_data_3.read, [(vr_data_3.read, 1)]),
47+
(vr_data_3.write, [(vr_data_3.write IF_w_enq_whas_THEN_IF_IF_pw_deq_whas_THEN_r_co_ETC___d35, 1)]),
48+
(w_enq.wget, [(w_enq.wget, 1)]),
49+
(w_enq.whas, [(w_enq.whas, 1)]),
50+
(w_enq.wset, [(w_enq.wset fifo_enq_1, 1)])]
51+
52+
-----
53+
54+
=== vschedinfo:
55+
SchedInfo
56+
[RDY_fifo_clear CF [RDY_fifo_clear,
57+
RDY_vector,
58+
fifo_clear,
59+
fifo_deq,
60+
fifo_enq,
61+
fifo_first,
62+
fifo_notEmpty,
63+
fifo_notFull,
64+
vector],
65+
RDY_fifo_deq CF [RDY_fifo_clear,
66+
RDY_fifo_deq,
67+
RDY_fifo_first,
68+
RDY_fifo_notEmpty,
69+
RDY_fifo_notFull,
70+
RDY_vector,
71+
fifo_clear,
72+
fifo_deq,
73+
fifo_enq,
74+
fifo_first,
75+
fifo_notEmpty,
76+
fifo_notFull,
77+
vector],
78+
RDY_fifo_enq CF [RDY_fifo_clear,
79+
RDY_fifo_deq,
80+
RDY_fifo_enq,
81+
RDY_fifo_first,
82+
RDY_fifo_notEmpty,
83+
RDY_fifo_notFull,
84+
RDY_vector,
85+
fifo_clear,
86+
fifo_deq,
87+
fifo_enq,
88+
fifo_first,
89+
fifo_notEmpty,
90+
fifo_notFull,
91+
vector],
92+
RDY_fifo_first CF [RDY_fifo_clear,
93+
RDY_fifo_first,
94+
RDY_fifo_notEmpty,
95+
RDY_fifo_notFull,
96+
RDY_vector,
97+
fifo_clear,
98+
fifo_deq,
99+
fifo_enq,
100+
fifo_first,
101+
fifo_notEmpty,
102+
fifo_notFull,
103+
vector],
104+
RDY_fifo_notEmpty CF [RDY_fifo_clear,
105+
RDY_fifo_notEmpty,
106+
RDY_vector,
107+
fifo_clear,
108+
fifo_deq,
109+
fifo_enq,
110+
fifo_first,
111+
fifo_notEmpty,
112+
fifo_notFull,
113+
vector],
114+
RDY_fifo_notFull CF [RDY_fifo_clear,
115+
RDY_fifo_notEmpty,
116+
RDY_fifo_notFull,
117+
RDY_vector,
118+
fifo_clear,
119+
fifo_deq,
120+
fifo_enq,
121+
fifo_first,
122+
fifo_notEmpty,
123+
fifo_notFull,
124+
vector],
125+
RDY_vector CF [RDY_vector,
126+
fifo_clear,
127+
fifo_deq,
128+
fifo_enq,
129+
fifo_first,
130+
fifo_notEmpty,
131+
fifo_notFull,
132+
vector],
133+
fifo_enq CF [fifo_deq, fifo_first],
134+
fifo_first CF [fifo_first, fifo_notEmpty, fifo_notFull, vector],
135+
fifo_notEmpty CF [fifo_notEmpty, vector],
136+
fifo_notFull CF [fifo_notEmpty, fifo_notFull, vector],
137+
vector CF vector,
138+
[fifo_deq, fifo_enq] SB fifo_clear,
139+
fifo_first SB [fifo_clear, fifo_deq],
140+
[fifo_notEmpty, fifo_notFull, vector] SB [fifo_clear, fifo_deq, fifo_enq],
141+
fifo_clear C fifo_clear,
142+
fifo_deq C fifo_deq,
143+
fifo_enq C fifo_enq]
144+
[]
145+
[]
146+
[]
147+
148+
-----
149+
150+
Schedule dump file created: mkVectorFIFOF_4_Bool.sched
151+
=== Generated schedule for mkVectorFIFOF_4_Bool ===
152+
153+
Method schedule
154+
---------------
155+
Method: fifo_enq
156+
Ready signal: (r_count < 3'd4) && beforeClear.read
157+
Conflict-free: fifo_deq, fifo_first
158+
Sequenced before: fifo_clear
159+
Sequenced after: fifo_notFull, fifo_notEmpty, vector
160+
Conflicts: fifo_enq
161+
162+
Method: fifo_deq
163+
Ready signal: (! (r_count == 3'd0)) && beforeClear.read
164+
Conflict-free: fifo_enq
165+
Sequenced before: fifo_clear
166+
Sequenced after: fifo_first, fifo_notFull, fifo_notEmpty, vector
167+
Conflicts: fifo_deq
168+
169+
Method: fifo_first
170+
Ready signal: beforeDeq.read && beforeClear.read && (! (r_count == 3'd0))
171+
Conflict-free: fifo_enq, fifo_first, fifo_notFull, fifo_notEmpty, vector
172+
Sequenced before: fifo_deq, fifo_clear
173+
174+
Method: fifo_notFull
175+
Ready signal: beforeEnq.read && beforeDeq.read && beforeClear.read
176+
Conflict-free: fifo_first, fifo_notFull, fifo_notEmpty, vector
177+
Sequenced before: fifo_enq, fifo_deq, fifo_clear
178+
179+
Method: fifo_notEmpty
180+
Ready signal: beforeEnq.read && beforeDeq.read && beforeClear.read
181+
Conflict-free: fifo_first, fifo_notFull, fifo_notEmpty, vector
182+
Sequenced before: fifo_enq, fifo_deq, fifo_clear
183+
184+
Method: fifo_clear
185+
Ready signal: True
186+
Sequenced after: fifo_enq,
187+
fifo_deq,
188+
fifo_first,
189+
fifo_notFull,
190+
fifo_notEmpty,
191+
vector
192+
Conflicts: fifo_clear
193+
194+
Method: vector
195+
Ready signal: beforeEnq.read && beforeDeq.read && beforeClear.read
196+
Conflict-free: fifo_first, fifo_notFull, fifo_notEmpty, vector
197+
Sequenced before: fifo_enq, fifo_deq, fifo_clear
198+
199+
Rule schedule
200+
-------------
201+
Rule: rl_magic
202+
Predicate: True
203+
Blocking rules: (none)
204+
205+
Logical execution order: fifo_first,
206+
fifo_notFull,
207+
fifo_notEmpty,
208+
vector,
209+
fifo_enq,
210+
fifo_deq,
211+
fifo_clear,
212+
rl_magic
213+
214+
====================================================
215+
Verilog file created: mkVectorFIFOF_4_Bool.v
216+
All packages are up to date.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import Cur_Cycle ::*;
2+
import FIFOF ::*;
3+
import VectorFIFOF ::*;
4+
5+
(* synthesize *)
6+
module sysTest_VectorFIFOF();
7+
VectorFIFOF#(3,Bit#(4)) vf <- mkVectorFIFOF;
8+
9+
Reg#(Bit#(4)) rg_send <- mkReg(0);
10+
11+
rule do_enq (rg_send < 8);
12+
vf.fifo.enq(rg_send);
13+
rg_send <= rg_send + 1;
14+
$display("[%d] Contents: ", cur_cycle, fshow(vf.vector));
15+
$display("[%d] Enq %d", cur_cycle, rg_send);
16+
endrule
17+
18+
Reg#(Bit#(4)) rg_recv <- mkReg(0);
19+
20+
rule do_deq;
21+
vf.fifo.deq();
22+
$display("[%d] Deq %d", cur_cycle, vf.fifo.first);
23+
rg_recv <= rg_recv + 1;
24+
if (rg_recv == 7)
25+
$finish(0);
26+
endrule
27+
28+
endmodule

testing/bsc.contrib/Misc/misc.exp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Include the boilerplate for bsc-contrib tests
2+
set here [file join [absolute $srcdir] $subdir]
3+
source $here/../contrib.tcl
4+
5+
if { $contribtest } {
6+
7+
add_contrib_dirs_to_path { Misc }
8+
9+
# ---------------
10+
# VectorFIFOF
11+
12+
# Check that the method scheduling relationships are as expected
13+
compile_verilog_schedule_pass TestSched_VectorFIFOF.bsv
14+
compare_file_filter_ids TestSched_VectorFIFOF.bsv.bsc-sched-out
15+
16+
# Test that the module operates as a FIFO
17+
# and confirm that enq and deq occur in the same cycle
18+
# Note: The use of Cur_Cycle requires separate .ba elaboration
19+
test_c_veri_bsv_separately Test_VectorFIFOF
20+
21+
# ---------------
22+
23+
restore_path
24+
25+
}

0 commit comments

Comments
 (0)