def verif(*stim, f, ref, delays=None, cmp=None, check_timing=False, make_report=False): """Verification environment for comparing DUV results with reference model. The environment instantiates the DUV and reference model and drives the passed stimulus to both. The outpus are passed to the scoreboard which compares the results. Outputs are decoupled to ensure there is no connection between the DUV and the environment. Optional delays can be added to all input and output interfaces. Args: stim: Input stimulus f: Gear to be verified ref: Gear used as reference model delays: List of delays for all inputs and outputs tolerance: Tolerance window when performing equality checks Returns: A report dictionary with pass/fail statistics """ if stim: res_tlm = stim | f ref_tlm = stim | ref else: res_tlm = f ref_tlm = ref if check_timing: ref_tlm, res_tlm = match_timing(ref_tlm, res_tlm) if not isinstance(res_tlm, tuple): res_tlm = (res_tlm, ) ref_tlm = (ref_tlm, ) if make_report: report = [[] for _ in range(len(res_tlm))] else: report = [None for _ in range(len(res_tlm))] if delays is None: delays = (None, ) * len(res_tlm) assert len(ref_tlm) == len(res_tlm) assert len(delays) == len(res_tlm) for r, res_intf, ref_intf, d in zip(report, res_tlm, ref_tlm, delays): if d is not None: res_intf = res_intf | d res_intf = res_intf | decouple(depth=0) ref_intf = ref_intf | decouple(depth=0) scoreboard(res_intf, ref_intf, report=r, cmp=cmp) return report
def matrix_multiplication(cfg, mat1, mat2, *, cols_per_row): """General idea is to parallelize matrix multiplication, this is achieved by multiplying one row with several columns at the same time. Number of columns that are multiplied with one row is cols_per_row. Column_multiplication is module that multiplies one row with one column at the time, it can also store several columns in it. First we need to split mat2 by columns and send them to different column_multiplication modules, to be stored, then send every row on each column_multiplication.""" col_chunks = qdeal(mat2, num=cols_per_row, lvl=1) row_chunks = row_dispatch(mat1, cols_per_row=cols_per_row) \ | dreg \ | decouple(latency=2) \ | dispatch tmp = [] if not isinstance(col_chunks, tuple): col_chunks = (col_chunks, ) if not isinstance(row_chunks, tuple): row_chunks = (row_chunks, ) for col, row in zip(col_chunks, row_chunks): # col is flattened because, after qdeal, every col has type Queue lvl1 with eot == True # after flattening, we group it by cols_per_multiplier (set eot (last) after last column that goes # to specific column multiplier) col = col | flatten | group(size=cfg['cols_per_multiplier']) tmp.append(column_multiplication(cfg, row, col) | flatten) res = ccat(*tmp) | Array return res
def test_cosim(cosim_cls): seq = list(range(1, 10)) directed(drv(t=Uint[16], seq=seq) | delay_rng(0, 2), f=decouple(sim_cls=cosim_cls), ref=seq, delays=[delay_rng(0, 2)]) sim()
def iir_2tsos(din, *, a, b, gain): din = din * gain y = Intf(din.dtype * 5) a1 = ((din * b[2]) - (y * a[2])) z1 = a1 | dreg(init=0) z2 = ((din * b[1]) + z1 - (y * a[1])) | decouple(init=0) y |= (din * b[0]) + z2 return y
def iir_1dsos(din, *, a, b, gain): din = din * gain zu1 = din | dreg(init=0) zu2 = zu1 | dreg(init=0) a1 = (zu1 * b[1]) + (zu2 * b[2]) a2 = a1 + (din * b[0]) y = Intf(a2.dtype * 2) zy1 = y | a2.dtype | decouple(init=0) zy2 = zy1 | dreg(init=0) a3 = (zy2 * a[2]) + (zy1 * a[1]) y |= a2 - a3 return y
def echo(din: Fixp, *, feedback_gain, sample_rate, delay): """Performs echo audio effect on the continuous input sample stream Args: din: Stream of audio samples Keyword Args: feedback_gain (float): gain of the feedback loop sample_rate (int): samples per second delay (float): delay in seconds precision (int): sample fixed point precision sample_width (int): sample width in bits Returns: - **dout** - Stream of audio samples with applied echo """ ######################### # Parameter calculation # ######################### sample_dly_len = round(sample_rate * delay) fifo_depth = ceil_pow2(sample_dly_len) feedback_gain_fixp = din.dtype(feedback_gain) ######################### # Hardware description # ######################### dout = Intf(din.dtype) feedback = dout \ | decouple(depth=fifo_depth) \ | prefill(dtype=din.dtype, num=sample_dly_len) feedback_attenuated = (feedback * feedback_gain_fixp) | din.dtype dout |= (din + feedback_attenuated) | dout.dtype return dout
def directed_on_the_fly(*stim, f, refs, delays=None): """Similar to ``directed`` function, except ``ref`` is a generator and checking is done `on-the-fly`""" res_tlm = stim | f if not isinstance(res_tlm, tuple): res_tlm = (res_tlm, ) if delays is None: delays = (None, ) * len(res_tlm) report = [[] for _ in range(len(res_tlm))] for r, res_intf, ref, d in zip(report, res_tlm, refs, delays): if d is not None: res_intf = res_intf | d res_intf = res_intf | decouple(depth=0) # ref = ref | decouple(depth=0) scoreboard(res_intf, ref, report=r) return report
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_synth_u1_vivado(): decouple(Intf(Uint[1]))
def test_synth_u64_vivado(): decouple(Intf(Uint[64]))