Mercurial > pygar
diff 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 |
line wrap: on
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/core/src/BFIFO.bsv Tue Apr 13 17:34:33 2010 -0400 1.3 @@ -0,0 +1,222 @@ 1.4 +import FIFO::*; 1.5 +import FIFOF::*; 1.6 +import List::*; 1.7 +import Assert::*; 1.8 + 1.9 +module mkBFIFO1( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 1.10 + 1.11 + RWire#(item_t) inputWire <- mkRWire(); 1.12 + PulseWire deqEnabled <- mkPulseWire(); 1.13 + PulseWire clearEnabled <- mkPulseWire(); 1.14 + 1.15 + Reg#(item_t) register <- mkRegU(); 1.16 + Reg#(Bool) valid <- mkReg(False); 1.17 + 1.18 + // If there is an input item on the inputWire wire and dequeue did not 1.19 + // execute this cycle then we need to store the item in the register 1.20 + 1.21 + (*fire_when_enabled*) 1.22 + rule update ( True ); 1.23 + case (inputWire.wget()) matches 1.24 + tagged Invalid: 1.25 + if (deqEnabled || clearEnabled) 1.26 + valid <= False; 1.27 + tagged Valid .x: 1.28 + begin 1.29 + register <= x; 1.30 + valid <= !(deqEnabled || clearEnabled); 1.31 + end 1.32 + endcase 1.33 + endrule 1.34 + 1.35 + // On enqueue we write the input item to the inputWire wire 1.36 + 1.37 + method Action enq( item_t item ) if ( !valid ); 1.38 + inputWire.wset(item); 1.39 + endmethod 1.40 + 1.41 + // On dequeue we always invalidate the storage register regardless 1.42 + // of whether or not the item was actually bypassed or not. We also 1.43 + // set a combinational signal so that we know not to move the item 1.44 + // into the register this cycle. 1.45 + 1.46 + method Action deq() if ( valid || isValid(inputWire.wget()) ); 1.47 + deqEnabled.send(); 1.48 + endmethod 1.49 + 1.50 + // We get the item either from the register (if register is valid) or 1.51 + // from the combinational bypasss (if the rwire is valid). 1.52 + 1.53 + method item_t first() if ( valid || isValid(inputWire.wget()) ); 1.54 + if ( valid ) 1.55 + return register; 1.56 + else 1.57 + return unJust(inputWire.wget()); 1.58 + endmethod 1.59 + 1.60 + method Action clear(); 1.61 + clearEnabled.send(); 1.62 + endmethod 1.63 + 1.64 +endmodule 1.65 + 1.66 +module mkSizedBFIFO#(Integer n) ( FIFO#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 1.67 + 1.68 + RWire#(item_t) inputWire <- mkRWire(); 1.69 + PulseWire deqEnabled <- mkPulseWire(); 1.70 + PulseWire clearEnabled <- mkPulseWire(); 1.71 + 1.72 + List#(Reg#(item_t)) registers <- replicateM(n, mkRegU); 1.73 + List#(Reg#(Bool)) valids <- replicateM(n, mkReg(False)); 1.74 + 1.75 + function Nat getNextFree (List#(Reg#(Bool)) vs); 1.76 + 1.77 + Nat res = fromInteger(n - 1); 1.78 + 1.79 + for (Integer x = n - 1; x > -1; x = x - 1) 1.80 + res = !vs[x]._read() ? fromInteger(x) : res; 1.81 + 1.82 + return res; 1.83 + 1.84 + endfunction 1.85 + 1.86 + function Bool notFull(); 1.87 + 1.88 + Bool full = True; 1.89 + 1.90 + for (Integer x = 0; x < length(valids); x = x + 1) 1.91 + full = full && valids[x]._read(); 1.92 + 1.93 + return !full; 1.94 + 1.95 + endfunction 1.96 + // If there is an input item on the inputWire wire and dequeue did not 1.97 + // execute this cycle then we need to store the item in the register 1.98 + 1.99 + rule update ( True ); 1.100 + Nat next = getNextFree(valids); 1.101 + 1.102 + next = (deqEnabled) ? next - 1 : next; 1.103 + 1.104 + (valids[next]) <= isValid(inputWire.wget()); 1.105 + (registers[next]) <= validValue(inputWire.wget()); 1.106 + 1.107 + if (deqEnabled && !clearEnabled) 1.108 + begin 1.109 + 1.110 + for (Nat x = 0; x < (next - 1); x = x + 1) 1.111 + begin 1.112 + (valids[x]) <= valids[x+1]._read(); 1.113 + (registers[x]) <= registers[x+1]._read(); 1.114 + end 1.115 + 1.116 + end 1.117 + else if (clearEnabled) 1.118 + begin 1.119 + 1.120 + for (Integer x = 0; x < n; x = x + 1) 1.121 + (valids[x]) <= False; 1.122 + 1.123 + end 1.124 + endrule 1.125 + 1.126 + // On enqueue we write the input item to the inputWire wire 1.127 + 1.128 + method Action enq( item_t item ) if ( notFull ); 1.129 + inputWire.wset(item); 1.130 + endmethod 1.131 + 1.132 + // On dequeue we always invalidate the storage register regardless 1.133 + // of whether or not the item was actually bypassed or not. We also 1.134 + // set a combinational signal so that we know not to move the item 1.135 + // into the register this cycle. 1.136 + 1.137 + method Action deq() if ( valids[0]._read() || isValid(inputWire.wget()) ); 1.138 + deqEnabled.send(); 1.139 + endmethod 1.140 + 1.141 + // We get the item either from the register (if register is valid) or 1.142 + // from the combinational bypasss (if the rwire is valid). 1.143 + 1.144 + method item_t first() if ( valids[0]._read() || isValid(inputWire.wget()) ); 1.145 + if ( valids[0]._read() ) 1.146 + return registers[0]._read(); 1.147 + else 1.148 + return unJust(inputWire.wget()); 1.149 + endmethod 1.150 + 1.151 + 1.152 + method Action clear(); 1.153 + clearEnabled.send(); 1.154 + endmethod 1.155 + 1.156 +endmodule 1.157 + 1.158 + 1.159 +module mkBFIFOF1( FIFOF#(item_t) ) provisos ( Bits#(item_t,item_sz) ); 1.160 + 1.161 + RWire#(item_t) inputWire <- mkRWire(); 1.162 + RWire#(Bool) deqEnabled <- mkRWire(); 1.163 + 1.164 + Reg#(Maybe#(item_t)) register <- mkReg(Invalid); 1.165 + 1.166 + // If there is an input item on the inputWire wire and dequeue did not 1.167 + // execute this cycle then we need to store the item in the register 1.168 + 1.169 + rule noDeq ( isValid(inputWire.wget()) && !isValid(deqEnabled.wget()) ); 1.170 + register <= inputWire.wget(); 1.171 + endrule 1.172 + 1.173 + // On enqueue we write the input item to the inputWire wire 1.174 + 1.175 + method Action enq( item_t item ) if ( !isValid(register) ); 1.176 + inputWire.wset(item); 1.177 + endmethod 1.178 + 1.179 + // On dequeue we always invalidate the storage register regardless 1.180 + // of whether or not the item was actually bypassed or not. We also 1.181 + // set a combinational signal so that we know not to move the item 1.182 + // into the register this cycle. 1.183 + 1.184 + method Action deq() if ( isValid(register) || isValid(inputWire.wget()) ); 1.185 + register <= Invalid; 1.186 + deqEnabled.wset(True); 1.187 + endmethod 1.188 + 1.189 + // We get the item either from the register (if register is valid) or 1.190 + // from the combinational bypasss (if the rwire is valid). 1.191 + 1.192 + method item_t first() if ( isValid(register) || isValid(inputWire.wget()) ); 1.193 + if ( isValid(register) ) 1.194 + return unJust(register); 1.195 + else 1.196 + return unJust(inputWire.wget()); 1.197 + endmethod 1.198 + 1.199 + // FIFOF adds the following two methods 1.200 + 1.201 + method Bool notFull(); 1.202 + return !isValid(register); 1.203 + endmethod 1.204 + 1.205 + method Bool notEmpty(); 1.206 + return (isValid(register) || isValid(inputWire.wget())); 1.207 + endmethod 1.208 + 1.209 + // Not sure about the clear method ... 1.210 + 1.211 + method Action clear(); 1.212 + dynamicAssert( False, "BFIFO.clear() not implemented yet!" ); 1.213 + endmethod 1.214 + 1.215 +endmodule 1.216 + 1.217 +(* synthesize *) 1.218 +module mkBFIFO_16 (FIFO#(Bit#(16))); 1.219 + 1.220 + let f <- mkBFIFO1(); 1.221 + 1.222 + return f; 1.223 + 1.224 +endmodule 1.225 +