Example #1
0
def test_outsig(lang):
    @gear(signals=[InSig('clk', 1), InSig('rst', 1), OutSig('flush', 1)])
    async def local_rst(din):
        sig = module().signals['flush']
        sig.write(0)
        async with din as d:
            if d:
                sig.write(1)
            else:
                sig.write(0)

    @gear
    def hier(din: Bool):
        din | local_rst

    drv(t=Bool, seq=[False, True]) | hier
    cosim('/hier', 'verilator', lang=lang)
    sim()
Example #2
0
def test_clk_channeling():
    @gear
    def dut(din):
        return din \
            | gear_clk2

    Intf(Uint[16]) | dut

    mod_dut = find('/dut')

    assert InSig('clk2', 1) in mod_dut.meta_kwds['signals']
Example #3
0
from pygears import gear
from pygears.hdl import hdlgen
from pygears.typing import Uint
from pygears.typing.math import ceil_chunk
from pygears.core.gear import InSig
from pygears import Intf
from pygears_vivado.ipinst import ipinst
from pygears_vivado.vivmod import SVVivModuleInst

@gear(
    hdl={'hdlgen_cls': SVVivModuleInst},
    sigmap={
        's_axis_aresetn': '~rst',
        's_axis_aclk': 'clk'
    },
    signals=[InSig('s_axis_aresetn', 1),
             InSig('s_axis_aclk', 1)],
)
async def axis_data_fifo(
        s_axis: Uint['W'],
        *,
        tdata_num_bytes=b'W//8',
        fifo_depth=b'depth'
) -> {
        'm_axis': b's_axis'
}:
    pass


@gear
def viv_fifo(din, *, depth):
Example #4
0
from pygears.lib.verif import directed, drv
from pygears.core.gear import InSig, OutSig


@pytest.fixture(autouse=True)
def configure():
    reg['hdl/include'].append(
        os.path.join(os.path.dirname(__file__), 'test_signals'))


@gear(signals=[OutSig('dout_sig', 16)])
async def bc_sig(din) -> b'din':
    pass


@gear(signals=[InSig('din_sig', 16)])
async def add_sig(din) -> b'din':
    pass


def test_local_signal():
    @gear
    def dut(din):
        return din \
            | bc_sig(sigmap={'dout_sig': 'sig'}) \
            | add_sig(sigmap={'din_sig': 'sig'})

    directed(drv(t=Uint[16], seq=list(range(3))),
             f=dut(sim_cls=SimVerilated),
             ref=(list(range(0, 6, 2))))
Example #5
0
def generate(top, intfdef):
    files = set()
    if isinstance(top, str):
        top = find(top)

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

    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)

    intfs = {p['name']: p for p in get_port_intfs(top)}

    for i in intfs.values():
        dtype = i['type']
        w_data = i['width']
        w_eot = 0
        if typeof(dtype, Queue):
            w_data = dtype.data.width
            w_eot = int(dtype.eot)

        i['w_data'] = w_data
        i['w_eot'] = w_eot

    defs = []
    for name, p in intfdef.items():
        if p.t == 'axidma':
            params = {n: c.params for n, c in p.comp.items()}
            defs.extend(
                axi_intfs.port_def(axi_intfs.AXI_MASTER, name, **params))

            params = {
                n: c.params
                for n, c in intfdef[f'{name}_ctrl'].comp.items()
            }
            defs.extend(
                axi_intfs.port_def(axi_intfs.AXIL_SLAVE, f'{name}_ctrl',
                                   **params))

            files.update({'sfifo.v', 'axi_addr.v', 'skidbuffer.v'})

            if 'rdata' in p.comp:
                files.add('aximm2s.v')

            if 'wdata' in p.comp:
                files.add('axis2mm.v')

        elif p.t in ['bram', 'bram.req', 'axi']:

            params = {n: c.params for n, c in p.comp.items()}

            pdefs = axi_intfs.port_def(axi_intfs.AXI_SLAVE, name, **params)

            if 'rdata' in params:
                files.add('axi_slave_read.v')

            if 'wdata' in params:
                files.add('axi_slave_write.v')

            if 'rdata' in params or 'wdata' in params:
                files.update({'sfifo.v', 'axi_addr.v', 'skidbuffer.v'})

            defs.extend(pdefs)

        elif p.t == 'axis':
            if p.direction == 'w':
                tmplt = axi_intfs.AXIS_SLAVE
            else:
                tmplt = axi_intfs.AXIS_MASTER

            params = {n: c.params for n, c in p.comp.items()}

            pdefs = axi_intfs.port_def(tmplt, name, **params)

            defs.extend(pdefs)

    context = {
        'wrap_module_name': f'wrap_{modinst.module_name}',
        'module_name': modinst.wrap_module_name,
        'inst_name': modinst.wrap_module_name,
        'intfs': intfs,
        'sigs': sigs,
        'param_map': modinst.params if not modinst.wrapped else {},
        'port_def': defs,
        'ports': intfdef
    }

    context['pg_clk'] = 'aclk'
    tmplt = 'wrapper.j2'

    base_addr = os.path.dirname(__file__)
    lang_dir = os.path.join(os.path.dirname(base_addr), 'sv')
    env = TemplateEnv(lang_dir)

    env.jenv.globals.update(zip=zip,
                            ceil_pow2=ceil_pow2,
                            ceil_div=ceil_div,
                            bitw=bitw,
                            ceil_chunk=ceil_chunk,
                            axi_intfs=axi_intfs)

    return env.render(base_addr, tmplt, context), files
Example #6
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()
Example #7
0
import os
import math
from pygears import gear
from pygears.typing import Fixp, Tuple
from pygears_vivado.vivmod import SVVivModuleInst
from pygears.core.gear import InSig

# TODO: Make it work properly with widths that are not multiple of 8


@gear(hdl={'hdlgen_cls': SVVivModuleInst},
      sigmap={'aclk': 'clk'},
      signals=[InSig('aclk', 1)])
async def cordic(
    s_axis_phase: Fixp[3, 'W'],
    *,
    output_width=b'input_width',
    input_width=b'W',
    functional_selection="Sin_and_Cos",
    architectural_configuration="Word_Serial",  # Word_Serial, Parallel
    pipelining_mode="Optimal",  # Optimal, Maximum
    phase_format="Scaled_Radians",
    flow_control="Blocking",  # NonBlocking, Blocking
    out_tready=True,
    data_format="SignedFraction",
    _w_out=b'((W+7)//8)*8'
) -> {
        'm_axis_dout': Tuple[Fixp[2, '_w_out'], Fixp[2, '_w_out']]
}:
    async with s_axis_phase as p:
        yield (Fixp[2, output_width](math.cos(math.pi * float(p))),