Mercurial > pygar
comparison core/src/BFIFO.bsv @ 1:91a1f76ddd62 pygar svn.2
[svn r2] Adding initial lab 5 source
author | punk |
---|---|
date | Tue, 13 Apr 2010 17:34:33 -0400 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:6d1ff93e3afa | 1:91a1f76ddd62 |
---|---|
1 import FIFO::*; | |
2 import FIFOF::*; | |
3 import List::*; | |
4 import Assert::*; | |
5 | |
6 module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); | |
7 | |
8 RWire#(item_t) inputWire <- mkRWire(); | |
9 PulseWire deqEnabled <- mkPulseWire(); | |
10 PulseWire clearEnabled <- mkPulseWire(); | |
11 | |
12 Reg#(item_t) register <- mkRegU(); | |
13 Reg#(Bool) valid <- mkReg(False); | |
14 | |
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 | |
17 | |
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 | |
31 | |
32 // On enqueue we write the input item to the inputWire wire | |
33 | |
34 method Action enq( item_t item ) if ( !valid ); | |
35 inputWire.wset(item); | |
36 endmethod | |
37 | |
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. | |
42 | |
43 method Action deq() if ( valid || isValid(inputWire.wget()) ); | |
44 deqEnabled.send(); | |
45 endmethod | |
46 | |
47 // We get the item either from the register (if register is valid) or | |
48 // from the combinational bypasss (if the rwire is valid). | |
49 | |
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 | |
56 | |
57 method Action clear(); | |
58 clearEnabled.send(); | |
59 endmethod | |
60 | |
61 endmodule | |
62 | |
63 module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); | |
64 | |
65 RWire#(item_t) inputWire <- mkRWire(); | |
66 PulseWire deqEnabled <- mkPulseWire(); | |
67 PulseWire clearEnabled <- mkPulseWire(); | |
68 | |
69 List#(Reg#(item_t)) registers <- replicateM(n, mkRegU); | |
70 List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); | |
71 | |
72 function Nat getNextFree (List#(Reg#(Bool)) vs); | |
73 | |
74 Nat res = fromInteger(n - 1); | |
75 | |
76 for (Integer x = n - 1; x > -1; x = x - 1) | |
77 res = !vs[x]._read() ? fromInteger(x) : res; | |
78 | |
79 return res; | |
80 | |
81 endfunction | |
82 | |
83 function Bool notFull(); | |
84 | |
85 Bool full = True; | |
86 | |
87 for (Integer x = 0; x < length(valids); x = x + 1) | |
88 full = full && valids[x]._read(); | |
89 | |
90 return !full; | |
91 | |
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 | |
95 | |
96 rule update ( True ); | |
97 Nat next = getNextFree(valids); | |
98 | |
99 next = (deqEnabled) ? next - 1 : next; | |
100 | |
101 (valids[next]) <= isValid(inputWire.wget()); | |
102 (registers[next]) <= validValue(inputWire.wget()); | |
103 | |
104 if (deqEnabled && !clearEnabled) | |
105 begin | |
106 | |
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 | |
112 | |
113 end | |
114 else if (clearEnabled) | |
115 begin | |
116 | |
117 for (Integer x = 0; x < n; x = x + 1) | |
118 (valids[x]) <= False; | |
119 | |
120 end | |
121 endrule | |
122 | |
123 // On enqueue we write the input item to the inputWire wire | |
124 | |
125 method Action enq( item_t item ) if ( notFull ); | |
126 inputWire.wset(item); | |
127 endmethod | |
128 | |
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. | |
133 | |
134 method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) ); | |
135 deqEnabled.send(); | |
136 endmethod | |
137 | |
138 // We get the item either from the register (if register is valid) or | |
139 // from the combinational bypasss (if the rwire is valid). | |
140 | |
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 | |
147 | |
148 | |
149 method Action clear(); | |
150 clearEnabled.send(); | |
151 endmethod | |
152 | |
153 endmodule | |
154 | |
155 | |
156 module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) ); | |
157 | |
158 RWire#(item_t) inputWire <- mkRWire(); | |
159 RWire#(Bool) deqEnabled <- mkRWire(); | |
160 | |
161 Reg#(Maybe#(item_t)) register <- mkReg(Invalid); | |
162 | |
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 | |
165 | |
166 rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) ); | |
167 register <= inputWire.wget(); | |
168 endrule | |
169 | |
170 // On enqueue we write the input item to the inputWire wire | |
171 | |
172 method Action enq( item_t item ) if ( !isValid(register) ); | |
173 inputWire.wset(item); | |
174 endmethod | |
175 | |
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. | |
180 | |
181 method Action deq() if ( isValid(register) || isValid(inputWire.wget()) ); | |
182 register <= Invalid; | |
183 deqEnabled.wset(True); | |
184 endmethod | |
185 | |
186 // We get the item either from the register (if register is valid) or | |
187 // from the combinational bypasss (if the rwire is valid). | |
188 | |
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 | |
195 | |
196 // FIFOF adds the following two methods | |
197 | |
198 method Bool notFull(); | |
199 return !isValid(register); | |
200 endmethod | |
201 | |
202 method Bool notEmpty(); | |
203 return (isValid(register) || isValid(inputWire.wget())); | |
204 endmethod | |
205 | |
206 // Not sure about the clear method ... | |
207 | |
208 method Action clear(); | |
209 dynamicAssert( False, "BFIFO.clear() not implemented yet!" ); | |
210 endmethod | |
211 | |
212 endmodule | |
213 | |
214 (* synthesize *) | |
215 module mkBFIFO_16 (FIFO#(Bit#(16))); | |
216 | |
217 let f <- mkBFIFO1(); | |
218 | |
219 return f; | |
220 | |
221 endmodule | |
222 |