Skip to content
Open
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 21 additions & 6 deletions iir.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# First order IIR filter for multiple channels and profiles with one DSP and no blockram.
# First order IIR filter for multiple channels and profiles with one DSP and no block ram.
# DSP block with MSB aligned inputs and "round half down" rounding.
#
#
# Note: Migen translates the "out of range" pc mux selector to the last vaid mux input.
# Note: Migen translates the "out of range" pc mux selector to the last valid mux input.

from ast import Constant
from migen import *
Expand All @@ -18,8 +18,16 @@ def __init__(self):
self.c = c = Signal((48, True), reset_less=True)
self.mux_p = mux_p = Signal() # accumulator mux
self.m = m = Signal((48, True), reset_less=True)
self.mult_out = mult_out = Signal.like(m)
self.p = p = Signal((48, True), reset_less=True)
self.sync += [m.eq(a * b), p.eq(m + c), If(mux_p, p.eq(m + p))]
self.comb += mult_out.eq(a * b)
self.sync += [
m.eq(
Cat(mult_out, [mult_out[-1]] * (len(m) - len(a) - len(b)))
), # extend sign bit
p.eq(m + c),
If(mux_p, p.eq(m + p)),
]


class Iir(Module):
Expand Down Expand Up @@ -50,7 +58,7 @@ def __init__(self, w_coeff, w_data, log2_a0, n_profiles, n_channels):

###

# Making these registers reset less results in worsend timing.
# Making these registers reset less results in worse timing.
# y1 register unique for each profile
y1 = Array(
Array(Signal((w_data, True)) for _ in range(n_channels))
Expand All @@ -73,7 +81,7 @@ def __init__(self, w_coeff, w_data, log2_a0, n_profiles, n_channels):
# 2(4) -> p2=p1+m2
# 3(5) -> retrieve data y0=clip(p2)?hold
step = Signal(2) # computation step
ch_profile_last_ch = Signal(max=n_profiles + 1) # auxillary signal for muxing
ch_profile_last_ch = Signal(max=n_profiles + 1) # auxiliary signal for muxing
self.submodules.dsp = dsp = Dsp()
assert w_data <= len(dsp.b)
assert w_coeff <= len(dsp.a)
Expand All @@ -91,7 +99,14 @@ def __init__(self, w_coeff, w_data, log2_a0, n_profiles, n_channels):
dsp.b.eq(
x[channel_index][step] << shift_b
), # overwritten later if at step==2
dsp.c.eq(Cat(c_rounding_offset, offset[profile_index][channel_index])),
dsp.c.eq(
Cat(
c_rounding_offset,
offset[profile_index][channel_index],
[offset[profile_index][channel_index][-1]] # extend sign bit
* (len(dsp.c) - len(dsp.a) - len(dsp.b) + (w_data - log2_a0)),
)
),
If(
stb_in & ~busy,
busy.eq(1),
Expand Down