Mercurial > pygar
view core/src/BFIFO.bsv @ 3:5e0595db14f6 pygar svn.4
[svn r4] added bluespec manual to documents
author | rlm |
---|---|
date | Tue, 20 Apr 2010 20:09:46 -0400 |
parents | 91a1f76ddd62 |
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 not16 // execute this cycle then we need to store the item in the register18 (*fire_when_enabled*)19 rule update ( True );20 case (inputWire.wget()) matches21 tagged Invalid:22 if (deqEnabled || clearEnabled)23 valid <= False;24 tagged Valid .x:25 begin26 register <= x;27 valid <= !(deqEnabled || clearEnabled);28 end29 endcase30 endrule32 // On enqueue we write the input item to the inputWire wire34 method Action enq( item_t item ) if ( !valid );35 inputWire.wset(item);36 endmethod38 // On dequeue we always invalidate the storage register regardless39 // of whether or not the item was actually bypassed or not. We also40 // set a combinational signal so that we know not to move the item41 // into the register this cycle.43 method Action deq() if ( valid || isValid(inputWire.wget()) );44 deqEnabled.send();45 endmethod47 // We get the item either from the register (if register is valid) or48 // 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 else54 return unJust(inputWire.wget());55 endmethod57 method Action clear();58 clearEnabled.send();59 endmethod61 endmodule63 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 endfunction83 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 endfunction93 // If there is an input item on the inputWire wire and dequeue did not94 // execute this cycle then we need to store the item in the register96 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 begin107 for (Nat x = 0; x < (next - 1); x = x + 1)108 begin109 (valids[x]) <= valids[x+1]._read();110 (registers[x]) <= registers[x+1]._read();111 end113 end114 else if (clearEnabled)115 begin117 for (Integer x = 0; x < n; x = x + 1)118 (valids[x]) <= False;120 end121 endrule123 // On enqueue we write the input item to the inputWire wire125 method Action enq( item_t item ) if ( notFull );126 inputWire.wset(item);127 endmethod129 // On dequeue we always invalidate the storage register regardless130 // of whether or not the item was actually bypassed or not. We also131 // set a combinational signal so that we know not to move the item132 // into the register this cycle.134 method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) );135 deqEnabled.send();136 endmethod138 // We get the item either from the register (if register is valid) or139 // 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 else145 return unJust(inputWire.wget());146 endmethod149 method Action clear();150 clearEnabled.send();151 endmethod153 endmodule156 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 not164 // execute this cycle then we need to store the item in the register166 rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) );167 register <= inputWire.wget();168 endrule170 // On enqueue we write the input item to the inputWire wire172 method Action enq( item_t item ) if ( !isValid(register) );173 inputWire.wset(item);174 endmethod176 // On dequeue we always invalidate the storage register regardless177 // of whether or not the item was actually bypassed or not. We also178 // set a combinational signal so that we know not to move the item179 // into the register this cycle.181 method Action deq() if ( isValid(register) || isValid(inputWire.wget()) );182 register <= Invalid;183 deqEnabled.wset(True);184 endmethod186 // We get the item either from the register (if register is valid) or187 // 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 else193 return unJust(inputWire.wget());194 endmethod196 // FIFOF adds the following two methods198 method Bool notFull();199 return !isValid(register);200 endmethod202 method Bool notEmpty();203 return (isValid(register) || isValid(inputWire.wget()));204 endmethod206 // Not sure about the clear method ...208 method Action clear();209 dynamicAssert( False, "BFIFO.clear() not implemented yet!" );210 endmethod212 endmodule214 (* synthesize *)215 module mkBFIFO_16 (FIFO#(Bit#(16)));217 let f <- mkBFIFO1();219 return f;221 endmodule