examples: FIR filter simulation
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 8 Mar 2012 19:49:36 +0000 (20:49 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Thu, 8 Mar 2012 19:49:36 +0000 (20:49 +0100)
examples/fir.py [new file with mode: 0644]

diff --git a/examples/fir.py b/examples/fir.py
new file mode 100644 (file)
index 0000000..b5d366e
--- /dev/null
@@ -0,0 +1,61 @@
+from scipy import signal
+from math import cos, pi
+
+from migen.fhdl.structure import *
+from migen.fhdl import verilog
+from migen.corelogic.misc import optree
+from migen.fhdl import autofragment
+from migen.sim.generic import Simulator
+from migen.sim.icarus import Runner
+
+class FIR:
+       def __init__(self, coef, wsize=16):
+               self.coef = coef
+               self.wsize = wsize
+               self.i = Signal(BV(self.wsize, True))
+               self.o = Signal(BV(self.wsize, True))
+       
+       def get_fragment(self):
+               muls = []
+               sync = []
+               src = self.i
+               for c in self.coef:
+                       sreg = Signal(BV(self.wsize, True))
+                       sync.append(sreg.eq(src))
+                       src = sreg
+                       c_fp = int(c*2**(self.wsize - 1))
+                       c_e = Constant(c_fp, BV(bits_for(c_fp), True))
+                       muls.append(c_e*sreg)
+               sum_full = Signal(BV(2*self.wsize-1, True))
+               sync.append(sum_full.eq(optree("+", muls)))
+               comb = [self.o.eq(sum_full[self.wsize-1:])]
+               return Fragment(comb, sync)
+
+class TB:
+       def __init__(self, fir, frequency):
+               self.fir = fir
+               self.frequency = frequency
+               self.inputs = []
+               self.outputs = []
+       
+       def do_simulation(self, s):
+               f = 2**(self.fir.wsize - 1)
+               v = 0.1*cos(2*pi*self.frequency*s.cycle_counter)
+               s.wr(self.fir.i, int(f*v))
+               self.inputs.append(v)
+               self.outputs.append(s.rd(self.fir.o)/f)
+       
+       def get_fragment(self):
+               return Fragment(sim=[self.do_simulation])
+
+def main():
+       coef = signal.remez(80, [0, 0.1, 0.1, 0.5], [1, 0])
+       fir = FIR(coef)
+       tb = TB(fir, 0.3)
+       fragment = autofragment.from_local()
+       sim = Simulator(fragment, Runner())
+       sim.run(200)
+       print(tb.inputs)
+       print(tb.outputs)
+
+main()