rlm@8
|
1 import FIFO::*;
|
rlm@8
|
2 import FIFOF::*;
|
rlm@8
|
3 import List::*;
|
rlm@8
|
4 import Assert::*;
|
rlm@8
|
5
|
rlm@8
|
6 module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) );
|
rlm@8
|
7
|
rlm@8
|
8 RWire#(item_t) inputWire <- mkRWire();
|
rlm@8
|
9 PulseWire deqEnabled <- mkPulseWire();
|
rlm@8
|
10 PulseWire clearEnabled <- mkPulseWire();
|
rlm@8
|
11
|
rlm@8
|
12 Reg#(item_t) register <- mkRegU();
|
rlm@8
|
13 Reg#(Bool) valid <- mkReg(False);
|
rlm@8
|
14
|
rlm@8
|
15 // If there is an input item on the inputWire wire and dequeue did not
|
rlm@8
|
16 // execute this cycle then we need to store the item in the register
|
rlm@8
|
17
|
rlm@8
|
18 (*fire_when_enabled*)
|
rlm@8
|
19 rule update ( True );
|
rlm@8
|
20 case (inputWire.wget()) matches
|
rlm@8
|
21 tagged Invalid:
|
rlm@8
|
22 if (deqEnabled || clearEnabled)
|
rlm@8
|
23 valid <= False;
|
rlm@8
|
24 tagged Valid .x:
|
rlm@8
|
25 begin
|
rlm@8
|
26 register <= x;
|
rlm@8
|
27 valid <= !(deqEnabled || clearEnabled);
|
rlm@8
|
28 end
|
rlm@8
|
29 endcase
|
rlm@8
|
30 endrule
|
rlm@8
|
31
|
rlm@8
|
32 // On enqueue we write the input item to the inputWire wire
|
rlm@8
|
33
|
rlm@8
|
34 method Action enq( item_t item ) if ( !valid );
|
rlm@8
|
35 inputWire.wset(item);
|
rlm@8
|
36 endmethod
|
rlm@8
|
37
|
rlm@8
|
38 // On dequeue we always invalidate the storage register regardless
|
rlm@8
|
39 // of whether or not the item was actually bypassed or not. We also
|
rlm@8
|
40 // set a combinational signal so that we know not to move the item
|
rlm@8
|
41 // into the register this cycle.
|
rlm@8
|
42
|
rlm@8
|
43 method Action deq() if ( valid || isValid(inputWire.wget()) );
|
rlm@8
|
44 deqEnabled.send();
|
rlm@8
|
45 endmethod
|
rlm@8
|
46
|
rlm@8
|
47 // We get the item either from the register (if register is valid) or
|
rlm@8
|
48 // from the combinational bypasss (if the rwire is valid).
|
rlm@8
|
49
|
rlm@8
|
50 method item_t first() if ( valid || isValid(inputWire.wget()) );
|
rlm@8
|
51 if ( valid )
|
rlm@8
|
52 return register;
|
rlm@8
|
53 else
|
rlm@8
|
54 return unJust(inputWire.wget());
|
rlm@8
|
55 endmethod
|
rlm@8
|
56
|
rlm@8
|
57 method Action clear();
|
rlm@8
|
58 clearEnabled.send();
|
rlm@8
|
59 endmethod
|
rlm@8
|
60
|
rlm@8
|
61 endmodule
|
rlm@8
|
62
|
rlm@8
|
63 module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) );
|
rlm@8
|
64
|
rlm@8
|
65 RWire#(item_t) inputWire <- mkRWire();
|
rlm@8
|
66 PulseWire deqEnabled <- mkPulseWire();
|
rlm@8
|
67 PulseWire clearEnabled <- mkPulseWire();
|
rlm@8
|
68
|
rlm@8
|
69 List#(Reg#(item_t)) registers <- replicateM(n, mkRegU);
|
rlm@8
|
70 List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False));
|
rlm@8
|
71
|
rlm@8
|
72 function Nat getNextFree (List#(Reg#(Bool)) vs);
|
rlm@8
|
73
|
rlm@8
|
74 Nat res = fromInteger(n - 1);
|
rlm@8
|
75
|
rlm@8
|
76 for (Integer x = n - 1; x > -1; x = x - 1)
|
rlm@8
|
77 res = !vs[x]._read() ? fromInteger(x) : res;
|
rlm@8
|
78
|
rlm@8
|
79 return res;
|
rlm@8
|
80
|
rlm@8
|
81 endfunction
|
rlm@8
|
82
|
rlm@8
|
83 function Bool notFull();
|
rlm@8
|
84
|
rlm@8
|
85 Bool full = True;
|
rlm@8
|
86
|
rlm@8
|
87 for (Integer x = 0; x < length(valids); x = x + 1)
|
rlm@8
|
88 full = full && valids[x]._read();
|
rlm@8
|
89
|
rlm@8
|
90 return !full;
|
rlm@8
|
91
|
rlm@8
|
92 endfunction
|
rlm@8
|
93 // If there is an input item on the inputWire wire and dequeue did not
|
rlm@8
|
94 // execute this cycle then we need to store the item in the register
|
rlm@8
|
95
|
rlm@8
|
96 rule update ( True );
|
rlm@8
|
97 Nat next = getNextFree(valids);
|
rlm@8
|
98
|
rlm@8
|
99 next = (deqEnabled) ? next - 1 : next;
|
rlm@8
|
100
|
rlm@8
|
101 (valids[next]) <= isValid(inputWire.wget());
|
rlm@8
|
102 (registers[next]) <= validValue(inputWire.wget());
|
rlm@8
|
103
|
rlm@8
|
104 if (deqEnabled && !clearEnabled)
|
rlm@8
|
105 begin
|
rlm@8
|
106
|
rlm@8
|
107 for (Nat x = 0; x < (next - 1); x = x + 1)
|
rlm@8
|
108 begin
|
rlm@8
|
109 (valids[x]) <= valids[x+1]._read();
|
rlm@8
|
110 (registers[x]) <= registers[x+1]._read();
|
rlm@8
|
111 end
|
rlm@8
|
112
|
rlm@8
|
113 end
|
rlm@8
|
114 else if (clearEnabled)
|
rlm@8
|
115 begin
|
rlm@8
|
116
|
rlm@8
|
117 for (Integer x = 0; x < n; x = x + 1)
|
rlm@8
|
118 (valids[x]) <= False;
|
rlm@8
|
119
|
rlm@8
|
120 end
|
rlm@8
|
121 endrule
|
rlm@8
|
122
|
rlm@8
|
123 // On enqueue we write the input item to the inputWire wire
|
rlm@8
|
124
|
rlm@8
|
125 method Action enq( item_t item ) if ( notFull );
|
rlm@8
|
126 inputWire.wset(item);
|
rlm@8
|
127 endmethod
|
rlm@8
|
128
|
rlm@8
|
129 // On dequeue we always invalidate the storage register regardless
|
rlm@8
|
130 // of whether or not the item was actually bypassed or not. We also
|
rlm@8
|
131 // set a combinational signal so that we know not to move the item
|
rlm@8
|
132 // into the register this cycle.
|
rlm@8
|
133
|
rlm@8
|
134 method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) );
|
rlm@8
|
135 deqEnabled.send();
|
rlm@8
|
136 endmethod
|
rlm@8
|
137
|
rlm@8
|
138 // We get the item either from the register (if register is valid) or
|
rlm@8
|
139 // from the combinational bypasss (if the rwire is valid).
|
rlm@8
|
140
|
rlm@8
|
141 method item_t first() if ( valids[0]._read() || isValid(inputWire.wget()) );
|
rlm@8
|
142 if ( valids[0]._read() )
|
rlm@8
|
143 return registers[0]._read();
|
rlm@8
|
144 else
|
rlm@8
|
145 return unJust(inputWire.wget());
|
rlm@8
|
146 endmethod
|
rlm@8
|
147
|
rlm@8
|
148
|
rlm@8
|
149 method Action clear();
|
rlm@8
|
150 clearEnabled.send();
|
rlm@8
|
151 endmethod
|
rlm@8
|
152
|
rlm@8
|
153 endmodule
|
rlm@8
|
154
|
rlm@8
|
155
|
rlm@8
|
156 module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) );
|
rlm@8
|
157
|
rlm@8
|
158 RWire#(item_t) inputWire <- mkRWire();
|
rlm@8
|
159 RWire#(Bool) deqEnabled <- mkRWire();
|
rlm@8
|
160
|
rlm@8
|
161 Reg#(Maybe#(item_t)) register <- mkReg(Invalid);
|
rlm@8
|
162
|
rlm@8
|
163 // If there is an input item on the inputWire wire and dequeue did not
|
rlm@8
|
164 // execute this cycle then we need to store the item in the register
|
rlm@8
|
165
|
rlm@8
|
166 rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) );
|
rlm@8
|
167 register <= inputWire.wget();
|
rlm@8
|
168 endrule
|
rlm@8
|
169
|
rlm@8
|
170 // On enqueue we write the input item to the inputWire wire
|
rlm@8
|
171
|
rlm@8
|
172 method Action enq( item_t item ) if ( !isValid(register) );
|
rlm@8
|
173 inputWire.wset(item);
|
rlm@8
|
174 endmethod
|
rlm@8
|
175
|
rlm@8
|
176 // On dequeue we always invalidate the storage register regardless
|
rlm@8
|
177 // of whether or not the item was actually bypassed or not. We also
|
rlm@8
|
178 // set a combinational signal so that we know not to move the item
|
rlm@8
|
179 // into the register this cycle.
|
rlm@8
|
180
|
rlm@8
|
181 method Action deq() if ( isValid(register) || isValid(inputWire.wget()) );
|
rlm@8
|
182 register <= Invalid;
|
rlm@8
|
183 deqEnabled.wset(True);
|
rlm@8
|
184 endmethod
|
rlm@8
|
185
|
rlm@8
|
186 // We get the item either from the register (if register is valid) or
|
rlm@8
|
187 // from the combinational bypasss (if the rwire is valid).
|
rlm@8
|
188
|
rlm@8
|
189 method item_t first() if ( isValid(register) || isValid(inputWire.wget()) );
|
rlm@8
|
190 if ( isValid(register) )
|
rlm@8
|
191 return unJust(register);
|
rlm@8
|
192 else
|
rlm@8
|
193 return unJust(inputWire.wget());
|
rlm@8
|
194 endmethod
|
rlm@8
|
195
|
rlm@8
|
196 // FIFOF adds the following two methods
|
rlm@8
|
197
|
rlm@8
|
198 method Bool notFull();
|
rlm@8
|
199 return !isValid(register);
|
rlm@8
|
200 endmethod
|
rlm@8
|
201
|
rlm@8
|
202 method Bool notEmpty();
|
rlm@8
|
203 return (isValid(register) || isValid(inputWire.wget()));
|
rlm@8
|
204 endmethod
|
rlm@8
|
205
|
rlm@8
|
206 // Not sure about the clear method ...
|
rlm@8
|
207
|
rlm@8
|
208 method Action clear();
|
rlm@8
|
209 dynamicAssert( False, "BFIFO.clear() not implemented yet!" );
|
rlm@8
|
210 endmethod
|
rlm@8
|
211
|
rlm@8
|
212 endmodule
|
rlm@8
|
213
|
rlm@8
|
214 (* synthesize *)
|
rlm@8
|
215 module mkBFIFO_16 (FIFO#(Bit#(16)));
|
rlm@8
|
216
|
rlm@8
|
217 let f <- mkBFIFO1();
|
rlm@8
|
218
|
rlm@8
|
219 return f;
|
rlm@8
|
220
|
rlm@8
|
221 endmodule
|
rlm@8
|
222
|