From ad60212afea1d56c6eaf8984ea21e87f1ae43d40 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sat, 2 Jun 2018 01:41:15 +0530 Subject: [PATCH 01/46] added filter_df1 and test_df1 --- filter_blocks/fir/fir_df1.py | 76 ++++++++++++++++++++++++++++++++++++ tests/test_fir/test.txt | 36 +++++++++++++++++ tests/test_fir/test_df1.py | 43 ++++++++++++++++++++ 3 files changed, 155 insertions(+) create mode 100644 filter_blocks/fir/fir_df1.py create mode 100644 tests/test_fir/test.txt create mode 100644 tests/test_fir/test_df1.py diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py new file mode 100644 index 0000000..43e9ffb --- /dev/null +++ b/filter_blocks/fir/fir_df1.py @@ -0,0 +1,76 @@ +import myhdl as hdl +from myhdl import Signal, intbv, always_seq + +from filter_blocks.support import Samples, Signals + +@hdl.block +def filter_fir(glbl, sigin,sigout, b, shared_multiplier=False): + """Basic FIR direct-form I filter. + + Ports: + glbl (Global): global signals. + sigin (SignalBus): input digital signal. + sigout (SignalBus): output digitla signal. + + Args: + b (tuple, list): numerator coefficents. + + Returns: + inst (myhdl.Block, list): + """ + assert isinstance(sigin, Samples) + assert isinstance(sigout, Samples) + assert isinstance(b, tuple) + # All the coefficients need to be an `int` + + rb = [isinstance(bb, int) for bb in b] + assert all(rb) + + w = sigin.word_format + ymax = 2**(w[0]-1) + vmax = 2**(2*w[0]) # double width max and min + vmin = -vmax + ymin = -ymax + N=len(b)-1 + + # Locally reference the interface signals + clock, reset = glbl.clock, glbl.reset + xdv = sigin.valid + y, ydv = sigout.data, sigout.valid + x = Signal(intbv(0, min=vmin, max=vmax)) + + # Delay elements, list-of-signals (double length for all) + ffd = Signals(intbv(0, min=ymin, max=ymax), N) + yacc = Signal(intbv(0, min=vmin, max=vmax)) # verify the length of this + dvd = Signal(bool(0)) + + @hdl.always(clock.posedge) + def beh_direct_form_one(): + #print(sigin.valid) + print(sigin.data) + if sigin.valid: + x.next=sigin.data + #print("hello from inside") + #print(sigin.data) + for i in range(N-1): + ffd[i+1].next = ffd[i] + + ffd[0].next = x + #multiplication doesnt work if b0*x + # sum-of-products loop + c = b[0] + sop = x*c + for ii in range(N): + c = b[ii+1] + sop = sop + (c * ffd[ii]) + + yacc.next =sop + + @always_seq(clock.posedge, reset=reset) + def beh_output(): + dvd.next = xdv + y.next = yacc.signed() + ydv.next = dvd + print(yacc) + + return beh_direct_form_one,beh_output \ No newline at end of file diff --git a/tests/test_fir/test.txt b/tests/test_fir/test.txt new file mode 100644 index 0000000..ad6e109 --- /dev/null +++ b/tests/test_fir/test.txt @@ -0,0 +1,36 @@ +1 +2 +1 +3 +4 +10 +20 +10 +1 +2 +3 +5 +3 +6 +15 +14 +10 +1 +1 +2 +3 +4 +1 +4 +5 +23 +30 +35 +20 +10 +5 +6 +7 +1 +2 +3 \ No newline at end of file diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py new file mode 100644 index 0000000..5df7b3f --- /dev/null +++ b/tests/test_fir/test_df1.py @@ -0,0 +1,43 @@ +import myhdl as hdl +from myhdl import Signal, intbv, delay, StopSimulation +from filter_blocks.support import Clock, Reset, Global, ResetSignal +from filter_blocks.fir import fir_df1 +from filter_blocks.fda import fir_test as ft + +@hdl.block +def test_fir_df1(): + clock = Clock(0, frequency=50e6) + reset = Reset(0, active=0, async=True) + glbl = Global(clock, reset) + tbclk = clock.process() + # glbl.clock = Signal(bool(1)) + # glbl.reset = ResetSignal(bool(1), bool(0), True) + x = Signal(intbv(0)[8:]) + y = Signal(intbv(0)[8:]) + # xt= Samples(x.min, x.max) + # yt= Samples(y.min, y.max) + a_coef = (1) + b = (1, 2, 1) + w = (24, 23, 0) + hello = ft.FIRFilter(b, a_coef) + fir = hello.filter_block(glbl, x, y, b, w) + + + @hdl.instance + def stimulus(): + "input for test bench taken from text file test.txt" + for line in open('test.txt'): + x.next = int(line) + # xt.valid=bool(1) + #print(x) + yield clock.posedge + raise StopSimulation + return fir, stimulus + +def main(): + testBench = test_fir_df1() + testBench.run_sim() + + +if __name__ == '__main__': + main() From e121a409cc93450016b6e67fe38e6e15eb98d634 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 18 Jun 2018 02:31:50 +0530 Subject: [PATCH 02/46] updates to test_df1 to enable plotting feature --- tests/test_fir/test_df1.py | 26 -------------------------- 1 file changed, 26 deletions(-) diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 82f5fb0..5df7b3f 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -1,11 +1,6 @@ import myhdl as hdl -<<<<<<< HEAD from myhdl import Signal, intbv, delay, StopSimulation from filter_blocks.support import Clock, Reset, Global, ResetSignal -======= -from myhdl import Signal, intbv, StopSimulation -from filter_blocks.support import Clock, Reset, Global ->>>>>>> upstream/master from filter_blocks.fir import fir_df1 from filter_blocks.fda import fir_test as ft @@ -15,7 +10,6 @@ def test_fir_df1(): reset = Reset(0, active=0, async=True) glbl = Global(clock, reset) tbclk = clock.process() -<<<<<<< HEAD # glbl.clock = Signal(bool(1)) # glbl.reset = ResetSignal(bool(1), bool(0), True) x = Signal(intbv(0)[8:]) @@ -28,22 +22,12 @@ def test_fir_df1(): hello = ft.FIRFilter(b, a_coef) fir = hello.filter_block(glbl, x, y, b, w) -======= - x = Signal(intbv(0)[8:]) - y = Signal(intbv(0)[8:]) - a = (1) - b = (1, 2, 1) - w = (24, 23, 0) - fir_test = ft.FIRFilter(b, a) - fir = fir_test.filter_block(glbl, x, y, b, w) ->>>>>>> upstream/master @hdl.instance def stimulus(): "input for test bench taken from text file test.txt" for line in open('test.txt'): x.next = int(line) -<<<<<<< HEAD # xt.valid=bool(1) #print(x) yield clock.posedge @@ -53,16 +37,6 @@ def stimulus(): def main(): testBench = test_fir_df1() testBench.run_sim() -======= - yield clock.posedge - raise StopSimulation - - return fir, stimulus, tbclk - -def main(): - test_bench = test_fir_df1() - test_bench.run_sim() ->>>>>>> upstream/master if __name__ == '__main__': From 6c8040c22b7be17ba1a433d78adae3dcf44769bc Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 18 Jun 2018 02:49:28 +0530 Subject: [PATCH 03/46] resolving conflicts --- filter_blocks/fir/fir_df1.py | 45 ------------------------------------ 1 file changed, 45 deletions(-) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 600b60b..9be8385 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -4,11 +4,7 @@ from filter_blocks.support import Samples, Signals @hdl.block -<<<<<<< HEAD -def filter_fir(glbl, sigin,sigout, b, shared_multiplier=False): -======= def filter_fir(glbl, sigin, sigout, b, shared_multiplier=False): ->>>>>>> upstream/master """Basic FIR direct-form I filter. Ports: @@ -35,19 +31,6 @@ def filter_fir(glbl, sigin, sigout, b, shared_multiplier=False): vmax = 2**(2*w[0]) # double width max and min vmin = -vmax ymin = -ymax -<<<<<<< HEAD - N=len(b)-1 - - # Locally reference the interface signals - clock, reset = glbl.clock, glbl.reset - xdv = sigin.valid - y, ydv = sigout.data, sigout.valid - x = Signal(intbv(0, min=vmin, max=vmax)) - - # Delay elements, list-of-signals (double length for all) - ffd = Signals(intbv(0, min=ymin, max=ymax), N) - yacc = Signal(intbv(0, min=vmin, max=vmax)) # verify the length of this -======= N = len(b)-1 clock, reset = glbl.clock, glbl.reset xdv = sigin.valid @@ -56,38 +39,17 @@ def filter_fir(glbl, sigin, sigout, b, shared_multiplier=False): # Delay elements, list-of-signals ffd = Signals(intbv(0, min=ymin, max=ymax), N) yacc = Signal(intbv(0, min=vmin, max=vmax)) #verify the length of this ->>>>>>> upstream/master dvd = Signal(bool(0)) @hdl.always(clock.posedge) def beh_direct_form_one(): -<<<<<<< HEAD - #print(sigin.valid) - print(sigin.data) - if sigin.valid: - x.next=sigin.data - #print("hello from inside") - #print(sigin.data) -======= if sigin.valid: x.next = sigin.data ->>>>>>> upstream/master for i in range(N-1): ffd[i+1].next = ffd[i] ffd[0].next = x -<<<<<<< HEAD - #multiplication doesnt work if b0*x - # sum-of-products loop - c = b[0] - sop = x*c - for ii in range(N): - c = b[ii+1] - sop = sop + (c * ffd[ii]) - - yacc.next =sop -======= # sum-of-products loop c = b[0] sop = x*c @@ -97,18 +59,11 @@ def beh_direct_form_one(): sop = sop + (c * ffd[ii]) yacc.next = sop print(yacc) ->>>>>>> upstream/master @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv y.next = yacc.signed() ydv.next = dvd -<<<<<<< HEAD - print(yacc) - - return beh_direct_form_one,beh_output -======= return beh_direct_form_one, beh_output ->>>>>>> upstream/master From 4ac9bbfb4973a972c2551756bd79319d1329753e Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 18 Jun 2018 02:50:50 +0530 Subject: [PATCH 04/46] plot feature to test_df1 --- tests/test_fir/test_df1.py | 61 ++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 19 deletions(-) diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 5df7b3f..ff7fb73 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -1,42 +1,65 @@ import myhdl as hdl -from myhdl import Signal, intbv, delay, StopSimulation -from filter_blocks.support import Clock, Reset, Global, ResetSignal +from myhdl import Signal, intbv, StopSimulation +from filter_blocks.support import Clock, Reset, Global, Samples from filter_blocks.fir import fir_df1 from filter_blocks.fda import fir_test as ft +import matplotlib.pyplot as pl @hdl.block def test_fir_df1(): clock = Clock(0, frequency=50e6) - reset = Reset(0, active=0, async=True) + reset = Reset(1, active=0, async=True) glbl = Global(clock, reset) tbclk = clock.process() - # glbl.clock = Signal(bool(1)) - # glbl.reset = ResetSignal(bool(1), bool(0), True) - x = Signal(intbv(0)[8:]) + #x = Signal(intbv(0)[8:]) y = Signal(intbv(0)[8:]) - # xt= Samples(x.min, x.max) - # yt= Samples(y.min, y.max) - a_coef = (1) + xt = Samples(y.min, y.max) + yt = Samples(y.min, y.max) + a = (1) b = (1, 2, 1) w = (24, 23, 0) - hello = ft.FIRFilter(b, a_coef) - fir = hello.filter_block(glbl, x, y, b, w) + numsample = 0 + #note: the filter interface has been bypassed for the purpose + #of plotting the output. Will have to include this in future + + #fir_test = ft.FIRFilter(b, a) + #fir = fir_test.filter_block(glbl, x, y, b, w) + + + fir = fir_df1.filter_fir(glbl, xt, yt, b, w) + + + for line in open('test.txt'): + numsample += 1 + + rec_insts = yt.process_record(clock, num_samples=numsample) @hdl.instance def stimulus(): "input for test bench taken from text file test.txt" for line in open('test.txt'): - x.next = int(line) - # xt.valid=bool(1) - #print(x) - yield clock.posedge - raise StopSimulation - return fir, stimulus + xt.data.next = int(line) + xt.valid = bool(1) + + yt.record = True + yt.valid = True + yield clock.posedge + #Collect a sample from each filter + yt.record = False + yt.valid = False + + print(yt.sample_buffer) + pl.plot(yt.sample_buffer) + pl.show() + + raise StopSimulation() + + return hdl.instances() def main(): - testBench = test_fir_df1() - testBench.run_sim() + test_bench = test_fir_df1() + test_bench.run_sim() if __name__ == '__main__': From ff9050cb847d19667abb8a9b0d249f18a9d7eebb Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 18 Jun 2018 02:59:14 +0530 Subject: [PATCH 05/46] reverting conflicts in filter_iir --- filter_blocks/filter_iir.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/filter_blocks/filter_iir.py b/filter_blocks/filter_iir.py index b67377a..82ee446 100644 --- a/filter_blocks/filter_iir.py +++ b/filter_blocks/filter_iir.py @@ -1,9 +1,13 @@ + """ Simple IIR Filter ================= The following is a straight forward HDL description of a direct-form-I IIR filter. This module can be used to generate synthesizable Verilg/VHDL. + + + :Author: Christopher Felton """ @@ -15,13 +19,16 @@ @hdl.block def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): """Basic IIR direct-form I filter. + Ports: glbl (Global): global signals. sigin (SignalBus): input digital signal. sigout (SignalBus): output digitla signal. + Args: b (tuple, list): numerator coefficents. a (tuple, list): denominator coefficents. + Returns: inst (myhdl.Block, list): """ @@ -103,4 +110,5 @@ def filter_iir_sos(glbl, x, y, b, a, w): b=tuple(map(int, b[ii])), a=tuple(map(int, a[ii])), ) - return list_of_insts \ No newline at end of file + return list_of_insts + From 9eec8183e02a9fd4f46af065c2269378a046e810 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Tue, 19 Jun 2018 18:25:31 +0530 Subject: [PATCH 06/46] new interface file fir_pyfda and test file test_pyfda_df1. added functions and --- filter_blocks/fda/__init__.py | 2 +- filter_blocks/fda/fir_pyfda.py | 93 ++++++++++++++++++++++++++++++++ tests/test_fir/test_pyfda_df1.py | 20 +++++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 filter_blocks/fda/fir_pyfda.py create mode 100644 tests/test_fir/test_pyfda_df1.py diff --git a/filter_blocks/fda/__init__.py b/filter_blocks/fda/__init__.py index be1a0a7..0e76588 100644 --- a/filter_blocks/fda/__init__.py +++ b/filter_blocks/fda/__init__.py @@ -1,3 +1,3 @@ from .iir import FilterIIR -from .fir import FilterFIR \ No newline at end of file +from .fir_pyfda import FilterFIR \ No newline at end of file diff --git a/filter_blocks/fda/fir_pyfda.py b/filter_blocks/fda/fir_pyfda.py new file mode 100644 index 0000000..028d2a2 --- /dev/null +++ b/filter_blocks/fda/fir_pyfda.py @@ -0,0 +1,93 @@ +import myhdl as hdl +from filter_blocks.support import Samples +from .filter_hw import FilterHardware +from ..fir import fir_df1 + +from myhdl import Signal, intbv, StopSimulation +from filter_blocks.support import Clock, Reset, Global, Samples +from filter_blocks.fda import fir_test as ft +import matplotlib.pyplot as pl +import numpy as np + +class FilterFIR(FilterHardware): + def __init__(self, b, a): + super().__init__(b, a) + self.filter_type = 'direct_form' + self.n_cascades = 0 + self.direct_form_type = 1 + self.sigin = np.array([]) + + def set_cascade(self, n_cascades): + self.n_cascades = n_cascades + + def set_coefficients(self, coefficients): + self.b = coefficients + + def set_stimulation(self, sigin): + self.sigin = sigin.tolist() + + def runsim(self): + pass + + @hdl.block + def filter_block(self): + # this elaboration code will select the different structure and implementations + x = Signal(intbv(0)[8:]) + y = Signal(intbv(0)[8:]) + xt = Samples(x.min, x.max) + yt = Samples(y.min, y.max) + xt.valid = bool(1) + clock = Clock(0, frequency=50e6) + reset = Reset(1, active=0, async=True) + glbl = Global(clock, reset) + + tbclk = clock.process() + + numsample = 0 + + for k in self.sigin: + numsample += 1 + + rec_insts = yt.process_record(clock, num_samples=numsample) + + + if self.filter_type == 'direct_form': + if self.direct_form_type == 1: + # all filters will need the same interface ports, this should be do able + dfilter = fir_df1.filter_fir + + if self.n_cascades > 0: + filter_insts = [None for _ in range(self.n_cascades)] + for ii in range(self.n_cascades): + pass + # filter_insts[ii] = fir_df1.filter_fir( + # glbl, sigin[ii], sigout[ii], b + # ) + else: + filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) + + + + + @hdl.instance + def stimulus(): + "input for test bench taken from text file test.txt" + for k in self.sigin: + xt.data.next = int(k) + #print(k) + xt.valid = bool(1) + + yt.record = True + yt.valid = True + yield clock.posedge + #Collect a sample from each filter + yt.record = False + yt.valid = False + + print(yt.sample_buffer) + pl.plot(yt.sample_buffer) + pl.show() + + raise StopSimulation() + + return hdl.instances() \ No newline at end of file diff --git a/tests/test_fir/test_pyfda_df1.py b/tests/test_fir/test_pyfda_df1.py new file mode 100644 index 0000000..ffb5c63 --- /dev/null +++ b/tests/test_fir/test_pyfda_df1.py @@ -0,0 +1,20 @@ +import myhdl as hdl +from myhdl import Signal, intbv, StopSimulation +from filter_blocks.support import Clock, Reset, Global, Samples +from filter_blocks.fir import fir_df1 +from filter_blocks.fda import FilterFIR +import matplotlib.pyplot as pl +import numpy as np + +def main(): + + hdlfilter = FilterFIR(0,0) + b=(1,2,3,1) + hdlfilter.set_coefficients(b) + + hdlfilter.set_stimulation(np.ones(100)) + testfil = hdlfilter.filter_block() + testfil.run_sim() + +if __name__ == '__main__': + main() From 6f1126a7c11b6750776216a60e318b16f8c42b41 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sat, 23 Jun 2018 00:55:26 +0530 Subject: [PATCH 07/46] deleted duplicate files. Tests written to mimic pyfda interface --- filter_blocks/fda/__init__.py | 2 +- filter_blocks/fda/fir_pyfda.py | 93 -------------------------------- filter_blocks/fda/fir_test.py | 76 ++++++++++++++++++++++---- filter_blocks/fir/fir_df1.py | 3 +- tests/test_fir/test_df1.py | 65 ++++------------------ tests/test_fir/test_pyfda_df1.py | 20 ------- 6 files changed, 77 insertions(+), 182 deletions(-) delete mode 100644 filter_blocks/fda/fir_pyfda.py delete mode 100644 tests/test_fir/test_pyfda_df1.py diff --git a/filter_blocks/fda/__init__.py b/filter_blocks/fda/__init__.py index 0e76588..a97ada5 100644 --- a/filter_blocks/fda/__init__.py +++ b/filter_blocks/fda/__init__.py @@ -1,3 +1,3 @@ from .iir import FilterIIR -from .fir_pyfda import FilterFIR \ No newline at end of file +from .fir_test import FilterFIR \ No newline at end of file diff --git a/filter_blocks/fda/fir_pyfda.py b/filter_blocks/fda/fir_pyfda.py deleted file mode 100644 index 028d2a2..0000000 --- a/filter_blocks/fda/fir_pyfda.py +++ /dev/null @@ -1,93 +0,0 @@ -import myhdl as hdl -from filter_blocks.support import Samples -from .filter_hw import FilterHardware -from ..fir import fir_df1 - -from myhdl import Signal, intbv, StopSimulation -from filter_blocks.support import Clock, Reset, Global, Samples -from filter_blocks.fda import fir_test as ft -import matplotlib.pyplot as pl -import numpy as np - -class FilterFIR(FilterHardware): - def __init__(self, b, a): - super().__init__(b, a) - self.filter_type = 'direct_form' - self.n_cascades = 0 - self.direct_form_type = 1 - self.sigin = np.array([]) - - def set_cascade(self, n_cascades): - self.n_cascades = n_cascades - - def set_coefficients(self, coefficients): - self.b = coefficients - - def set_stimulation(self, sigin): - self.sigin = sigin.tolist() - - def runsim(self): - pass - - @hdl.block - def filter_block(self): - # this elaboration code will select the different structure and implementations - x = Signal(intbv(0)[8:]) - y = Signal(intbv(0)[8:]) - xt = Samples(x.min, x.max) - yt = Samples(y.min, y.max) - xt.valid = bool(1) - clock = Clock(0, frequency=50e6) - reset = Reset(1, active=0, async=True) - glbl = Global(clock, reset) - - tbclk = clock.process() - - numsample = 0 - - for k in self.sigin: - numsample += 1 - - rec_insts = yt.process_record(clock, num_samples=numsample) - - - if self.filter_type == 'direct_form': - if self.direct_form_type == 1: - # all filters will need the same interface ports, this should be do able - dfilter = fir_df1.filter_fir - - if self.n_cascades > 0: - filter_insts = [None for _ in range(self.n_cascades)] - for ii in range(self.n_cascades): - pass - # filter_insts[ii] = fir_df1.filter_fir( - # glbl, sigin[ii], sigout[ii], b - # ) - else: - filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) - - - - - @hdl.instance - def stimulus(): - "input for test bench taken from text file test.txt" - for k in self.sigin: - xt.data.next = int(k) - #print(k) - xt.valid = bool(1) - - yt.record = True - yt.valid = True - yield clock.posedge - #Collect a sample from each filter - yt.record = False - yt.valid = False - - print(yt.sample_buffer) - pl.plot(yt.sample_buffer) - pl.show() - - raise StopSimulation() - - return hdl.instances() \ No newline at end of file diff --git a/filter_blocks/fda/fir_test.py b/filter_blocks/fda/fir_test.py index ca65921..bc2b3df 100644 --- a/filter_blocks/fda/fir_test.py +++ b/filter_blocks/fda/fir_test.py @@ -3,23 +3,54 @@ from .filter_hw import FilterHardware from ..fir import fir_df1 -class FIRFilter(FilterHardware): +from myhdl import Signal, intbv, StopSimulation +from filter_blocks.support import Clock, Reset, Global, Samples +from filter_blocks.fda import fir_test as ft +import matplotlib.pyplot as pl +import numpy as np + +class FilterFIR(FilterHardware): def __init__(self, b, a): super().__init__(b, a) self.filter_type = 'direct_form' self.n_cascades = 0 self.direct_form_type = 1 + self.sigin = np.array([]) def set_cascade(self, n_cascades): self.n_cascades = n_cascades + + def set_coefficients(self, coefficients): + self.b = coefficients + + def set_stimulation(self, sigin): + self.sigin = sigin.tolist() + def runsim(self): + pass + @hdl.block - def filter_block(self, glbl, sigin, sigout, b, w): + def filter_block(self): # this elaboration code will select the different structure and implementations - xt = Samples(sigin.min, sigin.max) - yt = Samples(sigout.min, sigout.max) - xt.data = sigin.val + x = Signal(intbv(0)[20:]) + y = Signal(intbv(0)[20:]) + xt = Samples(x.min, x.max) + yt = Samples(y.min, y.max) xt.valid = bool(1) + clock = Clock(0, frequency=50e6) + reset = Reset(1, active=0, async=True) + glbl = Global(clock, reset) + + tbclk = clock.process() + + numsample = 0 + + for k in self.sigin: + numsample += 1 + + rec_insts = yt.process_record(clock, num_samples=numsample) + + if self.filter_type == 'direct_form': if self.direct_form_type == 1: # all filters will need the same interface ports, this should be do able @@ -28,10 +59,35 @@ def filter_block(self, glbl, sigin, sigout, b, w): if self.n_cascades > 0: filter_insts = [None for _ in range(self.n_cascades)] for ii in range(self.n_cascades): - filter_insts[ii] = fir_df1.filter_fir( - glbl, sigin[ii], sigout[ii], b - ) + pass + # filter_insts[ii] = fir_df1.filter_fir( + # glbl, sigin[ii], sigout[ii], b + # ) else: - filter_insts = dfilter(glbl, xt, yt, b) + filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) + + + + + @hdl.instance + def stimulus(): + "input for test bench taken from text file test.txt" + for k in self.sigin: + xt.data.next = int(k) + #print(k) + xt.valid = bool(1) + + yt.record = True + yt.valid = True + yield clock.posedge + #Collect a sample from each filter + yt.record = False + yt.valid = False - return filter_insts + print(yt.sample_buffer) + pl.plot(yt.sample_buffer) + pl.show() + + raise StopSimulation() + + return hdl.instances() \ No newline at end of file diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 9be8385..7c73aa1 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -20,9 +20,8 @@ def filter_fir(glbl, sigin, sigout, b, shared_multiplier=False): """ assert isinstance(sigin, Samples) assert isinstance(sigout, Samples) - assert isinstance(b, tuple) + #assert isinstance(b, tuple) # All the coefficients need to be an `int` - rb = [isinstance(bb, int) for bb in b] assert all(rb) diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index ff7fb73..6916936 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -2,65 +2,18 @@ from myhdl import Signal, intbv, StopSimulation from filter_blocks.support import Clock, Reset, Global, Samples from filter_blocks.fir import fir_df1 -from filter_blocks.fda import fir_test as ft +from filter_blocks.fda import FilterFIR import matplotlib.pyplot as pl - -@hdl.block -def test_fir_df1(): - clock = Clock(0, frequency=50e6) - reset = Reset(1, active=0, async=True) - glbl = Global(clock, reset) - tbclk = clock.process() - #x = Signal(intbv(0)[8:]) - y = Signal(intbv(0)[8:]) - xt = Samples(y.min, y.max) - yt = Samples(y.min, y.max) - a = (1) - b = (1, 2, 1) - w = (24, 23, 0) - numsample = 0 - - #note: the filter interface has been bypassed for the purpose - #of plotting the output. Will have to include this in future - - #fir_test = ft.FIRFilter(b, a) - #fir = fir_test.filter_block(glbl, x, y, b, w) - - - fir = fir_df1.filter_fir(glbl, xt, yt, b, w) - - - for line in open('test.txt'): - numsample += 1 - - rec_insts = yt.process_record(clock, num_samples=numsample) - - @hdl.instance - def stimulus(): - "input for test bench taken from text file test.txt" - for line in open('test.txt'): - xt.data.next = int(line) - xt.valid = bool(1) - - yt.record = True - yt.valid = True - yield clock.posedge - #Collect a sample from each filter - yt.record = False - yt.valid = False - - print(yt.sample_buffer) - pl.plot(yt.sample_buffer) - pl.show() - - raise StopSimulation() - - return hdl.instances() +import numpy as np def main(): - test_bench = test_fir_df1() - test_bench.run_sim() - + hdlfilter = FilterFIR(0,0) + b=[1,2,3,1] + hdlfilter.set_coefficients(b) + hdlfilter.set_stimulation(np.ones(100)) + testfil = hdlfilter.filter_block() + testfil.run_sim() + if __name__ == '__main__': main() diff --git a/tests/test_fir/test_pyfda_df1.py b/tests/test_fir/test_pyfda_df1.py deleted file mode 100644 index ffb5c63..0000000 --- a/tests/test_fir/test_pyfda_df1.py +++ /dev/null @@ -1,20 +0,0 @@ -import myhdl as hdl -from myhdl import Signal, intbv, StopSimulation -from filter_blocks.support import Clock, Reset, Global, Samples -from filter_blocks.fir import fir_df1 -from filter_blocks.fda import FilterFIR -import matplotlib.pyplot as pl -import numpy as np - -def main(): - - hdlfilter = FilterFIR(0,0) - b=(1,2,3,1) - hdlfilter.set_coefficients(b) - - hdlfilter.set_stimulation(np.ones(100)) - testfil = hdlfilter.filter_block() - testfil.run_sim() - -if __name__ == '__main__': - main() From 449cec31e3bdbeb57db90ebd5d89bb793749cadf Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 25 Jun 2018 01:39:18 +0530 Subject: [PATCH 08/46] added get_response function to fir_test and fixed work length. --- filter_blocks/fda/fir_test.py | 20 ++++++++++++++------ filter_blocks/fir/fir_df1.py | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/filter_blocks/fda/fir_test.py b/filter_blocks/fda/fir_test.py index bc2b3df..68a98e8 100644 --- a/filter_blocks/fda/fir_test.py +++ b/filter_blocks/fda/fir_test.py @@ -16,6 +16,7 @@ def __init__(self, b, a): self.n_cascades = 0 self.direct_form_type = 1 self.sigin = np.array([]) + self.response = [] def set_cascade(self, n_cascades): self.n_cascades = n_cascades @@ -26,16 +27,22 @@ def set_coefficients(self, coefficients): def set_stimulation(self, sigin): self.sigin = sigin.tolist() + def get_response(self): + return self.response + def runsim(self): pass @hdl.block def filter_block(self): # this elaboration code will select the different structure and implementations - x = Signal(intbv(0)[20:]) - y = Signal(intbv(0)[20:]) - xt = Samples(x.min, x.max) - yt = Samples(y.min, y.max) + # x = Signal(intbv(0)[20:]) + # y = Signal(intbv(0)[20:]) + w = (25,24,0) + ymax = 2**(w[0]-1) + vmax = 2**(2*w[0]) + xt = Samples(-vmax, vmax) + yt = Samples(-vmax, vmax) xt.valid = bool(1) clock = Clock(0, frequency=50e6) reset = Reset(1, active=0, async=True) @@ -85,8 +92,9 @@ def stimulus(): yt.valid = False print(yt.sample_buffer) - pl.plot(yt.sample_buffer) - pl.show() + self.response = yt.sample_buffer + # pl.plot(yt.sample_buffer) + # pl.show() raise StopSimulation() diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 7c73aa1..4e2c7b4 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -57,7 +57,7 @@ def beh_direct_form_one(): c = b[ii+1] sop = sop + (c * ffd[ii]) yacc.next = sop - print(yacc) + #print(yacc) @always_seq(clock.posedge, reset=reset) def beh_output(): From 47156ba2e32cc4a3588495af430e07e3ee60c2f3 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Tue, 26 Jun 2018 10:38:46 +0530 Subject: [PATCH 09/46] fixed import issues --- filter_blocks/fda/fir_test.py | 37 ++++++++++++++++------------------- tests/test_fir/test_df1.py | 11 +++-------- 2 files changed, 20 insertions(+), 28 deletions(-) diff --git a/filter_blocks/fda/fir_test.py b/filter_blocks/fda/fir_test.py index 68a98e8..33c5424 100644 --- a/filter_blocks/fda/fir_test.py +++ b/filter_blocks/fda/fir_test.py @@ -1,13 +1,11 @@ import myhdl as hdl -from filter_blocks.support import Samples +import numpy as np from .filter_hw import FilterHardware from ..fir import fir_df1 - -from myhdl import Signal, intbv, StopSimulation from filter_blocks.support import Clock, Reset, Global, Samples -from filter_blocks.fda import fir_test as ft -import matplotlib.pyplot as pl -import numpy as np +from myhdl import Signal, intbv, StopSimulation + + class FilterFIR(FilterHardware): def __init__(self, b, a): @@ -20,7 +18,7 @@ def __init__(self, b, a): def set_cascade(self, n_cascades): self.n_cascades = n_cascades - + def set_coefficients(self, coefficients): self.b = coefficients @@ -32,13 +30,13 @@ def get_response(self): def runsim(self): pass - + @hdl.block def filter_block(self): # this elaboration code will select the different structure and implementations # x = Signal(intbv(0)[20:]) # y = Signal(intbv(0)[20:]) - w = (25,24,0) + w = (25, 24, 0) ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) xt = Samples(-vmax, vmax) @@ -47,14 +45,12 @@ def filter_block(self): clock = Clock(0, frequency=50e6) reset = Reset(1, active=0, async=True) glbl = Global(clock, reset) - tbclk = clock.process() - numsample = 0 for k in self.sigin: - numsample += 1 - + numsample += 1 + rec_insts = yt.process_record(clock, num_samples=numsample) @@ -72,7 +68,7 @@ def filter_block(self): # ) else: filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) - + @@ -85,8 +81,8 @@ def stimulus(): xt.valid = bool(1) yt.record = True - yt.valid = True - yield clock.posedge + yt.valid = True + yield clock.posedge #Collect a sample from each filter yt.record = False yt.valid = False @@ -94,8 +90,9 @@ def stimulus(): print(yt.sample_buffer) self.response = yt.sample_buffer # pl.plot(yt.sample_buffer) - # pl.show() - + # pl.show() + raise StopSimulation() - - return hdl.instances() \ No newline at end of file + + return hdl.instances() + \ No newline at end of file diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 6916936..5759fa9 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -1,19 +1,14 @@ -import myhdl as hdl -from myhdl import Signal, intbv, StopSimulation -from filter_blocks.support import Clock, Reset, Global, Samples -from filter_blocks.fir import fir_df1 from filter_blocks.fda import FilterFIR -import matplotlib.pyplot as pl import numpy as np def main(): - hdlfilter = FilterFIR(0,0) - b=[1,2,3,1] + hdlfilter = FilterFIR(0, 0) + b = [1, 2, 3, 1] hdlfilter.set_coefficients(b) hdlfilter.set_stimulation(np.ones(100)) testfil = hdlfilter.filter_block() testfil.run_sim() - + if __name__ == '__main__': main() From 0b5e895f4319bea2f2c91103ce8bce9c20d0c5f4 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Wed, 27 Jun 2018 16:45:39 +0530 Subject: [PATCH 10/46] updates to interface --- filter_blocks/fda/filter_hw.py | 55 ++++++++++++++++++++++++++++++++-- filter_blocks/fda/fir_test.py | 50 +++++++++++++++++-------------- tests/test_fir/test_df1.py | 11 ++++--- 3 files changed, 84 insertions(+), 32 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 6324062..17ec965 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -1,11 +1,26 @@ - +import numpy as np class FilterHardware(object): - def __init__(self, b, a): + """Top level class. Contains filter parameters.""" + def __init__(self, b, a, w): + """ + Args: + b (list of int): list of numerator coefficients. + a (list of int): list of denominator coefficients. + word_format (tuple of int): word format (W,WI,WF). + n_cascades(int): + sigin(numpy int array): + nfft(int): + hdl_name(str): + hdl_directory(str): + hdl_target(str): + """ self.b = b # numerator coefficients self.a = a # denominator coefficients + self.word_format = w - self.word_format = (24, 0, 23) + self.n_cascades = 0 + self.sigin = np.array([]) self._shared_multiplier = False self._sample_rate = 1 self._clock_frequency = 1 @@ -19,6 +34,40 @@ def __init__(self, b, a): # A reference to the HDL block self.hardware = None + def set_coefficients(self, coeff_b, coeff_a = None): + """Set filter coefficients. + + Args: + coefficients (list): list of filter coefficients + param2 (str): The second parameter. + """ + self.b = coeff_b + self.a = coeff_a + + def set_stimulus(self, sigin): + """Set filter stimulus + + Args: + sigin (np array int): numpy array of filter stimulus + """ + self.sigin = sigin.tolist() + + def set_cascade(self, n_cascades): + """Set number of filter cascades + + Args: + n_cascades (int): no of filter sections connected together + """ + self.n_cascades = n_cascades + + def set_word_format(self, w): + """Set word format + + Args: + word_format (tuple of int): word format (W,WI,WF) + """ + self.word_format = w + def get_fixed_coefficients(self): raise NotImplementedError diff --git a/filter_blocks/fda/fir_test.py b/filter_blocks/fda/fir_test.py index 33c5424..6311717 100644 --- a/filter_blocks/fda/fir_test.py +++ b/filter_blocks/fda/fir_test.py @@ -8,34 +8,39 @@ class FilterFIR(FilterHardware): - def __init__(self, b, a): - super().__init__(b, a) + """Contains FIR filter parameters. Parent Class : FilterHArdware""" + def __init__(self, b = None, a = None, w = (24, 0, 23)): + """ + Args: + b (list of int): list of numerator coefficients. + a (list of int): list of denominator coefficients. + filter_type: + filter_form_type: + response(list): list of filter output in int format. + """ + super(FilterFIR, self).__init__(b, a, w) self.filter_type = 'direct_form' - self.n_cascades = 0 self.direct_form_type = 1 - self.sigin = np.array([]) self.response = [] - def set_cascade(self, n_cascades): - self.n_cascades = n_cascades - - def set_coefficients(self, coefficients): - self.b = coefficients - - def set_stimulation(self, sigin): - self.sigin = sigin.tolist() - def get_response(self): + """Return filter output. + + returns: + response(numpy int array) : returns filter output as numpy array + """ return self.response def runsim(self): - pass + """Run filter simulation""" + + testfil = self.filter_block() + testfil.run_sim() @hdl.block def filter_block(self): - # this elaboration code will select the different structure and implementations - # x = Signal(intbv(0)[20:]) - # y = Signal(intbv(0)[20:]) + """ this elaboration code will select the different structure and implementations""" + w = (25, 24, 0) ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) @@ -47,10 +52,10 @@ def filter_block(self): glbl = Global(clock, reset) tbclk = clock.process() numsample = 0 - - for k in self.sigin: - numsample += 1 - + + # set numsample + numsample = len(self.sigin) + #process to record output in buffer rec_insts = yt.process_record(clock, num_samples=numsample) @@ -74,10 +79,9 @@ def filter_block(self): @hdl.instance def stimulus(): - "input for test bench taken from text file test.txt" + "record output in numpy array yt.sample_buffer" for k in self.sigin: xt.data.next = int(k) - #print(k) xt.valid = bool(1) yt.record = True diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 5759fa9..e1924c3 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -2,13 +2,12 @@ import numpy as np def main(): + """Meant to emulate how pyfda will pass parameters to filters""" - hdlfilter = FilterFIR(0, 0) + hdlfilter = FilterFIR() b = [1, 2, 3, 1] - hdlfilter.set_coefficients(b) - hdlfilter.set_stimulation(np.ones(100)) - testfil = hdlfilter.filter_block() - testfil.run_sim() - + hdlfilter.set_coefficients(coeff_b = b) + hdlfilter.set_stimulus(np.ones(100)) + hdlfilter.runsim() if __name__ == '__main__': main() From 7f6dc6e244cd1d08ee12f3de6c3bcb6a5bc2a8e6 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 29 Jun 2018 17:16:53 +0530 Subject: [PATCH 11/46] renamed file fir_test to fir_temp. new file iir_temp for iir interfafce. fixed _init_ file issues --- filter_blocks/fda/__init__.py | 2 +- .../fda/{fir_test.py => fir_temp.py} | 6 +- filter_blocks/fda/iir_temp.py | 102 ++++++++++++++++++ tests/test_fir/test_firs.py | 4 +- 4 files changed, 108 insertions(+), 6 deletions(-) rename filter_blocks/fda/{fir_test.py => fir_temp.py} (96%) create mode 100644 filter_blocks/fda/iir_temp.py diff --git a/filter_blocks/fda/__init__.py b/filter_blocks/fda/__init__.py index a97ada5..7dc7e35 100644 --- a/filter_blocks/fda/__init__.py +++ b/filter_blocks/fda/__init__.py @@ -1,3 +1,3 @@ from .iir import FilterIIR -from .fir_test import FilterFIR \ No newline at end of file +from .fir_temp import FilterFIR \ No newline at end of file diff --git a/filter_blocks/fda/fir_test.py b/filter_blocks/fda/fir_temp.py similarity index 96% rename from filter_blocks/fda/fir_test.py rename to filter_blocks/fda/fir_temp.py index 6311717..3752934 100644 --- a/filter_blocks/fda/fir_test.py +++ b/filter_blocks/fda/fir_temp.py @@ -8,16 +8,16 @@ class FilterFIR(FilterHardware): - """Contains FIR filter parameters. Parent Class : FilterHArdware""" - def __init__(self, b = None, a = None, w = (24, 0, 23)): - """ + """Contains FIR filter parameters. Parent Class : FilterHardware Args: b (list of int): list of numerator coefficients. a (list of int): list of denominator coefficients. + word format (tuple of int): (W, WI, WF) filter_type: filter_form_type: response(list): list of filter output in int format. """ + def __init__(self, b = None, a = None, w = (24, 0, 23)): super(FilterFIR, self).__init__(b, a, w) self.filter_type = 'direct_form' self.direct_form_type = 1 diff --git a/filter_blocks/fda/iir_temp.py b/filter_blocks/fda/iir_temp.py new file mode 100644 index 0000000..762aadf --- /dev/null +++ b/filter_blocks/fda/iir_temp.py @@ -0,0 +1,102 @@ +import myhdl as hdl +import numpy as np +from .filter_hw import FilterHardware +from ..fir import fir_df1 +from filter_blocks.support import Clock, Reset, Global, Samples +from myhdl import Signal, intbv, StopSimulation + + + +class FilterIIR(FilterHardware): + """Contains IIR filter parameters. Parent Class : FilterHardware + Args: + b (list of int): list of numerator coefficients. + a (list of int): list of denominator coefficients. + word format (tuple of int): (W, WI, WF) + filter_type: + filter_form_type: + response(list): list of filter output in int format. + """ + def __init__(self, b = None, a = None, w = (24, 0, 23)): + super(FilterIIR, self).__init__(b, a, w) + self.filter_type = 'direct_form' + self.direct_form_type = 1 + self.response = [] + + def get_response(self): + """Return filter output. + + returns: + response(numpy int array) : returns filter output as numpy array + """ + return self.response + + def runsim(self): + """Run filter simulation""" + + testfil = self.filter_block() + testfil.run_sim() + + @hdl.block + def filter_block(self): + """ this elaboration code will select the different structure and implementations""" + + w = (25, 24, 0) + ymax = 2**(w[0]-1) + vmax = 2**(2*w[0]) + xt = Samples(-vmax, vmax) + yt = Samples(-vmax, vmax) + xt.valid = bool(1) + clock = Clock(0, frequency=50e6) + reset = Reset(1, active=0, async=True) + glbl = Global(clock, reset) + tbclk = clock.process() + numsample = 0 + + # set numsample + numsample = len(self.sigin) + #process to record output in buffer + rec_insts = yt.process_record(clock, num_samples=numsample) + + + if self.filter_type == 'direct_form': + if self.direct_form_type == 1: + # all filters will need the same interface ports, this should be do able + dfilter = fir_df1.filter_fir + + if self.n_cascades > 0: + filter_insts = [None for _ in range(self.n_cascades)] + for ii in range(self.n_cascades): + pass + # filter_insts[ii] = fir_df1.filter_fir( + # glbl, sigin[ii], sigout[ii], b + # ) + else: + filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) + + + + + @hdl.instance + def stimulus(): + "record output in numpy array yt.sample_buffer" + for k in self.sigin: + xt.data.next = int(k) + xt.valid = bool(1) + + yt.record = True + yt.valid = True + yield clock.posedge + #Collect a sample from each filter + yt.record = False + yt.valid = False + + print(yt.sample_buffer) + self.response = yt.sample_buffer + # pl.plot(yt.sample_buffer) + # pl.show() + + raise StopSimulation() + + return hdl.instances() + \ No newline at end of file diff --git a/tests/test_fir/test_firs.py b/tests/test_fir/test_firs.py index 3927530..65a3f45 100644 --- a/tests/test_fir/test_firs.py +++ b/tests/test_fir/test_firs.py @@ -7,8 +7,8 @@ from filter_blocks.support import Clock, Reset, Global, Samples from filter_blocks.testing import DDSine -from filter_blocks.fda import FilterFIR - +from filter_blocks.fda.fir import FilterFIR +#from filter_blocks.fda import FilterFIR Change back to this when fir and fir_test are merged def test_filters(args=None): if args is None: From db079819008d71a95f217c93d2a1c71a0a772bf7 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 29 Jun 2018 17:25:34 +0530 Subject: [PATCH 12/46] added default argument for w in constructor in 'filter_hw' --- filter_blocks/fda/filter_hw.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 17ec965..9c965e9 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -2,7 +2,7 @@ class FilterHardware(object): """Top level class. Contains filter parameters.""" - def __init__(self, b, a, w): + def __init__(self, b, a, w = (24, 0, 23)): """ Args: b (list of int): list of numerator coefficients. From 2817a1f73e60ac1bd13cfe455a1fb97bce221131 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 9 Jul 2018 13:25:33 +0530 Subject: [PATCH 13/46] changed name runsim() to run_sim() --- filter_blocks/fda/fir_temp.py | 2 +- tests/test_fir/test_df1.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/filter_blocks/fda/fir_temp.py b/filter_blocks/fda/fir_temp.py index 3752934..a49a742 100644 --- a/filter_blocks/fda/fir_temp.py +++ b/filter_blocks/fda/fir_temp.py @@ -31,7 +31,7 @@ def get_response(self): """ return self.response - def runsim(self): + def run_sim(self): """Run filter simulation""" testfil = self.filter_block() diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index e1924c3..64e2467 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -8,6 +8,6 @@ def main(): b = [1, 2, 3, 1] hdlfilter.set_coefficients(coeff_b = b) hdlfilter.set_stimulus(np.ones(100)) - hdlfilter.runsim() + hdlfilter.run_sim() if __name__ == '__main__': main() From 358b0f02b38f3184de9a0228b687c0506921c82e Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 13 Jul 2018 15:07:08 +0800 Subject: [PATCH 14/46] added covert method to fda/fir.py and deleted excess files --- filter_blocks/fda/fir.py | 162 ++++++++++++++++++++++++++-------- filter_blocks/fda/fir_temp.py | 102 --------------------- filter_blocks/fda/iir.py | 156 ++++++++++++++++++-------------- filter_blocks/fda/iir_temp.py | 102 --------------------- filter_blocks/fda/iir_test.py | 45 ---------- filter_blocks/fir/fir_df1.py | 4 +- tests/test_fir/test_df1.py | 3 +- 7 files changed, 220 insertions(+), 354 deletions(-) delete mode 100644 filter_blocks/fda/fir_temp.py delete mode 100644 filter_blocks/fda/iir_temp.py delete mode 100644 filter_blocks/fda/iir_test.py diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 8d994f5..148b51f 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -1,53 +1,145 @@ - import myhdl as hdl -from myhdl import Signal, always_seq - -from filter_blocks.support import Samples +import numpy as np from .filter_hw import FilterHardware +from ..fir import fir_df1 +from filter_blocks.support import Clock, Reset, Global, Samples +from myhdl import Signal, intbv, StopSimulation, toVerilog, toVHDL class FilterFIR(FilterHardware): - def __init__(self, b, a): - super(FilterFIR, self).__init__(b, a) + """Contains FIR filter parameters. Parent Class : FilterHardware + Args: + b (list of int): list of numerator coefficients. + a (list of int): list of denominator coefficients. + word format (tuple of int): (W, WI, WF) + filter_type: + filter_form_type: + response(list): list of filter output in int format. + """ + def __init__(self, b = None, a = None, w = (24, 0, 23)): + super(FilterFIR, self).__init__(b, a, w) + self.filter_type = 'direct_form' + self.direct_form_type = 1 + self.response = [] - @hdl.block - def process(self, glbl, smpi, smpo): - """FIR filter model. + def get_response(self): + """Return filter output. - Args: - glbl: - smpi: sample stream input - smpo: sample stream output + returns: + response(numpy int array) : returns filter output as numpy array + """ + return self.response - Not convertible + def run_sim(self): + """Run filter simulation""" + + testfil = self.filter_block() + testfil.run_sim() + + def convert(self, path): + """Convert the HDL description to Verilog and VHDL. """ - assert isinstance(smpi, Samples) - assert isinstance(smpo, Samples) + w = self.word_format + imax = 2**(w[0]-1) + + # small top-level wrapper + def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): + sigin = Samples(x.min, x.max) + sigin.data, sigin.data_valid = x, xdv + sigout = Samples(y.min, y.max) + sigout.data, sigout.data_valid = y, ydv + clk = clock + rst = reset + glbl = Global(clk, rst) + + #choose appropriate filter + fir_hdl = fir_df1.filter_fir + + fir = fir_hdl(glbl, sigin, sigout, self.b, + shared_multiplier=self._shared_multiplier) + + fir.name = self.hdl_name + fir.directory = self.hdl_directory + fir.convert(hdl) + + + clock = Clock(0, frequency=50e6) + reset = Reset(1, active=0, async=True) + x = Signal(intbv(0, min=-imax, max=imax)) + y = Signal(intbv(0, min=-imax, max=imax)) + xdv, ydv = Signal(bool(0)), Signal(bool(0)) + + + if self.hdl_target.lower() == 'verilog': + filter_fir_top('verilog', clock, reset, x, xdv, y, ydv) + + elif self.hdl_target.lower() == 'vhdl': + filter_fir_top('verilog', clock, reset, x, xdv, y, ydv) + else: + raise ValueError('incorrect target HDL {}'.format(self.hdl_target)) + + + + @hdl.block + def filter_block(self): + """ this elaboration code will select the different structure and implementations""" + + w = (25, 24, 0) + ymax = 2**(w[0]-1) + vmax = 2**(2*w[0]) + xt = Samples(-vmax, vmax) + yt = Samples(-vmax, vmax) + xt.valid = bool(1) + clock = Clock(0, frequency=50e6) + reset = Reset(1, active=0, async=True) + glbl = Global(clock, reset) + tbclk = clock.process() + numsample = 0 + + # set numsample + numsample = len(self.sigin) + #process to record output in buffer + rec_insts = yt.process_record(clock, num_samples=numsample) + + + if self.filter_type == 'direct_form': + if self.direct_form_type == 1: + # all filters will need the same interface ports, this should be do able + dfilter = fir_df1.filter_fir + + if self.n_cascades > 0: + filter_insts = [None for _ in range(self.n_cascades)] + for ii in range(self.n_cascades): + pass + # filter_insts[ii] = fir_df1.filter_fir( + # glbl, sigin[ii], sigout[ii], b + # ) + else: + filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) + - clock, reset = glbl.clock, glbl.reset - x, y = smpi, smpo - ntaps = len(self.b) - h = tuple(self.b) - xd = [0 for _ in range(len(h))] @hdl.instance - def beh_proc(): - while True: - yield clock.posedge + def stimulus(): + "record output in numpy array yt.sample_buffer" + for k in self.sigin: + xt.data.next = int(k) + xt.valid = bool(1) - if x.valid: - xd.insert(0, int(smpi.data)) - xd.pop(-1) + yt.record = True + yt.valid = True + yield clock.posedge + #Collect a sample from each filter + yt.record = False + yt.valid = False - sop = 0 - for ii in range(ntaps): - sop = sop + (h[ii] * xd[ii]) + print(yt.sample_buffer) + self.response = yt.sample_buffer + # pl.plot(yt.sample_buffer) + # pl.show() - y.data.next = int(round(sop)) - y.valid.next = True - else: - y.valid.next = False + raise StopSimulation() return hdl.instances() - + \ No newline at end of file diff --git a/filter_blocks/fda/fir_temp.py b/filter_blocks/fda/fir_temp.py deleted file mode 100644 index a49a742..0000000 --- a/filter_blocks/fda/fir_temp.py +++ /dev/null @@ -1,102 +0,0 @@ -import myhdl as hdl -import numpy as np -from .filter_hw import FilterHardware -from ..fir import fir_df1 -from filter_blocks.support import Clock, Reset, Global, Samples -from myhdl import Signal, intbv, StopSimulation - - - -class FilterFIR(FilterHardware): - """Contains FIR filter parameters. Parent Class : FilterHardware - Args: - b (list of int): list of numerator coefficients. - a (list of int): list of denominator coefficients. - word format (tuple of int): (W, WI, WF) - filter_type: - filter_form_type: - response(list): list of filter output in int format. - """ - def __init__(self, b = None, a = None, w = (24, 0, 23)): - super(FilterFIR, self).__init__(b, a, w) - self.filter_type = 'direct_form' - self.direct_form_type = 1 - self.response = [] - - def get_response(self): - """Return filter output. - - returns: - response(numpy int array) : returns filter output as numpy array - """ - return self.response - - def run_sim(self): - """Run filter simulation""" - - testfil = self.filter_block() - testfil.run_sim() - - @hdl.block - def filter_block(self): - """ this elaboration code will select the different structure and implementations""" - - w = (25, 24, 0) - ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) - xt = Samples(-vmax, vmax) - yt = Samples(-vmax, vmax) - xt.valid = bool(1) - clock = Clock(0, frequency=50e6) - reset = Reset(1, active=0, async=True) - glbl = Global(clock, reset) - tbclk = clock.process() - numsample = 0 - - # set numsample - numsample = len(self.sigin) - #process to record output in buffer - rec_insts = yt.process_record(clock, num_samples=numsample) - - - if self.filter_type == 'direct_form': - if self.direct_form_type == 1: - # all filters will need the same interface ports, this should be do able - dfilter = fir_df1.filter_fir - - if self.n_cascades > 0: - filter_insts = [None for _ in range(self.n_cascades)] - for ii in range(self.n_cascades): - pass - # filter_insts[ii] = fir_df1.filter_fir( - # glbl, sigin[ii], sigout[ii], b - # ) - else: - filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) - - - - - @hdl.instance - def stimulus(): - "record output in numpy array yt.sample_buffer" - for k in self.sigin: - xt.data.next = int(k) - xt.valid = bool(1) - - yt.record = True - yt.valid = True - yield clock.posedge - #Collect a sample from each filter - yt.record = False - yt.valid = False - - print(yt.sample_buffer) - self.response = yt.sample_buffer - # pl.plot(yt.sample_buffer) - # pl.show() - - raise StopSimulation() - - return hdl.instances() - \ No newline at end of file diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index d9f40e9..762aadf 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -1,80 +1,102 @@ -""" -""" - import myhdl as hdl -from myhdl import Signal, ResetSignal, intbv, always - -from filter_blocks import Clock, Reset, Samples -from filter_blocks import filter_iir, filter_iir_sos - +import numpy as np from .filter_hw import FilterHardware +from ..fir import fir_df1 +from filter_blocks.support import Clock, Reset, Global, Samples +from myhdl import Signal, intbv, StopSimulation -class FilterIIR(FilterHardware): - def __init__(self, b, a, sos=None): - """Configuration and analysis of a hardware digital filter. - """ - super(FilterIIR, self).__init__(b, a) - self.n_sections = 1 - self.convert_coefficients(b, a, sos) - self .iir_sections = [None for _ in range(self.n_sections)] - self.first_pass = True - - def convert_coefficients(self, b, a, sos): - """Extract the coefficients and convert to fixed-point. - """ - pass - - def process(self, x): - for ii in range(self.n_sections): - x = self.iir_sections[ii].process(x) - y = x - return y - - def get_filter_instance(self, glbl, sigin, sigout): - """Get the filter hardware instance. +class FilterIIR(FilterHardware): + """Contains IIR filter parameters. Parent Class : FilterHardware Args: - glbl: global signals like clock, reset, enable - sigin: input signal bus - sigout: output signal bus + b (list of int): list of numerator coefficients. + a (list of int): list of denominator coefficients. + word format (tuple of int): (W, WI, WF) + filter_type: + filter_form_type: + response(list): list of filter output in int format. + """ + def __init__(self, b = None, a = None, w = (24, 0, 23)): + super(FilterIIR, self).__init__(b, a, w) + self.filter_type = 'direct_form' + self.direct_form_type = 1 + self.response = [] - Returns: - inst (myhdl.Block): an object that represents the - filter block. + def get_response(self): + """Return filter output. + returns: + response(numpy int array) : returns filter output as numpy array """ - inst = None - if self.is_sos: - pass - else: - pass + return self.response - return inst + def runsim(self): + """Run filter simulation""" + + testfil = self.filter_block() + testfil.run_sim() @hdl.block - def filter_iir_top(self, clock, reset, x, xdv, y, ydv): - """Small top-level wrapper""" - w = (len(x), 0, len(x)-1) - sigin = Samples(word_format=w) - sigin.data, sigin.valid = x, xdv - sigout = Samples(word_format=w) - sigout.data, sigout.valid = y, ydv - - return filter_inst - - def convert(self, hdl='verilog'): - """Convert to verilog or vhdl""" - w = self.word_format - imax = 2**(w[0]-1) + def filter_block(self): + """ this elaboration code will select the different structure and implementations""" + + w = (25, 24, 0) + ymax = 2**(w[0]-1) + vmax = 2**(2*w[0]) + xt = Samples(-vmax, vmax) + yt = Samples(-vmax, vmax) + xt.valid = bool(1) clock = Clock(0, frequency=50e6) - reset = Reset(0, active=0, async=True) - x = Signal(intbv(0, min=-imax, max=imax)) - y = Signal(intbv(0, min=-imax, max=imax)) - xdv, ydv = Signal(bool(0)), Signal(bool(0)) - - inst = self.filter_iir_top(clock, reset, x, xdv, y, ydv) - inst.name = self.hdl_name - inst.directory = self.hdl_directory - inst.convert(hdl=hdl) - + reset = Reset(1, active=0, async=True) + glbl = Global(clock, reset) + tbclk = clock.process() + numsample = 0 + + # set numsample + numsample = len(self.sigin) + #process to record output in buffer + rec_insts = yt.process_record(clock, num_samples=numsample) + + + if self.filter_type == 'direct_form': + if self.direct_form_type == 1: + # all filters will need the same interface ports, this should be do able + dfilter = fir_df1.filter_fir + + if self.n_cascades > 0: + filter_insts = [None for _ in range(self.n_cascades)] + for ii in range(self.n_cascades): + pass + # filter_insts[ii] = fir_df1.filter_fir( + # glbl, sigin[ii], sigout[ii], b + # ) + else: + filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) + + + + + @hdl.instance + def stimulus(): + "record output in numpy array yt.sample_buffer" + for k in self.sigin: + xt.data.next = int(k) + xt.valid = bool(1) + + yt.record = True + yt.valid = True + yield clock.posedge + #Collect a sample from each filter + yt.record = False + yt.valid = False + + print(yt.sample_buffer) + self.response = yt.sample_buffer + # pl.plot(yt.sample_buffer) + # pl.show() + + raise StopSimulation() + + return hdl.instances() + \ No newline at end of file diff --git a/filter_blocks/fda/iir_temp.py b/filter_blocks/fda/iir_temp.py deleted file mode 100644 index 762aadf..0000000 --- a/filter_blocks/fda/iir_temp.py +++ /dev/null @@ -1,102 +0,0 @@ -import myhdl as hdl -import numpy as np -from .filter_hw import FilterHardware -from ..fir import fir_df1 -from filter_blocks.support import Clock, Reset, Global, Samples -from myhdl import Signal, intbv, StopSimulation - - - -class FilterIIR(FilterHardware): - """Contains IIR filter parameters. Parent Class : FilterHardware - Args: - b (list of int): list of numerator coefficients. - a (list of int): list of denominator coefficients. - word format (tuple of int): (W, WI, WF) - filter_type: - filter_form_type: - response(list): list of filter output in int format. - """ - def __init__(self, b = None, a = None, w = (24, 0, 23)): - super(FilterIIR, self).__init__(b, a, w) - self.filter_type = 'direct_form' - self.direct_form_type = 1 - self.response = [] - - def get_response(self): - """Return filter output. - - returns: - response(numpy int array) : returns filter output as numpy array - """ - return self.response - - def runsim(self): - """Run filter simulation""" - - testfil = self.filter_block() - testfil.run_sim() - - @hdl.block - def filter_block(self): - """ this elaboration code will select the different structure and implementations""" - - w = (25, 24, 0) - ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) - xt = Samples(-vmax, vmax) - yt = Samples(-vmax, vmax) - xt.valid = bool(1) - clock = Clock(0, frequency=50e6) - reset = Reset(1, active=0, async=True) - glbl = Global(clock, reset) - tbclk = clock.process() - numsample = 0 - - # set numsample - numsample = len(self.sigin) - #process to record output in buffer - rec_insts = yt.process_record(clock, num_samples=numsample) - - - if self.filter_type == 'direct_form': - if self.direct_form_type == 1: - # all filters will need the same interface ports, this should be do able - dfilter = fir_df1.filter_fir - - if self.n_cascades > 0: - filter_insts = [None for _ in range(self.n_cascades)] - for ii in range(self.n_cascades): - pass - # filter_insts[ii] = fir_df1.filter_fir( - # glbl, sigin[ii], sigout[ii], b - # ) - else: - filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) - - - - - @hdl.instance - def stimulus(): - "record output in numpy array yt.sample_buffer" - for k in self.sigin: - xt.data.next = int(k) - xt.valid = bool(1) - - yt.record = True - yt.valid = True - yield clock.posedge - #Collect a sample from each filter - yt.record = False - yt.valid = False - - print(yt.sample_buffer) - self.response = yt.sample_buffer - # pl.plot(yt.sample_buffer) - # pl.show() - - raise StopSimulation() - - return hdl.instances() - \ No newline at end of file diff --git a/filter_blocks/fda/iir_test.py b/filter_blocks/fda/iir_test.py deleted file mode 100644 index 7af17a7..0000000 --- a/filter_blocks/fda/iir_test.py +++ /dev/null @@ -1,45 +0,0 @@ -import myhdl as hdl -from filter_blocks.support import Samples -from .filter_hw import FilterHardware -from ..iir import iir_parallel -from ..iir import iir_df1 - -class IIRFilter(FilterHardware): - def __init__(self, b, a): - super().__init__(b, a) - self.filter_type = 'parallel_form' - self.n_cascades = 0 - self.direct_form_type = 1 - - def set_cascade(self, n_cascades): - self.n_cascades = n_cascades - - def set_filter_type(self, filter_type): - self.filter_type = filter_type - - @hdl.block - def filter_block(self, glbl, sigin, sigout, b, a, w): - # this elaboration code will select the different structure and implementations - xt = Samples(sigin.min, sigin.max) - yt = Samples(sigout.min, sigout.max) - xt.data = sigin.val - xt.valid = bool(1) - if self.filter_type == 'parallel_form': - # if self.direct_form_type == 1: - # all filters will need the same interface ports, this should be do able - dfilter = iir_parallel.filter_iir_parallel - - if self.n_cascades > 0: - filter_insts = [None for _ in range(self.n_cascades)] - for ii in range(self.n_cascades): - filter_insts[ii] = iir_parallel.filter_iir_parallel( - glbl, sigin[ii], sigout[ii], b, a, w - ) - else: - filter_insts = iir_parallel.filter_iir_parallel(glbl, xt, yt, b, a, w) - - if self.filter_type == 'direct_form': - filter_insts = iir_df1.filter_iir(glbl, xt, yt, b, a) - - - return filter_insts diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 4e2c7b4..72281f5 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -22,8 +22,8 @@ def filter_fir(glbl, sigin, sigout, b, shared_multiplier=False): assert isinstance(sigout, Samples) #assert isinstance(b, tuple) # All the coefficients need to be an `int` - rb = [isinstance(bb, int) for bb in b] - assert all(rb) + #rb = [isinstance(bb, int) for bb in b] + #assert all(rb) w = sigin.word_format ymax = 2**(w[0]-1) diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 64e2467..de90348 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -5,9 +5,10 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" hdlfilter = FilterFIR() - b = [1, 2, 3, 1] + b = (1, 2, 3, 1) hdlfilter.set_coefficients(coeff_b = b) hdlfilter.set_stimulus(np.ones(100)) hdlfilter.run_sim() + hdlfilter.convert() if __name__ == '__main__': main() From 51628fd9b2e83bcaf5925ea1252e91bf059337e5 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 13 Jul 2018 15:55:12 +0800 Subject: [PATCH 15/46] finishing up convert method for fir --- filter_blocks/fda/__init__.py | 2 +- filter_blocks/fda/filter_hw.py | 9 +++++---- filter_blocks/fda/fir.py | 6 ++---- tests/test_fir/test_df1.py | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/filter_blocks/fda/__init__.py b/filter_blocks/fda/__init__.py index 7dc7e35..be1a0a7 100644 --- a/filter_blocks/fda/__init__.py +++ b/filter_blocks/fda/__init__.py @@ -1,3 +1,3 @@ from .iir import FilterIIR -from .fir_temp import FilterFIR \ No newline at end of file +from .fir import FilterFIR \ No newline at end of file diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 9c965e9..ba67c3e 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -38,11 +38,12 @@ def set_coefficients(self, coeff_b, coeff_a = None): """Set filter coefficients. Args: - coefficients (list): list of filter coefficients - param2 (str): The second parameter. + coeff_b (list): list of numerator filter coefficients + coeff_a (list): list of denominator filter coefficients """ - self.b = coeff_b - self.a = coeff_a + self.b = tuple(coeff_b) + if coeff_a is not None: + self.a = tuple(coeff_a) def set_stimulus(self, sigin): """Set filter stimulus diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 148b51f..73158e6 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -36,7 +36,7 @@ def run_sim(self): testfil = self.filter_block() testfil.run_sim() - def convert(self, path): + def convert(self, hdl='Verilog', **kwargs): """Convert the HDL description to Verilog and VHDL. """ w = self.word_format @@ -58,9 +58,7 @@ def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): fir = fir_hdl(glbl, sigin, sigout, self.b, shared_multiplier=self._shared_multiplier) - fir.name = self.hdl_name - fir.directory = self.hdl_directory - fir.convert(hdl) + fir.convert(hdl='Verilog', **kwargs) clock = Clock(0, frequency=50e6) diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index de90348..15d16a0 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -5,10 +5,10 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" hdlfilter = FilterFIR() - b = (1, 2, 3, 1) + b = [1, 2, 3, 1] hdlfilter.set_coefficients(coeff_b = b) hdlfilter.set_stimulus(np.ones(100)) hdlfilter.run_sim() - hdlfilter.convert() + hdlfilter.convert(name = 'hello') if __name__ == '__main__': main() From e8791cdd56f0ae32a0b0d440bc92488c9bdd9101 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sun, 15 Jul 2018 13:07:09 +0800 Subject: [PATCH 16/46] updates to fir_df1 to incorporate stimulus word format --- filter_blocks/fda/filter_hw.py | 12 +++++++----- filter_blocks/fda/fir.py | 11 ++++++----- filter_blocks/fir/fir_df1.py | 29 ++++++++++++++++++----------- filter_blocks/support.py | 4 ++-- tests/test_fir/test_df1.py | 10 ++++++---- 5 files changed, 39 insertions(+), 27 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index ba67c3e..a7627d9 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -2,12 +2,12 @@ class FilterHardware(object): """Top level class. Contains filter parameters.""" - def __init__(self, b, a, w = (24, 0, 23)): + def __init__(self, b, a, w ): """ Args: b (list of int): list of numerator coefficients. a (list of int): list of denominator coefficients. - word_format (tuple of int): word format (W,WI,WF). + coef_word_format (tuple of int): word format (W,WI,WF). n_cascades(int): sigin(numpy int array): nfft(int): @@ -17,7 +17,7 @@ def __init__(self, b, a, w = (24, 0, 23)): """ self.b = b # numerator coefficients self.a = a # denominator coefficients - self.word_format = w + self.coef_word_format = w self.n_cascades = 0 self.sigin = np.array([]) @@ -45,13 +45,15 @@ def set_coefficients(self, coeff_b, coeff_a = None): if coeff_a is not None: self.a = tuple(coeff_a) - def set_stimulus(self, sigin): + def set_stimulus(self, sigin, input_word_format = (24, 23, 0)): """Set filter stimulus Args: sigin (np array int): numpy array of filter stimulus + bits (int) : no of bits """ self.sigin = sigin.tolist() + self.input_word_format = input_word_format def set_cascade(self, n_cascades): """Set number of filter cascades @@ -67,7 +69,7 @@ def set_word_format(self, w): Args: word_format (tuple of int): word format (W,WI,WF) """ - self.word_format = w + self.coef_word_format = w def get_fixed_coefficients(self): raise NotImplementedError diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 73158e6..8f3541d 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -16,7 +16,7 @@ class FilterFIR(FilterHardware): filter_form_type: response(list): list of filter output in int format. """ - def __init__(self, b = None, a = None, w = (24, 0, 23)): + def __init__(self, b = None, a = None, w = (24,0,23)): super(FilterFIR, self).__init__(b, a, w) self.filter_type = 'direct_form' self.direct_form_type = 1 @@ -36,10 +36,11 @@ def run_sim(self): testfil = self.filter_block() testfil.run_sim() + def convert(self, hdl='Verilog', **kwargs): """Convert the HDL description to Verilog and VHDL. """ - w = self.word_format + w = self.input_word_format imax = 2**(w[0]-1) # small top-level wrapper @@ -82,10 +83,10 @@ def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): def filter_block(self): """ this elaboration code will select the different structure and implementations""" - w = (25, 24, 0) + w = self.input_word_format ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) - xt = Samples(-vmax, vmax) + xt = Samples(-vmax, vmax, self.input_word_format) yt = Samples(-vmax, vmax) xt.valid = bool(1) clock = Clock(0, frequency=50e6) @@ -113,7 +114,7 @@ def filter_block(self): # glbl, sigin[ii], sigout[ii], b # ) else: - filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) + filter_insts = dfilter(glbl, xt, yt, self.b, self.coef_word_format) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 72281f5..1cdc663 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -2,9 +2,10 @@ from myhdl import Signal, intbv, always_seq from filter_blocks.support import Samples, Signals +import math @hdl.block -def filter_fir(glbl, sigin, sigout, b, shared_multiplier=False): +def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): """Basic FIR direct-form I filter. Ports: @@ -20,24 +21,30 @@ def filter_fir(glbl, sigin, sigout, b, shared_multiplier=False): """ assert isinstance(sigin, Samples) assert isinstance(sigout, Samples) - #assert isinstance(b, tuple) - # All the coefficients need to be an `int` - #rb = [isinstance(bb, int) for bb in b] - #assert all(rb) + assert isinstance(b, tuple) + #All the coefficients need to be an `int` + rb = [isinstance(bb, int) for bb in b] + assert all(rb) w = sigin.word_format ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) # double width max and min - vmin = -vmax - ymin = -ymax + #vmax = 2**(2*w[0]) # double width max and min + N = len(b)-1 + + + acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) + amax = 2**(2*acc_bits) + + + clock, reset = glbl.clock, glbl.reset xdv = sigin.valid y, ydv = sigout.data, sigout.valid - x = Signal(intbv(0, min=vmin, max=vmax)) + x = Signal(intbv(0, min = - ymax, max = ymax)) # Delay elements, list-of-signals - ffd = Signals(intbv(0, min=ymin, max=ymax), N) - yacc = Signal(intbv(0, min=vmin, max=vmax)) #verify the length of this + ffd = Signals(intbv(0, min = -ymax, max = ymax), N) + yacc = Signal(intbv(0, min = - amax, max = amax)) #verify the length of this dvd = Signal(bool(0)) @hdl.always(clock.posedge) diff --git a/filter_blocks/support.py b/filter_blocks/support.py index f410b5d..8151aa0 100644 --- a/filter_blocks/support.py +++ b/filter_blocks/support.py @@ -49,12 +49,12 @@ def __init__(self, clock, reset): class Samples(object): - def __init__(self, min, max, res=0, dtype=intbv, sample_rate=1): + def __init__(self, min, max, word_format = (24, 23, 0), res=0, dtype=intbv, sample_rate=1): """Sample streams, input and output to filters. """ # @todo: fixed-point support ... - word_format = (24, 23, 0) + #word_format = (24, 23, 0) # The fixed-point word format is described by a tuple, the # tuple defines the number of integer bits and fractional bits: # (word, int, frac) where: word = int + frac + 1 diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 15d16a0..8199e35 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -3,12 +3,14 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" - + coef = np.empty(100) + coef.fill(8388607) hdlfilter = FilterFIR() - b = [1, 2, 3, 1] + b = [1, 2, 3, 1, 0] + hdlfilter.set_word_format((24, 23, 0)) hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_stimulus(np.ones(100)) + hdlfilter.set_stimulus(coef, (24,23,0)) hdlfilter.run_sim() - hdlfilter.convert(name = 'hello') + #hdlfilter.convert() if __name__ == '__main__': main() From 58bf66f4dc64b33b11e54b513b732d3b4a13eb3d Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 16 Jul 2018 16:54:30 +0800 Subject: [PATCH 17/46] minor fixes to fir interface --- filter_blocks/fda/filter_hw.py | 6 +++--- filter_blocks/fda/fir.py | 2 +- filter_blocks/fir/fir_df1.py | 4 ++-- tests/test_fir/test_df1.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index a7627d9..81cb26a 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -2,7 +2,7 @@ class FilterHardware(object): """Top level class. Contains filter parameters.""" - def __init__(self, b, a, w ): + def __init__(self, b, a, w): """ Args: b (list of int): list of numerator coefficients. @@ -15,8 +15,8 @@ def __init__(self, b, a, w ): hdl_directory(str): hdl_target(str): """ - self.b = b # numerator coefficients - self.a = a # denominator coefficients + self.b = tuple(b) # numerator coefficients + self.a = tuple(a) # denominator coefficients self.coef_word_format = w self.n_cascades = 0 diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 8f3541d..7110e0e 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -86,7 +86,7 @@ def filter_block(self): w = self.input_word_format ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) - xt = Samples(-vmax, vmax, self.input_word_format) + xt = Samples(-ymax, ymax, self.input_word_format) yt = Samples(-vmax, vmax) xt.valid = bool(1) clock = Clock(0, frequency=50e6) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 1cdc663..47874cd 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -35,7 +35,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) amax = 2**(2*acc_bits) - + print(acc_bits) clock, reset = glbl.clock, glbl.reset @@ -64,7 +64,7 @@ def beh_direct_form_one(): c = b[ii+1] sop = sop + (c * ffd[ii]) yacc.next = sop - #print(yacc) + print(yacc) @always_seq(clock.posedge, reset=reset) def beh_output(): diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 8199e35..5c02fd9 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -6,7 +6,7 @@ def main(): coef = np.empty(100) coef.fill(8388607) hdlfilter = FilterFIR() - b = [1, 2, 3, 1, 0] + b = [8388607, 8388607, 1, 1, 1] hdlfilter.set_word_format((24, 23, 0)) hdlfilter.set_coefficients(coeff_b = b) hdlfilter.set_stimulus(coef, (24,23,0)) From 2cd187a71a6e4a18f147596ef943e7dd246299a3 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 16 Jul 2018 17:24:26 +0800 Subject: [PATCH 18/46] minor fixes to hdl_interface and updates to iir interface --- filter_blocks/fda/filter_hw.py | 10 ++++++-- filter_blocks/fda/iir.py | 9 ++++--- filter_blocks/fir/fir_df1.py | 2 +- filter_blocks/iir/iir_df1.py | 19 ++++++++------ tests/test_iir/test_iir_df1.py | 46 ++++++++++------------------------ 5 files changed, 38 insertions(+), 48 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 81cb26a..277f881 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -15,8 +15,14 @@ def __init__(self, b, a, w): hdl_directory(str): hdl_target(str): """ - self.b = tuple(b) # numerator coefficients - self.a = tuple(a) # denominator coefficients + #numerator coefficient + if b is not None: + self.b = tuple(b) + + # denominator coefficients + if a is not None: + self.a = tuple(a) + self.coef_word_format = w self.n_cascades = 0 diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index 762aadf..52bf600 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -31,7 +31,7 @@ def get_response(self): """ return self.response - def runsim(self): + def run_sim(self): """Run filter simulation""" testfil = self.filter_block() @@ -41,10 +41,11 @@ def runsim(self): def filter_block(self): """ this elaboration code will select the different structure and implementations""" - w = (25, 24, 0) + + w = self.input_word_format ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) - xt = Samples(-vmax, vmax) + xt = Samples(-ymax, ymax, self.input_word_format) yt = Samples(-vmax, vmax) xt.valid = bool(1) clock = Clock(0, frequency=50e6) @@ -72,7 +73,7 @@ def filter_block(self): # glbl, sigin[ii], sigout[ii], b # ) else: - filter_insts = dfilter(glbl, xt, yt, self.b, self.word_format) + filter_insts = dfilter(glbl, xt, yt, self.b, self.a, self.coef_word_format) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 47874cd..7b250e2 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -14,7 +14,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): sigout (SignalBus): output digitla signal. Args: - b (tuple, list): numerator coefficents. + b (tuple): numerator coefficents. Returns: inst (myhdl.Block, list): diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 91298f7..3e1dc71 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -3,7 +3,7 @@ from filter_blocks.support import Samples, Signals @hdl.block -def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): +def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): """Basic FIR direct-form I filter. Ports: @@ -12,7 +12,9 @@ def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): sigout (SignalBus): output digitla signal. Args: - b (tuple, list): numerator coefficents. + b (tuple): numerator coefficents. + b (tuple): numerator coefficents. + Returns: inst (myhdl.Block, list): @@ -31,17 +33,18 @@ def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): w = sigin.word_format ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) # double width max and min - vmin = -vmax - ymin = -ymax + + N = len(b)-1 clock, reset = glbl.clock, glbl.reset xdv = sigin.valid y, ydv = sigout.data, sigout.valid - x = Signal(intbv(0, min=vmin, max=vmax)) + x = Signal(intbv(0, min=-ymax, max=ymax)) + # Delay elements, list-of-signals - ffd = Signals(intbv(0, min=ymin, max=ymax), N) - fbd = Signals(intbv(0, min=ymin, max=ymax), N) - yacc = Signal(intbv(0, min=vmin, max=vmax)) #verify the length of this + ffd = Signals(intbv(0, min=-ymax, max=ymax), N) + fbd = Signals(intbv(0, min=-ymax, max=ymax), N) + yacc = Signal(intbv(0, min=-vmax, max=vmax)) #verify the length of this dvd = Signal(bool(0)) @hdl.always(clock.posedge) diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index 6f5be11..a5c6c26 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -1,37 +1,17 @@ -import myhdl as hdl -from myhdl import Signal, intbv, StopSimulation, traceSignals -from filter_blocks.support import Clock, Reset, Global -from filter_blocks.fda import iir_test as ft - -@hdl.block -def test_iir_df1(): - clock = Clock(0, frequency=50e6) - reset = Reset(0, active=0, async=True) - glbl = Global(clock, reset) - tbclk = clock.process() - x = Signal(intbv(0)[8:]) - y = Signal(intbv(0)[8:]) - a = (1, 1) - b = (1, 2, 1) - w = (24, 23, 0) - iir_test = ft.IIRFilter(b, a) - iir_test.filter_type = 'direct_form' - fir = iir_test.filter_block(glbl, x, y, b, a, w) - - @hdl.instance - def stimulus(): - "input for test bench taken from text file test.txt" - for line in open('test.txt'): - x.next = int(line) - yield clock.posedge - raise StopSimulation - - return fir, stimulus, tbclk +from filter_blocks.fda import FilterIIR +import numpy as np def main(): - test_bench = traceSignals(test_iir_df1()) - test_bench.run_sim() - - + """Meant to emulate how pyfda will pass parameters to filters""" + coef = np.empty(100) + coef.fill(2) + hdlfilter = FilterIIR() + b = [8388607, 8388607, 1, 1, 1] + a = [1,2,1,1,1] + hdlfilter.set_word_format((24, 23, 0)) + hdlfilter.set_coefficients(coeff_b = b, coeff_a = a) + hdlfilter.set_stimulus(coef, (24,23,0)) + hdlfilter.run_sim() + #hdlfilter.convert() if __name__ == '__main__': main() From a53e14a82d3250cf7dc2e5b21af6906d5415e229 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Tue, 17 Jul 2018 01:24:52 +0800 Subject: [PATCH 19/46] updates to interface --- filter_blocks/fda/filter_hw.py | 8 +++++--- filter_blocks/fda/fir.py | 4 +++- filter_blocks/fir/fir_df1.py | 2 +- tests/test_fir/test_df1.py | 7 ++++--- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 277f881..d4708a4 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -69,13 +69,15 @@ def set_cascade(self, n_cascades): """ self.n_cascades = n_cascades - def set_word_format(self, w): + def set_word_format(self, coeff_w, input_w): """Set word format Args: - word_format (tuple of int): word format (W,WI,WF) + coef_word_format (tuple of int): word format (W,WI,WF) + input_word_format (tuple of int): word format (W,WI,WF) """ - self.coef_word_format = w + self.coef_word_format = coeff_w + self.input_word_format = input_w def get_fixed_coefficients(self): raise NotImplementedError diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 7110e0e..f97e1f1 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -56,7 +56,7 @@ def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): #choose appropriate filter fir_hdl = fir_df1.filter_fir - fir = fir_hdl(glbl, sigin, sigout, self.b, + fir = fir_hdl(glbl, sigin, sigout, self.b, self.coef_word_format, shared_multiplier=self._shared_multiplier) fir.convert(hdl='Verilog', **kwargs) @@ -84,6 +84,8 @@ def filter_block(self): """ this elaboration code will select the different structure and implementations""" w = self.input_word_format + print(self.input_word_format) + print(self.coef_word_format) ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) xt = Samples(-ymax, ymax, self.input_word_format) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 7b250e2..c7606ea 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -64,7 +64,7 @@ def beh_direct_form_one(): c = b[ii+1] sop = sop + (c * ffd[ii]) yacc.next = sop - print(yacc) + #print(yacc) @always_seq(clock.posedge, reset=reset) def beh_output(): diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 5c02fd9..111c91c 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -7,10 +7,11 @@ def main(): coef.fill(8388607) hdlfilter = FilterFIR() b = [8388607, 8388607, 1, 1, 1] - hdlfilter.set_word_format((24, 23, 0)) + hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_stimulus(coef, (24,23,0)) + hdlfilter.set_word_format((25, 24, 0),(24,23,0)) + #hdlfilter.set_stimulus(coef, (24,23,0)) hdlfilter.run_sim() - #hdlfilter.convert() + hdlfilter.convert() if __name__ == '__main__': main() From 20f28fb09192b21786a933d43c6649839482c7e2 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Wed, 18 Jul 2018 00:50:47 +0800 Subject: [PATCH 20/46] fixes to convert() --- filter_blocks/fda/fir.py | 10 +++++----- filter_blocks/fir/fir_df1.py | 6 +++--- tests/test_fir/test_df1.py | 7 +++---- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index f97e1f1..dc40ceb 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -3,7 +3,7 @@ from .filter_hw import FilterHardware from ..fir import fir_df1 from filter_blocks.support import Clock, Reset, Global, Samples -from myhdl import Signal, intbv, StopSimulation, toVerilog, toVHDL +from myhdl import Signal, intbv, StopSimulation class FilterFIR(FilterHardware): @@ -37,7 +37,7 @@ def run_sim(self): testfil.run_sim() - def convert(self, hdl='Verilog', **kwargs): + def convert(self, **kwargs): """Convert the HDL description to Verilog and VHDL. """ w = self.input_word_format @@ -59,7 +59,7 @@ def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): fir = fir_hdl(glbl, sigin, sigout, self.b, self.coef_word_format, shared_multiplier=self._shared_multiplier) - fir.convert(hdl='Verilog', **kwargs) + fir.convert(**kwargs) clock = Clock(0, frequency=50e6) @@ -70,10 +70,10 @@ def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): if self.hdl_target.lower() == 'verilog': - filter_fir_top('verilog', clock, reset, x, xdv, y, ydv) + filter_fir_top(hdl, clock, reset, x, xdv, y, ydv) elif self.hdl_target.lower() == 'vhdl': - filter_fir_top('verilog', clock, reset, x, xdv, y, ydv) + filter_fir_top(hdl, clock, reset, x, xdv, y, ydv) else: raise ValueError('incorrect target HDL {}'.format(self.hdl_target)) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index c7606ea..e98933c 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -10,8 +10,8 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): Ports: glbl (Global): global signals. - sigin (SignalBus): input digital signal. - sigout (SignalBus): output digitla signal. + sigin (Samples): input digital signal. + sigout (Samples): output digitla signal. Args: b (tuple): numerator coefficents. @@ -34,7 +34,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) - amax = 2**(2*acc_bits) + amax = 2**(acc_bits) print(acc_bits) diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 111c91c..7055b4a 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -7,11 +7,10 @@ def main(): coef.fill(8388607) hdlfilter = FilterFIR() b = [8388607, 8388607, 1, 1, 1] - hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_word_format((25, 24, 0),(24,23,0)) - #hdlfilter.set_stimulus(coef, (24,23,0)) + hdlfilter.set_word_format((26, 24, 0),(28,23,0)) + hdlfilter.set_stimulus(coef) hdlfilter.run_sim() - hdlfilter.convert() + hdlfilter.convert(hdl = 'vhdl') if __name__ == '__main__': main() From 771663cc6457b52c6677e9382d1559ead16c8cb7 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Wed, 18 Jul 2018 01:19:17 +0800 Subject: [PATCH 21/46] fixes to accumulator length --- filter_blocks/fda/filter_hw.py | 3 +-- filter_blocks/fda/fir.py | 4 ++-- filter_blocks/fir/fir_df1.py | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index d4708a4..9e5f336 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -51,7 +51,7 @@ def set_coefficients(self, coeff_b, coeff_a = None): if coeff_a is not None: self.a = tuple(coeff_a) - def set_stimulus(self, sigin, input_word_format = (24, 23, 0)): + def set_stimulus(self, sigin): """Set filter stimulus Args: @@ -59,7 +59,6 @@ def set_stimulus(self, sigin, input_word_format = (24, 23, 0)): bits (int) : no of bits """ self.sigin = sigin.tolist() - self.input_word_format = input_word_format def set_cascade(self, n_cascades): """Set number of filter cascades diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index dc40ceb..857a83b 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -84,8 +84,8 @@ def filter_block(self): """ this elaboration code will select the different structure and implementations""" w = self.input_word_format - print(self.input_word_format) - print(self.coef_word_format) + #print(self.input_word_format) + #print(self.coef_word_format) ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) xt = Samples(-ymax, ymax, self.input_word_format) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index e98933c..95e5452 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -35,7 +35,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) amax = 2**(acc_bits) - print(acc_bits) + #print(acc_bits) clock, reset = glbl.clock, glbl.reset From 60add0b67dafdb5039e5075bb6e0211908e6f517 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Wed, 18 Jul 2018 01:59:59 +0800 Subject: [PATCH 22/46] fixed ffd and x length issue --- filter_blocks/fda/filter_hw.py | 3 +-- filter_blocks/fda/fir.py | 8 ++++---- filter_blocks/fir/fir_df1.py | 3 ++- tests/test_fir/test_df1.py | 6 +++--- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 9e5f336..a360444 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -2,7 +2,7 @@ class FilterHardware(object): """Top level class. Contains filter parameters.""" - def __init__(self, b, a, w): + def __init__(self, b, a): """ Args: b (list of int): list of numerator coefficients. @@ -23,7 +23,6 @@ def __init__(self, b, a, w): if a is not None: self.a = tuple(a) - self.coef_word_format = w self.n_cascades = 0 self.sigin = np.array([]) diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 857a83b..a54ba10 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -16,8 +16,8 @@ class FilterFIR(FilterHardware): filter_form_type: response(list): list of filter output in int format. """ - def __init__(self, b = None, a = None, w = (24,0,23)): - super(FilterFIR, self).__init__(b, a, w) + def __init__(self, b = None, a = None): + super(FilterFIR, self).__init__(b, a) self.filter_type = 'direct_form' self.direct_form_type = 1 self.response = [] @@ -45,7 +45,7 @@ def convert(self, **kwargs): # small top-level wrapper def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): - sigin = Samples(x.min, x.max) + sigin = Samples(x.min, x.max, self.input_word_format) sigin.data, sigin.data_valid = x, xdv sigout = Samples(y.min, y.max) sigout.data, sigout.data_valid = y, ydv @@ -88,7 +88,7 @@ def filter_block(self): #print(self.coef_word_format) ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) - xt = Samples(-ymax, ymax, self.input_word_format) + xt = Samples(min=-ymax, max=ymax, word_format=self.input_word_format) yt = Samples(-vmax, vmax) xt.valid = bool(1) clock = Clock(0, frequency=50e6) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 95e5452..3ca9033 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -27,6 +27,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): assert all(rb) w = sigin.word_format + print(sigin.word_format) ymax = 2**(w[0]-1) #vmax = 2**(2*w[0]) # double width max and min @@ -35,7 +36,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) amax = 2**(acc_bits) - #print(acc_bits) + print(acc_bits) clock, reset = glbl.clock, glbl.reset diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 7055b4a..9d9cf06 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -4,11 +4,11 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" coef = np.empty(100) - coef.fill(8388607) + coef.fill(2) hdlfilter = FilterFIR() - b = [8388607, 8388607, 1, 1, 1] + b = [23424, 2434, 1, 1, 1] hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_word_format((26, 24, 0),(28,23,0)) + hdlfilter.set_word_format((26, 24, 0),(40,23,0)) hdlfilter.set_stimulus(coef) hdlfilter.run_sim() hdlfilter.convert(hdl = 'vhdl') From 1715601b2f2a37d06721d4d8776db6cb9453fc9d Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 20 Jul 2018 02:14:25 +0800 Subject: [PATCH 23/46] output word_format now included --- filter_blocks/fda/filter_hw.py | 4 +++- filter_blocks/fda/fir.py | 11 ++++++++--- filter_blocks/fir/fir_df1.py | 15 ++++++++++++--- tests/test_fir/test_df1.py | 8 ++++---- 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index a360444..8be9824 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -67,15 +67,17 @@ def set_cascade(self, n_cascades): """ self.n_cascades = n_cascades - def set_word_format(self, coeff_w, input_w): + def set_word_format(self, coeff_w, input_w, output_w = (24,23,0)): """Set word format Args: coef_word_format (tuple of int): word format (W,WI,WF) input_word_format (tuple of int): word format (W,WI,WF) + output_word_format (tuple of int): word format (W,WI,WF) """ self.coef_word_format = coeff_w self.input_word_format = input_w + self.output_word_format = output_w def get_fixed_coefficients(self): raise NotImplementedError diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index a54ba10..0ef7155 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -41,13 +41,15 @@ def convert(self, **kwargs): """Convert the HDL description to Verilog and VHDL. """ w = self.input_word_format + w_out = self.output_word_format + omax = 2**(w_out[0]-1) imax = 2**(w[0]-1) # small top-level wrapper def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): sigin = Samples(x.min, x.max, self.input_word_format) sigin.data, sigin.data_valid = x, xdv - sigout = Samples(y.min, y.max) + sigout = Samples(y.min, y.max, self.output_word_format) sigout.data, sigout.data_valid = y, ydv clk = clock rst = reset @@ -65,7 +67,7 @@ def filter_fir_top(hdl , clock, reset, x, xdv, y, ydv): clock = Clock(0, frequency=50e6) reset = Reset(1, active=0, async=True) x = Signal(intbv(0, min=-imax, max=imax)) - y = Signal(intbv(0, min=-imax, max=imax)) + y = Signal(intbv(0, min=-omax, max=omax)) xdv, ydv = Signal(bool(0)), Signal(bool(0)) @@ -84,12 +86,15 @@ def filter_block(self): """ this elaboration code will select the different structure and implementations""" w = self.input_word_format + w_out = self.output_word_format #print(self.input_word_format) #print(self.coef_word_format) ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) + omax = 2**(w_out[0]-1) xt = Samples(min=-ymax, max=ymax, word_format=self.input_word_format) - yt = Samples(-vmax, vmax) + yt = Samples(min=-omax, max=omax, word_format=self.output_word_format) + #yt = Samples(min=-vmax, max=vmax) xt.valid = bool(1) clock = Clock(0, frequency=50e6) reset = Reset(1, active=0, async=True) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 3ca9033..a97aa1a 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -27,7 +27,11 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): assert all(rb) w = sigin.word_format - print(sigin.word_format) + w_out = sigout.word_format + + #print(sigin.word_format) + #print(sigout.word_format) + ymax = 2**(w[0]-1) #vmax = 2**(2*w[0]) # double width max and min @@ -36,9 +40,13 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) amax = 2**(acc_bits) - print(acc_bits) + + #print(acc_bits) + qd = acc_bits + q = acc_bits-w_out[0] + #print(qd-q) clock, reset = glbl.clock, glbl.reset xdv = sigin.valid y, ydv = sigout.data, sigout.valid @@ -70,7 +78,8 @@ def beh_direct_form_one(): @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv - y.next = yacc.signed() + y.next = yacc[qd:q].signed() + #y.next = yacc.signed() ydv.next = dvd return beh_direct_form_one, beh_output diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 9d9cf06..ea008ea 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -4,13 +4,13 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" coef = np.empty(100) - coef.fill(2) + coef.fill(8388607) hdlfilter = FilterFIR() - b = [23424, 2434, 1, 1, 1] + b = [8388607, 8388607, 8388607, 8388607, 8388607] hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_word_format((26, 24, 0),(40,23,0)) + hdlfilter.set_word_format((24, 23, 0),(24,23,0),(24,23,0)) hdlfilter.set_stimulus(coef) hdlfilter.run_sim() - hdlfilter.convert(hdl = 'vhdl') + hdlfilter.convert(hdl = 'VHDL') if __name__ == '__main__': main() From bee194e51cfa2cfc1290baa82a41556d68d240aa Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Tue, 24 Jul 2018 02:41:12 +0800 Subject: [PATCH 24/46] test_df1_sine added --- filter_blocks/fda/filter_hw.py | 2 + filter_blocks/fda/iir.py | 17 +++-- filter_blocks/fir/fir_df1.py | 5 +- filter_blocks/iir/iir_df1.py | 3 + tests/test_fir/test_df1_sine.py | 129 ++++++++++++++++++++++++++++++++ 5 files changed, 147 insertions(+), 9 deletions(-) create mode 100644 tests/test_fir/test_df1_sine.py diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 8be9824..8c1a0df 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -57,7 +57,9 @@ def set_stimulus(self, sigin): sigin (np array int): numpy array of filter stimulus bits (int) : no of bits """ + self.sigin = sigin.tolist() + def set_cascade(self, n_cascades): """Set number of filter cascades diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index 52bf600..af80b89 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -1,12 +1,11 @@ import myhdl as hdl import numpy as np from .filter_hw import FilterHardware -from ..fir import fir_df1 +from ..iir import iir_df1 from filter_blocks.support import Clock, Reset, Global, Samples from myhdl import Signal, intbv, StopSimulation - class FilterIIR(FilterHardware): """Contains IIR filter parameters. Parent Class : FilterHardware Args: @@ -17,8 +16,8 @@ class FilterIIR(FilterHardware): filter_form_type: response(list): list of filter output in int format. """ - def __init__(self, b = None, a = None, w = (24, 0, 23)): - super(FilterIIR, self).__init__(b, a, w) + def __init__(self, b = None, a = None): + super(FilterIIR, self).__init__(b, a) self.filter_type = 'direct_form' self.direct_form_type = 1 self.response = [] @@ -41,12 +40,14 @@ def run_sim(self): def filter_block(self): """ this elaboration code will select the different structure and implementations""" - w = self.input_word_format + w_out = self.output_word_format + ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) - xt = Samples(-ymax, ymax, self.input_word_format) - yt = Samples(-vmax, vmax) + omax = 2**(w_out[0]-1) + xt = Samples(min=-ymax, max=ymax, word_format=self.input_word_format) + yt = Samples(min=-omax, max=omax, word_format=self.output_word_format) xt.valid = bool(1) clock = Clock(0, frequency=50e6) reset = Reset(1, active=0, async=True) @@ -63,7 +64,7 @@ def filter_block(self): if self.filter_type == 'direct_form': if self.direct_form_type == 1: # all filters will need the same interface ports, this should be do able - dfilter = fir_df1.filter_fir + dfilter = iir_df1.filter_iir if self.n_cascades > 0: filter_insts = [None for _ in range(self.n_cascades)] diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index a97aa1a..a596c1a 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -1,6 +1,5 @@ import myhdl as hdl from myhdl import Signal, intbv, always_seq - from filter_blocks.support import Samples, Signals import math @@ -46,6 +45,9 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): qd = acc_bits q = acc_bits-w_out[0] + if q<0: + q=0 + #print(qd-q) clock, reset = glbl.clock, glbl.reset xdv = sigin.valid @@ -79,6 +81,7 @@ def beh_direct_form_one(): def beh_output(): dvd.next = xdv y.next = yacc[qd:q].signed() + #print(y) #y.next = yacc.signed() ydv.next = dvd diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 3e1dc71..3ea039b 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -1,6 +1,7 @@ import myhdl as hdl from myhdl import Signal, intbv, always_seq from filter_blocks.support import Samples, Signals +import math @hdl.block def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): @@ -31,6 +32,8 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): assert all(ra) w = sigin.word_format + w_out = sigout.word_format + ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) # double width max and min diff --git a/tests/test_fir/test_df1_sine.py b/tests/test_fir/test_df1_sine.py new file mode 100644 index 0000000..10a903f --- /dev/null +++ b/tests/test_fir/test_df1_sine.py @@ -0,0 +1,129 @@ +from filter_blocks.fda import FilterFIR +import numpy as np +import scipy.signal as signal +import math +import matplotlib.pyplot as plt + + + +def fixp_sine(bsc_int, B1, L1): + + N=20 + sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] + + B2 = 12 # Number of bits + L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow + + sig = np.multiply(sig, 2**L2) + sig = sig.round() + sig = sig.astype(int) + + + hdlfilter = FilterFIR() + hdlfilter.set_coefficients(coeff_b = bsc_int) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(31 , 30, 0)) + hdlfilter.set_stimulus(sig) + hdlfilter.run_sim() + y = hdlfilter.get_response() + + yout = np.divide(y,2**L1) + #hdlfilter.convert(hdl = 'VHDL') + plt.plot(yout, 'b') + plt.show() + + return yout + + +def edge(B1, L1): + + + B2 = 12 + N = 10 # number of coefficients + + max_coef = 2**(B1-1)-1 + min_coef = -2**(B1-1) + + b_max = [max_coef] * N + + max_in = 2**(B2-1)-1 + min_in = -2**(B2-1) + + coef = np.empty(100) + coef.fill(max_in) + + hdlfilter = FilterFIR() + hdlfilter.set_coefficients(coeff_b = b_max) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1, 0),(40, 39, 0)) + hdlfilter.set_stimulus(coef) + hdlfilter.run_sim() + y = hdlfilter.get_response() + + # yout = np.divide(y,2**L1) + # hdlfilter.convert(hdl = 'VHDL') + # plt.plot(yout, 'b') + # plt.show() + + return y + + +def floatp_sine(b, L1): + + x=20 + sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] + #print(sig) + + + B2 = 12 # Number of bits + L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow + #print(L) + sig = np.multiply(sig, 2**L2) + sig = sig.round() + sig = sig.astype(int) + + y = [] + N = len(b) + + for n in range(N,len(sig)): + sop = 0 + for i in range(N): + sop += sig[n-i]*b[i] + + y.append(sop) + + return y + + + + +def main(): + """Meant to emulate how pyfda will pass parameters to filters""" + + fs = 1000. + f1 = 45. + f2 = 95. + b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps + + #convert floating point to fixed point + + B1 = 18 # Number of bits + L1 = math.floor(math.log((2**(B1-1)-1)/max(b), 2)) # Round towards zero to avoid overflow + bsc = b*(2**L1) + bsc_int = [int(x) for x in bsc] + + + y1 = fixp_sine(bsc_int, B1, L1) + y2 = floatp_sine(b, L1) + #y = edge(B1, L1) + + + y1 = y1[6:19] #hardcoded presently. Needs to be + y2 = y2[:13] + + print(y1) + print(y2) + print( ((y1 - y2) ** 2).mean(axis=None)) + + + +if __name__ == '__main__': + main() \ No newline at end of file From 20add4d2a5850e454764942787bceaae5c76a9ca Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Thu, 26 Jul 2018 01:48:48 +0800 Subject: [PATCH 25/46] fixed accumulator length for df1_fir filter and completed implementation df1_iir with tests --- filter_blocks/fda/iir.py | 43 ++++++++ filter_blocks/fir/fir_df1.py | 9 +- filter_blocks/iir/iir_df1.py | 24 +++-- tests/test_fir/test_df1_sine.py | 2 +- tests/test_iir/test_iir_df1.py | 14 +-- tests/test_iir/test_iir_df1_sine.py | 148 ++++++++++++++++++++++++++++ 6 files changed, 224 insertions(+), 16 deletions(-) create mode 100644 tests/test_iir/test_iir_df1_sine.py diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index af80b89..bec163b 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -34,8 +34,51 @@ def run_sim(self): """Run filter simulation""" testfil = self.filter_block() + testfil.config_sim(trace=True) testfil.run_sim() + def convert(self, **kwargs): + """Convert the HDL description to Verilog and VHDL. + """ + w = self.input_word_format + w_out = self.output_word_format + omax = 2**(w_out[0]-1) + imax = 2**(w[0]-1) + + # small top-level wrapper + def filter_iir_top(hdl , clock, reset, x, xdv, y, ydv): + sigin = Samples(x.min, x.max, self.input_word_format) + sigin.data, sigin.data_valid = x, xdv + sigout = Samples(y.min, y.max, self.output_word_format) + sigout.data, sigout.data_valid = y, ydv + clk = clock + rst = reset + glbl = Global(clk, rst) + + #choose appropriate filter + iir_hdl = iir_df1.filter_iir + + iir = iir_hdl(glbl, sigin, sigout, self.b, self.a, self.coef_word_format, + shared_multiplier=self._shared_multiplier) + + iir.convert(**kwargs) + + + clock = Clock(0, frequency=50e6) + reset = Reset(1, active=0, async=True) + x = Signal(intbv(0, min=-imax, max=imax)) + y = Signal(intbv(0, min=-omax, max=omax)) + xdv, ydv = Signal(bool(0)), Signal(bool(0)) + + + if self.hdl_target.lower() == 'verilog': + filter_iir_top(hdl, clock, reset, x, xdv, y, ydv) + + elif self.hdl_target.lower() == 'vhdl': + filter_iir_top(hdl, clock, reset, x, xdv, y, ydv) + else: + raise ValueError('incorrect target HDL {}'.format(self.hdl_target)) + @hdl.block def filter_block(self): """ this elaboration code will select the different structure and implementations""" diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index a596c1a..3097347 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -29,7 +29,8 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): w_out = sigout.word_format #print(sigin.word_format) - #print(sigout.word_format) + print(sigout.word_format) + ymax = 2**(w[0]-1) #vmax = 2**(2*w[0]) # double width max and min @@ -37,7 +38,11 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): N = len(b)-1 - acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) + sum_abs_b = (sum([abs(x) for x in b]))/2**coef_w[0] + #acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) + #print(w[0] + coef_w[0] + int(math.log(N, 2))) + print(w[0] + coef_w[0] + int(math.log(sum_abs_b, 2))) + acc_bits = w[0] + coef_w[0] + int(math.log(sum_abs_b, 2)) amax = 2**(acc_bits) #print(acc_bits) diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 3ea039b..ea0f3ec 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -24,6 +24,8 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): assert isinstance(sigout, Samples) assert isinstance(b, tuple) assert isinstance(a, tuple) + + # All the coefficients need to be an `int` rb = [isinstance(bb, int) for bb in b] @@ -37,6 +39,14 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) # double width max and min + q, qd = w[0], 2*w[0] + + od = 2*w[0] + o = 2*w[0]-w_out[0] + + if o<0: + o=0 + N = len(b)-1 clock, reset = glbl.clock, glbl.reset @@ -45,8 +55,8 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): x = Signal(intbv(0, min=-ymax, max=ymax)) # Delay elements, list-of-signals - ffd = Signals(intbv(0, min=-ymax, max=ymax), N) - fbd = Signals(intbv(0, min=-ymax, max=ymax), N) + ffd = Signals(intbv(0, min=-ymax, max=vmax), N) + fbd = Signals(intbv(0, min=-ymax, max=vmax), N) yacc = Signal(intbv(0, min=-vmax, max=vmax)) #verify the length of this dvd = Signal(bool(0)) @@ -60,22 +70,24 @@ def beh_direct_form_one(): fbd[i+1].next = fbd[i] ffd[0].next = x - fbd[0].next = yacc.signed() + fbd[0].next = yacc[qd:q].signed() # sum-of-products loop c = b[0] sop = x*c for ii in range(N): c = b[ii+1] #first element in list in b0 - d = a[ii] #first element in list is a1 + d = a[ii+1] #first element in list is a1 sop = sop + (c * ffd[ii]) - (d * fbd[ii]) yacc.next = sop - print(yacc) + #print(yacc) @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv - y.next = yacc.signed() + y.next = yacc[od:o].signed() + #y.next = yacc.signed() + #print(y) ydv.next = dvd return beh_direct_form_one, beh_output diff --git a/tests/test_fir/test_df1_sine.py b/tests/test_fir/test_df1_sine.py index 10a903f..c47256b 100644 --- a/tests/test_fir/test_df1_sine.py +++ b/tests/test_fir/test_df1_sine.py @@ -21,7 +21,7 @@ def fixp_sine(bsc_int, B1, L1): hdlfilter = FilterFIR() hdlfilter.set_coefficients(coeff_b = bsc_int) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(31 , 30, 0)) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(1000 , 999, 0)) hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index a5c6c26..62e4330 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -3,15 +3,15 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" - coef = np.empty(100) - coef.fill(2) + stim = np.empty(15) + stim.fill(1) hdlfilter = FilterIIR() - b = [8388607, 8388607, 1, 1, 1] - a = [1,2,1,1,1] - hdlfilter.set_word_format((24, 23, 0)) + b = [1, 2, 1] + a = [1,2,1] hdlfilter.set_coefficients(coeff_b = b, coeff_a = a) - hdlfilter.set_stimulus(coef, (24,23,0)) + hdlfilter.set_word_format((24, 23, 0),(24,23,0),(54,53,0)) + hdlfilter.set_stimulus(stim) hdlfilter.run_sim() - #hdlfilter.convert() + hdlfilter.convert(hdl = 'verilog') if __name__ == '__main__': main() diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py new file mode 100644 index 0000000..a1cb80d --- /dev/null +++ b/tests/test_iir/test_iir_df1_sine.py @@ -0,0 +1,148 @@ +from filter_blocks.fda import FilterIIR +import numpy as np +import scipy.signal as signal +import math +import matplotlib.pyplot as plt + + + +def fixp_sine(bsc_int, asc_int, B1, L1): + + N=20 + sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] + + B2 = 12 # Number of bits + L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow + + sig = np.multiply(sig, 2**L2) + sig = sig.round() + sig = sig.astype(int) + print(sig) + + + hdlfilter = FilterIIR() + hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a= asc_int) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(1000 , 999 , 0)) + hdlfilter.set_stimulus(sig) + hdlfilter.run_sim() + y = hdlfilter.get_response() + + yout = np.divide(y,2**B1) + print(yout) + #hdlfilter.convert(hdl = 'VHDL') + plt.plot(yout, 'b') + plt.show() + + return yout + + +def edge(B1, L1): + + + B2 = 12 + N = 10 # number of coefficients + + max_coef = 2**(B1-1)-1 + min_coef = -2**(B1-1) + + b_max = [max_coef] * N + + max_in = 2**(B2-1)-1 + min_in = -2**(B2-1) + + coef = np.empty(100) + coef.fill(max_in) + + hdlfilter = FilterFIR() + hdlfilter.set_coefficients(coeff_b = b_max) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1, 0),(40, 39, 0)) + hdlfilter.set_stimulus(coef) + hdlfilter.run_sim() + y = hdlfilter.get_response() + + # yout = np.divide(y,2**L1) + # hdlfilter.convert(hdl = 'VHDL') + # plt.plot(yout, 'b') + # plt.show() + + return y + + +def floatp_sine(b, a, B1, L1): + + x=20 + sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] + #print(sig) + + + B2 = 12 # Number of bits + L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow + #print(L) + sig = np.multiply(sig, 2**L2) + sig = sig.round() + sig = sig.astype(int) + + y = [] + w = [] + N = len(b) + + for n in range(N,len(sig)): + sop = 0 + for i in range(N): + sop = sop + sig[n-i]*b[i] + w.append(sop) + + for n in range(N,len(sig)): + sop = 0 + for i in range(N): + sop = w[n] - w[n-i]*a[i] + w.append(sop) + + return y + + + + +def main(): + """Meant to emulate how pyfda will pass parameters to filters""" + + # fs = 1000. + # f1 = 45. + # f2 = 95. + # b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps + b, a = signal.iirfilter(3, [0.4, 0.7], rs=60, btype='band', ftype='cheby2') + # print(len(b)) + # print(len(a)) + # print(b) + # print(a) + + #print(max([max(b),max(a)])) + #convert floating point to fixed point + + B1 = 12 # Number of bits + L1 = math.floor(math.log((2**(B1-1)-1)/max([max(b),max(a)]), 2)) # Round towards zero to avoid overflow + bsc = b*(2**B1) + asc = a*(2**B1) + bsc_int = [int(x) for x in bsc] + asc_int = [int(x) for x in asc] + print(bsc_int) + print(asc_int) + + y1 = fixp_sine(bsc_int, asc_int, B1, L1) + #print(y1/2**B1) + y2 = floatp_sine(b, a, B1, L1) + #y = edge(B1, L1) + + #print(y1) + #print(y2) + y1 = y1[6:19] #hardcoded presently. Needs to be + y2 = y2[:13] + + #print(y1) + #print(y2) + #print( ((y1 - y2) ** 2).mean(axis=None)) + + + +if __name__ == '__main__': + main() \ No newline at end of file From c25ed41d63f8b1a39c32acdf52a8ea0924931629 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Thu, 26 Jul 2018 01:55:23 +0800 Subject: [PATCH 26/46] stop creating trace file --- filter_blocks/fda/iir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index bec163b..8de68b0 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -34,7 +34,7 @@ def run_sim(self): """Run filter simulation""" testfil = self.filter_block() - testfil.config_sim(trace=True) + #testfil.config_sim(trace=True) testfil.run_sim() def convert(self, **kwargs): From 6152eb7ea6f9c64e3b7424c1e87b65bd20af1768 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Thu, 26 Jul 2018 02:08:44 +0800 Subject: [PATCH 27/46] fixing ffd convert bit-length --- filter_blocks/iir/iir_df1.py | 4 ++-- tests/test_fir/test_df1_sine.py | 6 +++--- tests/test_iir/test_iir_df1_sine.py | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index ea0f3ec..3a964cb 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -55,8 +55,8 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): x = Signal(intbv(0, min=-ymax, max=ymax)) # Delay elements, list-of-signals - ffd = Signals(intbv(0, min=-ymax, max=vmax), N) - fbd = Signals(intbv(0, min=-ymax, max=vmax), N) + ffd = Signals(intbv(0, min=-ymax, max=ymax), N) + fbd = Signals(intbv(0, min=-ymax, max=ymax), N) yacc = Signal(intbv(0, min=-vmax, max=vmax)) #verify the length of this dvd = Signal(bool(0)) diff --git a/tests/test_fir/test_df1_sine.py b/tests/test_fir/test_df1_sine.py index c47256b..d964b56 100644 --- a/tests/test_fir/test_df1_sine.py +++ b/tests/test_fir/test_df1_sine.py @@ -21,7 +21,7 @@ def fixp_sine(bsc_int, B1, L1): hdlfilter = FilterFIR() hdlfilter.set_coefficients(coeff_b = bsc_int) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(1000 , 999, 0)) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(31 , 30, 0)) hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() @@ -59,14 +59,14 @@ def edge(B1, L1): y = hdlfilter.get_response() # yout = np.divide(y,2**L1) - # hdlfilter.convert(hdl = 'VHDL') + hdlfilter.convert(hdl = 'verilog') # plt.plot(yout, 'b') # plt.show() return y -def floatp_sine(b, L1): +def floatp(b, L1): x=20 sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py index a1cb80d..ee7dd61 100644 --- a/tests/test_iir/test_iir_df1_sine.py +++ b/tests/test_iir/test_iir_df1_sine.py @@ -29,7 +29,7 @@ def fixp_sine(bsc_int, asc_int, B1, L1): yout = np.divide(y,2**B1) print(yout) - #hdlfilter.convert(hdl = 'VHDL') + hdlfilter.convert(hdl = 'verilog') plt.plot(yout, 'b') plt.show() From d7019025878d39421134d869d32f8b9859773416 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Thu, 26 Jul 2018 17:54:03 +0800 Subject: [PATCH 28/46] fixed accumulator bits for fir_df1 implementation --- filter_blocks/fir/fir_df1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 3097347..d68a959 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -38,7 +38,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): N = len(b)-1 - sum_abs_b = (sum([abs(x) for x in b]))/2**coef_w[0] + sum_abs_b = (sum([abs(x) for x in b]))/2.**(coef_w[0]-1) #acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) #print(w[0] + coef_w[0] + int(math.log(N, 2))) print(w[0] + coef_w[0] + int(math.log(sum_abs_b, 2))) From 8338a8ff71eda501655bae59c024544311335de0 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Thu, 26 Jul 2018 17:56:27 +0800 Subject: [PATCH 29/46] fixes to test_df1_sine --- tests/test_fir/test_df1_sine.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_fir/test_df1_sine.py b/tests/test_fir/test_df1_sine.py index d964b56..1423075 100644 --- a/tests/test_fir/test_df1_sine.py +++ b/tests/test_fir/test_df1_sine.py @@ -59,14 +59,14 @@ def edge(B1, L1): y = hdlfilter.get_response() # yout = np.divide(y,2**L1) - hdlfilter.convert(hdl = 'verilog') + hdlfilter.convert(hdl = 'verilog') # plt.plot(yout, 'b') # plt.show() return y -def floatp(b, L1): +def floatp_sine(b, L1): x=20 sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] From ac6cf819c764d35e66fd60e1ee9bc4a7c91eae5e Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 27 Jul 2018 13:42:48 +0800 Subject: [PATCH 30/46] saturation logic added to iir_df1 and fixes to fir_df1 --- filter_blocks/fir/fir_df1.py | 14 +++++++++----- filter_blocks/iir/iir_df1.py | 28 ++++++++++++++++++++-------- tests/test_fir/test_df1.py | 2 +- tests/test_fir/test_df1_sine.py | 2 +- tests/test_iir/test_iir_df1.py | 10 ++++++++-- tests/test_iir/test_iir_df1_sine.py | 2 +- 6 files changed, 40 insertions(+), 18 deletions(-) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index d68a959..9875203 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -29,7 +29,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): w_out = sigout.word_format #print(sigin.word_format) - print(sigout.word_format) + #print(sigout.word_format) ymax = 2**(w[0]-1) @@ -41,19 +41,23 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): sum_abs_b = (sum([abs(x) for x in b]))/2.**(coef_w[0]-1) #acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) #print(w[0] + coef_w[0] + int(math.log(N, 2))) - print(w[0] + coef_w[0] + int(math.log(sum_abs_b, 2))) - acc_bits = w[0] + coef_w[0] + int(math.log(sum_abs_b, 2)) - amax = 2**(acc_bits) + #print(w[0] + coef_w[0] + int(math.log(sum_abs_b, 2))) + print(w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2))) + acc_bits = w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2)) + amax = 2**(acc_bits-1) #print(acc_bits) qd = acc_bits q = acc_bits-w_out[0] + print(qd) + print(q) + if q<0: q=0 - #print(qd-q) + print(qd-q) clock, reset = glbl.clock, glbl.reset xdv = sigin.valid y, ydv = sigout.data, sigout.valid diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 3a964cb..659b9b9 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -37,12 +37,13 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): w_out = sigout.word_format ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) # double width max and min + vmax = 2**(2*w[0]) # top bit is guard bit - q, qd = w[0], 2*w[0] + q, qd = w[0], 2*w[0] #guard bit not fed back - od = 2*w[0] - o = 2*w[0]-w_out[0] + o, od = 2*w[0]-w_out[0], 2*w[0] # guard bit not passed to output + + print("od-o",od-o) if o<0: o=0 @@ -59,6 +60,7 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): fbd = Signals(intbv(0, min=-ymax, max=ymax), N) yacc = Signal(intbv(0, min=-vmax, max=vmax)) #verify the length of this dvd = Signal(bool(0)) + print(len(yacc)) @hdl.always(clock.posedge) def beh_direct_form_one(): @@ -79,15 +81,25 @@ def beh_direct_form_one(): c = b[ii+1] #first element in list in b0 d = a[ii+1] #first element in list is a1 sop = sop + (c * ffd[ii]) - (d * fbd[ii]) - yacc.next = sop - #print(yacc) + #yacc.next = sop # from the earlier implementation without saturation + + if (yacc[qd]==1 and yacc[qd-1]==1) or (yacc[qd]==0 and yacc[qd-1]==0): + yacc.next = sop + elif yacc[qd]==1 and yacc[qd-1]==0: + print('underflow') + yacc.next = yacc.min + elif yacc[qd]==0 and yacc[qd-1]==1: + print('overflow') + yacc.next = yacc.max-1 + + #print("yacc" , yacc) @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv - y.next = yacc[od:o].signed() + y.next = yacc[od+1:o].signed() #without the +1 to od the saturation doesn't work. rest unaafected #y.next = yacc.signed() - #print(y) + #print("y" , y) ydv.next = dvd return beh_direct_form_one, beh_output diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index ea008ea..86436a6 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -8,7 +8,7 @@ def main(): hdlfilter = FilterFIR() b = [8388607, 8388607, 8388607, 8388607, 8388607] hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_word_format((24, 23, 0),(24,23,0),(24,23,0)) + hdlfilter.set_word_format((24, 23, 0),(24,23,0),(50,23,0)) hdlfilter.set_stimulus(coef) hdlfilter.run_sim() hdlfilter.convert(hdl = 'VHDL') diff --git a/tests/test_fir/test_df1_sine.py b/tests/test_fir/test_df1_sine.py index 1423075..24dad21 100644 --- a/tests/test_fir/test_df1_sine.py +++ b/tests/test_fir/test_df1_sine.py @@ -21,7 +21,7 @@ def fixp_sine(bsc_int, B1, L1): hdlfilter = FilterFIR() hdlfilter.set_coefficients(coeff_b = bsc_int) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(31 , 30, 0)) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(17 , 30, 0)) hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index 62e4330..6b9ca4b 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -1,17 +1,23 @@ from filter_blocks.fda import FilterIIR import numpy as np +import matplotlib.pyplot as plt def main(): """Meant to emulate how pyfda will pass parameters to filters""" stim = np.empty(15) - stim.fill(1) + stim.fill(-8388607) hdlfilter = FilterIIR() - b = [1, 2, 1] + b = [8388607, 8388607, 8388607] a = [1,2,1] hdlfilter.set_coefficients(coeff_b = b, coeff_a = a) hdlfilter.set_word_format((24, 23, 0),(24,23,0),(54,53,0)) hdlfilter.set_stimulus(stim) hdlfilter.run_sim() hdlfilter.convert(hdl = 'verilog') + y = hdlfilter.get_response() + print(y) + hdlfilter.convert(hdl = 'verilog') + plt.plot(y, 'b') + plt.show() if __name__ == '__main__': main() diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py index ee7dd61..afb8fc4 100644 --- a/tests/test_iir/test_iir_df1_sine.py +++ b/tests/test_iir/test_iir_df1_sine.py @@ -22,7 +22,7 @@ def fixp_sine(bsc_int, asc_int, B1, L1): hdlfilter = FilterIIR() hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a= asc_int) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(1000 , 999 , 0)) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(10 , 999 , 0)) hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() From 2cf8b0f4ead95bf0daee9c66ce7d6b1b69205c2b Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sat, 28 Jul 2018 12:48:53 +0800 Subject: [PATCH 31/46] iir_df1 with saturatoin --- filter_blocks/iir/iir_df1.py | 59 ++++++++++++++++++++++++++-------- tests/test_fir/test_firs.py | 1 + tests/test_iir/test_iir_df1.py | 2 +- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 659b9b9..96cf046 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -38,12 +38,14 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): ymax = 2**(w[0]-1) vmax = 2**(2*w[0]) # top bit is guard bit + amax = 2**(2*w[0]-1) #max without guard bit. Value at which output will saturate + #print(2**(2*w[0]-1)) q, qd = w[0], 2*w[0] #guard bit not fed back o, od = 2*w[0]-w_out[0], 2*w[0] # guard bit not passed to output - print("od-o",od-o) + #print("od-o",od-o) if o<0: o=0 @@ -60,7 +62,9 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): fbd = Signals(intbv(0, min=-ymax, max=ymax), N) yacc = Signal(intbv(0, min=-vmax, max=vmax)) #verify the length of this dvd = Signal(bool(0)) - print(len(yacc)) + overflow = Signal(bool(0)) + underflow = Signal(bool(0)) + #print(len(yacc)) @hdl.always(clock.posedge) def beh_direct_form_one(): @@ -82,24 +86,53 @@ def beh_direct_form_one(): d = a[ii+1] #first element in list is a1 sop = sop + (c * ffd[ii]) - (d * fbd[ii]) #yacc.next = sop # from the earlier implementation without saturation - if (yacc[qd]==1 and yacc[qd-1]==1) or (yacc[qd]==0 and yacc[qd-1]==0): yacc.next = sop - elif yacc[qd]==1 and yacc[qd-1]==0: - print('underflow') - yacc.next = yacc.min + + elif yacc[qd+1]==1 and yacc[qd]==0: + #print('underflow') # and change y as well + yacc.next == -amax + elif yacc[qd]==0 and yacc[qd-1]==1: - print('overflow') - yacc.next = yacc.max-1 + #print('overflow') + yacc.next == amax-1 + + print("yacc" , yacc) + - #print("yacc" , yacc) + @hdl.always_comb + def beh_acc(): + + if (yacc[qd]==1 and yacc[qd-1]==1) or (yacc[qd]==0 and yacc[qd-1]==0): + #y.next = yacc[od+1:o].signed() + #ydv.next = dvd + pass + elif yacc[qd+1]==1 and yacc[qd]==0: + #print('underflow2') # and change y as well + underflow.next = bool(1) + + elif yacc[qd]==0 and yacc[qd-1]==1: + #print('overflow2') + overflow.next = bool(1) + + #print("yacc" , yacc) @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv - y.next = yacc[od+1:o].signed() #without the +1 to od the saturation doesn't work. rest unaafected - #y.next = yacc.signed() + if overflow == 1 : + y.next = amax-1 + ydv.next = dvd + overflow.next == bool(0) + elif underflow == 1: + y.next = -amax + ydv.next = dvd + underflow.next == bool(0) + else: + y.next = yacc[od:o].signed() + y.next = yacc.signed() + ydv.next = dvd + #print("y" , y) - ydv.next = dvd - return beh_direct_form_one, beh_output + return hdl.instances() diff --git a/tests/test_fir/test_firs.py b/tests/test_fir/test_firs.py index 65a3f45..75c218f 100644 --- a/tests/test_fir/test_firs.py +++ b/tests/test_fir/test_firs.py @@ -80,6 +80,7 @@ def tbstim(): for sr in rlist: sr.record = False + yield delay(1100) raise hdl.StopSimulation diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index 6b9ca4b..08749d9 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -5,7 +5,7 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" stim = np.empty(15) - stim.fill(-8388607) + stim.fill(8388607) hdlfilter = FilterIIR() b = [8388607, 8388607, 8388607] a = [1,2,1] From aacc08790c51b9177a0af90985307eaa8671ac1b Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Tue, 31 Jul 2018 20:20:19 +0800 Subject: [PATCH 32/46] overflow fix to output --- filter_blocks/iir/iir_df1.py | 2 +- tests/test_iir/test_iir_df1.py | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 96cf046..b304627 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -130,7 +130,7 @@ def beh_output(): underflow.next == bool(0) else: y.next = yacc[od:o].signed() - y.next = yacc.signed() + #y.next = yacc.signed() ydv.next = dvd #print("y" , y) diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index 08749d9..e2a8290 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -5,12 +5,12 @@ def main(): """Meant to emulate how pyfda will pass parameters to filters""" stim = np.empty(15) - stim.fill(8388607) + stim.fill(32767) hdlfilter = FilterIIR() - b = [8388607, 8388607, 8388607] - a = [1,2,1] + b = [1287, 5148, 7722, 5148, 1287] + a = [1, -22954, 14021, -3702, 459] hdlfilter.set_coefficients(coeff_b = b, coeff_a = a) - hdlfilter.set_word_format((24, 23, 0),(24,23,0),(54,53,0)) + hdlfilter.set_word_format((16, 23, 0),(16,23,0),(26,53,0)) hdlfilter.set_stimulus(stim) hdlfilter.run_sim() hdlfilter.convert(hdl = 'verilog') From 7fb6914e586f2429e966f038fe09b09fe4f08944 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Wed, 1 Aug 2018 16:04:55 +0800 Subject: [PATCH 33/46] Jupyter notebook with examples --- docs/Notebooks/Documentation.ipynb | 158 +++++++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 docs/Notebooks/Documentation.ipynb diff --git a/docs/Notebooks/Documentation.ipynb b/docs/Notebooks/Documentation.ipynb new file mode 100644 index 0000000..d6dda87 --- /dev/null +++ b/docs/Notebooks/Documentation.ipynb @@ -0,0 +1,158 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Introduction\n", + "Filter-blocks repository contains a collection of hardware digital filter implementations coded with myhdl.\n", + "\n", + "### Installation\n", + "insert installation steps here\n", + "\n", + "### object oriented API\n", + "An API has been built for the filter-blocks package which allows easy access to the filter implementations. It also helps set parameters required by serving as a wrapper around MyHDL methods. \n", + "\n", + "### filter implementations \n", + "\n", + "The filter implementations that presently exist in the filter blocks package:\n", + "\n", + "- fir filters\n", + " - direct form I fir filter\n", + " - cascaded second order sections \n", + "- iir filters\n", + " - direct form I iir filter \n", + " - cascaded \n", + " - parallel \n", + "\n", + "### class hierarchy\n", + "insert class hierarchy figure here\n", + "\n", + "A visual representation of all the methods and attributes which can be set/modified according to requirements. " + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Create FIR filter with integer coefficients\n", + "Here is an example of how you can create a filter with integer coefficients. In this example, scipy library is used to generate floating point filter coefficients which are then converted to integers.\n", + "#### Create filter coefficients\n", + "\n", + "```python \n", + "import scipy.signal as signal\n", + "\n", + "fs = 1000.\n", + "f1 = 45.\n", + "f2 = 95.\n", + "b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps\n", + "```\n", + "Next, we need to convert the coefficients to integers for which they will need to be scaled. For this example we assume, the coefficients are scaled to 18 bits. The exponent of the scale factor is determined as follows:\n", + "\n", + "```python\n", + "B1 = 18 # Number of bits for coefficients\n", + "L1 = math.floor(math.log((2**(B1-1)-1)/max(b), 2)) #Scale factor exponent\n", + "bsc = b*(2**L1) #scaled coefficients\n", + "bsc_int = [int(x) for x in bsc] #convert coefficient to type int\n", + "```\n", + "#### Build the FIR Filter\n", + "``` python \n", + "from filter_blocks.fda import FilterFIR\n", + "hdlfilter = FilterFIR()\n", + "```\n", + "#### Set the Filter Parameters to Work with Integers\n", + "Next, we set the input parameters of the filter to appropriate values.\n", + "\n", + "```python \n", + "hdlfilter.set_word_format(coeff_w = (18, 17, 0), input_w = (12,11,0), output_w = (24,23,0))\n", + "```\n", + "Args:
\n", + "coeff_w (tuple of int): word format (W,WI,WF)
\n", + "input_w (tuple of int): word format (W,WI,WF)
\n", + "output_w (tuple of int): word format (W,WI,WF)
\n", + "Where WI is the number of integer bits, WF is the number of fractional bit and W = WI+WF+1 (extra 1 for the sign bit). It is important to set the coefficient bits to 18, as this was used to calculate the scaling factor. In this example we are assuming that the input signal is of 12 bits and the output is set to 24 bits. \n", + "\n", + "Next, we pass the filter coefficients as determined earlier.\n", + "```python\n", + "hdlfilter.set_coefficients(coeff_b = bsc_int)\n", + "\n", + "```\n", + "\n", + "\n", + "#### Create a Stimulus for the Filter\n", + "We generate an input signal (stimulus) for the filter by following the same steps that were used for the coefficients, discussed previously. In this example, create a signal which is a sine wave:\n", + "\n", + "```python \n", + "import numpy as np\n", + "\n", + "N=20 #length of input signal\n", + "sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)]\n", + "\n", + "B2 = 12 # Number of bits\n", + "L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # calculate scaling factor\n", + "\n", + "sig = np.multiply(sig, 2**L2) \n", + "sig = sig.round()\n", + "sig = sig.astype(int)\n", + "\n", + "hdlfilter.set_stimulus(sig) #pass the stimulus to the filter object\n", + "\n", + "```\n", + "\n", + "#### Run the simulation\n", + "\n", + "To filter the input signal generated above, we need to run a simulation and obtain the output signal. Enter the following:\n", + "\n", + "```python \n", + "hdlfilter.run_sim()\n", + "y = hdlfilter.get_response()\n", + "\n", + "```\n", + "Filter-blocks returns a numpy array of the output which is stored in 'y'. Here y is a 24 bits as was set earlier, meaning that some bits might have possibly been discarded to fit the output. The most significant 24 bits from the accumulator are assigned to y.\n", + "\n", + "\n", + "#### Converting design to Verilog or VHDL\n", + "```python \n", + "hdlfilter.convert(hdl = 'VHDL')\n", + "```\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.6.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} From 9638668b25dae122e617f38577971b87af3837b5 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Wed, 1 Aug 2018 16:08:16 +0800 Subject: [PATCH 34/46] -1 to accumulator bits --- filter_blocks/fir/fir_df1.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 9875203..7bb2767 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -43,7 +43,7 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): #print(w[0] + coef_w[0] + int(math.log(N, 2))) #print(w[0] + coef_w[0] + int(math.log(sum_abs_b, 2))) print(w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2))) - acc_bits = w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2)) + acc_bits = w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2)) -1 amax = 2**(acc_bits-1) #print(acc_bits) From 1991d82ae06dd58f57774e5acc800b78241363da Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sun, 5 Aug 2018 05:22:44 +0800 Subject: [PATCH 35/46] fixes to iir df1 --- filter_blocks/fda/iir.py | 10 +--- filter_blocks/iir/iir_df1.py | 71 +++++++++-------------- tests/test_fir/test_df1.py | 2 +- tests/test_iir/test_iir_df1_sine.py | 90 +++++++++++------------------ 4 files changed, 63 insertions(+), 110 deletions(-) diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index 8de68b0..c8c9f85 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -110,12 +110,8 @@ def filter_block(self): dfilter = iir_df1.filter_iir if self.n_cascades > 0: - filter_insts = [None for _ in range(self.n_cascades)] - for ii in range(self.n_cascades): - pass - # filter_insts[ii] = fir_df1.filter_fir( - # glbl, sigin[ii], sigout[ii], b - # ) + filter_insts = iir_sos.filter_iir_sos(glbl, xt, yt, self.b, self.a, self.coef_word_format) + else: filter_insts = dfilter(glbl, xt, yt, self.b, self.a, self.coef_word_format) @@ -136,7 +132,7 @@ def stimulus(): yt.record = False yt.valid = False - print(yt.sample_buffer) + #print(yt.sample_buffer) self.response = yt.sample_buffer # pl.plot(yt.sample_buffer) # pl.show() diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index b304627..6143af7 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -55,21 +55,22 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): clock, reset = glbl.clock, glbl.reset xdv = sigin.valid y, ydv = sigout.data, sigout.valid - x = Signal(intbv(0, min=-ymax, max=ymax)) + x, xdv = sigin.data, sigin.valid - # Delay elements, list-of-signals + #Delay elements, list-of-signals ffd = Signals(intbv(0, min=-ymax, max=ymax), N) fbd = Signals(intbv(0, min=-ymax, max=ymax), N) yacc = Signal(intbv(0, min=-vmax, max=vmax)) #verify the length of this + + dvd = Signal(bool(0)) - overflow = Signal(bool(0)) - underflow = Signal(bool(0)) + #print(len(yacc)) @hdl.always(clock.posedge) def beh_direct_form_one(): if sigin.valid: - x.next = sigin.data + #print(x) for i in range(N-1): ffd[i+1].next = ffd[i] @@ -77,60 +78,40 @@ def beh_direct_form_one(): ffd[0].next = x fbd[0].next = yacc[qd:q].signed() - # sum-of-products loop - c = b[0] - sop = x*c - - for ii in range(N): - c = b[ii+1] #first element in list in b0 - d = a[ii+1] #first element in list is a1 - sop = sop + (c * ffd[ii]) - (d * fbd[ii]) - #yacc.next = sop # from the earlier implementation without saturation - if (yacc[qd]==1 and yacc[qd-1]==1) or (yacc[qd]==0 and yacc[qd-1]==0): - yacc.next = sop - - elif yacc[qd+1]==1 and yacc[qd]==0: - #print('underflow') # and change y as well - yacc.next == -amax - - elif yacc[qd]==0 and yacc[qd-1]==1: - #print('overflow') - yacc.next == amax-1 - - print("yacc" , yacc) @hdl.always_comb def beh_acc(): + c = b[0] + sop = x*c - if (yacc[qd]==1 and yacc[qd-1]==1) or (yacc[qd]==0 and yacc[qd-1]==0): - #y.next = yacc[od+1:o].signed() - #ydv.next = dvd - pass - elif yacc[qd+1]==1 and yacc[qd]==0: - #print('underflow2') # and change y as well - underflow.next = bool(1) + for ii in range(N): + c = b[ii+1] #first element in list in b0 + d = a[ii+1] #first element in list is a0 =1 + sop = sop + (c * ffd[ii]) - (d * fbd[ii]) - elif yacc[qd]==0 and yacc[qd-1]==1: - #print('overflow2') - overflow.next = bool(1) + yacc.next = sop - #print("yacc" , yacc) @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv - if overflow == 1 : - y.next = amax-1 + #y.next = yacc[od:o].signed() + + + if (yacc[qd]==1 and yacc[qd-1]==1) or (yacc[qd]==0 and yacc[qd-1]==0): ydv.next = dvd - overflow.next == bool(0) - elif underflow == 1: + y.next = yacc[od:o].signed() + + elif yacc[qd+1]==1 and yacc[qd]==0: + #print('underflow2') y.next = -amax ydv.next = dvd - underflow.next == bool(0) - else: - y.next = yacc[od:o].signed() - #y.next = yacc.signed() + + + elif yacc[qd]==0 and yacc[qd-1]==1: + #print('overflow2') + y.next = amax-1 ydv.next = dvd #print("y" , y) diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index 86436a6..b524c1a 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -8,7 +8,7 @@ def main(): hdlfilter = FilterFIR() b = [8388607, 8388607, 8388607, 8388607, 8388607] hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_word_format((24, 23, 0),(24,23,0),(50,23,0)) + hdlfilter.set_word_format(coeff_w = (24, 23, 0), input_w = (24,23,0), output_w = (50,23,0)) hdlfilter.set_stimulus(coef) hdlfilter.run_sim() hdlfilter.convert(hdl = 'VHDL') diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py index afb8fc4..9055692 100644 --- a/tests/test_iir/test_iir_df1_sine.py +++ b/tests/test_iir/test_iir_df1_sine.py @@ -8,8 +8,10 @@ def fixp_sine(bsc_int, asc_int, B1, L1): - N=20 - sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] + # N=20 + # sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] + + sig = signal.unit_impulse(20) B2 = 12 # Number of bits L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow @@ -22,56 +24,26 @@ def fixp_sine(bsc_int, asc_int, B1, L1): hdlfilter = FilterIIR() hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a= asc_int) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(10 , 999 , 0)) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(1000 , 39 , 0)) hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() yout = np.divide(y,2**B1) print(yout) - hdlfilter.convert(hdl = 'verilog') - plt.plot(yout, 'b') - plt.show() + #hdlfilter.convert(hdl = 'verilog') + #plt.plot(yout, 'b') + #plt.show() return yout -def edge(B1, L1): - - - B2 = 12 - N = 10 # number of coefficients - - max_coef = 2**(B1-1)-1 - min_coef = -2**(B1-1) - - b_max = [max_coef] * N - - max_in = 2**(B2-1)-1 - min_in = -2**(B2-1) - - coef = np.empty(100) - coef.fill(max_in) - - hdlfilter = FilterFIR() - hdlfilter.set_coefficients(coeff_b = b_max) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1, 0),(40, 39, 0)) - hdlfilter.set_stimulus(coef) - hdlfilter.run_sim() - y = hdlfilter.get_response() - - # yout = np.divide(y,2**L1) - # hdlfilter.convert(hdl = 'VHDL') - # plt.plot(yout, 'b') - # plt.show() - - return y def floatp_sine(b, a, B1, L1): - x=20 - sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] + #sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] + sig = signal.unit_impulse(10) #print(sig) @@ -82,23 +54,11 @@ def floatp_sine(b, a, B1, L1): sig = sig.round() sig = sig.astype(int) - y = [] - w = [] - N = len(b) - - for n in range(N,len(sig)): - sop = 0 - for i in range(N): - sop = sop + sig[n-i]*b[i] - w.append(sop) - - for n in range(N,len(sig)): - sop = 0 - for i in range(N): - sop = w[n] - w[n-i]*a[i] - w.append(sop) + y_tf = signal.lfilter(b, a, sig) + + print(y_tf) - return y + return y_tf @@ -110,7 +70,7 @@ def main(): # f1 = 45. # f2 = 95. # b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps - b, a = signal.iirfilter(3, [0.4, 0.7], rs=60, btype='band', ftype='cheby2') + #b, a = signal.iirfilter(3, [0.4, 0.7], rs=60, btype='band', ftype='cheby2') # print(len(b)) # print(len(a)) # print(b) @@ -119,6 +79,22 @@ def main(): #print(max([max(b),max(a)])) #convert floating point to fixed point + + b, a = signal.ellip(3, 0.009, 80, 0.05, output='ba') + + print(b) + print(a) + + #y_sos = signal.sosfilt(sos, x) + # plt.plot(y_tf, 'r', label='TF') + # plt.plot(y_sos, 'k', label='SOS') + # plt.legend(loc='best') + # plt.show() + + + + + B1 = 12 # Number of bits L1 = math.floor(math.log((2**(B1-1)-1)/max([max(b),max(a)]), 2)) # Round towards zero to avoid overflow bsc = b*(2**B1) @@ -135,8 +111,8 @@ def main(): #print(y1) #print(y2) - y1 = y1[6:19] #hardcoded presently. Needs to be - y2 = y2[:13] + #y1 = y1[6:19] #hardcoded presently. Needs to be + #y2 = y2[:13] #print(y1) #print(y2) From 78407aba98580fc10717d9adba31d4fe47bec5e7 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sun, 5 Aug 2018 12:23:52 +0800 Subject: [PATCH 36/46] fixes to iir_df1 saturation logic and including sos files --- filter_blocks/iir/iir_df1.py | 7 +- filter_blocks/iir/iir_sos.py | 114 +++++++++++++++++++++++ tests/test_iir/test_iir_df1.py | 2 +- tests/test_iir/test_iir_sos.py | 163 +++++++++++++++++++++++++++++++++ 4 files changed, 281 insertions(+), 5 deletions(-) create mode 100644 filter_blocks/iir/iir_sos.py create mode 100644 tests/test_iir/test_iir_sos.py diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 6143af7..7522e26 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -64,7 +64,6 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): dvd = Signal(bool(0)) - #print(len(yacc)) @hdl.always(clock.posedge) @@ -103,14 +102,14 @@ def beh_output(): ydv.next = dvd y.next = yacc[od:o].signed() - elif yacc[qd+1]==1 and yacc[qd]==0: - #print('underflow2') + elif yacc[qd]==1 and yacc[qd-1]==0: + print('underflow2') y.next = -amax ydv.next = dvd elif yacc[qd]==0 and yacc[qd-1]==1: - #print('overflow2') + print('overflow2') y.next = amax-1 ydv.next = dvd diff --git a/filter_blocks/iir/iir_sos.py b/filter_blocks/iir/iir_sos.py new file mode 100644 index 0000000..b6bc482 --- /dev/null +++ b/filter_blocks/iir/iir_sos.py @@ -0,0 +1,114 @@ + +""" +Simple IIR Filter +================= +The following is a straight forward HDL description of a +direct-form-I IIR filter. This module can be used to +generate synthesizable Verilg/VHDL. + + + +:Author: Christopher Felton +""" + +import myhdl as hdl +from myhdl import Signal, intbv, always, always_comb, always_seq +from filter_blocks.support import Samples + + +@hdl.block +def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): + """Basic IIR direct-form I filter. + + Ports: + glbl (Global): global signals. + sigin (SignalBus): input digital signal. + sigout (SignalBus): output digitla signal. + + Args: + b (tuple, list): numerator coefficents. + a (tuple, list): denominator coefficents. + + Returns: + inst (myhdl.Block, list): + """ + assert isinstance(sigin, Samples) + assert isinstance(sigout, Samples) + assert isinstance(a, tuple) + assert isinstance(b, tuple) + + # All the coefficients need to be an `int`, the + # class (`???`) handles all the float to fixed-poit + # conversions. + ra = [isinstance(aa, int) for aa in a] + rb = [isinstance(bb, int) for bb in b] + assert all(ra) + assert all(rb) + + w = sigin.word_format + ymax = 2**(w[0]-1) + vmax = 2**(2*w[0]) # double width max and min + vmin = -vmax + + # Quantized IIR coefficients + b0, b1, b2 = b + a0, a1, a2 = a + q, qd = w[0]-1, 2*w[0] + + # Locally reference the interface signals + clock, reset = glbl.clock, glbl.reset + x, xdv = sigin.data, sigin.data_valid + y, ydv = sigout.data, sigout.data_valid + + # Delay elements, list-of-signals (double length for all) + ffd = [Signal(intbv(0, min=vmin, max=vmax)) for _ in range(2)] + fbd = [Signal(intbv(0, min=vmin, max=vmax)) for _ in range(2)] + yacc = Signal(intbv(0, min=vmin, max=vmax)) + dvd = Signal(bool(0)) + + @always(clock.posedge) + def beh_direct_form_one(): + if sigin.valid: + ffd[1].next = ffd[0] + ffd[0].next = x + + fbd[1].next = fbd[0] + fbd[0].next = yacc[qd:q].signed() + + @always_comb + def beh_acc(): + # double precision accumulator + yacc.next = (b0 * x) + (b1 * ffd[0]) + (b2 * ffd[1]) \ + - (a1 * fbd[0]) - (a2 * fbd[1]) + + @always_seq(clock.posedge, reset=reset) + def beh_output(): + dvd.next = xdv + y.next = yacc[qd:q].signed() + ydv.next = dvd + + # @todo add shared multiplier version ... + + return hdl.instance() + + +@hdl.block +def filter_iir_sos(glbl, x, y, b, a, w): + """IIR sum of sections ... + """ + assert len(b) == len(a) + number_of_sections = len(b) + list_of_insts = [None for _ in range(number_of_sections)] + + xb = [Samples(x.val) for _ in range(number_of_sections)] + xb[0] = x + xb[number_of_sections-1] = y + + for ii in range(len(b)): + list_of_insts[ii] = filter_iir( + glbl, xb[ii], xb[ii+1], + b=tuple(map(int, b[ii])), a=tuple(map(int, a[ii])), + ) + + return list_of_insts + diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index e2a8290..9c6352b 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -7,7 +7,7 @@ def main(): stim = np.empty(15) stim.fill(32767) hdlfilter = FilterIIR() - b = [1287, 5148, 7722, 5148, 1287] + b = [32767, 32767, 32767, 32767, 32767] a = [1, -22954, 14021, -3702, 459] hdlfilter.set_coefficients(coeff_b = b, coeff_a = a) hdlfilter.set_word_format((16, 23, 0),(16,23,0),(26,53,0)) diff --git a/tests/test_iir/test_iir_sos.py b/tests/test_iir/test_iir_sos.py new file mode 100644 index 0000000..cbf8888 --- /dev/null +++ b/tests/test_iir/test_iir_sos.py @@ -0,0 +1,163 @@ +from filter_blocks.fda import FilterIIR +import numpy as np +import scipy.signal as signal +import math +import matplotlib.pyplot as plt + + + +def fixp_sine(bsc_int, asc_int, B1, L1): + + N=20 + sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] + + B2 = 12 # Number of bits + L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow + + sig = np.multiply(sig, 2**L2) + sig = sig.round() + sig = sig.astype(int) + print(sig) + + + hdlfilter = FilterIIR() + hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a= asc_int) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(10 , 999 , 0)) + hdlfilter.set_stimulus(sig) + hdlfilter.run_sim() + y = hdlfilter.get_response() + + yout = np.divide(y,2**B1) + print(yout) + hdlfilter.convert(hdl = 'verilog') + plt.plot(yout, 'b') + plt.show() + + return yout + + +def edge(B1, L1): + + + B2 = 12 + N = 10 # number of coefficients + + max_coef = 2**(B1-1)-1 + min_coef = -2**(B1-1) + + b_max = [max_coef] * N + + max_in = 2**(B2-1)-1 + min_in = -2**(B2-1) + + coef = np.empty(100) + coef.fill(max_in) + + hdlfilter = FilterFIR() + hdlfilter.set_coefficients(coeff_b = b_max) + hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1, 0),(40, 39, 0)) + hdlfilter.set_stimulus(coef) + hdlfilter.run_sim() + y = hdlfilter.get_response() + + # yout = np.divide(y,2**L1) + # hdlfilter.convert(hdl = 'VHDL') + # plt.plot(yout, 'b') + # plt.show() + + return y + + +def floatp_sine(b, a, B1, L1): + + x=20 + sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] + #print(sig) + + + B2 = 12 # Number of bits + L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow + #print(L) + sig = np.multiply(sig, 2**L2) + sig = sig.round() + sig = sig.astype(int) + + y = [] + w = [] + N = len(b) + + for n in range(N,len(sig)): + sop = 0 + for i in range(N): + sop = sop + sig[n-i]*b[i] + w.append(sop) + + for n in range(N,len(sig)): + sop = 0 + for i in range(N): + sop = w[n] - w[n-i]*a[i] + w.append(sop) + + return y + + + + +def main(): + """Meant to emulate how pyfda will pass parameters to filters""" + + # fs = 1000. + # f1 = 45. + # f2 = 95. + # b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps + #b, a = signal.iirfilter(3, [0.4, 0.7], rs=60, btype='band', ftype='cheby2') + # print(len(b)) + # print(len(a)) + # print(b) + # print(a) + + #print(max([max(b),max(a)])) + #convert floating point to fixed point + + + #b, a = signal.ellip(13, 0.009, 80, 0.05, output='ba') + sos = signal.ellip(13, 0.009, 80, 0.05, output='sos') + x = signal.unit_impulse(700) + #y_tf = signal.lfilter(b, a, x) + y_sos = signal.sosfilt(sos, x) + plt.plot(y_tf, 'r', label='TF') + plt.plot(y_sos, 'k', label='SOS') + plt.legend(loc='best') + plt.show() + + + + + + B1 = 12 # Number of bits + L1 = math.floor(math.log((2**(B1-1)-1)/max([max(b),max(a)]), 2)) # Round towards zero to avoid overflow + bsc = b*(2**B1) + asc = a*(2**B1) + bsc_int = [int(x) for x in bsc] + asc_int = [int(x) for x in asc] + print(bsc_int) + print(asc_int) + + y1 = fixp_sine(bsc_int, asc_int, B1, L1) + #print(y1/2**B1) + y2 = floatp_sine(b, a, B1, L1) + #y = edge(B1, L1) + + #print(y1) + #print(y2) + y1 = y1[6:19] #hardcoded presently. Needs to be + y2 = y2[:13] + + #print(y1) + #print(y2) + #print( ((y1 - y2) ** 2).mean(axis=None)) + + + +if __name__ == '__main__': + main() \ No newline at end of file From 097fbe7f1128656eb9e27bd5d7ed2c8276df8285 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sun, 5 Aug 2018 18:13:15 +0800 Subject: [PATCH 37/46] updates from master --- filter_blocks/fda/filter_hw.py | 47 ------------ filter_blocks/fda/fir.py | 29 -------- filter_blocks/fir/fir_df1.py | 80 -------------------- filter_blocks/iir/iir_df1.py | 79 -------------------- tests/test_fir/test_df1.py | 16 ---- tests/test_fir/test_df1_sine.py | 53 -------------- tests/test_fir/test_firs.py | 5 -- tests/test_iir/test_iir_df1.py | 16 ---- tests/test_iir/test_iir_df1_sine.py | 109 ---------------------------- 9 files changed, 434 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index b4b4a08..71ce166 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -1,23 +1,3 @@ -<<<<<<< HEAD -import numpy as np - -class FilterHardware(object): - """Top level class. Contains filter parameters.""" - def __init__(self, b, a): - """ - Args: - b (list of int): list of numerator coefficients. - a (list of int): list of denominator coefficients. - coef_word_format (tuple of int): word format (W,WI,WF). - n_cascades(int): - sigin(numpy int array): - nfft(int): - hdl_name(str): - hdl_directory(str): - hdl_target(str): - """ - #numerator coefficient -======= import numpy as np @@ -39,17 +19,12 @@ def __init__(self, b=None, a=None): hdl_target (str): """ # numerator coefficient ->>>>>>> master if b is not None: self.b = tuple(b) # denominator coefficients if a is not None: self.a = tuple(a) -<<<<<<< HEAD - - -======= # TODO: need a default word format, the coefficient # can be determined from the coefficients if passed @@ -58,7 +33,6 @@ def __init__(self, b=None, a=None): self.input_word_format = (16, 0, 15) self.output_word_format = (16, 0, 15) ->>>>>>> master self.n_cascades = 0 self.sigin = np.array([]) self._shared_multiplier = False @@ -74,11 +48,7 @@ def __init__(self, b=None, a=None): # A reference to the HDL block self.hardware = None -<<<<<<< HEAD - def set_coefficients(self, coeff_b, coeff_a = None): -======= def set_coefficients(self, coeff_b, coeff_a=None): ->>>>>>> master """Set filter coefficients. Args: @@ -96,15 +66,8 @@ def set_stimulus(self, sigin): sigin (np array int): numpy array of filter stimulus bits (int) : no of bits """ -<<<<<<< HEAD - - self.sigin = sigin.tolist() - - -======= self.sigin = sigin.tolist() ->>>>>>> master def set_cascade(self, n_cascades): """Set number of filter cascades @@ -113,15 +76,6 @@ def set_cascade(self, n_cascades): """ self.n_cascades = n_cascades -<<<<<<< HEAD - def set_word_format(self, coeff_w, input_w, output_w = (24,23,0)): - """Set word format - - Args: - coef_word_format (tuple of int): word format (W,WI,WF) - input_word_format (tuple of int): word format (W,WI,WF) - output_word_format (tuple of int): word format (W,WI,WF) -======= def set_word_format(self, coeff_w, input_w, output_w=(24, 0, 23)): """Set word format @@ -129,7 +83,6 @@ def set_word_format(self, coeff_w, input_w, output_w=(24, 0, 23)): coef_w (tuple of int): word format (W, WI, WF) input_w (tuple of int): word format (W, WI, WF) output_w (tuple of int): word format (W, WI, WF) ->>>>>>> master """ self.coef_word_format = coeff_w self.input_word_format = input_w diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 2f06639..df87d78 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -1,24 +1,3 @@ -<<<<<<< HEAD -import myhdl as hdl -import numpy as np -from .filter_hw import FilterHardware -from ..fir import fir_df1 -from filter_blocks.support import Clock, Reset, Global, Samples -from myhdl import Signal, intbv, StopSimulation - - -class FilterFIR(FilterHardware): - """Contains FIR filter parameters. Parent Class : FilterHardware - Args: - b (list of int): list of numerator coefficients. - a (list of int): list of denominator coefficients. - word format (tuple of int): (W, WI, WF) - filter_type: - filter_form_type: - response(list): list of filter output in int format. - """ - def __init__(self, b = None, a = None): -======= import numpy as np import myhdl as hdl @@ -40,13 +19,10 @@ def __init__(self, b = None, a = None): filter_form_type: response (list): list of filter output in int format. """ ->>>>>>> master super(FilterFIR, self).__init__(b, a) self.filter_type = 'direct_form' self.direct_form_type = 1 self.response = [] -<<<<<<< HEAD -======= def get_response(self): """Return filter output. @@ -163,7 +139,6 @@ def stimulus(): raise StopSimulation() return hdl.instances() ->>>>>>> master def get_response(self): """Return filter output. @@ -291,7 +266,3 @@ def stimulus(): raise StopSimulation() return hdl.instances() -<<<<<<< HEAD - -======= ->>>>>>> master diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 6925f8d..9019636 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -3,14 +3,10 @@ import myhdl as hdl from myhdl import Signal, intbv, always_seq from filter_blocks.support import Samples, Signals -import math @hdl.block -<<<<<<< HEAD -======= ->>>>>>> master def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): """Basic FIR direct-form I filter. @@ -28,70 +24,14 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): assert isinstance(sigin, Samples) assert isinstance(sigout, Samples) assert isinstance(b, tuple) -<<<<<<< HEAD - #All the coefficients need to be an `int` -======= # All the coefficients need to be an `int` ->>>>>>> master rb = [isinstance(bb, int) for bb in b] assert all(rb) w = sigin.word_format w_out = sigout.word_format -<<<<<<< HEAD -======= -<<<<<<< HEAD ->>>>>>> master - - #print(sigin.word_format) - #print(sigout.word_format) - - - ymax = 2**(w[0]-1) -<<<<<<< HEAD -======= - vmax = 2**(2*w[0]) # double width max and min - vmin = -vmax - ymin = -ymax ->>>>>>> master - #vmax = 2**(2*w[0]) # double width max and min - - N = len(b)-1 - - -<<<<<<< HEAD - sum_abs_b = (sum([abs(x) for x in b]))/2.**(coef_w[0]-1) - #acc_bits = w[0] + coef_w[0] + int(math.log(N, 2)) - #print(w[0] + coef_w[0] + int(math.log(N, 2))) - #print(w[0] + coef_w[0] + int(math.log(sum_abs_b, 2))) - print(w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2))) - acc_bits = w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2)) -1 - amax = 2**(acc_bits-1) - - #print(acc_bits) - - qd = acc_bits - q = acc_bits-w_out[0] - - print(qd) - print(q) - - if q<0: - q=0 - - print(qd-q) - clock, reset = glbl.clock, glbl.reset - xdv = sigin.valid - y, ydv = sigout.data, sigout.valid - x = Signal(intbv(0, min = - ymax, max = ymax)) - # Delay elements, list-of-signals - ffd = Signals(intbv(0, min = -ymax, max = ymax), N) - yacc = Signal(intbv(0, min = - amax, max = amax)) #verify the length of this -======= -======= ntaps = len(b)-1 ymax = 2 ** (w[0]-1) ->>>>>>> upstream/master sum_abs_b = (sum([abs(x) for x in b]))/2.**(coef_w[0]-1) acc_bits = w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2)) amax = 2**(acc_bits-1) @@ -108,7 +48,6 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): # Delay elements, list-of-signals ffd = Signals(intbv(0, min=-ymax, max=ymax), ntaps) yacc = Signal(intbv(0, min=-amax, max=amax)) ->>>>>>> master dvd = Signal(bool(0)) @hdl.always(clock.posedge) @@ -116,42 +55,23 @@ def beh_direct_form_one(): if sigin.valid: x.next = sigin.data -<<<<<<< HEAD - for i in range(N-1): -======= for i in range(ntaps-1): ->>>>>>> master ffd[i+1].next = ffd[i] ffd[0].next = x # sum-of-products loop c = b[0] -<<<<<<< HEAD - sop = x*c - - for ii in range(N): - c = b[ii+1] - sop = sop + (c * ffd[ii]) - yacc.next = sop - #print(yacc) -======= sop = x * c for ii in range(ntaps): c = b[ii+1] sop = sop + (c * ffd[ii]) yacc.next = sop ->>>>>>> master @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv y.next = yacc[qd:q].signed() -<<<<<<< HEAD - #print(y) - #y.next = yacc.signed() -======= ->>>>>>> master ydv.next = dvd return beh_direct_form_one, beh_output diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index df33ca5..649cf69 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -17,11 +17,6 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): Args: b (tuple): numerator coefficents. b (tuple): numerator coefficents. -<<<<<<< HEAD - - -======= ->>>>>>> master Returns: inst (myhdl.Block, list): """ @@ -30,10 +25,6 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): assert isinstance(b, tuple) assert isinstance(a, tuple) -<<<<<<< HEAD - -======= ->>>>>>> master # All the coefficients need to be an `int` rb = [isinstance(bb, int) for bb in b] @@ -43,25 +34,6 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): w = sigin.word_format w_out = sigout.word_format -<<<<<<< HEAD - - ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) # top bit is guard bit - amax = 2**(2*w[0]-1) #max without guard bit. Value at which output will saturate - #print(2**(2*w[0]-1)) - - q, qd = w[0], 2*w[0] #guard bit not fed back - - o, od = 2*w[0]-w_out[0], 2*w[0] # guard bit not passed to output - - #print("od-o",od-o) - - if o<0: - o=0 - - - N = len(b)-1 -======= ymax = 2 ** (w[0] - 1) vmax = 2 ** (2 * w[0]) # top bit is guard bit @@ -75,24 +47,15 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): o = 0 if o < 0 else o N = len(b) - 1 ->>>>>>> master clock, reset = glbl.clock, glbl.reset xdv = sigin.valid y, ydv = sigout.data, sigout.valid x, xdv = sigin.data, sigin.valid -<<<<<<< HEAD - #Delay elements, list-of-signals - ffd = Signals(intbv(0, min=-ymax, max=ymax), N) - fbd = Signals(intbv(0, min=-ymax, max=ymax), N) - yacc = Signal(intbv(0, min=-vmax, max=vmax)) #verify the length of this - -======= # Delay elements, list-of-signals ffd = Signals(intbv(0, min=-ymax, max=ymax), N) fbd = Signals(intbv(0, min=-ymax, max=ymax), N) yacc = Signal(intbv(0, min=-vmax, max=vmax)) # verify the length of this ->>>>>>> master dvd = Signal(bool(0)) #print(len(yacc)) @@ -102,11 +65,7 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): @hdl.always(clock.posedge) def beh_direct_form_one(): if sigin.valid: -<<<<<<< HEAD - #print(x) -======= # print(x) ->>>>>>> master for i in range(N - 1): ffd[i + 1].next = ffd[i] @@ -115,21 +74,6 @@ def beh_direct_form_one(): ffd[0].next = x fbd[0].next = yacc[qd:q].signed() -<<<<<<< HEAD - - @hdl.always_comb - def beh_acc(): - c = b[0] - sop = x*c - - for ii in range(N): - c = b[ii+1] #first element in list in b0 - d = a[ii+1] #first element in list is a0 =1 - sop = sop + (c * ffd[ii]) - (d * fbd[ii]) - - yacc.next = sop - -======= @hdl.always_comb def beh_acc(): c = b[0] @@ -141,32 +85,10 @@ def beh_acc(): sop = sop + (c * ffd[ii]) - (d * fbd[ii]) yacc.next = sop ->>>>>>> master @always_seq(clock.posedge, reset=reset) def beh_output(): dvd.next = xdv -<<<<<<< HEAD - #y.next = yacc[od:o].signed() - - - if (yacc[qd]==1 and yacc[qd-1]==1) or (yacc[qd]==0 and yacc[qd-1]==0): - ydv.next = dvd - y.next = yacc[od:o].signed() - - elif yacc[qd]==1 and yacc[qd-1]==0: - print('underflow2') - y.next = -amax - ydv.next = dvd - - - elif yacc[qd]==0 and yacc[qd-1]==1: - print('overflow2') - y.next = amax-1 - ydv.next = dvd - - #print("y" , y) -======= # y.next = yacc[od:o].signed() if (yacc[qd] == 1 and yacc[qd - 1] == 1) or (yacc[qd] == 0 and yacc[qd - 1] == 0): @@ -180,6 +102,5 @@ def beh_output(): elif yacc[qd] == 0 and yacc[qd - 1] == 1: y.next = amax - 1 ydv.next = dvd ->>>>>>> master return hdl.instances() diff --git a/tests/test_fir/test_df1.py b/tests/test_fir/test_df1.py index fd42c0d..688a295 100644 --- a/tests/test_fir/test_df1.py +++ b/tests/test_fir/test_df1.py @@ -1,10 +1,3 @@ -<<<<<<< HEAD -from filter_blocks.fda import FilterFIR -import numpy as np - -def main(): - """Meant to emulate how pyfda will pass parameters to filters""" -======= from filter_blocks.fda import FilterFIR import numpy as np @@ -13,18 +6,10 @@ def main(): def test_fda_fir(): """Test basic API parameter passing """ ->>>>>>> master coef = np.empty(100) coef.fill(8388607) hdlfilter = FilterFIR() b = [8388607, 8388607, 8388607, 8388607, 8388607] -<<<<<<< HEAD - hdlfilter.set_coefficients(coeff_b = b) - hdlfilter.set_word_format(coeff_w = (24, 23, 0), input_w = (24,23,0), output_w = (50,23,0)) - hdlfilter.set_stimulus(coef) - hdlfilter.run_sim() - hdlfilter.convert(hdl = 'VHDL') -======= hdlfilter.set_coefficients(coeff_b=b) hdlfilter.set_word_format( coeff_w=(24, 23, 0), input_w=(24, 23, 0), output_w=(50, 23, 0) @@ -34,6 +19,5 @@ def test_fda_fir(): hdlfilter.convert(hdl='Verilog') ->>>>>>> master if __name__ == '__main__': test_fda_fir() diff --git a/tests/test_fir/test_df1_sine.py b/tests/test_fir/test_df1_sine.py index b2eee31..8e2b33a 100644 --- a/tests/test_fir/test_df1_sine.py +++ b/tests/test_fir/test_df1_sine.py @@ -1,15 +1,3 @@ -<<<<<<< HEAD -from filter_blocks.fda import FilterFIR -import numpy as np -import scipy.signal as signal -import math -import matplotlib.pyplot as plt - - - -def fixp_sine(bsc_int, B1, L1): - -======= import math @@ -21,7 +9,6 @@ def fixp_sine(bsc_int, B1, L1): def fixp_sine(bsc_int, B1, L1): ->>>>>>> master N=20 sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] @@ -32,10 +19,6 @@ def fixp_sine(bsc_int, B1, L1): sig = sig.round() sig = sig.astype(int) -<<<<<<< HEAD - -======= ->>>>>>> master hdlfilter = FilterFIR() hdlfilter.set_coefficients(coeff_b = bsc_int) hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(17 , 30, 0)) @@ -44,28 +27,17 @@ def fixp_sine(bsc_int, B1, L1): y = hdlfilter.get_response() yout = np.divide(y,2**L1) -<<<<<<< HEAD - #hdlfilter.convert(hdl = 'VHDL') - plt.plot(yout, 'b') - plt.show() -======= # hdlfilter.convert(hdl = 'VHDL') # TODO: plotting should not be included in the tests, # create simple scripts in filter-blocks/scripts # for plotting ... # plt.plot(yout, 'b') # plt.show() ->>>>>>> master return yout def edge(B1, L1): -<<<<<<< HEAD - - -======= ->>>>>>> master B2 = 12 N = 10 # number of coefficients @@ -122,16 +94,8 @@ def floatp_sine(b, L1): return y -<<<<<<< HEAD - - -def main(): - """Meant to emulate how pyfda will pass parameters to filters""" - -======= def test_df1_sine(): """Meant to emulate how pyfda will pass parameters to filters""" ->>>>>>> master fs = 1000. f1 = 45. f2 = 95. @@ -144,34 +108,17 @@ def test_df1_sine(): bsc = b*(2**L1) bsc_int = [int(x) for x in bsc] -<<<<<<< HEAD - - y1 = fixp_sine(bsc_int, B1, L1) - y2 = floatp_sine(b, L1) - #y = edge(B1, L1) - -======= y1 = fixp_sine(bsc_int, B1, L1) y2 = floatp_sine(b, L1) # y = edge(B1, L1) ->>>>>>> master y1 = y1[6:19] #hardcoded presently. Needs to be y2 = y2[:13] print(y1) print(y2) -<<<<<<< HEAD - print( ((y1 - y2) ** 2).mean(axis=None)) - - - -if __name__ == '__main__': - main() -======= print(((y1 - y2) ** 2).mean(axis=None)) if __name__ == '__main__': test_df1_sine() ->>>>>>> master diff --git a/tests/test_fir/test_firs.py b/tests/test_fir/test_firs.py index a6dca1c..cecede2 100644 --- a/tests/test_fir/test_firs.py +++ b/tests/test_fir/test_firs.py @@ -8,11 +8,6 @@ from filter_blocks.testing import DDSine from filter_blocks.fda.fir import FilterFIR -<<<<<<< HEAD -#from filter_blocks.fda import FilterFIR Change back to this when fir and fir_test are merged -======= - ->>>>>>> master def test_filters(args=None): if args is None: diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index b930347..f130c98 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -2,39 +2,24 @@ import numpy as np import matplotlib.pyplot as plt -<<<<<<< HEAD -def main(): -======= def test_iir_df1(): ->>>>>>> master """Meant to emulate how pyfda will pass parameters to filters""" stim = np.empty(15) stim.fill(32767) hdlfilter = FilterIIR() -<<<<<<< HEAD - b = [32767, 32767, 32767, 32767, 32767] - a = [1, -22954, 14021, -3702, 459] - hdlfilter.set_coefficients(coeff_b = b, coeff_a = a) - hdlfilter.set_word_format((16, 23, 0),(16,23,0),(26,53,0)) -======= b = [1287, 5148, 7722, 5148, 1287] a = [1, -22954, 14021, -3702, 459] hdlfilter.set_coefficients(coeff_b=b, coeff_a=a) # TODO: increase the test coverage by adding contraint random # hdlfilter.set_word_format((16,23,0), (16, 23, 0), (26, 53, 0)) ->>>>>>> master hdlfilter.set_stimulus(stim) hdlfilter.run_sim() hdlfilter.convert(hdl = 'verilog') y = hdlfilter.get_response() print(y) hdlfilter.convert(hdl = 'verilog') -<<<<<<< HEAD - plt.plot(y, 'b') - plt.show() -======= # TODO: plotting should not be included in the tests, # create simple scripts in filter-blocks/scripts # for plotting ... @@ -42,6 +27,5 @@ def test_iir_df1(): # plt.show() ->>>>>>> master if __name__ == '__main__': test_iir_df1() diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py index ae76f0b..4400262 100644 --- a/tests/test_iir/test_iir_df1_sine.py +++ b/tests/test_iir/test_iir_df1_sine.py @@ -1,15 +1,3 @@ -<<<<<<< HEAD -from filter_blocks.fda import FilterIIR -import numpy as np -import scipy.signal as signal -import math -import matplotlib.pyplot as plt - - - -def fixp_sine(bsc_int, asc_int, B1, L1): - -======= import math @@ -21,48 +9,26 @@ def fixp_sine(bsc_int, asc_int, B1, L1): def fixp_sine(bsc_int, asc_int, B1, L1): ->>>>>>> master # N=20 # sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] sig = signal.unit_impulse(20) -<<<<<<< HEAD - B2 = 12 # Number of bits - L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow - - sig = np.multiply(sig, 2**L2) -======= B2 = 12 # Number of bits L2 = math.floor(math.log((2 ** (B2 - 1) - 1) / max(sig), 2)) # Round towards zero to avoid overflow sig = np.multiply(sig, 2 ** L2) ->>>>>>> master sig = sig.round() sig = sig.astype(int) print(sig) -<<<<<<< HEAD - - hdlfilter = FilterIIR() - hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a= asc_int) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(1000 , 39 , 0)) -======= hdlfilter = FilterIIR() hdlfilter.set_coefficients(coeff_b=bsc_int, coeff_a=asc_int) hdlfilter.set_word_format((B1, B1 - 1, 0), (B2, B2 - 1, 0), (1000, 39, 0)) ->>>>>>> master hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() -<<<<<<< HEAD - yout = np.divide(y,2**B1) - print(yout) - #hdlfilter.convert(hdl = 'verilog') - #plt.plot(yout, 'b') - #plt.show() -======= yout = np.divide(y, 2 ** B1) print(yout) # hdlfilter.convert(hdl = 'verilog') @@ -71,26 +37,10 @@ def fixp_sine(bsc_int, asc_int, B1, L1): # for plotting ... # plt.plot(yout, 'b') # plt.show() ->>>>>>> master return yout -<<<<<<< HEAD - - -def floatp_sine(b, a, B1, L1): - - #sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] - sig = signal.unit_impulse(10) - #print(sig) - - - B2 = 12 # Number of bits - L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow - #print(L) - sig = np.multiply(sig, 2**L2) -======= def floatp_sine(b, a, B1, L1): # sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] sig = signal.unit_impulse(10) @@ -100,24 +50,12 @@ def floatp_sine(b, a, B1, L1): L2 = math.floor(math.log((2 ** (B2 - 1) - 1) / max(sig), 2)) # Round towards zero to avoid overflow # print(L) sig = np.multiply(sig, 2 ** L2) ->>>>>>> master sig = sig.round() sig = sig.astype(int) y_tf = signal.lfilter(b, a, sig) print(y_tf) -<<<<<<< HEAD - - return y_tf - - - - -def main(): - """Meant to emulate how pyfda will pass parameters to filters""" - -======= return y_tf @@ -125,86 +63,40 @@ def main(): def test_iir_df1_sine(): """Meant to emulate how pyfda will pass parameters to filters""" ->>>>>>> master # fs = 1000. # f1 = 45. # f2 = 95. # b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps -<<<<<<< HEAD - #b, a = signal.iirfilter(3, [0.4, 0.7], rs=60, btype='band', ftype='cheby2') -======= # b, a = signal.iirfilter(3, [0.4, 0.7], rs=60, btype='band', ftype='cheby2') ->>>>>>> master # print(len(b)) # print(len(a)) # print(b) # print(a) -<<<<<<< HEAD - #print(max([max(b),max(a)])) - #convert floating point to fixed point - -======= # print(max([max(b),max(a)])) # convert floating point to fixed point ->>>>>>> master b, a = signal.ellip(3, 0.009, 80, 0.05, output='ba') print(b) print(a) -<<<<<<< HEAD - - #y_sos = signal.sosfilt(sos, x) -======= # y_sos = signal.sosfilt(sos, x) ->>>>>>> master # plt.plot(y_tf, 'r', label='TF') # plt.plot(y_sos, 'k', label='SOS') # plt.legend(loc='best') # plt.show() -<<<<<<< HEAD - - - - - B1 = 12 # Number of bits - L1 = math.floor(math.log((2**(B1-1)-1)/max([max(b),max(a)]), 2)) # Round towards zero to avoid overflow - bsc = b*(2**B1) - asc = a*(2**B1) -======= B1 = 12 # Number of bits L1 = math.floor(math.log((2 ** (B1 - 1) - 1) / max([max(b), max(a)]), 2)) # Round towards zero to avoid overflow bsc = b * (2 ** B1) asc = a * (2 ** B1) ->>>>>>> master bsc_int = [int(x) for x in bsc] asc_int = [int(x) for x in asc] print(bsc_int) print(asc_int) y1 = fixp_sine(bsc_int, asc_int, B1, L1) -<<<<<<< HEAD - #print(y1/2**B1) - y2 = floatp_sine(b, a, B1, L1) - #y = edge(B1, L1) - - #print(y1) - #print(y2) - #y1 = y1[6:19] #hardcoded presently. Needs to be - #y2 = y2[:13] - - #print(y1) - #print(y2) - #print( ((y1 - y2) ** 2).mean(axis=None)) - - - -if __name__ == '__main__': - main() -======= # print(y1/2**B1) y2 = floatp_sine(b, a, B1, L1) # y = edge(B1, L1) @@ -221,4 +113,3 @@ def test_iir_df1_sine(): if __name__ == '__main__': test_iir_df1_sine() ->>>>>>> master From 0da8f36911cd52e6a6a82b5c872216c1d4e53bf8 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 6 Aug 2018 02:11:34 +0800 Subject: [PATCH 38/46] adding sos filter --- filter_blocks/fda/filter_hw.py | 9 +- filter_blocks/fda/iir.py | 96 ++------------------- filter_blocks/iir/iir_sos.py | 40 +++++---- tests/test_iir/test_iir_sos.py | 148 ++++++++++----------------------- 4 files changed, 80 insertions(+), 213 deletions(-) diff --git a/filter_blocks/fda/filter_hw.py b/filter_blocks/fda/filter_hw.py index 71ce166..bb5a6c8 100644 --- a/filter_blocks/fda/filter_hw.py +++ b/filter_blocks/fda/filter_hw.py @@ -48,17 +48,22 @@ def __init__(self, b=None, a=None): # A reference to the HDL block self.hardware = None - def set_coefficients(self, coeff_b, coeff_a=None): + def set_coefficients(self, coeff_b = None, coeff_a = None, sos = None): """Set filter coefficients. Args: coeff_b (list): list of numerator filter coefficients coeff_a (list): list of denominator filter coefficients """ - self.b = tuple(coeff_b) + if coeff_b is not None: + self.b = tuple(coeff_b) + if coeff_a is not None: self.a = tuple(coeff_a) + if sos is not None: + self.sos = sos + def set_stimulus(self, sigin): """Set filter stimulus diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index 0f49d79..33f75a8 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -1,31 +1,10 @@ -<<<<<<< HEAD -import myhdl as hdl -import numpy as np -from .filter_hw import FilterHardware -from ..iir import iir_df1 -from filter_blocks.support import Clock, Reset, Global, Samples -from myhdl import Signal, intbv, StopSimulation - - -class FilterIIR(FilterHardware): - """Contains IIR filter parameters. Parent Class : FilterHardware - Args: - b (list of int): list of numerator coefficients. - a (list of int): list of denominator coefficients. - word format (tuple of int): (W, WI, WF) - filter_type: - filter_form_type: - response(list): list of filter output in int format. - """ - def __init__(self, b = None, a = None): -======= import numpy as np import myhdl as hdl from myhdl import Signal, intbv, StopSimulation from .filter_hw import FilterHardware -from ..iir import iir_df1 +from ..iir import iir_df1, iir_sos from filter_blocks.support import Clock, Reset, Global, Samples @@ -40,7 +19,6 @@ def __init__(self, b=None, a=None): filter_form_type: response(list): list of filter output in int format. """ ->>>>>>> master super(FilterIIR, self).__init__(b, a) self.filter_type = 'direct_form' self.direct_form_type = 1 @@ -49,14 +27,9 @@ def __init__(self, b=None, a=None): def get_response(self): """Return filter output. -<<<<<<< HEAD - returns: - response(numpy int array) : returns filter output as numpy array -======= Returns: response(numpy int array) : returns filter output as numpy array ->>>>>>> master """ return self.response @@ -64,11 +37,7 @@ def run_sim(self): """Run filter simulation""" testfil = self.filter_block() -<<<<<<< HEAD - #testfil.config_sim(trace=True) -======= # testfil.config_sim(trace=True) ->>>>>>> master testfil.run_sim() def convert(self, **kwargs): @@ -78,27 +47,6 @@ def convert(self, **kwargs): w_out = self.output_word_format omax = 2**(w_out[0]-1) imax = 2**(w[0]-1) -<<<<<<< HEAD - - # small top-level wrapper - def filter_iir_top(hdl , clock, reset, x, xdv, y, ydv): - sigin = Samples(x.min, x.max, self.input_word_format) - sigin.data, sigin.data_valid = x, xdv - sigout = Samples(y.min, y.max, self.output_word_format) - sigout.data, sigout.data_valid = y, ydv - clk = clock - rst = reset - glbl = Global(clk, rst) - - #choose appropriate filter - iir_hdl = iir_df1.filter_iir - - iir = iir_hdl(glbl, sigin, sigout, self.b, self.a, self.coef_word_format, - shared_multiplier=self._shared_multiplier) - - iir.convert(**kwargs) - -======= # small top-level wrapper def filter_iir_top(hdl , clock, reset, x, xdv, y, ydv): @@ -117,7 +65,6 @@ def filter_iir_top(hdl , clock, reset, x, xdv, y, ydv): shared_multiplier=self._shared_multiplier ) iir.convert(**kwargs) ->>>>>>> master clock = Clock(0, frequency=50e6) reset = Reset(1, active=0, async=True) @@ -155,40 +102,20 @@ def filter_block(self): # set numsample numsample = len(self.sigin) -<<<<<<< HEAD - #process to record output in buffer - rec_insts = yt.process_record(clock, num_samples=numsample) - - -======= # process to record output in buffer rec_insts = yt.process_record(clock, num_samples=numsample) ->>>>>>> master if self.filter_type == 'direct_form': if self.direct_form_type == 1: # all filters will need the same interface ports, this should be do able dfilter = iir_df1.filter_iir if self.n_cascades > 0: -<<<<<<< HEAD - filter_insts = iir_sos.filter_iir_sos(glbl, xt, yt, self.b, self.a, self.coef_word_format) - - else: - filter_insts = dfilter(glbl, xt, yt, self.b, self.a, self.coef_word_format) - - - - - @hdl.instance - def stimulus(): - "record output in numpy array yt.sample_buffer" -======= # TODO: port the SOS iir into the latest set of interfaces - # filter_insts = iir_sos.filter_iir_sos( - # glbl, xt, yt, self.b, self.a, self.coef_word_format - # ) - pass + filter_insts = iir_sos.filter_iir_sos( + glbl, xt, yt, self.sos, self.coef_word_format + ) + else: filter_insts = dfilter( glbl, xt, yt, self.b, self.a, self.coef_word_format @@ -197,7 +124,6 @@ def stimulus(): @hdl.instance def stimulus(): """record output in numpy array yt.sample_buffer""" ->>>>>>> master for k in self.sigin: xt.data.next = int(k) xt.valid = bool(1) @@ -205,18 +131,10 @@ def stimulus(): yt.record = True yt.valid = True yield clock.posedge -<<<<<<< HEAD - #Collect a sample from each filter - yt.record = False - yt.valid = False - - #print(yt.sample_buffer) -======= # Collect a sample from each filter yt.record = False yt.valid = False ->>>>>>> master self.response = yt.sample_buffer # pl.plot(yt.sample_buffer) # pl.show() @@ -224,7 +142,3 @@ def stimulus(): raise StopSimulation() return hdl.instances() -<<<<<<< HEAD - -======= ->>>>>>> master diff --git a/filter_blocks/iir/iir_sos.py b/filter_blocks/iir/iir_sos.py index b6bc482..cd0d418 100644 --- a/filter_blocks/iir/iir_sos.py +++ b/filter_blocks/iir/iir_sos.py @@ -17,7 +17,7 @@ @hdl.block -def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): +def filter_iir(glbl, sigin, sigout, sos, shared_multiplier=False): """Basic IIR direct-form I filter. Ports: @@ -34,16 +34,16 @@ def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): """ assert isinstance(sigin, Samples) assert isinstance(sigout, Samples) - assert isinstance(a, tuple) - assert isinstance(b, tuple) + assert isinstance(sos, tuple) + #assert isinstance(b, tuple) # All the coefficients need to be an `int`, the # class (`???`) handles all the float to fixed-poit # conversions. - ra = [isinstance(aa, int) for aa in a] - rb = [isinstance(bb, int) for bb in b] + ra = [isinstance(aa, int) for aa in sos] + #rb = [isinstance(bb, int) for bb in b] assert all(ra) - assert all(rb) + #assert all(rb) w = sigin.word_format ymax = 2**(w[0]-1) @@ -51,14 +51,15 @@ def filter_iir(glbl, sigin, sigout, b, a, shared_multiplier=False): vmin = -vmax # Quantized IIR coefficients - b0, b1, b2 = b - a0, a1, a2 = a + b0, b1, b2, a0, a1, a2 = sos + print(sos) + print(b0,b1,b2,a0,a1,a2) q, qd = w[0]-1, 2*w[0] # Locally reference the interface signals clock, reset = glbl.clock, glbl.reset - x, xdv = sigin.data, sigin.data_valid - y, ydv = sigout.data, sigout.data_valid + x, xdv = sigin.data, sigin.valid + y, ydv = sigout.data, sigout.valid # Delay elements, list-of-signals (double length for all) ffd = [Signal(intbv(0, min=vmin, max=vmax)) for _ in range(2)] @@ -89,25 +90,28 @@ def beh_output(): # @todo add shared multiplier version ... - return hdl.instance() + return hdl.instances() @hdl.block -def filter_iir_sos(glbl, x, y, b, a, w): +def filter_iir_sos(glbl, x, y, sos, w): """IIR sum of sections ... """ - assert len(b) == len(a) - number_of_sections = len(b) + #assert len(b) == len(a) + number_of_sections = len(sos) list_of_insts = [None for _ in range(number_of_sections)] - xb = [Samples(x.val) for _ in range(number_of_sections)] + xmax = x.imax + xmin = x.imin + + xb = [Samples(min = xmin, max = xmax) for _ in range(number_of_sections+1)] xb[0] = x - xb[number_of_sections-1] = y + xb[number_of_sections] = y - for ii in range(len(b)): + for ii in range(len(sos)): list_of_insts[ii] = filter_iir( glbl, xb[ii], xb[ii+1], - b=tuple(map(int, b[ii])), a=tuple(map(int, a[ii])), + sos=tuple(map(int, sos[ii])) ) return list_of_insts diff --git a/tests/test_iir/test_iir_sos.py b/tests/test_iir/test_iir_sos.py index cbf8888..97ccea7 100644 --- a/tests/test_iir/test_iir_sos.py +++ b/tests/test_iir/test_iir_sos.py @@ -1,104 +1,56 @@ -from filter_blocks.fda import FilterIIR + import numpy as np import scipy.signal as signal import math import matplotlib.pyplot as plt +from filter_blocks.fda import FilterIIR -def fixp_sine(bsc_int, asc_int, B1, L1): +def fixp_sine(sos_asc_int, B1, L1): - N=20 - sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] + sig = signal.unit_impulse(10) - B2 = 12 # Number of bits - L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow + B2 = 12 # Number of bits + L2 = math.floor(math.log((2 ** (B2 - 1) - 1) / max(sig), 2)) # Round towards zero to avoid overflow - sig = np.multiply(sig, 2**L2) + sig = np.multiply(sig, 2 ** L2) sig = sig.round() sig = sig.astype(int) print(sig) - hdlfilter = FilterIIR() - hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a= asc_int) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1 ,0),(10 , 999 , 0)) + hdlfilter.set_coefficients(sos = sos_asc_int) + hdlfilter.set_cascade(3) + hdlfilter.set_word_format((B1, B1 - 1, 0), (B2, B2 - 1, 0), (1000, 39, 0)) hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() - yout = np.divide(y,2**B1) - print(yout) - hdlfilter.convert(hdl = 'verilog') - plt.plot(yout, 'b') - plt.show() - - return yout - - -def edge(B1, L1): - - - B2 = 12 - N = 10 # number of coefficients - - max_coef = 2**(B1-1)-1 - min_coef = -2**(B1-1) - - b_max = [max_coef] * N - - max_in = 2**(B2-1)-1 - min_in = -2**(B2-1) - - coef = np.empty(100) - coef.fill(max_in) - - hdlfilter = FilterFIR() - hdlfilter.set_coefficients(coeff_b = b_max) - hdlfilter.set_word_format((B1, B1-1, 0),(B2, B2-1, 0),(40, 39, 0)) - hdlfilter.set_stimulus(coef) - hdlfilter.run_sim() - y = hdlfilter.get_response() - - # yout = np.divide(y,2**L1) - # hdlfilter.convert(hdl = 'VHDL') - # plt.plot(yout, 'b') - # plt.show() + #yout = np.divide(y, 2 ** B1) + print(y) return y -def floatp_sine(b, a, B1, L1): - - x=20 - sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] - #print(sig) +def floatp_sine(sos, B1, L1): + # sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,x,1)] + sig = signal.unit_impulse(10) + # print(sig) - B2 = 12 # Number of bits - L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # Round towards zero to avoid overflow - #print(L) - sig = np.multiply(sig, 2**L2) + B2 = 12 # Number of bits + L2 = math.floor(math.log((2 ** (B2 - 1) - 1) / max(sig), 2)) # Round towards zero to avoid overflow + # print(L) + sig = np.multiply(sig, 2 ** L2) sig = sig.round() sig = sig.astype(int) - y = [] - w = [] - N = len(b) - - for n in range(N,len(sig)): - sop = 0 - for i in range(N): - sop = sop + sig[n-i]*b[i] - w.append(sop) - - for n in range(N,len(sig)): - sop = 0 - for i in range(N): - sop = w[n] - w[n-i]*a[i] - w.append(sop) + y_sos = signal.sosfilt(sos, sig) + + print(y_sos) - return y + return y_sos @@ -120,42 +72,34 @@ def main(): #convert floating point to fixed point - #b, a = signal.ellip(13, 0.009, 80, 0.05, output='ba') - sos = signal.ellip(13, 0.009, 80, 0.05, output='sos') - x = signal.unit_impulse(700) - #y_tf = signal.lfilter(b, a, x) + sos = signal.ellip(3, 0.009, 80, 0.05, output='sos') + x = signal.unit_impulse(10) y_sos = signal.sosfilt(sos, x) - plt.plot(y_tf, 'r', label='TF') - plt.plot(y_sos, 'k', label='SOS') - plt.legend(loc='best') - plt.show() + print(sos) + + #print(y_sos) + + B1 = 12 # Number of bits + L1 = 2**(B1-1) # Round towards zero to avoid overflow + sos_sc = sos*(2**(B1-1)) + sos_sc_int = sos_sc.astype(int) + print(sos_sc_int) + y1 = fixp_sine(sos_sc_int, B1, L1) + # #print(y1/2**B1) + y2 = floatp_sine(sos, B1, L1) - B1 = 12 # Number of bits - L1 = math.floor(math.log((2**(B1-1)-1)/max([max(b),max(a)]), 2)) # Round towards zero to avoid overflow - bsc = b*(2**B1) - asc = a*(2**B1) - bsc_int = [int(x) for x in bsc] - asc_int = [int(x) for x in asc] - print(bsc_int) - print(asc_int) - - y1 = fixp_sine(bsc_int, asc_int, B1, L1) - #print(y1/2**B1) - y2 = floatp_sine(b, a, B1, L1) - #y = edge(B1, L1) - - #print(y1) - #print(y2) - y1 = y1[6:19] #hardcoded presently. Needs to be - y2 = y2[:13] - - #print(y1) - #print(y2) - #print( ((y1 - y2) ** 2).mean(axis=None)) + # #print(y1) + # #print(y2) + # y1 = y1[6:19] #hardcoded presently. Needs to be + # y2 = y2[:13] + + # #print(y1) + # #print(y2) + # #print( ((y1 - y2) ** 2).mean(axis=None)) From ba3c6069fb3fad3cd16d76212d4a656a550ba194 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 10 Aug 2018 00:07:14 +0800 Subject: [PATCH 39/46] saturation logic to iir filter --- filter_blocks/fda/iir.py | 20 +++++++-- filter_blocks/iir/iir_df1.py | 63 ++++++++++++++++++++++++----- filter_blocks/iir/iir_sos.py | 5 ++- tests/test_iir/test_iir_df1.py | 46 ++++++++++++++++----- tests/test_iir/test_iir_df1_sine.py | 21 +++++----- 5 files changed, 122 insertions(+), 33 deletions(-) diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index 33f75a8..3e330eb 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -37,8 +37,22 @@ def run_sim(self): """Run filter simulation""" testfil = self.filter_block() - # testfil.config_sim(trace=True) - testfil.run_sim() + testfil.config_sim(trace=True) + #testfil.run_sim() + + def info(self): + """Print filter info""" + print("Filter type :", self.filter_type, "\n" + "Filter order :", len(self.b), "\n" + "Arithmatic :", "fixed", "\n" + "Coefficient format :", self.coef_word_format ,"\n" + "Input format :", self.input_word_format ,"\n" + "Accumulator size :", "\n" + "Output format :", self.output_word_format ,"\n" + "Round mode :", "no rounding", "\n" + "Overflow mode :" "saturate" + + ) def convert(self, **kwargs): """Convert the HDL description to Verilog and VHDL. @@ -88,7 +102,7 @@ def filter_block(self): w = self.input_word_format w_out = self.output_word_format - ymax = 2**(w[0]-1) + ymax = 2**(2*w[0]-1) vmax = 2**(2*w[0]) omax = 2**(w_out[0]-1) xt = Samples(min=-ymax, max=ymax, word_format=self.input_word_format) diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 649cf69..170cc80 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -38,13 +38,6 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): ymax = 2 ** (w[0] - 1) vmax = 2 ** (2 * w[0]) # top bit is guard bit # max without guard bit. Value at which output will saturate - amax = 2 ** (2 * w[0] - 1) - - q, qd = w[0], 2 * w[0] # guard bit not fed back - - # guard bit not passed to output - o, od = 2 * w[0] - w_out[0], 2 * w[0] - o = 0 if o < 0 else o N = len(b) - 1 clock, reset = glbl.clock, glbl.reset @@ -52,12 +45,46 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): y, ydv = sigout.data, sigout.valid x, xdv = sigin.data, sigin.valid + + + ######### method 1 for calculating accumulator + + # amax = 2 ** (2 * w[0] - 1) + + # q, qd = w[0], 2 * w[0] # guard bit not fed back + # q = 0 if q < 0 else q + + # # guard bit not passed to output + # o, od = 2 * w[0] - w_out[0], 2 * w[0] + # o = 0 if o < 0 else o + # yacc = Signal(intbv(0, min=-vmax, max=vmax)) # verify the length of this + + ######### + + + ########## method 2 of calculating accumulator size based on fir filter implementation + + acc_bits = w[0] + coef_w[0] + math.floor(math.log(N, 2)) + print(acc_bits) + amax = 2**(acc_bits-1) + od = acc_bits - 1 + o = acc_bits-w_out[0] - 1 + o = 0 if o < 0 else o + q, qd = acc_bits - w[0] -1 , acc_bits -1 + q = 0 if q < 0 else q + + yacc = Signal(intbv(0, min=-amax, max=amax)) + + ########## + # Delay elements, list-of-signals ffd = Signals(intbv(0, min=-ymax, max=ymax), N) fbd = Signals(intbv(0, min=-ymax, max=ymax), N) - yacc = Signal(intbv(0, min=-vmax, max=vmax)) # verify the length of this + dvd = Signal(bool(0)) + overflow = Signal(bool(0)) + underflow = Signal(bool(0)) #print(len(yacc)) # print(len(yacc)) @@ -79,12 +106,21 @@ def beh_acc(): c = b[0] sop = x * c + for ii in range(N): c = b[ii + 1] # first element in list in b0 d = a[ii + 1] # first element in list is a0 =1 sop = sop + (c * ffd[ii]) - (d * fbd[ii]) - yacc.next = sop + if overflow: + yacc.next = amax-1 + + if underflow: + yacc.next = -amax + + else : + yacc.next = sop + @always_seq(clock.posedge, reset=reset) def beh_output(): @@ -94,13 +130,20 @@ def beh_output(): if (yacc[qd] == 1 and yacc[qd - 1] == 1) or (yacc[qd] == 0 and yacc[qd - 1] == 0): ydv.next = dvd y.next = yacc[od:o].signed() + overflow = 0 + underflow = 0 - elif yacc[qd + 1] == 1 and yacc[qd] == 0: + elif yacc[qd] == 1 and yacc[qd-1] == 0: y.next = -amax ydv.next = dvd + underflow = 1 + print('underflow') + elif yacc[qd] == 0 and yacc[qd - 1] == 1: y.next = amax - 1 ydv.next = dvd + overflow = 1 + print('overflow') return hdl.instances() diff --git a/filter_blocks/iir/iir_sos.py b/filter_blocks/iir/iir_sos.py index cd0d418..501dff1 100644 --- a/filter_blocks/iir/iir_sos.py +++ b/filter_blocks/iir/iir_sos.py @@ -47,7 +47,7 @@ def filter_iir(glbl, sigin, sigout, sos, shared_multiplier=False): w = sigin.word_format ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) # double width max and min + vmax = 2**(100*w[0]) # double width max and min vmin = -vmax # Quantized IIR coefficients @@ -74,7 +74,8 @@ def beh_direct_form_one(): ffd[0].next = x fbd[1].next = fbd[0] - fbd[0].next = yacc[qd:q].signed() + #fbd[0].next = yacc[qd:q].signed() + fbd[0].next = yacc.signed() @always_comb def beh_acc(): diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index f130c98..11f5926 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -1,30 +1,58 @@ -from filter_blocks.fda import FilterIIR + +import math import numpy as np +import scipy.signal as signal import matplotlib.pyplot as plt +from filter_blocks.fda import FilterIIR + + def test_iir_df1(): """Meant to emulate how pyfda will pass parameters to filters""" + + sig = signal.unit_impulse(10) + # print(sig) + + B2 = 17 # Number of bits + L2 = math.floor(math.log((2 ** (B2 - 1) - 1) / max(sig), 2)) # Round towards zero to avoid overflow + # print(L) + sig = np.multiply(sig, 2 ** L2) + sig = sig.round() + sig = sig.astype(int) + + + + + stim = np.empty(15) stim.fill(32767) hdlfilter = FilterIIR() - b = [1287, 5148, 7722, 5148, 1287] + #b = [1287, 5148, 7722, 5148, 1287] + #a = [1, -22954, 14021, -3702, 459] + b = [32767, 32767, 32767, 32767, 32767] a = [1, -22954, 14021, -3702, 459] + hdlfilter.set_coefficients(coeff_b=b, coeff_a=a) # TODO: increase the test coverage by adding contraint random # - hdlfilter.set_word_format((16,23,0), (16, 23, 0), (26, 53, 0)) + hdlfilter.set_word_format((16,23,0), (16, 23, 0), (100, 53, 0)) hdlfilter.set_stimulus(stim) - hdlfilter.run_sim() - hdlfilter.convert(hdl = 'verilog') - y = hdlfilter.get_response() - print(y) + #hdlfilter.run_sim() + #hdlfilter.convert(hdl = 'verilog') + hdlfilter.info() + #y = hdlfilter.get_response() + + y_tf = signal.lfilter(b, a, stim) + + #print(y) + print(y_tf) hdlfilter.convert(hdl = 'verilog') # TODO: plotting should not be included in the tests, # create simple scripts in filter-blocks/scripts # for plotting ... - # plt.plot(y, 'b') - # plt.show() + #plt.plot(y, 'b') + #plt.show() if __name__ == '__main__': diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py index 4400262..bab7520 100644 --- a/tests/test_iir/test_iir_df1_sine.py +++ b/tests/test_iir/test_iir_df1_sine.py @@ -12,19 +12,19 @@ def fixp_sine(bsc_int, asc_int, B1, L1): # N=20 # sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)] - sig = signal.unit_impulse(20) + sig = signal.unit_impulse(10) - B2 = 12 # Number of bits + B2 = 17 # Number of bits L2 = math.floor(math.log((2 ** (B2 - 1) - 1) / max(sig), 2)) # Round towards zero to avoid overflow sig = np.multiply(sig, 2 ** L2) sig = sig.round() sig = sig.astype(int) - print(sig) + #print(sig) hdlfilter = FilterIIR() hdlfilter.set_coefficients(coeff_b=bsc_int, coeff_a=asc_int) - hdlfilter.set_word_format((B1, B1 - 1, 0), (B2, B2 - 1, 0), (1000, 39, 0)) + hdlfilter.set_word_format(coeff_w = (B1, B1 - 1, 0), input_w = (B2, B2 - 1, 0), output_w = (35, 25, 0)) hdlfilter.set_stimulus(sig) hdlfilter.run_sim() y = hdlfilter.get_response() @@ -46,7 +46,7 @@ def floatp_sine(b, a, B1, L1): sig = signal.unit_impulse(10) # print(sig) - B2 = 12 # Number of bits + B2 = 17 # Number of bits L2 = math.floor(math.log((2 ** (B2 - 1) - 1) / max(sig), 2)) # Round towards zero to avoid overflow # print(L) sig = np.multiply(sig, 2 ** L2) @@ -76,7 +76,9 @@ def test_iir_df1_sine(): # print(max([max(b),max(a)])) # convert floating point to fixed point - b, a = signal.ellip(3, 0.009, 80, 0.05, output='ba') + #b, a = signal.ellip(3, 0.009, 80, 0.05, output='ba') + b, a = signal.ellip(3, 0.1, 0.2, 0.009, output='ba') + #b, a = signal.bessel(4, 0.09, 'low') print(b) print(a) @@ -87,14 +89,15 @@ def test_iir_df1_sine(): # plt.legend(loc='best') # plt.show() - B1 = 12 # Number of bits + B1 = 17 # Number of bits L1 = math.floor(math.log((2 ** (B1 - 1) - 1) / max([max(b), max(a)]), 2)) # Round towards zero to avoid overflow + #print(L1) bsc = b * (2 ** B1) asc = a * (2 ** B1) bsc_int = [int(x) for x in bsc] asc_int = [int(x) for x in asc] - print(bsc_int) - print(asc_int) + #print(bsc_int) + #print(asc_int) y1 = fixp_sine(bsc_int, asc_int, B1, L1) # print(y1/2**B1) From 774f532b56538aa488fced9199d3b4cebe5e61a6 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 10 Aug 2018 00:18:40 +0800 Subject: [PATCH 40/46] info method added --- filter_blocks/fda/fir.py | 13 +++++++++++++ filter_blocks/fda/iir.py | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index df87d78..3790294 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -37,6 +37,19 @@ def run_sim(self): testfil = self.filter_block() testfil.run_sim() + def info(self): + """Print filter info""" + print("Filter type :", self.filter_type, "\n" + "Filter order :", len(self.b), "\n" + "Arithmatic :", "fixed", "\n" + "Coefficient format :", self.coef_word_format ,"\n" + "Input format :", self.input_word_format ,"\n" + "Accumulator size :", "\n" + "Output format :", self.output_word_format ,"\n" + "Round mode :", "no rounding", "\n" + "Overflow mode :" "saturate" + ) + def convert(self, **kwargs): """Convert the HDL description to Verilog and VHDL. """ diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index 3e330eb..500a31b 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -52,7 +52,7 @@ def info(self): "Round mode :", "no rounding", "\n" "Overflow mode :" "saturate" - ) + ) def convert(self, **kwargs): """Convert the HDL description to Verilog and VHDL. From 06e4c91b094bceb89389519bd563a62127cd2652 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Fri, 10 Aug 2018 00:25:03 +0800 Subject: [PATCH 41/46] fixes to fir interface --- filter_blocks/fda/fir.py | 118 +-------------------------------------- 1 file changed, 2 insertions(+), 116 deletions(-) diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 3790294..ab962a1 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -23,6 +23,8 @@ def __init__(self, b = None, a = None): self.filter_type = 'direct_form' self.direct_form_type = 1 self.response = [] + self.bit_growth + def get_response(self): """Return filter output. @@ -32,11 +34,6 @@ def get_response(self): """ return self.response - def run_sim(self): - """Run filter simulation""" - testfil = self.filter_block() - testfil.run_sim() - def info(self): """Print filter info""" print("Filter type :", self.filter_type, "\n" @@ -50,117 +47,6 @@ def info(self): "Overflow mode :" "saturate" ) - def convert(self, **kwargs): - """Convert the HDL description to Verilog and VHDL. - """ - w = self.input_word_format - w_out = self.output_word_format - omax = 2**(w_out[0]-1) - imax = 2**(w[0]-1) - - # small top-level wrapper - def filter_fir_top(hdl, clock, reset, x, xdv, y, ydv): - sigin = Samples(x.min, x.max, self.input_word_format) - sigin.data, sigin.data_valid = x, xdv - sigout = Samples(y.min, y.max, self.output_word_format) - sigout.data, sigout.data_valid = y, ydv - clk = clock - rst = reset - glbl = Global(clk, rst) - - # choose appropriate filter - fir_hdl = fir_df1.filter_fir - - fir = fir_hdl(glbl, sigin, sigout, self.b, self.coef_word_format, - shared_multiplier=self._shared_multiplier) - - fir.convert(**kwargs) - - clock = Clock(0, frequency=50e6) - reset = Reset(1, active=0, async=True) - x = Signal(intbv(0, min=-imax, max=imax)) - y = Signal(intbv(0, min=-omax, max=omax)) - xdv, ydv = Signal(bool(0)), Signal(bool(0)) - - if self.hdl_target.lower() == 'verilog': - filter_fir_top(hdl, clock, reset, x, xdv, y, ydv) - - elif self.hdl_target.lower() == 'vhdl': - filter_fir_top(hdl, clock, reset, x, xdv, y, ydv) - else: - raise ValueError('incorrect target HDL {}'.format(self.hdl_target)) - - @hdl.block - def filter_block(self): - """ - This elaboration code will select the different structure and - implementations - """ - - w = self.input_word_format - w_out = self.output_word_format - ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) - omax = 2**(w_out[0]-1) - xt = Samples(min=-ymax, max=ymax, word_format=self.input_word_format) - yt = Samples(min=-omax, max=omax, word_format=self.output_word_format) - xt.valid = bool(1) - clock = Clock(0, frequency=50e6) - reset = Reset(1, active=0, async=True) - glbl = Global(clock, reset) - tbclk = clock.process() - numsample = 0 - - # set numsample - numsample = len(self.sigin) - # process to record output in buffer - rec_insts = yt.process_record(clock, num_samples=numsample) - - if self.filter_type == 'direct_form': - if self.direct_form_type == 1: - # all filters will need the same interface ports, this should be do able - dfilter = fir_df1.filter_fir - else: - raise NotImplementedError - - if self.n_cascades > 0: - filter_insts = [None for _ in range(self.n_cascades)] - for ii in range(self.n_cascades): - pass - else: - filter_insts = dfilter(glbl, xt, yt, self.b, self.coef_word_format) - - @hdl.instance - def stimulus(): - """record output in numpy array yt.sample_buffer""" - for k in self.sigin: - xt.data.next = int(k) - xt.valid = bool(1) - - yt.record = True - yt.valid = True - yield clock.posedge - # Collect a sample from each filter - yt.record = False - yt.valid = False - - print(yt.sample_buffer) - self.response = yt.sample_buffer - # pl.plot(yt.sample_buffer) - # pl.show() - - raise StopSimulation() - - return hdl.instances() - - def get_response(self): - """Return filter output. - - returns: - response(numpy int array) : returns filter output as numpy array - """ - return self.response - def run_sim(self): """Run filter simulation""" From 093423fe382aab71c45fead3d0dee782ae14975d Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Sat, 11 Aug 2018 13:34:03 +0800 Subject: [PATCH 42/46] fixes to iir filter --- filter_blocks/fda/fir.py | 1 - filter_blocks/fda/iir.py | 15 +++-- filter_blocks/iir/iir_df1.py | 3 +- notebooks/pyfda_api_example.ipynb | 101 +++++++++++++++++++++++++++- tests/test_iir/test_iir_df1.py | 10 +-- tests/test_iir/test_iir_df1_sine.py | 27 ++------ tests/test_iir/test_iir_parallel.py | 7 +- 7 files changed, 122 insertions(+), 42 deletions(-) diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index ab962a1..286c1a4 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -23,7 +23,6 @@ def __init__(self, b = None, a = None): self.filter_type = 'direct_form' self.direct_form_type = 1 self.response = [] - self.bit_growth def get_response(self): diff --git a/filter_blocks/fda/iir.py b/filter_blocks/fda/iir.py index 500a31b..40617cd 100644 --- a/filter_blocks/fda/iir.py +++ b/filter_blocks/fda/iir.py @@ -9,7 +9,7 @@ class FilterIIR(FilterHardware): - def __init__(self, b=None, a=None): + def __init__(self, b = None, a = None): """Contains IIR filter parameters. Parent Class : FilterHardware Args: b (list of int): list of numerator coefficients. @@ -37,8 +37,8 @@ def run_sim(self): """Run filter simulation""" testfil = self.filter_block() - testfil.config_sim(trace=True) - #testfil.run_sim() + #testfil.config_sim(trace=True) + testfil.run_sim() def info(self): """Print filter info""" @@ -51,7 +51,6 @@ def info(self): "Output format :", self.output_word_format ,"\n" "Round mode :", "no rounding", "\n" "Overflow mode :" "saturate" - ) def convert(self, **kwargs): @@ -74,6 +73,7 @@ def filter_iir_top(hdl , clock, reset, x, xdv, y, ydv): # choose appropriate filter iir_hdl = iir_df1.filter_iir + iir = iir_hdl( glbl, sigin, sigout, self.b, self.a, self.coef_word_format, shared_multiplier=self._shared_multiplier @@ -126,9 +126,10 @@ def filter_block(self): if self.n_cascades > 0: # TODO: port the SOS iir into the latest set of interfaces - filter_insts = iir_sos.filter_iir_sos( - glbl, xt, yt, self.sos, self.coef_word_format - ) + #filter_insts = iir_sos.filter_iir_sos( + # glbl, xt, yt, self.sos, self.coef_word_format + #) + pass else: filter_insts = dfilter( diff --git a/filter_blocks/iir/iir_df1.py b/filter_blocks/iir/iir_df1.py index 170cc80..6c5f9c9 100644 --- a/filter_blocks/iir/iir_df1.py +++ b/filter_blocks/iir/iir_df1.py @@ -65,7 +65,7 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): ########## method 2 of calculating accumulator size based on fir filter implementation acc_bits = w[0] + coef_w[0] + math.floor(math.log(N, 2)) - print(acc_bits) + #print(acc_bits) amax = 2**(acc_bits-1) od = acc_bits - 1 o = acc_bits-w_out[0] - 1 @@ -92,7 +92,6 @@ def filter_iir(glbl, sigin, sigout, b, a, coef_w, shared_multiplier=False): @hdl.always(clock.posedge) def beh_direct_form_one(): if sigin.valid: - # print(x) for i in range(N - 1): ffd[i + 1].next = ffd[i] diff --git a/notebooks/pyfda_api_example.ipynb b/notebooks/pyfda_api_example.ipynb index d6dda87..9736038 100644 --- a/notebooks/pyfda_api_example.ipynb +++ b/notebooks/pyfda_api_example.ipynb @@ -115,6 +115,17 @@ "```python \n", "hdlfilter.convert(hdl = 'VHDL')\n", "```\n", + "inst.convert(hdl='Verilog', **kwargs)\n", + "Converts MyHDL code to a target HDL.\n", + "\n", + "hdl: 'VHDL' or 'Verilog'. Defaults to Verilog.\n", + "\n", + "Args:
\n", + "path: Destination folder. Defaults to current working dir.
\n", + "name: Module and output file name. Defaults to self.mod.name.
\n", + "trace: Whether the testbench should dump all signal waveforms. Defaults to False.
\n", + "testbench: Verilog only. Specifies whether a testbench should be created. Defaults to True.
\n", + "timescale: timescale parameter. Defaults to '1ns/10ps'. Verilog only.
\n", "\n", "\n" ] @@ -122,7 +133,95 @@ { "cell_type": "markdown", "metadata": {}, - "source": [] + "source": [ + "### Create IIR filter with integer coefficients\n", + "\n", + "The steps to be followed are the same as that of FIR filter. Hence only an example should suffice with minimal explanation. \n", + "\n", + "#### Create filter coefficients\n", + "\n", + "In this example we will be using the scipy library to create iir coefficients for a low pass elliptical filter. We design a 3rd-order lowpass elliptic filter with 5 dB of passband ripple, 40 dB of stopband attenuation, and a passband edge frequency of 0.6$\\pi$ rad/sample\n", + "\n", + "```python \n", + "import scipy.signal as signal\n", + "\n", + "b, a = signal.ellip(3, 5, 40, 0.6, output='ba') # 3 taps \n", + "```\n", + "Next, the coefficients are scaled up.\n", + "\n", + "```python\n", + "B1 = 18 # Number of bits for coefficients\n", + "bsc = b*(2**B1) #scaled coefficients\n", + "asc = a*(2**B1) \n", + "bsc_int = [int(x) for x in bsc] #convert coefficient to type int\n", + "asc_int = [int(x) for x in bsc] \n", + "```\n", + "#### Build the IIR Filter\n", + "``` python \n", + "from filter_blocks.fda import FilterIIR\n", + "hdlfilter = FilterIIR()\n", + "```\n", + "#### Set the Filter Parameters to Work with Integers\n", + "Next, we set the input parameters of the filter to appropriate values.\n", + "\n", + "```python \n", + "hdlfilter.set_word_format(coeff_w = (18, 17, 0), input_w = (12,11,0), output_w = (24,23,0))\n", + "```\n", + "Args:
\n", + "coeff_w (tuple of int): word format (W,WI,WF)
\n", + "input_w (tuple of int): word format (W,WI,WF)
\n", + "output_w (tuple of int): word format (W,WI,WF)
\n", + "Where WI is the number of integer bits, WF is the number of fractional bit and W = WI+WF+1 (extra 1 for the sign bit). It is important to set the coefficient bits to 18, as this was used to calculate the scaling factor. In this example we are assuming that the input signal is of 12 bits and the output is set to 24 bits. \n", + "\n", + "Next, we pass the filter coefficients as determined earlier.\n", + "```python\n", + "hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a = asc_int)\n", + "\n", + "```\n", + "\n", + "\n", + "#### Create a Stimulus for the Filter\n", + "We generate an input signal (stimulus) exactly the same way as for the fir filter. \n", + "\n", + "```python \n", + "import numpy as np\n", + "\n", + "N=20 #length of input signal\n", + "sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)]\n", + "\n", + "B2 = 12 # Number of bits\n", + "L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # calculate scaling factor\n", + "\n", + "sig = np.multiply(sig, 2**L2) \n", + "sig = sig.round()\n", + "sig = sig.astype(int)\n", + "\n", + "hdlfilter.set_stimulus(sig) #pass the stimulus to the filter object\n", + "\n", + "```\n", + "\n", + "#### Run the simulation\n", + "\n", + "To filter the input signal generated above, we need to run a simulation and obtain the output signal. Enter the following:\n", + "\n", + "```python \n", + "hdlfilter.run_sim()\n", + "y = hdlfilter.get_response()\n", + "```\n", + "Filter-blocks returns a numpy array of the output which is stored in 'y'. Here y is a 24 bits as was set earlier, meaning that some bits might have possibly been discarded to fit the output. The most significant 24 bits from the accumulator are assigned to y.\n", + "\n", + "\n", + "#### Converting design to Verilog or VHDL\n", + "```python \n", + "hdlfilter.convert(hdl = 'VHDL')\n", + "```\n", + "Args:
\n", + "path: Destination folder. Defaults to current working dir.
\n", + "name: Module and output file name. Defaults to self.mod.name.
\n", + "trace: Whether the testbench should dump all signal waveforms. Defaults to False.
\n", + "testbench: Verilog only. Specifies whether a testbench should be created. Defaults to True.
\n", + "timescale: timescale parameter. Defaults to '1ns/10ps'. Verilog only.
" + ] }, { "cell_type": "code", diff --git a/tests/test_iir/test_iir_df1.py b/tests/test_iir/test_iir_df1.py index 11f5926..dc7d5c6 100644 --- a/tests/test_iir/test_iir_df1.py +++ b/tests/test_iir/test_iir_df1.py @@ -38,15 +38,15 @@ def test_iir_df1(): # hdlfilter.set_word_format((16,23,0), (16, 23, 0), (100, 53, 0)) hdlfilter.set_stimulus(stim) - #hdlfilter.run_sim() + hdlfilter.run_sim() #hdlfilter.convert(hdl = 'verilog') - hdlfilter.info() - #y = hdlfilter.get_response() + #hdlfilter.info() + y = hdlfilter.get_response() y_tf = signal.lfilter(b, a, stim) - #print(y) - print(y_tf) + print(y) + #print(y_tf) hdlfilter.convert(hdl = 'verilog') # TODO: plotting should not be included in the tests, # create simple scripts in filter-blocks/scripts diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py index bab7520..1d1e6d8 100644 --- a/tests/test_iir/test_iir_df1_sine.py +++ b/tests/test_iir/test_iir_df1_sine.py @@ -63,35 +63,16 @@ def floatp_sine(b, a, B1, L1): def test_iir_df1_sine(): """Meant to emulate how pyfda will pass parameters to filters""" - # fs = 1000. - # f1 = 45. - # f2 = 95. - # b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps - # b, a = signal.iirfilter(3, [0.4, 0.7], rs=60, btype='band', ftype='cheby2') - # print(len(b)) - # print(len(a)) - # print(b) - # print(a) - - # print(max([max(b),max(a)])) - # convert floating point to fixed point - - #b, a = signal.ellip(3, 0.009, 80, 0.05, output='ba') - b, a = signal.ellip(3, 0.1, 0.2, 0.009, output='ba') + + b, a = signal.ellip(3, 5, 40, 0.6, output='ba') #b, a = signal.bessel(4, 0.09, 'low') print(b) print(a) - # y_sos = signal.sosfilt(sos, x) - # plt.plot(y_tf, 'r', label='TF') - # plt.plot(y_sos, 'k', label='SOS') - # plt.legend(loc='best') - # plt.show() - B1 = 17 # Number of bits L1 = math.floor(math.log((2 ** (B1 - 1) - 1) / max([max(b), max(a)]), 2)) # Round towards zero to avoid overflow - #print(L1) + bsc = b * (2 ** B1) asc = a * (2 ** B1) bsc_int = [int(x) for x in bsc] @@ -102,7 +83,7 @@ def test_iir_df1_sine(): y1 = fixp_sine(bsc_int, asc_int, B1, L1) # print(y1/2**B1) y2 = floatp_sine(b, a, B1, L1) - # y = edge(B1, L1) + # print(y1) # print(y2) diff --git a/tests/test_iir/test_iir_parallel.py b/tests/test_iir/test_iir_parallel.py index 076c8d4..ba74fd8 100644 --- a/tests/test_iir/test_iir_parallel.py +++ b/tests/test_iir/test_iir_parallel.py @@ -23,10 +23,11 @@ def test_iir_api(): b = [[1, 0, 1], [0, 0, 1]] a = [[0, 1], [0, 0]] - w = (24, 0) + w = (24, 23, 0) - iir_test = FilterIIR(b, a) - iir = iir_test.filter_block(glbl, x, y, b, a, w) + #iir_test = FilterIIR(b, a) + + iir = iir_parallel.filter_iir_parallel(glbl, x, y, b, a, w) @hdl.instance def stimulus(): From a14a21001216f13b1eb89202b1cd4a6d8840ae6f Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 13 Aug 2018 01:03:45 +0800 Subject: [PATCH 43/46] fixed broken iir parallel test --- filter_blocks/fda/fir.py | 2 +- notebooks/pyfda_api_example.ipynb | 6 ++++++ tests/test_iir/test_iir_df1_sine.py | 4 ++-- tests/test_iir/test_iir_parallel.py | 27 +++++++++++++-------------- 4 files changed, 22 insertions(+), 17 deletions(-) diff --git a/filter_blocks/fda/fir.py b/filter_blocks/fda/fir.py index 286c1a4..68b3623 100644 --- a/filter_blocks/fda/fir.py +++ b/filter_blocks/fda/fir.py @@ -43,7 +43,7 @@ def info(self): "Accumulator size :", "\n" "Output format :", self.output_word_format ,"\n" "Round mode :", "no rounding", "\n" - "Overflow mode :" "saturate" + "Overflow mode :" "no overflow" ) def run_sim(self): diff --git a/notebooks/pyfda_api_example.ipynb b/notebooks/pyfda_api_example.ipynb index 9736038..a69a7f2 100644 --- a/notebooks/pyfda_api_example.ipynb +++ b/notebooks/pyfda_api_example.ipynb @@ -179,6 +179,12 @@ "\n", "```\n", "\n", + "the info method prints details about the filter implementation \n", + "\n", + "```python \n", + "hdlfilter.info()\n", + "```\n", + "\n", "\n", "#### Create a Stimulus for the Filter\n", "We generate an input signal (stimulus) exactly the same way as for the fir filter. \n", diff --git a/tests/test_iir/test_iir_df1_sine.py b/tests/test_iir/test_iir_df1_sine.py index 1d1e6d8..b6613a4 100644 --- a/tests/test_iir/test_iir_df1_sine.py +++ b/tests/test_iir/test_iir_df1_sine.py @@ -64,8 +64,8 @@ def test_iir_df1_sine(): """Meant to emulate how pyfda will pass parameters to filters""" - b, a = signal.ellip(3, 5, 40, 0.6, output='ba') - #b, a = signal.bessel(4, 0.09, 'low') + #b, a = signal.ellip(3, 5, 40, 0.6, output='ba') + b, a = signal.bessel(4, 0.09, 'low') print(b) print(a) diff --git a/tests/test_iir/test_iir_parallel.py b/tests/test_iir/test_iir_parallel.py index ba74fd8..2b3a8fe 100644 --- a/tests/test_iir/test_iir_parallel.py +++ b/tests/test_iir/test_iir_parallel.py @@ -9,7 +9,6 @@ # TODO: fix these, they should not be failing! -@pytest.mark.xfail @hdl.block def test_iir_api(): @@ -18,26 +17,26 @@ def test_iir_api(): glbl = Global(clock, reset) tbclk = clock.process() - x = Signal(intbv(0)[8:]) - y = Signal(intbv(0)[20:]) + w = (24,0,23) + w_out = (24,0,23) + + ymax = 2**(2*w[0]-1) + vmax = 2**(2*w[0]) + omax = 2**(w_out[0]-1) + + xt = Samples(min=-ymax, max=ymax, word_format = w) + yt = Samples(min=-omax, max=omax, word_format = w_out) - b = [[1, 0, 1], [0, 0, 1]] - a = [[0, 1], [0, 0]] + b = [[101, 0, 132], [23324, 0, 232]] + a = [[24223, 1], [233, 0]] w = (24, 23, 0) #iir_test = FilterIIR(b, a) - iir = iir_parallel.filter_iir_parallel(glbl, x, y, b, a, w) + iir = iir_parallel.filter_iir_parallel(glbl, xt, yt, b, a, w) - @hdl.instance - def stimulus(): - """Input for test bench taken from text file test.txt""" - for line in open('test.txt'): - x.next = int(line) - yield clock.posedge - raise StopSimulation - return iir, stimulus, tbclk + return hdl.instances() @pytest.mark.xfail From 1c1a96d335b4c0bd95d6c94923dde119920e27a1 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 13 Aug 2018 01:17:52 +0800 Subject: [PATCH 44/46] updates to tutorial notebook --- notebooks/pyfda_api_example.ipynb | 126 ++++++++++++++++++++++++++---- 1 file changed, 112 insertions(+), 14 deletions(-) diff --git a/notebooks/pyfda_api_example.ipynb b/notebooks/pyfda_api_example.ipynb index d6dda87..943f5a1 100644 --- a/notebooks/pyfda_api_example.ipynb +++ b/notebooks/pyfda_api_example.ipynb @@ -7,8 +7,6 @@ "## Introduction\n", "Filter-blocks repository contains a collection of hardware digital filter implementations coded with myhdl.\n", "\n", - "### Installation\n", - "insert installation steps here\n", "\n", "### object oriented API\n", "An API has been built for the filter-blocks package which allows easy access to the filter implementations. It also helps set parameters required by serving as a wrapper around MyHDL methods. \n", @@ -18,17 +16,12 @@ "The filter implementations that presently exist in the filter blocks package:\n", "\n", "- fir filters\n", - " - direct form I fir filter\n", + " - direct form I \n", " - cascaded second order sections \n", "- iir filters\n", - " - direct form I iir filter \n", - " - cascaded \n", - " - parallel \n", - "\n", - "### class hierarchy\n", - "insert class hierarchy figure here\n", - "\n", - "A visual representation of all the methods and attributes which can be set/modified according to requirements. " + " - direct form I\n", + " - cascaded second order sections\n", + " - parallel implementation\n" ] }, { @@ -116,13 +109,118 @@ "hdlfilter.convert(hdl = 'VHDL')\n", "```\n", "\n", - "\n" + "hdl: 'VHDL' or 'Verilog'. Defaults to Verilog.\n", + "\n", + "Args:
\n", + "path: Destination folder. Defaults to current working dir.
\n", + "name: Module and output file name. Defaults to self.mod.name.
\n", + "trace: Whether the testbench should dump all signal waveforms. Defaults to False.
\n", + "testbench: Verilog only. Specifies whether a testbench should be created. Defaults to True.
\n", + "timescale: timescale parameter. Defaults to '1ns/10ps'. Verilog only.
" ] }, { "cell_type": "markdown", - "metadata": {}, - "source": [] + "metadata": { + "collapsed": true + }, + "source": [ + "### Create IIR filter with integer coefficients\n", + "\n", + "The steps to be followed are the same as that of FIR filter. Hence only an example should suffice with minimal explanation. \n", + "\n", + "#### Create filter coefficients\n", + "\n", + "In this example we will be using the scipy library to create iir coefficients for a low pass elliptical filter. We design a 3rd-order lowpass elliptic filter with 5 dB of passband ripple, 40 dB of stopband attenuation, and a passband edge frequency of 0.6$\\pi$ rad/sample\n", + "\n", + "```python \n", + "import scipy.signal as signal\n", + "\n", + "b, a = signal.ellip(3, 5, 40, 0.6, output='ba') # 3 taps \n", + "```\n", + "Next, the coefficients are scaled up.\n", + "\n", + "```python\n", + "B1 = 18 # Number of bits for coefficients\n", + "bsc = b*(2**B1) #scaled coefficients\n", + "asc = a*(2**B1) \n", + "bsc_int = [int(x) for x in bsc] #convert coefficient to type int\n", + "asc_int = [int(x) for x in bsc] \n", + "```\n", + "#### Build the IIR Filter\n", + "``` python \n", + "from filter_blocks.fda import FilterIIR\n", + "hdlfilter = FilterIIR()\n", + "```\n", + "#### Set the Filter Parameters to Work with Integers\n", + "Next, we set the input parameters of the filter to appropriate values.\n", + "\n", + "```python \n", + "hdlfilter.set_word_format(coeff_w = (18, 17, 0), input_w = (12,11,0), output_w = (24,23,0))\n", + "```\n", + "Args:
\n", + "coeff_w (tuple of int): word format (W,WI,WF)
\n", + "input_w (tuple of int): word format (W,WI,WF)
\n", + "output_w (tuple of int): word format (W,WI,WF)
\n", + "Where WI is the number of integer bits, WF is the number of fractional bit and W = WI+WF+1 (extra 1 for the sign bit). It is important to set the coefficient bits to 18, as this was used to calculate the scaling factor. In this example we are assuming that the input signal is of 12 bits and the output is set to 24 bits. \n", + "\n", + "Next, we pass the filter coefficients as determined earlier.\n", + "```python\n", + "hdlfilter.set_coefficients(coeff_b = bsc_int, coeff_a = asc_int)\n", + "\n", + "```\n", + "\n", + "the info method prints details about the filter implementation \n", + "\n", + "```python \n", + "hdlfilter.info()\n", + "```\n", + "\n", + "\n", + "#### Create a Stimulus for the Filter\n", + "We generate an input signal (stimulus) exactly the same way as for the fir filter. \n", + "\n", + "```python \n", + "import numpy as np\n", + "\n", + "N=20 #length of input signal\n", + "sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)]\n", + "\n", + "B2 = 12 # Number of bits\n", + "L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # calculate scaling factor\n", + "\n", + "sig = np.multiply(sig, 2**L2) \n", + "sig = sig.round()\n", + "sig = sig.astype(int)\n", + "\n", + "hdlfilter.set_stimulus(sig) #pass the stimulus to the filter object\n", + "\n", + "```\n", + "\n", + "#### Run the simulation\n", + "\n", + "To filter the input signal generated above, we need to run a simulation and obtain the output signal. Enter the following:\n", + "\n", + "```python \n", + "hdlfilter.run_sim()\n", + "y = hdlfilter.get_response()\n", + "```\n", + "Filter-blocks returns a numpy array of the output which is stored in 'y'. Here y is a 24 bits as was set earlier, meaning that some bits might have possibly been discarded to fit the output. The most significant 24 bits from the accumulator are assigned to y.\n", + "\n", + "\n", + "#### Converting design to Verilog or VHDL\n", + "```python \n", + "hdlfilter.convert(hdl = 'VHDL')\n", + "```\n", + "hdl: 'VHDL' or 'Verilog'. Defaults to Verilog.\n", + "\n", + "Args:
\n", + "path: Destination folder. Defaults to current working dir.
\n", + "name: Module and output file name. Defaults to self.mod.name.
\n", + "trace: Whether the testbench should dump all signal waveforms. Defaults to False.
\n", + "testbench: Verilog only. Specifies whether a testbench should be created. Defaults to True.
\n", + "timescale: timescale parameter. Defaults to '1ns/10ps'. Verilog only.
" + ] }, { "cell_type": "code", From c4c0d16bdb5833a1b5997e733f00870802caba13 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 13 Aug 2018 01:23:38 +0800 Subject: [PATCH 45/46] resolving merge conflicts --- filter_blocks/fir/fir_df1.py | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/filter_blocks/fir/fir_df1.py b/filter_blocks/fir/fir_df1.py index 221f95c..9019636 100644 --- a/filter_blocks/fir/fir_df1.py +++ b/filter_blocks/fir/fir_df1.py @@ -30,25 +30,8 @@ def filter_fir(glbl, sigin, sigout, b, coef_w, shared_multiplier=False): w = sigin.word_format w_out = sigout.word_format -<<<<<<< HEAD - - #print(sigin.word_format) - #print(sigout.word_format) - - - ymax = 2**(w[0]-1) - vmax = 2**(2*w[0]) # double width max and min - vmin = -vmax - ymin = -ymax - #vmax = 2**(2*w[0]) # double width max and min - - N = len(b)-1 - - -======= ntaps = len(b)-1 ymax = 2 ** (w[0]-1) ->>>>>>> upstream/master sum_abs_b = (sum([abs(x) for x in b]))/2.**(coef_w[0]-1) acc_bits = w[0] + coef_w[0] + math.ceil(math.log(sum_abs_b, 2)) amax = 2**(acc_bits-1) From 18bd6a10d8570c7d3db228d1cfdb42cc64bf4187 Mon Sep 17 00:00:00 2001 From: Sriyash Caculo Date: Mon, 13 Aug 2018 01:39:38 +0800 Subject: [PATCH 46/46] remove duplicate notebook --- docs/Notebooks/Documentation.ipynb | 158 ----------------------------- 1 file changed, 158 deletions(-) delete mode 100644 docs/Notebooks/Documentation.ipynb diff --git a/docs/Notebooks/Documentation.ipynb b/docs/Notebooks/Documentation.ipynb deleted file mode 100644 index d6dda87..0000000 --- a/docs/Notebooks/Documentation.ipynb +++ /dev/null @@ -1,158 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "## Introduction\n", - "Filter-blocks repository contains a collection of hardware digital filter implementations coded with myhdl.\n", - "\n", - "### Installation\n", - "insert installation steps here\n", - "\n", - "### object oriented API\n", - "An API has been built for the filter-blocks package which allows easy access to the filter implementations. It also helps set parameters required by serving as a wrapper around MyHDL methods. \n", - "\n", - "### filter implementations \n", - "\n", - "The filter implementations that presently exist in the filter blocks package:\n", - "\n", - "- fir filters\n", - " - direct form I fir filter\n", - " - cascaded second order sections \n", - "- iir filters\n", - " - direct form I iir filter \n", - " - cascaded \n", - " - parallel \n", - "\n", - "### class hierarchy\n", - "insert class hierarchy figure here\n", - "\n", - "A visual representation of all the methods and attributes which can be set/modified according to requirements. " - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Create FIR filter with integer coefficients\n", - "Here is an example of how you can create a filter with integer coefficients. In this example, scipy library is used to generate floating point filter coefficients which are then converted to integers.\n", - "#### Create filter coefficients\n", - "\n", - "```python \n", - "import scipy.signal as signal\n", - "\n", - "fs = 1000.\n", - "f1 = 45.\n", - "f2 = 95.\n", - "b = signal.firwin(3,[f1/fs*2,f2/fs*2]) #3 taps\n", - "```\n", - "Next, we need to convert the coefficients to integers for which they will need to be scaled. For this example we assume, the coefficients are scaled to 18 bits. The exponent of the scale factor is determined as follows:\n", - "\n", - "```python\n", - "B1 = 18 # Number of bits for coefficients\n", - "L1 = math.floor(math.log((2**(B1-1)-1)/max(b), 2)) #Scale factor exponent\n", - "bsc = b*(2**L1) #scaled coefficients\n", - "bsc_int = [int(x) for x in bsc] #convert coefficient to type int\n", - "```\n", - "#### Build the FIR Filter\n", - "``` python \n", - "from filter_blocks.fda import FilterFIR\n", - "hdlfilter = FilterFIR()\n", - "```\n", - "#### Set the Filter Parameters to Work with Integers\n", - "Next, we set the input parameters of the filter to appropriate values.\n", - "\n", - "```python \n", - "hdlfilter.set_word_format(coeff_w = (18, 17, 0), input_w = (12,11,0), output_w = (24,23,0))\n", - "```\n", - "Args:
\n", - "coeff_w (tuple of int): word format (W,WI,WF)
\n", - "input_w (tuple of int): word format (W,WI,WF)
\n", - "output_w (tuple of int): word format (W,WI,WF)
\n", - "Where WI is the number of integer bits, WF is the number of fractional bit and W = WI+WF+1 (extra 1 for the sign bit). It is important to set the coefficient bits to 18, as this was used to calculate the scaling factor. In this example we are assuming that the input signal is of 12 bits and the output is set to 24 bits. \n", - "\n", - "Next, we pass the filter coefficients as determined earlier.\n", - "```python\n", - "hdlfilter.set_coefficients(coeff_b = bsc_int)\n", - "\n", - "```\n", - "\n", - "\n", - "#### Create a Stimulus for the Filter\n", - "We generate an input signal (stimulus) for the filter by following the same steps that were used for the coefficients, discussed previously. In this example, create a signal which is a sine wave:\n", - "\n", - "```python \n", - "import numpy as np\n", - "\n", - "N=20 #length of input signal\n", - "sig = [np.sin(0.1*np.pi*i) for i in np.arange(0,N,1)]\n", - "\n", - "B2 = 12 # Number of bits\n", - "L2 = math.floor(math.log((2**(B2-1)-1)/max(sig), 2)) # calculate scaling factor\n", - "\n", - "sig = np.multiply(sig, 2**L2) \n", - "sig = sig.round()\n", - "sig = sig.astype(int)\n", - "\n", - "hdlfilter.set_stimulus(sig) #pass the stimulus to the filter object\n", - "\n", - "```\n", - "\n", - "#### Run the simulation\n", - "\n", - "To filter the input signal generated above, we need to run a simulation and obtain the output signal. Enter the following:\n", - "\n", - "```python \n", - "hdlfilter.run_sim()\n", - "y = hdlfilter.get_response()\n", - "\n", - "```\n", - "Filter-blocks returns a numpy array of the output which is stored in 'y'. Here y is a 24 bits as was set earlier, meaning that some bits might have possibly been discarded to fit the output. The most significant 24 bits from the accumulator are assigned to y.\n", - "\n", - "\n", - "#### Converting design to Verilog or VHDL\n", - "```python \n", - "hdlfilter.convert(hdl = 'VHDL')\n", - "```\n", - "\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.6.1" - } - }, - "nbformat": 4, - "nbformat_minor": 2 -}