Update copyright notices
[litex.git] / examples / fir.py
1 # Copyright (C) 2012 Vermeer Manufacturing Co.
2 # License: GPLv3 with additional permissions (see README).
3
4 from math import cos, pi
5 from scipy import signal
6
7 from migen.fhdl.structure import *
8 from migen.fhdl import verilog
9 from migen.corelogic.misc import optree
10 from migen.fhdl import autofragment
11 from migen.sim.generic import Simulator
12 from migen.sim.icarus import Runner
13
14 # A synthesizable FIR filter.
15 class FIR:
16 def __init__(self, coef, wsize=16):
17 self.coef = coef
18 self.wsize = wsize
19 self.i = Signal(BV(self.wsize, True))
20 self.o = Signal(BV(self.wsize, True))
21
22 def get_fragment(self):
23 muls = []
24 sync = []
25 src = self.i
26 for c in self.coef:
27 sreg = Signal(BV(self.wsize, True))
28 sync.append(sreg.eq(src))
29 src = sreg
30 c_fp = int(c*2**(self.wsize - 1))
31 c_e = Constant(c_fp, BV(bits_for(c_fp), True))
32 muls.append(c_e*sreg)
33 sum_full = Signal(BV(2*self.wsize-1, True))
34 sync.append(sum_full.eq(optree("+", muls)))
35 comb = [self.o.eq(sum_full[self.wsize-1:])]
36 return Fragment(comb, sync)
37
38 # A test bench for our FIR filter.
39 # Generates a sine wave at the input and records the output.
40 class TB:
41 def __init__(self, fir, frequency):
42 self.fir = fir
43 self.frequency = frequency
44 self.inputs = []
45 self.outputs = []
46
47 def do_simulation(self, s):
48 f = 2**(self.fir.wsize - 1)
49 v = 0.1*cos(2*pi*self.frequency*s.cycle_counter)
50 s.wr(self.fir.i, int(f*v))
51 self.inputs.append(v)
52 self.outputs.append(s.rd(self.fir.o)/f)
53
54 def get_fragment(self):
55 return Fragment(sim=[self.do_simulation])
56
57 def main():
58 # Compute filter coefficients with SciPy.
59 coef = signal.remez(80, [0, 0.1, 0.1, 0.5], [1, 0])
60 fir = FIR(coef)
61 tb = TB(fir, 0.3)
62 # Combine the FIR filter with its test bench.
63 fragment = autofragment.from_local()
64 sim = Simulator(fragment, Runner())
65 sim.run(200)
66 # Print data from the input and output waveforms.
67 # When matplotlib works easily with Python 3, we could
68 # display them graphically here.
69 print(tb.inputs)
70 print(tb.outputs)
71
72 main()