示例#1
0
def test_fir_random_type(impl, seed, do_cosim):
    # Set random seed
    set_seed(seed)

    log.info(f'{__name__} impl: {impl}, seed: {seed}')

    fixp_w = random.randint(16, 32)
    int_w = random.randint(1, 3)

    t_b = Fixp[int_w, fixp_w]
    log.info(
        f'{__name__} FIR input type t_b: {t_b} min: {t_b.fmin}, max: {t_b.fmax}'
    )

    seq = []
    # generate multiple constant sequences of certain size
    for i in range(10):
        num = np.random.uniform(t_b.fmin, t_b.fmax)
        for i in range(50):
            seq.append(num)
    # add a random sequence of certain size
    seq.extend(random_seq(t_b, 100))

    # genrate  random numbers in [-1,1)
    # seq = np.random.random(size=(100, )) * 2 - 1
    log.debug(f'Generated sequence: {seq}')

    res = fir_sim(impl, t_b, seq, do_cosim=do_cosim)
示例#2
0
def test_iir_random(impl, seed, do_cosim):
    log.info(f'Running test_iir_random seed: {seed}')
    set_seed(seed)

    ftype = Fixp[5, 32]

    seq = constant_seq(ftype, 10, 0)
    seq.extend(random_seq(ftype, 100))
    seq.extend(constant_seq(ftype, 10, 0))

    iir_sim(impl, ftype, ftype, ftype, seq, do_cosim=do_cosim)
示例#3
0
def test_fir_random(impl, seed, do_cosim):
    # Set random seed
    set_seed(seed)

    log.info(f'Running {__name__} impl: {impl}, seed: {seed}')

    t_b = Fixp[1, 15]

    # genrate  random numbers in [-1,1)
    seq = np.random.random(size=(100, )) * 2 - 1
    log.debug(f'Generated sequence: {seq}')

    res = fir_sim(impl, t_b, seq, do_cosim=do_cosim)
示例#4
0
def xsim(outdir=None,
         makefile=True,
         files=None,
         includes=None,
         batch=True,
         seed=None):
    outdir = os.path.abspath(outdir)

    if not makefile and not shutil.which('xsim'):
        raise CosimulatorUnavailable

    dpi_path = os.path.abspath(os.path.join(ROOT_DIR, 'sim', 'dpi'))
    context = {
        'dti_verif_path': dpi_path,
        'outdir': outdir,
        'top_name': '_top',
        'files': files,
        'includes': includes,
    }

    base_addr = os.path.dirname(__file__)
    env = jinja2.Environment(loader=jinja2.FileSystemLoader(base_addr),
                             trim_blocks=True,
                             lstrip_blocks=True)

    res = env.get_template('run_xsim.j2').render(context)
    fname = save_file('run_xsim.sh', outdir, res)
    os.chmod(fname, 0o777)

    kwds = {
        'batch': batch,
        'seed': seed if seed is not None else reg["sim/rand_seed"]
    }

    if makefile:
        log.info(f"Waiting for manual XSim invocation. Run script: {fname}...")

        return None

    args = ' '.join(f'-{k} {v if not isinstance(v, bool) else ""}'
                    for k, v in kwds.items() if not isinstance(v, bool) or v)

    # stdout = None
    stdout = DEVNULL

    log.info(f'Starting XSim...')

    return Popen([f'./run_xsim.sh'] + args.split(' '),
                 stdout=stdout,
                 stderr=stdout,
                 cwd=outdir)
示例#5
0
def test_iir_limits(fixp_w, int_w, impl, seed, do_cosim):
    """[Drive filter with extreme values [min, 0 , max]
    """
    log.info(f'Running test_iir_limits, seed: {seed}')
    set_seed(seed)
    factor = 0.5  # supported factor

    ftype = Fixp[int_w, fixp_w]
    print(f'max possible value {ftype.fmax}')
    extremes = [[0 for i in range(50)]]
    extremes.append([ftype.fmin * factor for i in range(10)])
    seq = random_choice_seq(extremes, 10)
    extremes.append([ftype.fmax * factor for i in range(10)])
    seq = random_choice_seq(extremes, 10)
    iir_sim(impl, ftype, ftype, ftype, seq, do_cosim=do_cosim)
示例#6
0
def test_iir_direct(tmpdir, impl, seed, do_cosim):
    reg['sim/rand_seed'] = seed
    random.seed(reg['sim/rand_seed'])
    log.info(
        f'Running test_fir_direct tmpdir: {tmpdir}, impl: {impl}, seed: {seed}'
    )
    reg['sim/clk_freq'] = 100000
    t = list(range(reg['sim/clk_freq']))[0:100]
    fs = reg['sim/clk_freq']
    f1 = 1000
    f2 = 70000

    seq = []
    for n in t:
        seq.append(1 * sin(2 * pi * f1 / fs * n) +
                   0.1 * sin(2 * pi * f2 / fs * n))

    sos = signal.butter(N=5,
                        Wn=30000 / 100000,
                        btype='lowpass',
                        analog=False,
                        output='sos')

    a, b = [], []
    for s in sos:
        b.append(list(s[0:3]))
        a.append(list(s[3:]))

    t_coef = Fixp[5, 32]

    b = [[t_coef(coef) for coef in section] for section in b]
    a = [[t_coef(coef) for coef in section] for section in a]

    gain = [Fixp[2, 23](1)] * len(b)
    ref = signal.sosfilt(sos, seq)
    fp_ref = [float(r) for r in ref]

    log.debug(f'Generated sequence: {seq}')
    drv(t=Fixp[5, 24], seq=seq) \
    | impl(a=a, b=b, gain=gain, ogain=Fixp[5, 24](1)) \
    | Float \
    | check(ref=fp_ref[:len(seq)], cmp=lambda x, y: abs(x - y) < 1e-3)

    if do_cosim:
        cosim(f'{impl}', 'verilator', outdir=tmpdir, timeout=1000)

    sim(tmpdir, check_activity=False)
示例#7
0
文件: sim.py 项目: jesseclin/pygears
def sim(resdir=None,
        timeout=None,
        extens=None,
        run=True,
        check_activity=False,
        seed=None):
    if reg['sim/dryrun']:
        return

    if extens is None:
        extens = []

    extens.extend(reg['sim/extens'])

    if resdir is None:
        resdir = reg['results-dir']

    reg['results-dir'] = resdir
    os.makedirs(resdir, exist_ok=True)

    if reg['sim/rand_seed'] is None:
        if seed is None:
            seed = random.randrange(sys.maxsize)

        reg['sim/rand_seed'] = seed

    random.seed(reg['sim/rand_seed'])

    log.info(f'Running sim with seed: {reg["sim/rand_seed"]}')

    loop = EventLoop()
    asyncio.set_event_loop(loop)
    reg['sim/simulator'] = loop

    if check_activity:
        from pygears.sim.extens.activity import ActivityChecker
        if ActivityChecker not in extens:
            extens.append(ActivityChecker)

    for oper in itertools.chain(reg['sim/flow'], extens):
        oper()

    if run:
        loop.run(timeout)

    return loop
示例#8
0
def test_iir_random_type(impl, seed, do_cosim):
    log.info(f'Running test_iir_random, seed: {seed}')
    set_seed(seed)

    # minimum supported precision Fixp[3,19]
    int_w = random.randint(3, 7)
    fixp_w = random.randint(int_w + 19, int_w + 32)
    ftype = Fixp[int_w, fixp_w]

    log.info(
        f'{__name__} FIR input type t_b: {ftype} min: {ftype.fmin}, max: {ftype.fmax}'
    )

    seq = constant_seq(ftype, 10, 0)
    seq.extend(random_seq(ftype, 100))
    seq.extend(constant_seq(ftype, 10, 0))

    iir_sim(impl, ftype, ftype, ftype, seq, do_cosim=do_cosim)
示例#9
0
    def finish(self):
        if self.sock:
            if self.conn:
                try:
                    self.send_cmd(CMD_FINISH)
                    time.sleep(0.5)
                except BrokenPipeError:
                    pass

            log.info(f'Done. Closing the socket...')
            self.sock.close()
            time.sleep(1)

            if self.cosim_pid is not None:
                self.cosim_pid.terminate()

            self.sock = None
            self.cosim_pid = None
            self.conn = None
            atexit.unregister(self.finish)
示例#10
0
def test_fir_sine(freq, impl, seed, do_cosim):
    """[Drive filter with sine signal at fs fs/2 and fs*2 
    """
    # Set random seed
    set_seed(seed)
    # set clock freq
    reg['sim/clk_freq'] = freq
    t = list(range(reg['sim/clk_freq']))[0:100]
    fs = reg['sim/clk_freq']
    f1 = freq / 100
    log.info(f'Running {__name__} impl: {impl}, seed: {seed}, fs:{fs},f1:{f1}')

    ftype = Fixp[5, 32]
    seq = [0 for i in range(10)]
    seq.extend(sine_seq(f1, fs, 200, ftype))
    seq.extend([0 for i in range(100)])
    seq.extend(sine_seq(f1, fs / 2, 100, ftype))
    seq.extend([0 for i in range(100)])
    seq.extend(sine_seq(f1, fs * 2, 400, ftype))
    seq.extend([0 for i in range(10)])
    res = iir_sim(impl, ftype, ftype, ftype, seq, do_cosim=do_cosim)
示例#11
0
def test_fir_limits(fixp_w, int_w, impl, seed, do_cosim):
    """[Drive filter with extreme values [min, 0 , max]
    """
    # Set random seed
    set_seed(seed)

    log.info(f'Running {__name__} impl: {impl}, seed: {seed}')

    t_b = Fixp[int_w, fixp_w]
    log.info(
        f'{__name__} FIR input type t_b: {t_b} min: {t_b.fmin}, max: {t_b.fmax}'
    )

    extremes = [[0 for i in range(50)]]
    extremes.append([t_b.fmin for i in range(50)])
    extremes.append([t_b.fmax for i in range(50)])
    seq = random_choice_seq(extremes, 10)

    log.debug(f'Generated sequence: {seq}')

    res = fir_sim(impl, t_b, seq, do_cosim=do_cosim)
示例#12
0
def test_fir_sine(freq, impl, seed, do_cosim):
    """[Drive filter with sine signal at fs fs/2 and fs*2 
    """
    # Set random seed
    set_seed(seed)
    # set clock freq
    reg['sim/clk_freq'] = freq
    t = list(range(reg['sim/clk_freq']))[0:100]
    fs = reg['sim/clk_freq']
    f1 = freq / 100

    log.info(f'Running {__name__} impl: {impl}, seed: {seed}')

    t_b = Fixp[1, 15]
    seq = [0 for i in range(10)]
    seq.extend(sine_seq(f1, fs, 200, t_b))
    seq.extend(sine_seq(f1, fs / 2, 100, t_b))
    seq.extend(sine_seq(f1, fs * 2, 400, t_b))
    seq.extend([0 for i in range(10)])

    log.debug(f'Generated sequence: {seq}')

    res = fir_sim(impl, t_b, seq, do_cosim=do_cosim)
示例#13
0
文件: vcd.py 项目: jesseclin/pygears
    def __init__(self,
                 trace_fn='pygears.vcd',
                 include=Inject('debug/trace'),
                 tlm=False,
                 shmidcat=Inject('sim_extens/vcd/shmidcat'),
                 vcd_fifo=Inject('sim_extens/vcd/vcd_fifo'),
                 sim=Inject('sim/simulator'),
                 outdir=Inject('results-dir')):

        super().__init__()
        self.sim = sim
        self.finished = False
        self.vcd_fifo = vcd_fifo
        self.shmidcat = shmidcat
        self.outdir = outdir
        self.trace_fn = None
        self.shmid_proc = None

        vcd_visitor = VCDHierVisitor(include, tlm)
        vcd_visitor.visit(find('/'))

        if not vcd_visitor.vcd_vars:
            self.deactivate()
            return

        self.trace_fn = os.path.abspath(os.path.join(self.outdir, trace_fn))
        atexit.register(self.finish)

        try:
            subprocess.call(f"rm -f {self.trace_fn}", shell=True)
        except OSError:
            pass

        if self.vcd_fifo:
            subprocess.call(f"mkfifo {self.trace_fn}", shell=True)
        else:
            log.info(f'Main VCD dump to "{self.trace_fn}"')

        if self.shmidcat:
            self.shmid_proc = subprocess.Popen(f'shmidcat {self.trace_fn}',
                                               shell=True,
                                               stdout=subprocess.PIPE)

            # Wait for shmidcat to actually open the pipe, which is necessary
            # to happen prior to init of the verilator. If shmidcat does not
            # open the pipe, verilator will get stuck
            import time
            time.sleep(0.1)

        self.vcd_file = open(self.trace_fn, 'w')

        if self.shmidcat:
            self.shmid = self.shmid_proc.stdout.readline().decode().strip()
            log.info(f'Main VCD dump to shared memory at 0x{self.shmid}')

        self.writer = VCDWriter(self.vcd_file, timescale='1 ns', date='today')

        reg['VCDWriter'] = self.writer
        reg['VCD'] = self

        self.clk_var = self.writer.register_var('', 'clk', 'wire', size=1, init=1)

        self.timestep_var = self.writer.register_var('', 'timestep', 'integer', init=0)

        self.handhake = set()

        self.vcd_vars = {
            p: register_traces_for_intf(p.dtype, scope, self.writer)
            for p, scope in vcd_visitor.vcd_vars.items()
        }

        self.writer.flush()
示例#14
0
 def after_call_forward(self, sim, sim_gear):
     log.info(f'forward')
     return True
示例#15
0
文件: sim.py 项目: bogdanvuk/pygears
    def sim_loop(self, timeout):
        clk = reg['sim/clk_event']
        delta = reg['sim/delta_event']

        global gear_reg, sim_reg
        gear_reg = reg['gear']._dict
        sim_reg = reg['sim']._dict

        reg['sim/timestep'] = 0

        timestep = -1
        start_time = time.time()
        finished = False

        log.info("-------------- Simulation start --------------")
        while (self.forward_ready or self.back_ready or self._schedule_to_finish or not finished):
            # Conditional timeout context
            with contextlib.ExitStack() as stack:
                if self.step_timeout:
                    stack.enter_context(stopit.ThreadingTimeout(self.step_timeout, swallow_exc=False))

                finished = not bool(self.forward_ready or self.back_ready
                                    or self._schedule_to_finish)

                timestep += 1
                reg['sim/timestep'] = timestep
                if (timeout is not None) and (timestep == timeout):
                    break

                # if (timestep % 1000) == 0:
                #     log.info("-------------- Simulation cycle --------------")

                # print(f"-------------- {timestep} ------------------")
                # print(f'Tasks: {len(self.tasks)}')

                # if timestep == 516:
                #     breakpoint()

                self.phase = 'forward'
                self.sim_list(self.sim_gears)

                self.phase = 'delta'
                delta.set()
                delta.clear()

                self.phase = 'back'
                while self._schedule_to_finish:
                    for sim_gear in self._schedule_to_finish.copy():
                        self._finish(sim_gear)
                        self._schedule_to_finish.remove(sim_gear)

                self.sim_list(self.sim_gears)

                self.phase = 'cycle'
                self.events['before_timestep'](self, timestep)

                clk.set()
                clk.clear()

                # for sim_gear in reversed(self.sim_gears):
                #     if sim_gear in self.delta_ready:
                #         # if hasattr(sim_gear, 'port'):
                #         #     print(f'Clock: {sim_gear.gear.name}.{sim_gear.port.basename}')
                #         # else:
                #         #     print(f'Clock: {sim_gear.gear.name}')

                #         self.maybe_run_gear(sim_gear, self.delta_ready)

                for sim_gear in self.done:
                    self.remove(sim_gear)

                self.done.clear()

                self.events['after_timestep'](self, timestep)

        log.info(f"----------- Simulation done ---------------")
        log.info(f'Elapsed: {time.time() - start_time:.2f}')
示例#16
0
############################## SELECT TEST ###############################
test_sel = 1  # 0=fir_direct; 1=fir_transposed
enable_svgen = 1  # enables systemVerilog generation
##########################################################################
# >> used to probe all signals
reg['debug/trace'] = ['*']
# >> used to enable JSON file creation for webviewer support
reg['debug/webviewer'] = True

# set either random or custom seed
seed = random.randrange(0, 2**32, 1)
# seed = 1379896999

# """Unify all seeds"""
log.info(f"Random SEED: {seed}")
set_seed(seed)

# generate b coefficients
b_coef = firwin(8, [0.05, 0.95], width=0.05, pass_zero=False)

# generate quantized b coefficients
b_coef_type = Fixp[1, 15]
b_coef_fixp = [b_coef_type(i) for i in b_coef]

# generate random inputs
x = np.random.random(size=(10, ))

# calculated expected outputs
ref = np.convolve(x, b_coef)
def matrix_ops_single():
    ########################## DESIGN CONTROLS ##########################
    num_cols = 8
    num_rows = 6  # HINT suppoerted all dimesitions > 1
    cols_per_row = 2  # HINT suported values that are divisible with num_colls
    ########################### TEST CONTROLS ###########################
    sv_gen = 1
    ###########################################################################
    # set either random or custom seed
    seed = random.randrange(0, 2**32, 1)
    # seed = 1379896999

    # """Unify all seeds"""
    log.info(f"Random SEED: {seed}")
    set_seed(seed)

    ## input randomization
    mat1 = np.random.randint(128, size=(num_rows, num_cols))
    mat2 = np.random.randint(128, size=(num_rows, num_cols))
    mat1 = np.ones((num_rows, num_cols))
    mat2 = np.ones((num_rows, num_cols))

    # input the constatn value optionally
    # mat1 = np.empty((num_rows, num_cols))
    # mat2 = np.empty((num_rows, num_cols))
    # # fill the matrix with the same value
    # mat1.fill(32767)
    # mat2.fill(-32768)

    print("Inputs: ")
    print(type(mat1))
    print(mat1)
    print(type(mat2))
    print(mat2)

    reg['trace/level'] = 0
    reg['gear/memoize'] = False

    reg['debug/trace'] = ['*']
    reg['debug/webviewer'] = True
    res_list = []

    cfg = {
        "cols_per_row": cols_per_row,
        "num_rows": num_rows,
        "num_cols": num_cols,
        'cols_per_multiplier': num_rows // cols_per_row
    }
    cfg_seq = [cfg]
    cfg_drv = drv(t=TCfg, seq=cfg_seq)

    # Add one more dimenstion to the matrix to support input type for design
    mat1 = mat1.reshape(1, mat1.shape[0], mat1.shape[1])
    mat2 = mat2.reshape(mat2.shape[0], 1, mat2.shape[1])
    mat1_seq = [mat1]
    mat2_seq = [mat2]

    row_t = Queue[Array[Int[16], cfg['num_cols']]]
    mat1_drv = drv(t=Queue[row_t], seq=mat1_seq)
    mat2_drv = drv(t=Queue[row_t], seq=mat2_seq)
    res = matrix_multiplication(cfg_drv,
                                mat1_drv,
                                mat2_drv,
                                cols_per_row=cols_per_row)
    collect(res, result=res_list)

    if sv_gen:
        cosim('/matrix_multiplication',
              'verilator',
              outdir='build/matrix_multiplication/rtl',
              rebuild=True,
              timeout=100)
    sim('build/matrix_multiplication')

    ## Print raw results results
    log.info(f'len_res_list: \n{len(res_list)}')
    try:
        pg_res = [int(el) for row_chunk in res_list for el in row_chunk]
        # calc refference data - matrix2 needs to be transposed before doing multiplocation
        np_res = np.dot(np.squeeze(mat1), np.transpose(mat2.squeeze()))
        pg_res = np.array(pg_res).reshape(np_res.shape)

        log.info(f'result: \n{res}')
        log.info(f'pg_res: \n{pg_res}, shape: {pg_res.shape}')
        log.info(f'np_res: \n{np_res}, shape: {np_res.shape}')
        sim_assert(
            np.equal(pg_res, np_res).all(), "Error in compatring results")
        log.info("\033[92m //==== PASS ====// \033[90m")
    except:
        # printing stack trace
        traceback.print_exc()
        log.info("\033[91m //==== FAILED ====// \033[90m")
示例#18
0
 def after_call_back(self, sim, sim_gear):
     log.info(f'back')
     return True
示例#19
0
@pytest.mark.parametrize('num_cols', [2, 3, 4, 5, 6, 7, 8])
@pytest.mark.parametrize('num_rows', [2, 3, 4, 5, 6, 7, 8])
@pytest.mark.parametrize('cols_per_row', [1])
@pytest.mark.parametrize('impl', ['high', 'hw'])
def test_column_multiplicator(impl, num_cols, num_rows, cols_per_row, seed):
    set_seed(seed)
    res_list = []

    mat1 = np.random.randint(256, size=(num_cols, num_rows))
    mat2 = np.random.randint(256, size=(num_cols, num_rows))

    run_matrix(impl, mat1, mat2, cols_per_row, col_only=True)


# run individual test with python command
if __name__ == '__main__':
    reg['debug/trace'] = ['*']
    reg['debug/webviewer'] = True

    try:
        ## HINT : for debugging individual tests
        test_column_multiplicator('sim', 3, 3, 1, 1)
        # test_matrix_mult('sim',num_cols=3,num_rows=3,cols_per_row=1,seed=1)
        # test_matrix_mult_cols('hw', 5, 1)
        # log.info("\033[92m //==== PASS ====// \033[90m")
    except:
        # printing stack trace
        traceback.print_exc()
        log.info("\033[91m //==== FAILED ====// \033[90m")
示例#20
0
async def check(din, *, ref, cmp=None):
    """Checks equality of input data with expected.

    Args:
        ref: A list of expected values

    Returns:
        None

    If type ``din`` is a :class:`Queue` of certain level, then ``ref`` should
    generate nested iterables of the same level
    """
    def match_exact(x, y):
        return x == y

    if cmp is None:
        cmp = match_exact

    iter_ref = iter(ref)
    ref_seq = iter(())

    try:
        items = []
        while True:
            data = await din.get()
            items.append(data)

            try:
                ref_item = next(ref_seq)
            except StopIteration:
                ref_seq = typeseq(din.dtype, next(iter_ref))
                ref_item = next(ref_seq)

            cmp_res = cmp(data, ref_item)

            if not cmp_res:
                if cmp is match_exact:
                    v = ErrorVisitor()
                    err = None
                    try:
                        v.visit(data, ref_item)
                    except ValueError as e:
                        err = e

                    if err:
                        log.error(
                            f'mismatch in item #{len(items)}\n {str(err)}')
                    else:
                        breakpoint()
                else:
                    log.error(
                        f'mismatch in item #{len(items)}. Got: {data}, expected: {ref_item}'
                    )

    except GearDone:
        ref_empty = False
        try:
            next(ref_seq)
        except StopIteration:
            try:
                next(iter_ref)
            except StopIteration:
                ref_empty = True

        if ref_empty:
            log.info(f'Number of matches: {len(items)}')
        else:
            log.error(
                f"mismatch in number of items, got '{len(items)}' but expected '{len(ref)}'. "
                f"\ngot:\n{textwrap.indent(pprint.pformat(items), ' '*4)}"
                f"\nexp:\n{textwrap.indent(pprint.pformat(ref), ' '*4)}")

    except (GearDone, StopIteration):
        log.error(f"mismatch in number of items {len(items)} vs {len(ref)}. "
                  f"\ngot:\n{textwrap.indent(pprint.pformat(items), ' '*4)}"
                  f"\nexp:\n{textwrap.indent(pprint.pformat(ref), ' '*4)}")

    raise GearDone
示例#21
0
async def scoreboard(*din: b't', report=None, cmp=None) -> None:
    """Generic scoreboard used from comparing actual results from the DUT to
    expected results. Eventual mismatches are asserted using the ``sim_assert``
    function meaning that any ``error`` behaviour is controled via the ``sim``
    logger ``error`` settings.

    Args:
        din: Outputs from both the DUT and ref. model. All intpus are a PyGears
          interface
        report: List to with comparison results are appended
        tolerance: Optional tolerance when comparing results. The DUT result must
          be in the (expected - tolerance, expected+tolerance) range

    Returns:
        None
    """
    def match_exact(x, y):
        return x == y

    if cmp is None:
        cmp = match_exact

    # print(f'Number of matches: -\r', end='')
    cnt = 0
    match_cnt = 0
    try:
        while True:
            items = []
            for d in din:
                items.append(await d.get())

            match = all(cmp(v, items[0]) for v in items)

            if report is not None:
                report.append({'match': match, 'items': items})

            cnt += 1
            if match:
                match_cnt += 1

            sim_assert(match, f'mismatch on #{cnt}: {items[0]}, {items[1]}')

            # print(f'Number of matches: {match_cnt:>4}/{cnt:>4}\r', end='')

    except GearDone as e:
        log.info(f'Number of matches: {match_cnt:>4}/{cnt:>4}')
        offending = None

        if len(items):
            offending = len(items)

        if any(not d.empty() for d in din):
            for i, d in enumerate(din):
                if d.empty():
                    offending = i
                    break

        if offending is not None:
            log.error(f"Input {offending} didn't produce enough output data")

        raise e
示例#22
0
def run_matrix(impl, mat1, mat2, cols_per_row, col_only: bool = False):
    reg['trace/level'] = 0
    reg['gear/memoize'] = False
    # Add one more dimension to the matrix to support input type for design
    mat1 = mat1.reshape(1, mat1.shape[0], mat1.shape[1])
    mat2 = mat2.reshape(mat2.shape[0], 1, mat2.shape[1])

    # configuration driving
    cfg = create_valid_cfg(cols_per_row, mat1)
    cfg_drv = drv(t=TCfg, seq=[cfg])

    row_t = Queue[Array[Int[16], cfg['num_cols']]]
    mat1_drv = drv(t=Queue[row_t], seq=[mat1])
    res_list = []

    if col_only:
        # remove the extra dimension that was previously added since colum mult accepts
        mat2 = np.squeeze(mat2)
        # for columtn multiplication second operand needs to be only one row
        mat2_drv = drv(t=row_t, seq=[mat2])
        res = column_multiplication(cfg_drv, mat1_drv, mat2_drv)
        # column multiplication returns result in a queue so flatening makes it a regular list
        collect(res | flatten, result=res_list)
        if impl == 'hw':
            cosim('/column_multiplication',
                  'verilator',
                  outdir='/tmp/column_multiplication',
                  rebuild=True,
                  timeout=100)
    else:
        mat2_drv = drv(t=Queue[row_t], seq=[mat2])
        res = matrix_multiplication(cfg_drv,
                                    mat1_drv,
                                    mat2_drv,
                                    cols_per_row=cols_per_row)
        collect(res, result=res_list)
        if impl == 'hw':
            cosim('/matrix_multiplication',
                  'verilator',
                  outdir='/tmp/matrix_multiplication',
                  rebuild=True,
                  timeout=100)
    try:
        sim()
        # convert PG results into regular 'int'

        if col_only:
            pg_res = [int(el) for el in res_list]
        else:
            pg_res = [int(el) for row_chunk in res_list for el in row_chunk]

        # calculate reference NumPy resutls
        np_res = np.dot(np.squeeze(mat1), np.transpose(mat2.squeeze()))
        # reshape PG results into the same format as
        pg_res = np.array(pg_res).reshape(np_res.shape)
        sim_assert(
            np.equal(pg_res, np_res).all(), "Error in compatring results")
        log.info("\033[92m //==== PASS ====// \033[90m")

    except:
        # printing stack trace
        traceback.print_exc()
        log.info("\033[91m //==== FAILED ====// \033[90m")
示例#23
0
    def setup(self):
        # TODO: When reusing existing verilated build, add test to check
        # whether verilated module is the same as the current one (Maybe hash check?)
        if self.rebuild:
            log.info(f'Verilating...')
            build(self.top, self.outdir, postsynth=False, lang=self.lang)
            log.info(f'Done')

        file_struct = get_file_struct(self.top, self.outdir)

        tracing_enabled = bool(reg['debug/trace'])
        if tracing_enabled:
            log.info(f"Debug: {reg['debug/trace']}")
            self.trace_fn = os.path.join(reg["results-dir"],
                                         f'{self.name}.vcd')
            try:
                subprocess.call(f"rm -f {self.trace_fn}", shell=True)
            except OSError:
                pass

            if self.vcd_fifo:
                subprocess.call(f"mkfifo {self.trace_fn}", shell=True)
            else:
                log.info(f'Verilator VCD dump to "{self.trace_fn}"')
        else:
            self.trace_fn = ''

        try:
            self.verilib = ctypes.CDLL(file_struct['dll_path'])
        except OSError:
            raise VerilatorCompileError(
                f'Verilator compiled library for the gear "{self.gear.name}"'
                f' not found at: "{file_struct["dll_path"]}"')

        self.finished = False
        atexit.register(self._finish)

        if self.shmidcat and tracing_enabled:
            self.shmid_proc = subprocess.Popen(f'shmidcat {self.trace_fn}',
                                               shell=True,
                                               stdout=subprocess.PIPE)

            # Wait for shmidcat to actually open the pipe, which is necessary
            # to happen prior to init of the verilator. If shmidcat does not
            # open the pipe, verilator will get stuck
            import time
            time.sleep(0.1)

        self.verilib.init.argtypes = [ctypes.c_char_p]

        assert self.verilib.init(self.trace_fn.encode('utf8')) != 0

        if self.shmid_proc:
            self.shmid = self.shmid_proc.stdout.readline().decode().strip()
            log.info(f'Verilator VCD dump to shared memory at 0x{self.shmid}')

        self.handlers = {}
        for cp in self.in_cosim_ports:
            self.handlers[cp.name] = CInputDrv(self.verilib, cp.port, cp.name)

        for cp in self.out_cosim_ports:
            self.handlers[cp.name] = COutputDrv(self.verilib, cp.port, cp.name)

        super().setup()