Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #
- # Based heavily on code from https://bitbucket.org/cfelton/examples/src/tip/siir/siir.py
- # which is Copyright (c) 2011 Christopher Felton
- #
- # This program is free software: you can redistribute it and/or modify
- # it under the terms of the GNU Lesser General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU Lesser General Public License for more details.
- #
- # You should have received a copy of the GNU Lesser General Public License
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
- #
- from myhdl import *
- import numpy as np
- from scipy.signal import firwin
- def adc_straight(
- clk,
- x,
- y,
- B=None, # Numerator coefficients, in fixed-point specified
- A=None, # Denominator coefficients, in fixed-point specified
- W=(24,0) # Fixed-point description, tuple,
- # W[0] = word length (wl)
- # W[1] = integer word length (iwl)
- ):
- @always(clk.posedge)
- def adc_test():
- y.next = x
- return instances()
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- # RTL description of the FIR filter
- def sfir_hdl(
- # ~~ Ports ~~
- clk, # Synchronous clock
- x, # Input word, fixed-point format described by "W"
- y, # Output word, fixed-point format described by "W"
- # ~~ Parameters ~~
- B=None, # Numerator coefficients, in fixed-point specified
- W=(24,0) # Fixed-point description, tuple,
- # W[0] = word length (wl)
- # W[1] = integer word length (iwl)
- # fraction word length (fwl) = wl-iwl-1
- ):
- assert isinstance(B, tuple), "Tuple of numerator coefficients length 3"
- assert len(B) == 5, "Tuple of numerator coefficients length 5"
- assert isinstance(W, tuple), "Fixed-Point format (W) should be a 2-element tuple"
- assert len(W) == 2, "Fixed-Point format (W) should be a 2-element tuple"
- # Make sure all coefficients are int, the class wrapper handles all float to
- # fixed-point conversion.
- rB = [isinstance(B[ii], int) for ii in range(len(B))]
- assert False not in rB, "All B coefficients must be type int (fixed-point)"
- # double width max and min
- _max = 2**(2*W[0])
- _min = -1*_max
- Q = W[0]-1
- Qd = 2*W[0]
- # Delay elements, list of signals (double length for all)
- ffd = [Signal(intbv(0, min=_min, max=_max)) for ii in range(len(B))]
- yacc = Signal(intbv(0, min=_min, max=_max))
- b0 = B[0]
- b1 = B[1]
- b2 = B[2]
- b3 = B[3]
- b4 = B[4]
- @always(clk.posedge)
- def rtl_fir():
- #for i in range(0, len(B-1)):
- # ffd[i+1].next = ffd[i]
- # ffd[i].next = x
- ffd[4].next = ffd[3]
- ffd[3].next = ffd[2]
- ffd[2].next = ffd[1]
- ffd[1].next = ffd[0]
- ffd[0].next = x
- # Double precision accumulator
- y.next = yacc[Qd:Q].signed()
- @always_comb
- def rtl_acc():
- # Double precision accumulator
- yacc.next = b0*ffd[0] + b1*ffd[1] + b2*ffd[2] + b3*ffd[3] + b4*ffd[4]
- return instances()
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- class SIIR():
- """
- This is a simple example that illustrates how to create
- an object for designing an simple (fixed structure) IIR
- filter and the RTL implementation.
- """
- def __init__(self,
- Fc=9200, # cutoff frequency
- Fs=96000, # sample rate
- b = None, # or pass b,a coefficients
- a = None, # or pass b,a coefficients
- sos = None, # WIP sos of section matrix
- W=(24,0) # Fixed-point to use
- ):
- """
- In general this object can be used to generate the HDL
- for an IIR filter by passing the cutoff frequency
- and stop frequency (absolute): It can also generate
- the HDL based on a set of coefficients or a sum of
- sections matrix. This object can only be used for 2nd
- order type=I IIR filters or cascaded 2nd orders.
- -------
- """
- # The W format, intended to be (total bits, integer bits,
- # fraction bits) is not fully support.
- # Determine the max and min for the word-widths specified
- self.W = W
- self.max = int(2**(W[0]-1))
- self.min = int(-1*self.max)
- # Filter Design
- N = 5
- Wn = 0
- self.isSos = False
- if b is not None and a is not None:
- self.b = b
- self.nSection = 1
- else:
- # Define the cutoff as a fraction of the nyquist
- Wn = float(Fc)/(Fs/2.0)
- self.b = firwin(N, Wn)
- self.nSection = 1
- # fixed-point Coefficients for the IIR filter
- self.fxb = np.round(self.b * self.max)/self.max
- # Create the integer version
- self.fxb = tuple(map(int, self.fxb*self.max))
- print "FIR w,b", Wn, self.b
- print "FIR fixed-point b", self.fxb
- def Convert(self, W=None):
- """Convert the HDL description to Verilog
- """
- clk = Signal(False)
- #ts = Signal(False)
- x = Signal(intbv(0,min=-2**(self.W[0]-1), max=2**(self.W[0]-1)))
- y = Signal(intbv(0,min=-2**(self.W[0]-1), max=2**(self.W[0]-1)))
- print("Convert IIR to Verilog")
- toVerilog(sfir_hdl, clk, x, y, B=self.fxb, W=self.W)
- #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- if __name__ == '__main__':
- # Instantiate the filter and define the Signal
- W = (10,0)
- flt = SIIR(W=W)
- flt.Convert()
Advertisement
Add Comment
Please, Sign In to add comment