Exemplo n.º 1
0
    def create_scv(self):
        for constraint in self.constraints:
            jenv = jinja2.Environment(trim_blocks=True, lstrip_blocks=True)
            jenv.globals.update(int=int)
            jenv.loader = jinja2.FileSystemLoader([os.path.dirname(__file__)])

            def add_parens_for_vars(cons, cvars):
                def add_parens(matchobj):
                    if matchobj.group(0) in cvars:
                        return f'{matchobj.group(0)}()'
                    else:
                        return matchobj.group(0)

                return re.sub(r'([^\d\W]\w*)', add_parens, cons)

            scv_cons = [
                add_parens_for_vars(c, constraint.cvars)
                for c in constraint.cons
            ]
            context = {
                'vars': constraint.cvars,
                'constraints': scv_cons,
                'base_cls': constraint.cls
            }
            c = jenv.get_template('scv_wrap.j2').render(context)
            save_file(f'{constraint.name}.cpp', self.outdir, c)
Exemplo n.º 2
0
    def build(self, intfs=Inject('sim/svsock/intfs')):

        base_addr = os.path.dirname(__file__)
        env = jinja2.Environment(loader=jinja2.FileSystemLoader(base_addr),
                                 trim_blocks=True,
                                 lstrip_blocks=True)
        env.globals.update(zip=zip,
                           int=int,
                           print=print,
                           issubclass=issubclass)

        context = {'port': self.port}
        for phase in [
                'declaration', 'init', 'set_data', 'read', 'ack', 'reset',
                'sys_reset'
        ]:
            context[phase] = {}
            for i, intf in enumerate(intfs):
                if not hasattr(intf, phase):
                    continue

                phase_sv = getattr(intf, phase)()

                if phase_sv is not None:
                    context[phase][i] = phase_sv

        res = env.get_template('svsock_top.j2').render(context)
        save_file('_top.sv', self.outdir, res)
Exemplo n.º 3
0
def generate(top,
             outdir,
             lang,
             util,
             timing,
             prjdir,
             part,
             yosys_preproc=True):

    if lang not in ['sv', 'v']:
        raise Exception(f"Synth test unknown language: {lang}")

    if lang == 'sv':
        yosys_preproc = False

    hdlgen(top=top, lang=lang, toplang=lang, outdir=outdir)

    vgen_map = reg['hdlgen/map']
    top_name = vgen_map[top].wrap_module_name

    if not yosys_preproc or not shutil.which('yosys'):
        files = list_hdl_files(top, outdir, lang, wrapper=True)

        if lang == 'sv':
            save_file(f'{top_name}_synth_wrap.sv', outdir,
                      vgen_map[top].get_synth_wrap(reg[f'svgen/templenv']))
            top_name = f'{top_name}_synth_wrap'
            files.append(os.path.join(outdir, f'{top_name}.sv'))
    else:
        files = [os.path.join(outdir, 'synth.v')]
        # files.append(os.path.join(os.path.dirname(__file__), 'yosys_blocks.v'))

        yosys_synth(outdir=outdir,
                    srcdir=outdir,
                    top=top,
                    synthout=files[0],
                    synthcmd='synth -noalumacc -noabc -run coarse')

    jinja_context = {
        'res_dir': prjdir,
        'outdir': outdir,
        'files': files,
        'top': top_name,
        'util': util,
        'timing': timing,
        'part': part
    }

    env = jinja2.Environment(loader=jinja2.FileSystemLoader(
        searchpath=os.path.dirname(__file__)))

    if timing:
        with open(f'{outdir}/synth.xdc', 'w') as f:
            f.write(
                f'create_clock -name clk -period {timing} [get_ports clk]\n')

    env.get_template('synth.j2').stream(jinja_context).dump(
        f'{outdir}/synth.tcl')
Exemplo n.º 4
0
    def generate(self, template_env, outdir):
        if not self.memoized:
            self.resolver.generate(template_env, outdir)

        if not self.node.parent:
            return

        # TODO: What about reusing memoized module that didn't need a
        # wrapper. Discern this.
        if self.wrapped:
            save_file(self.wrap_file_name, outdir, self.get_wrap(self.parent_lang))
Exemplo n.º 5
0
def drvgen(top, intfdef, outdir):
    xparams = []
    for name, usr_axip in intfdef.items():
        if usr_axip.t == 'axidma':
            xparams.append(f'"C_{name.upper()}_CTRL_BASEADDR"')
        elif usr_axip.t == 'axi':
            xparams.append(f'"C_{name.upper()}_BASEADDR"')

    modinst = reg['hdlgen/map'][top]
    drvname = modinst.module_name

    files_dir = os.path.join(os.path.dirname(__file__), '..', 'drivers')
    env = TemplateEnv(files_dir)

    context = {'module_name': drvname, 'params': ' '.join(xparams)}

    files = []

    outdir = os.path.join(outdir, f'{drvname}_v1_0')
    datadir = os.path.join(outdir, 'data')
    srcdir = os.path.join(outdir, 'src')

    os.makedirs(datadir, exist_ok=True)
    os.makedirs(srcdir, exist_ok=True)

    files.append(
        save_file(f'{drvname}.mdd', datadir,
                  env.render('.', 'drvgen_mdd.j2', context)))

    files.append(
        save_file(f'{drvname}.tcl', datadir,
                  env.render('.', 'drvgen_tcl.j2', context)))

    context = {'module_name': drvname, 'intfdef': intfdef}

    files.append(
        save_file(f'{drvname}.h', srcdir,
                  env.render('.', 'drvgen_new_h.j2', context)))

    files.append(
        save_file(f'{drvname}.c', srcdir,
                  env.render('.', 'drvgen_new_c.j2', context)))

    files.append(
        copy_file('Makefile', srcdir, os.path.join(files_dir, 'Makefile')))

    files.append(
        copy_file('pgaxi.c', srcdir, os.path.join(files_dir, 'pgaxi.c')))
    files.append(
        copy_file('pgaxi.h', srcdir, os.path.join(files_dir, 'pgaxi.h')))

    return files
Exemplo n.º 6
0
    def generate(self, template_env, outdir):
        ctx = self.module_context(template_env)
        module = template_env.render_local(self.impl_path, self.impl_basename,
                                           self.module_context(template_env))

        if template_env.lang == 'v':
            index = {}
            for intf in ctx['intfs']:
                index[intf['name']] = Intf(intf['type'])
                index[f'{intf["name"]}_s'] = intf['type']

            module = rewrite(module, index)

        save_file(self.file_basename, outdir, module)
Exemplo n.º 7
0
def vgen_generate(top, conf):
    if not conf['generate']:
        return top

    v = VGenGenerateVisitor(top, conf.get('wrapper', False))
    for file_names, contents in v.visit(top):
        if contents:
            if isinstance(contents, (tuple, list)):
                for fn, c in zip(file_names, contents):
                    save_file(fn, conf['outdir'], c)
            else:
                save_file(file_names, conf['outdir'], contents)

    return top
Exemplo n.º 8
0
    def generate(self, template_env, outdir):
        attrib = self.cfg.get('attrib', None)
        if isinstance(attrib, str):
            attrib = [attrib]

        contents, subsvmods = compile_gear(self.node,
                                           template_env,
                                           self.module_name,
                                           outdir,
                                           attrib=attrib)

        save_file(self.file_basename, outdir, contents)

        for s in subsvmods:
            self._files.extend(s.files)
Exemplo n.º 9
0
def gen_file(template_fn, out_fn, outdir, context, overwrite=True):
    template_dir = importlib.machinery.PathFinder().find_spec("pygears_uvm")
    template_dir = template_dir.submodule_search_locations[0]
    template_dir = os.path.join(template_dir, "templates")

    env = jinja2.Environment(loader=jinja2.FileSystemLoader(template_dir),
                             trim_blocks=True,
                             lstrip_blocks=True)

    res = env.get_template(template_fn).render(context)

    if overwrite:
        save_file(out_fn, outdir, res)
    else:
        save_if_nexist(out_fn, outdir, res)
Exemplo n.º 10
0
    def generate(self, template_env, outdir):
        ctx = self.module_context(template_env)
        module = template_env.render_local(self.impl_path, self.impl_basename,
                                           self.module_context(template_env))

        if template_env.lang == 'v':
            index = {}
            for intf in ctx['intfs']:
                from pygears.hls import ir
                direction = ir.IntfType.iin if intf['modport'] == 'consumer' else ir.IntfType.iout

                index[intf['name']] = ir.IntfType[intf['type'], direction]
                index[f'{intf["name"]}_s'] = intf['type']

            module = rewrite(module, index)

        save_file(self.file_basename, outdir, module)
Exemplo n.º 11
0
    def create_svrand_top(self):
        base_addr = os.path.dirname(__file__)
        env = jinja2.Environment(loader=jinja2.FileSystemLoader(base_addr),
                                 trim_blocks=True,
                                 lstrip_blocks=True)

        context = {
            'tcons': self.constraints,
        }

        res = env.get_template('svrand_top.j2').render(context)
        save_file('svrand_top.sv', self.outdir, res)

        # custom classes
        for con in self.constraints:
            if con.cls == 'qenvelope':
                context = {'tcon': con}
                res = env.get_template('qenvelope.j2').render(context)
                save_file(f'qenvelope_{con.name}.sv', self.outdir, res)
Exemplo n.º 12
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)
Exemplo n.º 13
0
def save_if_nexist(fn, outdir, content):
    file_path = os.path.join(outdir, fn)
    if os.path.exists(file_path):
        pass
    else:
        save_file(fn, outdir, content)
Exemplo n.º 14
0
def ippack(top, dirs, intfdef, lang, prjdir, files, drv_files):

    hdlgen_map = reg['hdlgen/map']
    modinst = hdlgen_map[top]
    wrap_name = f'wrap_{modinst.module_name}'

    for fn in files:
        try:
            shutil.copy(os.path.join(LIB_VLIB_DIR, fn), dirs['hdl'])
        except shutil.SameFileError:
            pass

    files = [dirs['hdl']]
    for rtl, mod in hdlgen_map.items():
        if isinstance(mod, SVVivModuleInst):
            for f in mod.files:
                if os.path.splitext(os.path.basename(f))[0] == mod.wrap_module_name:
                    continue

                try:
                    os.remove(os.path.join(dirs['hdl'], os.path.basename(f)))
                except FileNotFoundError:
                    pass

            xci = glob.glob(f'{mod.resolver.ipdir}/*.xci')[0]
            if xci not in files:
                files.append(xci)

    c_files = []
    if drv_files:
        for f in drv_files:
            if f[-3:] in ['mdd', 'tcl']:
                continue

            if os.path.basename(f) == 'Makefile':
                continue

            c_files.append(os.path.relpath(f, dirs['root']))

    context = {
        'prjdir': prjdir,
        'hdldir': dirs['hdl'],
        'ipdir': dirs['root'],
        'ip_name': top.basename,
        'wrap_name': wrap_name,
        'files': files,
        'drv_files': c_files,
        'axi_port_cfg': intfdef,
        'description': '"PyGears {} IP"'.format(top.basename)
    }

    base_addr = os.path.dirname(__file__)
    env = jinja2.Environment(
        extensions=['jinja2.ext.loopcontrols'],
        loader=jinja2.FileSystemLoader([base_addr, os.path.dirname(base_addr)]),
        trim_blocks=True,
        lstrip_blocks=True)
    env.globals.update(zip=zip)

    tmplt = 'axipack.j2'

    env.globals.update(os=os)

    res = env.get_template(tmplt).render(context)
    save_file('ippack.tcl', dirs['script'], res)
Exemplo n.º 15
0
def build(top, outdir=None, postsynth=False, lang=None, rebuild=True):
    if isinstance(top, str):
        top_name = top
        top = find(top)

        if top is None:
            raise Exception(f'No gear found on path: "{top_name}"')

    if lang is None:
        lang = reg['hdl/lang']

    if lang != 'v':
        postsynth = False
    else:
        pass
        # postsynth = True

    file_struct = get_file_struct(top, outdir)

    outdir = file_struct['outdir']

    if not rebuild and os.path.exists(file_struct['dll_path']):
        return

    shutil.rmtree(outdir, ignore_errors=True)

    reg['svgen/spy_connection_template'] = (signal_spy_connect_hide_interm_t
                                            if reg['debug/hide_interm_vals']
                                            else signal_spy_connect_t)

    synth_src_dir = os.path.join(outdir, 'src')
    hdlgen(top,
           outdir=synth_src_dir if postsynth else outdir,
           generate=True,
           lang=lang,
           copy_files=True,
           toplang='v')

    hdlmod = reg['hdlgen/map'][top]

    if postsynth:
        # TODO: change this to the call of the toplevel synth function
        from pygears.hdl.yosys import synth
        synth(outdir=outdir,
              top=top,
              synthcmd='synth',
              srcdir=synth_src_dir,
              synthout=os.path.join(outdir, hdlmod.file_basename))

    tracing_enabled = bool(reg['debug/trace'])
    context = {
        'in_ports': top.in_ports,
        'out_ports': top.out_ports,
        'top_name': hdlmod.wrap_module_name,
        'tracing': tracing_enabled,
        'aux_clock': reg['sim/aux_clock']
    }

    jenv = jinja2.Environment(trim_blocks=True, lstrip_blocks=True)
    jenv.globals.update(int=int)
    jenv.loader = jinja2.FileSystemLoader([os.path.dirname(__file__)])
    c = jenv.get_template('sim_veriwrap.j2').render(context)
    save_file('sim_main.cpp', outdir, c)

    verilate(outdir, lang, top, hdlmod.wrap_module_name, tracing_enabled)

    make(file_struct['objdir'], hdlmod.wrap_module_name)
Exemplo n.º 16
0
 def generate(self, template_env, outdir):
     save_file(self.file_basename, outdir,
               self.get_hier_module(template_env))
Exemplo n.º 17
0
def generate(top, outdir, lang, intfdef, prjdir, presynth=False, rst=True, drvgen=False):
    dirs = get_folder_struct(outdir)
    create_folder_struct(dirs)

    drv_files = []

    if presynth:
        hdl_lang = 'v'
        srcdir = os.path.join(dirs['root'], 'src')
    else:
        hdl_lang = lang
        srcdir = dirs['hdl']

    top = hdlgen(top,
                 outdir=srcdir,
                 wrapper=False,
                 copy_files=True,
                 lang=hdl_lang,
                 toplang=lang,
                 generate=True)

    topinst = reg['hdlgen/map'][top]

    if topinst.wrapped:
        try:
            shutil.copy(os.path.join(srcdir, f'{topinst.wrap_module_name}.sv'),
                        dirs['hdl'])
        except shutil.SameFileError:
            pass

    if presynth:
        if lang == 'sv':
            # TODO: Use some general file finder (as in hdl resolver)
            shutil.copy(os.path.join(srcdir, 'dti.sv'), dirs['hdl'])

        v = IPHierVisitor()
        v.visit(top)

        blackbox = [ip.node.name for ip in v.ips]

        synth('yosys',
              top=top,
              outdir=dirs['hdl'],
              lang=hdl_lang,
              synthcmd=None,
              synthout=os.path.join(dirs['hdl'], topinst.file_basename),
              blackbox=','.join(blackbox),
              srcdir=srcdir)

    sigs = []
    for s in top.signals.values():
        if s.name == 'clk':
            sigs.append(InSig('aclk', 1))
        elif s.name == 'rst':
            sigs.append(InSig('aresetn', 1))
        else:
            sigs.append(s)

    if drvgen:
        drv_files = drvgen(top, intfdef, dirs['driver'])
    else:
        drv_files = None

    wrp, files = generate_wrap(top, intfdef, rst=rst)

    for p in intfdef.values():
        if p.t == 'axi':
            from pygears.lib.strb_combiner import strb_combiner
            from pygears import Intf, find
            from pygears.typing import Tuple, Array, Uint

            num = p.comp['wdata'].params['wstrb']

            # strb_combiner generation requires deeper recursion limit for large buses
            import sys
            sys.setrecursionlimit(1500)

            cur = reg['gear/current_module']
            reg['gear/current_module'] = top
            strb_combiner(Intf(Tuple[Array[Uint[8], num], Uint[num]]), name=f'{p.name}_strb_combiner')
            reg['gear/current_module'] = cur
            hdlgen(f'{top.name}/{p.name}_strb_combiner',
                   outdir=srcdir,
                   wrapper=False,
                   copy_files=True,
                   lang=hdl_lang,
                   toplang=lang,
                   generate=True)


    ippack(top,
           dirs,
           intfdef=intfdef,
           lang=lang,
           prjdir=prjdir,
           files=files,
           drv_files=drv_files)

    preproc_hdl(dirs['hdl'], mapping=default_preproc)

    save_file(f'wrap_{os.path.basename(topinst.inst_name)}.{lang}',
              dirs['hdl'], wrp)

    # TODO: Remove this when memoization gets smarter. Right now this removes
    # the problem where memoization can make one IP rely on files stored in
    # another IP without proper copying
    reg['hdlgen/map'].clear()
Exemplo n.º 18
0
def hdlgen(top=None,
           lang=None,
           toplang=None,
           copy_files=False,
           generate=True,
           outdir=None,
           **conf):

    if lang is None:
        lang = reg['hdl/lang']
    else:
        # TODO: should we save/restore previous setting for 'hdl/lang'?
        reg['hdl/lang'] = lang

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

    conf['outdir'] = expand(outdir)
    outdir = conf['outdir']

    if isinstance(top, tuple):
        top = top[0]

    if isinstance(top, Intf):
        top = top.producer.gear

    if top is None:
        top = reg['gear/root']
    elif isinstance(top, str):
        mtop = find(top)
        if mtop is None:
            raise Exception(f'No module "{top}" found')

        top = mtop
    else:
        top = top

    if toplang is None:
        toplang = reg['hdl/toplang']
        if toplang is None:
            toplang = reg['hdl/lang']
    else:
        reg['hdl/top'] = top

    reg['hdl/toplang'] = toplang

    reg['svgen/conf'] = conf
    for oper in reg[f'{lang}gen/flow']:
        oper(top, conf)

    os.makedirs(outdir, exist_ok=True)
    if generate:
        hdlgen_generate(top, conf)
        hdltop = reg[f'hdlgen/map'][top]
        if toplang == hdltop.lang == 'sv':
            save_file(f'{hdltop.wrap_module_name}_wrap.sv', outdir,
                      hdltop.get_synth_wrap(reg[f'svgen/templenv']))

        for (modname, lang), (fn, fn_dis) in reg['hdlgen/disambig'].items():
            with open(fn) as fin:
                with open(fn_dis, 'w') as fout:
                    mod = fin.read()
                    mod = mod.replace(f'module {modname}',
                                      f'module {modname}_{lang}')
                    fout.write(mod)

    if copy_files and generate:
        for fn in list_hdl_files(top.name, outdir=outdir, rtl_only=True):
            modname, ext = os.path.splitext(os.path.basename(fn))
            if (modname, ext[1:]) in reg['hdlgen/disambig']:
                continue

            try:
                shutil.copy(fn, outdir)
            except shutil.SameFileError:
                pass
            except FileNotFoundError:
                pass

    return top