annotate modules/bluespec/Pygar/lab4/BFIFO.bsv @ 54:9b4f237e77e1 pygar svn.55

[svn r55] input a bit more parameterized
author punk
date Sun, 09 May 2010 12:24:35 -0400
parents 74716e9a81cc
children
rev   line source
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