diff modules/bluespec/Pygar/lab1/FIRFilterDefault.bsv @ 8:74716e9a81cc pygar svn.9

[svn r9] Pygar now has the proper directory structure to play nicely with awb. Also, the apm file for audio-core willcompile successfully.
author rlm
date Fri, 23 Apr 2010 02:32:05 -0400
parents
children
line wrap: on
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/modules/bluespec/Pygar/lab1/FIRFilterDefault.bsv	Fri Apr 23 02:32:05 2010 -0400
     1.3 @@ -0,0 +1,157 @@
     1.4 +// The MIT License
     1.5 +
     1.6 +// Copyright (c) 2009 Massachusetts Institute of Technology
     1.7 +
     1.8 +// Permission is hereby granted, free of charge, to any person obtaining a copy
     1.9 +// of this software and associated documentation files (the "Software"), to deal
    1.10 +// in the Software without restriction, including without limitation the rights
    1.11 +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    1.12 +// copies of the Software, and to permit persons to whom the Software is
    1.13 +// furnished to do so, subject to the following conditions:
    1.14 +
    1.15 +// The above copyright notice and this permission notice shall be included in
    1.16 +// all copies or substantial portions of the Software.
    1.17 +
    1.18 +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    1.19 +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    1.20 +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    1.21 +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    1.22 +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    1.23 +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    1.24 +// THE SOFTWARE.
    1.25 +
    1.26 +// Author: Kermin Fleming kfleming@mit.edu
    1.27 +
    1.28 +import Connectable::*;
    1.29 +import GetPut::*;
    1.30 +import ClientServer::*;
    1.31 +import FIFO::*;
    1.32 +import FixedPoint::*;
    1.33 +import Vector::*;
    1.34 +
    1.35 +//AWB includes.   These import the structure whcih allow us to communicate
    1.36 +// with the outside world, and are part of the AWB library code
    1.37 +
    1.38 +`include "asim/provides/soft_connections.bsh"
    1.39 +`include "asim/provides/common_services.bsh"
    1.40 +
    1.41 +// Local includes. Look for the correspondingly named .awb files
    1.42 +// workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/
    1.43 +// to find the actual Bluespec files which are used to generate
    1.44 +// these includes.  These files are specific to this audio processing
    1.45 +// pipeline
    1.46 +
    1.47 +`include "asim/provides/audio_pipeline_types.bsh"
    1.48 +`include "asim/provides/audio_processor_types.bsh"
    1.49 +
    1.50 +typedef 8 Taps;
    1.51 +
    1.52 +module [Connected_Module] mkFIRFilter (FIRFilter);
    1.53 +
    1.54 +
    1.55 +  // instantiate an input FIFO and an Output FIFO
    1.56 +  // mkFIFO returns a fifo of length 2 (by default)  
    1.57 +  // AudioProcessorUnit is the name given to the packets
    1.58 +  // of DATA processed by our audio pipeline.  For their 
    1.59 +  // definition, look in the file
    1.60 +  // workspace/labs/src/mit-6.375/modules/bluespec/mit-6.375/common/AudioProcessorTypes.bsv
    1.61 +
    1.62 +  FIFO#(AudioProcessorUnit) infifo <- mkFIFO;
    1.63 +  FIFO#(AudioProcessorUnit) outfifo <- mkFIFO;
    1.64 +
    1.65 +
    1.66 +  // an alternate syntax for instantiating the samples vector
    1.67 +  // would have been as follows:
    1.68 +  //
    1.69 +  // Vector#(Taps,Reg#(Sample)) samples <- replicateM(mkReg(0));
    1.70 +  // 
    1.71 +  // we have used an explicit loop here, to demonstrate how
    1.72 +  // vectors can be instantiated during the static elaboration 
    1.73 +  // phase, even though replicateM is far more concise.
    1.74 +
    1.75 +  Vector#(Taps,Reg#(Sample)) samples = newVector();
    1.76 +  for(Integer i = 0; i < valueof(Taps); i=i+1)
    1.77 +     samples[i] <- mkReg(0);
    1.78 +
    1.79 +  Vector#(9,Reg#(FixedPoint#(16,16))) pr <- replicateM(mkReg(0));
    1.80 +  
    1.81 +
    1.82 +  // fromReal takes a Real number and converts it to a FixedPoint
    1.83 +  // representation.   The compiler is smart enough to infer the 
    1.84 +  // type (bit width) of the fixed point (in this case, we have 16 
    1.85 +  // bits of integer, and 16 bits of fraction.
    1.86 +
    1.87 +  FixedPoint#(16,16) firCoefs [9] = {fromReal(-0.0124),
    1.88 +                                     fromReal(0.0),
    1.89 +                                     fromReal(-0.0133),
    1.90 +                                     fromReal(0.0),
    1.91 +                                     fromReal(0.8181),
    1.92 +                                     fromReal(0.0),
    1.93 +                                     fromReal(-0.0133),
    1.94 +                                     fromReal(0.0),
    1.95 +                                     fromReal(-0.0124)};
    1.96 +
    1.97 +
    1.98 +  // This rule implements a fir filter.  We do the fir computations in
    1.99 +  // 16.16 fixed point.  This preserves the magnitude of the input
   1.100 +  // pcm.  This code was implemented using for loops so as to be more
   1.101 +  // clear. Using the functions map, fold, readVReg, and writeVReg
   1.102 +  // would have been more concise.
   1.103 +
   1.104 +  rule process (infifo.first matches tagged Sample .sample);
   1.105 +
   1.106 +    // Advance the fir filter, by shifting all the elements
   1.107 +    // down the Vector of registers (like a shift register)
   1.108 +
   1.109 +    samples[0] <= sample;
   1.110 +    for(Integer i = 0; i < valueof(Taps) - 1; i = i + 1)
   1.111 +       begin
   1.112 +         samples[i+1] <= samples[i];           
   1.113 +       end
   1.114 +
   1.115 +    // Filter the values, using an inefficient adder chain.  You will
   1.116 +    // need to shorten the combinatorial path, by pipelining this logic.
   1.117 +
   1.118 +    FixedPoint#(16,16) accumulate= firCoefs[0] * fromInt(sample);  
   1.119 +    for(Integer i = 0; i < valueof(Taps); i = i + 1)
   1.120 +      begin
   1.121 +        accumulate = accumulate + firCoefs[1+i] * fromInt(samples[i]);  
   1.122 +      end 
   1.123 +
   1.124 +    outfifo.enq(tagged Sample fxptGetInt(accumulate));
   1.125 +    
   1.126 +    infifo.deq;
   1.127 +  endrule
   1.128 +  
   1.129 +  // Handle the end of stream condition.  Look at the two rule guards,
   1.130 +  // these are obviously mutually exclusive.  The definition of
   1.131 +  // AudioProcessorUnit shows that it can be tagged only as a Sample, or
   1.132 +  // EndOfFile; nothing else!
   1.133 +
   1.134 +  rule endOfFile (infifo.first matches tagged EndOfFile);
   1.135 +
   1.136 +    $display("FIR got end of file");
   1.137 +
   1.138 +    // Reset state for next invocation
   1.139 +    for(Integer i = 0; i < valueof(Taps); i = i + 1)
   1.140 +      begin
   1.141 +        samples[i] <= 0;
   1.142 +        pr[i] <= 0;
   1.143 +      end
   1.144 +
   1.145 +    // pass the end-of-file token down the pipeline, eventually this will
   1.146 +    // make it back to the software side, to notify it that the stream
   1.147 +    // has been processed completely
   1.148 +
   1.149 +    outfifo.enq(infifo.first);
   1.150 +    infifo.deq;
   1.151 +  endrule
   1.152 +
   1.153 +
   1.154 +  // this section connects the fifos instantiated internally to the 
   1.155 +  // externally visible interface
   1.156 +
   1.157 +  interface sampleInput = fifoToPut(infifo);
   1.158 +  interface sampleOutput = fifoToGet(outfifo);
   1.159 +
   1.160 +endmodule