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