annotate core/src/BFIFO.bsv @ 67:0ede0715dbd6 pygar svn.68

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