rlm@8
|
1
|
rlm@8
|
2 import FIFO::*;
|
rlm@8
|
3 import ConfigReg::*;
|
rlm@8
|
4 import RWire::*;
|
rlm@8
|
5
|
rlm@8
|
6 import List::*;
|
rlm@8
|
7 import Monad::*;
|
rlm@8
|
8
|
rlm@8
|
9 interface SFIFO#(type alpha_T, type search_T);
|
rlm@8
|
10 method Action enq(alpha_T x);
|
rlm@8
|
11 method Action deq();
|
rlm@8
|
12 method alpha_T first();
|
rlm@8
|
13 method Action clear();
|
rlm@8
|
14 method Bool find(search_T x);
|
rlm@8
|
15 method Bool find2(search_T x);
|
rlm@8
|
16 method Bool notEmpty();
|
rlm@8
|
17 method Bool notFull();
|
rlm@8
|
18 endinterface
|
rlm@8
|
19
|
rlm@8
|
20 module mkSFIFO#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T))
|
rlm@8
|
21 provisos
|
rlm@8
|
22 (Bits#(alpha_T,asz));
|
rlm@8
|
23
|
rlm@8
|
24 Reg#(alpha_T) f0 <- mkConfigRegU;
|
rlm@8
|
25 Reg#(alpha_T) f1 <- mkConfigRegU;
|
rlm@8
|
26
|
rlm@8
|
27 Reg#(Bool) vf0 <- mkConfigReg(False);
|
rlm@8
|
28 Reg#(Bool) vf1 <- mkConfigReg(False);
|
rlm@8
|
29
|
rlm@8
|
30 PulseWire edge1 <- mkPulseWire();
|
rlm@8
|
31
|
rlm@8
|
32 method Action enq(alpha_T x) if (!(vf0 && vf1));
|
rlm@8
|
33 if (edge1 || !vf0)//empty or we're dequeueing
|
rlm@8
|
34 begin
|
rlm@8
|
35 vf0 <= True; //True
|
rlm@8
|
36 vf1 <= False;
|
rlm@8
|
37 f0 <= x;
|
rlm@8
|
38 end
|
rlm@8
|
39 else // !vf1
|
rlm@8
|
40 begin
|
rlm@8
|
41 vf1 <= True;
|
rlm@8
|
42 f1 <= x;
|
rlm@8
|
43 end
|
rlm@8
|
44 endmethod
|
rlm@8
|
45
|
rlm@8
|
46 method Action deq() if (vf0);
|
rlm@8
|
47 edge1.send();
|
rlm@8
|
48 vf0 <= vf1;
|
rlm@8
|
49 f0 <= f1;
|
rlm@8
|
50 vf1 <= False;
|
rlm@8
|
51 endmethod
|
rlm@8
|
52
|
rlm@8
|
53 method alpha_T first() if(vf0);
|
rlm@8
|
54 return (f0);
|
rlm@8
|
55 endmethod
|
rlm@8
|
56
|
rlm@8
|
57 method Action clear();
|
rlm@8
|
58 vf0 <= False;
|
rlm@8
|
59 vf1 <= False;
|
rlm@8
|
60 endmethod
|
rlm@8
|
61
|
rlm@8
|
62 method Bool find(search_T sv);
|
rlm@8
|
63 Bool nvf0 = edge1 ? False: vf0;
|
rlm@8
|
64 Bool nvf1 = vf1;
|
rlm@8
|
65
|
rlm@8
|
66 return (nvf0 && searchfunc(sv, f0) ||
|
rlm@8
|
67 nvf1 && searchfunc(sv, f1));
|
rlm@8
|
68 endmethod
|
rlm@8
|
69
|
rlm@8
|
70 method Bool find2(search_T sv);
|
rlm@8
|
71 Bool nvf0 = edge1 ? False: vf0;
|
rlm@8
|
72 Bool nvf1 = vf1;
|
rlm@8
|
73
|
rlm@8
|
74 return (nvf0 && searchfunc(sv, f0) ||
|
rlm@8
|
75 nvf1 && searchfunc(sv, f1));
|
rlm@8
|
76 endmethod
|
rlm@8
|
77
|
rlm@8
|
78 method notEmpty() = vf0._read;
|
rlm@8
|
79
|
rlm@8
|
80 method Bool notFull();
|
rlm@8
|
81 return !(vf0 && vf1);
|
rlm@8
|
82 endmethod
|
rlm@8
|
83
|
rlm@8
|
84 endmodule
|
rlm@8
|
85
|
rlm@8
|
86 module mkSFIFO1#(function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T))
|
rlm@8
|
87 provisos
|
rlm@8
|
88 (Bits#(alpha_T,asz), Eq#(alpha_T));
|
rlm@8
|
89
|
rlm@8
|
90 Reg#(alpha_T) f0 <- mkConfigRegU;
|
rlm@8
|
91
|
rlm@8
|
92 Reg#(Bool) vf0 <- mkConfigReg(False);
|
rlm@8
|
93
|
rlm@8
|
94 PulseWire edge1 <- mkPulseWire();
|
rlm@8
|
95
|
rlm@8
|
96 method Action enq(alpha_T x) if (!vf0);
|
rlm@8
|
97 vf0 <= True; //True
|
rlm@8
|
98 f0 <= x;
|
rlm@8
|
99 endmethod
|
rlm@8
|
100
|
rlm@8
|
101 method Action deq() if (vf0);
|
rlm@8
|
102 edge1.send();
|
rlm@8
|
103 vf0 <= False;
|
rlm@8
|
104 endmethod
|
rlm@8
|
105
|
rlm@8
|
106 method alpha_T first() if(vf0);
|
rlm@8
|
107 return (f0);
|
rlm@8
|
108 endmethod
|
rlm@8
|
109
|
rlm@8
|
110 method Action clear();
|
rlm@8
|
111 vf0 <= False;
|
rlm@8
|
112 endmethod
|
rlm@8
|
113
|
rlm@8
|
114 method Bool find(search_T sv);
|
rlm@8
|
115 Bool nvf0 = edge1 ? False: vf0;
|
rlm@8
|
116
|
rlm@8
|
117 return (nvf0 && searchfunc(sv, f0));
|
rlm@8
|
118 endmethod
|
rlm@8
|
119
|
rlm@8
|
120 method Bool find2(search_T sv);
|
rlm@8
|
121 Bool nvf0 = edge1 ? False: vf0;
|
rlm@8
|
122 return (nvf0 && searchfunc(sv, f0));
|
rlm@8
|
123 endmethod
|
rlm@8
|
124
|
rlm@8
|
125 method notEmpty() = vf0._read;
|
rlm@8
|
126
|
rlm@8
|
127 method Bool notFull();
|
rlm@8
|
128 return !vf0;
|
rlm@8
|
129 endmethod
|
rlm@8
|
130
|
rlm@8
|
131 endmodule
|
rlm@8
|
132
|
rlm@8
|
133 module mkSizedSFIFOInternal#(Integer n,
|
rlm@8
|
134 function Bool searchfunc1(search_T s, alpha_T x),
|
rlm@8
|
135 function Bool searchfunc2(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T))
|
rlm@8
|
136
|
rlm@8
|
137 provisos ( Bits#(alpha_T,alpha_SZ) );
|
rlm@8
|
138
|
rlm@8
|
139 List#(Reg#(alpha_T)) registers <- replicateM(n, mkRegU);
|
rlm@8
|
140 List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False));
|
rlm@8
|
141
|
rlm@8
|
142 function Nat getNextFree (List#(Reg#(Bool)) vs);
|
rlm@8
|
143
|
rlm@8
|
144 Nat res = fromInteger(n - 1);
|
rlm@8
|
145
|
rlm@8
|
146 for (Integer x = n - 1; x > -1; x = x - 1)
|
rlm@8
|
147 res = !vs[x]._read() ? fromInteger(x) : res;
|
rlm@8
|
148
|
rlm@8
|
149 return res;
|
rlm@8
|
150
|
rlm@8
|
151 endfunction
|
rlm@8
|
152
|
rlm@8
|
153 function Bool notFullHelper();
|
rlm@8
|
154
|
rlm@8
|
155 Bool full = True;
|
rlm@8
|
156
|
rlm@8
|
157 for (Integer x = 0; x < n; x = x + 1)
|
rlm@8
|
158 full = full && valids[x]._read();
|
rlm@8
|
159
|
rlm@8
|
160 return !full;
|
rlm@8
|
161
|
rlm@8
|
162 endfunction
|
rlm@8
|
163
|
rlm@8
|
164 method Action enq( alpha_T item ) if ( notFullHelper() );
|
rlm@8
|
165
|
rlm@8
|
166 Nat k = getNextFree(valids);
|
rlm@8
|
167 select(valids, k)._write(True);
|
rlm@8
|
168 select(registers, k)._write(item);
|
rlm@8
|
169
|
rlm@8
|
170 endmethod
|
rlm@8
|
171
|
rlm@8
|
172 method Action deq() if ( valids[0]._read() );
|
rlm@8
|
173
|
rlm@8
|
174 for (Integer x = 0; x < (n-1); x = x + 1)
|
rlm@8
|
175 begin
|
rlm@8
|
176
|
rlm@8
|
177 (registers[x]) <= registers[x + 1]._read();
|
rlm@8
|
178 (valids[x]) <= valids[x + 1]._read();
|
rlm@8
|
179
|
rlm@8
|
180 end
|
rlm@8
|
181 (valids[n-1]) <= False;
|
rlm@8
|
182 endmethod
|
rlm@8
|
183
|
rlm@8
|
184 method alpha_T first() if ( valids[0]._read() );
|
rlm@8
|
185 return registers[0]._read();
|
rlm@8
|
186 endmethod
|
rlm@8
|
187
|
rlm@8
|
188 method Bool find(search_T sv);
|
rlm@8
|
189 Bool res = False;
|
rlm@8
|
190
|
rlm@8
|
191 for (Integer x = 0; x < n; x = x + 1)
|
rlm@8
|
192 if ( valids[x]._read() && searchfunc1(sv, registers[x]._read()) )
|
rlm@8
|
193 res = True;
|
rlm@8
|
194
|
rlm@8
|
195 return res;
|
rlm@8
|
196
|
rlm@8
|
197 endmethod
|
rlm@8
|
198
|
rlm@8
|
199 method Bool find2(search_T sv);
|
rlm@8
|
200 Bool res = False;
|
rlm@8
|
201
|
rlm@8
|
202 for (Integer x = 0; x < n; x = x + 1)
|
rlm@8
|
203 if ( valids[x]._read() && searchfunc2(sv, registers[x]._read()) )
|
rlm@8
|
204 res = True;
|
rlm@8
|
205
|
rlm@8
|
206 return res;
|
rlm@8
|
207
|
rlm@8
|
208 endmethod
|
rlm@8
|
209
|
rlm@8
|
210 method Action clear();
|
rlm@8
|
211
|
rlm@8
|
212 for (Integer x = 0; x < n; x = x + 1)
|
rlm@8
|
213 (valids[x]) <= False;
|
rlm@8
|
214
|
rlm@8
|
215 endmethod
|
rlm@8
|
216
|
rlm@8
|
217 method Bool notEmpty();
|
rlm@8
|
218 return valids[0]._read();
|
rlm@8
|
219 endmethod
|
rlm@8
|
220
|
rlm@8
|
221 method Bool notFull();
|
rlm@8
|
222 return notFullHelper();
|
rlm@8
|
223 endmethod
|
rlm@8
|
224
|
rlm@8
|
225 endmodule
|
rlm@8
|
226
|
rlm@8
|
227 module mkSizedSFIFO#(Integer n, function Bool searchfunc(search_T s, alpha_T x)) (SFIFO#(alpha_T, search_T))
|
rlm@8
|
228 provisos
|
rlm@8
|
229 (Bits#(alpha_T,asz));
|
rlm@8
|
230
|
rlm@8
|
231 let foo <- mkSizedSFIFOInternal(n, searchfunc, searchfunc);
|
rlm@8
|
232 return foo;
|
rlm@8
|
233
|
rlm@8
|
234 endmodule |