def iir_df1dsos(din, *, a, b, gain, ogain): # init temp temp = din # add cascades for all b coefficients for i in range(len(b)): # format every cascaded output as input temp = temp | iir_1dsos(a=a[i], b=b[i], gain=gain[i]) | qround( fract=din.dtype.fract) | saturate(t=din.dtype) # add output gain and format as input dout = (temp * ogain) | qround(fract=din.dtype.fract) | saturate(t=din.dtype) return dout
def test_saturate_uint(sim_cls): seq = [0, 14, 15, 16, 32, 63] ref = [0, 14, 15, 15, 15, 15] directed(drv(t=Uint[6], seq=seq), f=saturate(t=Uint[4], sim_cls=sim_cls), ref=ref) sim()
def test_saturate_ufixp(sim_cls): dtype = Ufixp[4, 8] sat_type = Ufixp[2, 6] seq = [0.0, sat_type.fmax, sat_type.fmax + dtype.quant, dtype.fmax] ref = [0.0, sat_type.fmax, sat_type.fmax, sat_type.fmax] directed(drv(t=dtype, seq=seq), f=saturate(t=sat_type), ref=ref) sim()
def test_saturate_int_to_larger(sim_cls): seq = [-63, -32, -17, -16, 0, 14, 15, 16, 32, 63] ref = seq directed(drv(t=Int[7], seq=seq), f=saturate(t=Int[9], sim_cls=sim_cls), ref=ref) sim()
def test_saturate_int(sim_cls): seq = [-63, -32, -17, -16, 0, 14, 15, 16, 32, 63] ref = [-16, -16, -16, -16, 0, 14, 15, 15, 15, 15] directed(drv(t=Int[7], seq=seq), f=saturate(t=Int[5], sim_cls=sim_cls), ref=ref) sim()
def dot(din: Queue[Tuple[Uint[8], Fixp]]): coef_t = din.dtype.data[1] accum_t = Fixp[coef_t.integer + 2, coef_t.width + 2] return din \ | queuemap(f=mul) \ | accum(init=accum_t(0.0), cast=saturate) \ | qround \ | saturate(t=Uint[8])
def filter(din: Queue[Uint[8]], *, coeffs, precision=32): accum_t = Ufixp[10, 10 + precision] coeff = qrange(3*3) \ | flatten \ | rom(data=coeffs, dtype=Ufixp[0, precision]) return czip(din, coeff) \ | queuemap(f=mul) \ | accum(init=accum_t(0.0), cast=saturate) \ | qround \ | saturate(t=Uint[8])
def fir_direct(din, *, b): # init delayed input and output sum x = din y_sum = x * b[0] # construct filter structure for all fir coefficients for b_coef in b[1:]: # add delay x = x | dreg(init=0) # summation y_sum = y_sum + (x * b_coef) # format sum as input return y_sum | qround(fract=din.dtype.fract) | saturate(t=din.dtype)
def filter(pixels: Queue[Uint[8]], coef: Queue[Fixp], *, window_num): coef_t = coef.dtype.data accum_t = Fixp[coef_t.integer + 2, coef_t.width + 2] window_cnt = replicate(window_num, 3 * 3) mem_wr_data = czip(qcnt(coef, running=True, w_out=4, init=0), coef) | flatten coef_rd = qrange(window_cnt['data']) \ | flatten \ | sdp(wr_addr_data=mem_wr_data, depth=16) return czip(pixels, coef_rd) \ | queuemap(f=mul) \ | accum(init=accum_t(0.0), cast=saturate) \ | qround \ | saturate(t=Uint[8])
def fir_transposed(din, *, b): # init output sum y_sum = din * b[0] # construct filter structure for all fir coefficients for b_coef in b[1:]: # multiply input with b coefficient mult_b_result = din * b_coef # delay output sum delayed_y_sum = y_sum | dreg(init=0) # add to output sum y_sum = mult_b_result + delayed_y_sum # format sum as input return y_sum | qround(fract=din.dtype.fract) | saturate(t=din.dtype)
def iir_1dsos(din, *, a, b, gain): # add input gain and init delayed inputs zu0 = din * gain zu1 = zu0 | dreg(init=0) zu2 = zu1 | dreg(init=0) # perform b coefficient sum a1 = (zu1 * b[1]) + (zu2 * b[2]) a2 = a1 + (zu0 * b[0]) # declare output interface and its type y = Intf(a2.dtype) # init delayed outputs zy1 = y | decouple(init=0) zy2 = zy1 | dreg(init=0) # perform a coefficient sum b1 = (zy2 * a[2]) + (zy1 * a[1]) # add both sums and set output y |= (a2 - b1) | qround(fract=a2.dtype.fract) | saturate(t=a2.dtype) return y
def iir_2tsos(din, *, a, b, gain): # add input gain x = din * gain # declare output interface and its type y = Intf(din.dtype) # perform first tap multiplication and sum z0 = ((x * b[2]) - (y * a[2])) # delay first sum output z0_delayed = z0 | dreg(init=0) # perform second tap multiplication and sum z1 = ((x * b[1]) + z0_delayed - (y * a[1])) # delay second sum output z1_delayed = z1 | decouple(init=0) # perform final sum and set output y |= ((x * b[0]) + z1_delayed) | qround(fract=din.dtype.fract) | saturate(t=din.dtype) return y
def test_saturate_fail(): with pytest.raises(TypeError): Intf(Fixp[4, 8]) | saturate(t=Fixp[3, 5]) with pytest.raises(TypeError): Intf(Fixp[4, 8]) | saturate(t=Fixp[3, 9])
def format_fixp(din, *, t): return din | qround(fract=t.fract) | saturate(t=t)