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 +