view modules/bluespec/Pygar/lab4/BFIFO.bsv @ 71:86360c5ae9f2 pygar svn.72

[svn r72] added config for htg
author punk
date Wed, 12 May 2010 00:21:40 -0400
parents 74716e9a81cc
children
line wrap: on
line source
1 import FIFO::*;
2 import FIFOF::*;
3 import List::*;
4 import Assert::*;
6 module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) );
8 RWire#(item_t) inputWire <- mkRWire();
9 PulseWire deqEnabled <- mkPulseWire();
10 PulseWire clearEnabled <- mkPulseWire();
12 Reg#(item_t) register <- mkRegU();
13 Reg#(Bool) valid <- mkReg(False);
15 // If there is an input item on the inputWire wire and dequeue did not
16 // execute this cycle then we need to store the item in the register
18 (*fire_when_enabled*)
19 rule update ( True );
20 case (inputWire.wget()) matches
21 tagged Invalid:
22 if (deqEnabled || clearEnabled)
23 valid <= False;
24 tagged Valid .x:
25 begin
26 register <= x;
27 valid <= !(deqEnabled || clearEnabled);
28 end
29 endcase
30 endrule
32 // On enqueue we write the input item to the inputWire wire
34 method Action enq( item_t item ) if ( !valid );
35 inputWire.wset(item);
36 endmethod
38 // On dequeue we always invalidate the storage register regardless
39 // of whether or not the item was actually bypassed or not. We also
40 // set a combinational signal so that we know not to move the item
41 // into the register this cycle.
43 method Action deq() if ( valid || isValid(inputWire.wget()) );
44 deqEnabled.send();
45 endmethod
47 // We get the item either from the register (if register is valid) or
48 // from the combinational bypasss (if the rwire is valid).
50 method item_t first() if ( valid || isValid(inputWire.wget()) );
51 if ( valid )
52 return register;
53 else
54 return unJust(inputWire.wget());
55 endmethod
57 method Action clear();
58 clearEnabled.send();
59 endmethod
61 endmodule
63 module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) );
65 RWire#(item_t) inputWire <- mkRWire();
66 PulseWire deqEnabled <- mkPulseWire();
67 PulseWire clearEnabled <- mkPulseWire();
69 List#(Reg#(item_t)) registers <- replicateM(n, mkRegU);
70 List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False));
72 function Nat getNextFree (List#(Reg#(Bool)) vs);
74 Nat res = fromInteger(n - 1);
76 for (Integer x = n - 1; x > -1; x = x - 1)
77 res = !vs[x]._read() ? fromInteger(x) : res;
79 return res;
81 endfunction
83 function Bool notFull();
85 Bool full = True;
87 for (Integer x = 0; x < length(valids); x = x + 1)
88 full = full && valids[x]._read();
90 return !full;
92 endfunction
93 // If there is an input item on the inputWire wire and dequeue did not
94 // execute this cycle then we need to store the item in the register
96 rule update ( True );
97 Nat next = getNextFree(valids);
99 next = (deqEnabled) ? next - 1 : next;
101 (valids[next]) <= isValid(inputWire.wget());
102 (registers[next]) <= validValue(inputWire.wget());
104 if (deqEnabled && !clearEnabled)
105 begin
107 for (Nat x = 0; x < (next - 1); x = x + 1)
108 begin
109 (valids[x]) <= valids[x+1]._read();
110 (registers[x]) <= registers[x+1]._read();
111 end
113 end
114 else if (clearEnabled)
115 begin
117 for (Integer x = 0; x < n; x = x + 1)
118 (valids[x]) <= False;
120 end
121 endrule
123 // On enqueue we write the input item to the inputWire wire
125 method Action enq( item_t item ) if ( notFull );
126 inputWire.wset(item);
127 endmethod
129 // On dequeue we always invalidate the storage register regardless
130 // of whether or not the item was actually bypassed or not. We also
131 // set a combinational signal so that we know not to move the item
132 // into the register this cycle.
134 method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) );
135 deqEnabled.send();
136 endmethod
138 // We get the item either from the register (if register is valid) or
139 // from the combinational bypasss (if the rwire is valid).
141 method item_t first() if ( valids[0]._read() || isValid(inputWire.wget()) );
142 if ( valids[0]._read() )
143 return registers[0]._read();
144 else
145 return unJust(inputWire.wget());
146 endmethod
149 method Action clear();
150 clearEnabled.send();
151 endmethod
153 endmodule
156 module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) );
158 RWire#(item_t) inputWire <- mkRWire();
159 RWire#(Bool) deqEnabled <- mkRWire();
161 Reg#(Maybe#(item_t)) register <- mkReg(Invalid);
163 // If there is an input item on the inputWire wire and dequeue did not
164 // execute this cycle then we need to store the item in the register
166 rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) );
167 register <= inputWire.wget();
168 endrule
170 // On enqueue we write the input item to the inputWire wire
172 method Action enq( item_t item ) if ( !isValid(register) );
173 inputWire.wset(item);
174 endmethod
176 // On dequeue we always invalidate the storage register regardless
177 // of whether or not the item was actually bypassed or not. We also
178 // set a combinational signal so that we know not to move the item
179 // into the register this cycle.
181 method Action deq() if ( isValid(register) || isValid(inputWire.wget()) );
182 register <= Invalid;
183 deqEnabled.wset(True);
184 endmethod
186 // We get the item either from the register (if register is valid) or
187 // from the combinational bypasss (if the rwire is valid).
189 method item_t first() if ( isValid(register) || isValid(inputWire.wget()) );
190 if ( isValid(register) )
191 return unJust(register);
192 else
193 return unJust(inputWire.wget());
194 endmethod
196 // FIFOF adds the following two methods
198 method Bool notFull();
199 return !isValid(register);
200 endmethod
202 method Bool notEmpty();
203 return (isValid(register) || isValid(inputWire.wget()));
204 endmethod
206 // Not sure about the clear method ...
208 method Action clear();
209 dynamicAssert( False, "BFIFO.clear() not implemented yet!" );
210 endmethod
212 endmodule
214 (* synthesize *)
215 module mkBFIFO_16 (FIFO#(Bit#(16)));
217 let f <- mkBFIFO1();
219 return f;
221 endmodule