litex/examples/sim/fir.py

77 lines
1.9 KiB
Python
Raw Normal View History

2012-03-23 11:41:30 -04:00
# Copyright (C) 2012 Vermeer Manufacturing Co.
# License: GPLv3 with additional permissions (see README).
2012-03-08 14:49:36 -05:00
from math import cos, pi
2012-03-10 13:38:39 -05:00
from scipy import signal
import matplotlib.pyplot as plt
2012-03-08 14:49:36 -05:00
from migen.fhdl.std import *
2012-03-08 14:49:36 -05:00
from migen.fhdl import verilog
2013-02-22 17:19:37 -05:00
from migen.genlib.misc import optree
from migen.sim.generic import Simulator
2012-03-08 14:49:36 -05:00
2012-03-10 13:38:39 -05:00
# A synthesizable FIR filter.
2013-03-19 06:46:27 -04:00
class FIR(Module):
2012-03-08 14:49:36 -05:00
def __init__(self, coef, wsize=16):
self.coef = coef
self.wsize = wsize
self.i = Signal((self.wsize, True))
self.o = Signal((self.wsize, True))
2012-03-08 14:49:36 -05:00
2013-03-19 06:46:27 -04:00
###
2012-03-08 14:49:36 -05:00
muls = []
src = self.i
for c in self.coef:
sreg = Signal((self.wsize, True))
2013-03-19 06:46:27 -04:00
self.sync += sreg.eq(src)
2012-03-08 14:49:36 -05:00
src = sreg
c_fp = int(c*2**(self.wsize - 1))
muls.append(c_fp*sreg)
sum_full = Signal((2*self.wsize-1, True))
2013-03-19 06:46:27 -04:00
self.sync += sum_full.eq(optree("+", muls))
self.comb += self.o.eq(sum_full[self.wsize-1:])
2012-03-08 14:49:36 -05:00
2012-03-10 13:38:39 -05:00
# A test bench for our FIR filter.
# Generates a sine wave at the input and records the output.
class TB(Module):
2013-03-19 06:46:27 -04:00
def __init__(self, coef, frequency):
self.submodules.fir = FIR(coef)
2012-03-08 14:49:36 -05:00
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 main():
2012-03-10 13:38:39 -05:00
# Compute filter coefficients with SciPy.
2013-02-22 17:19:56 -05:00
coef = signal.remez(30, [0, 0.1, 0.2, 0.4, 0.45, 0.5], [0, 1, 0])
# Simulate for different frequencies and concatenate
# the results.
in_signals = []
out_signals = []
2013-02-22 17:19:56 -05:00
for frequency in [0.05, 0.1, 0.25]:
2013-03-19 06:46:27 -04:00
tb = TB(coef, frequency)
sim = Simulator(tb)
2013-02-22 17:19:56 -05:00
sim.run(200)
2012-08-04 18:16:11 -04:00
del sim
in_signals += tb.inputs
out_signals += tb.outputs
# Plot data from the input and output waveforms.
plt.plot(in_signals)
plt.plot(out_signals)
plt.show()
2012-06-08 08:00:49 -04:00
# Print the Verilog source for the filter.
2013-03-19 06:46:27 -04:00
fir = FIR(coef)
print(verilog.convert(fir, ios={fir.i, fir.o}))
2012-03-08 14:49:36 -05:00
main()