コード例 #1
0
        def _subcomp_port_gen(c_name, c_id, n_dim, port_decls):
            p_wire_tplt = "logic {packed_type: <8} {id_};"
            p_conn_tplt = ".{port_id: <15}( {port_wire_id} )"
            template = \
      """\
{port_wires}

  {c_name} {c_id}
  (
{port_conn_decls}
  );\
"""
            if not n_dim:
                p_wires, p_conns = [], []
                for port in port_decls:
                    msb, _id = port["msb"], port["id_"]
                    id_ = c_id + "__" + _id
                    port_id = _id
                    port_wire_id = (f"{c_id}__{_id}").center(25)
                    packed_type = f"[{msb}:0]"
                    p_wires.append(p_wire_tplt.format(**locals()))
                    p_conns.append(p_conn_tplt.format(**locals()))
                make_indent(p_wires, 1)
                make_indent(p_conns, 2)
                port_wires = "\n".join(p_wires)
                port_conn_decls = ",\n".join(p_conns)
                return [template.format(**locals())]
            else:
                ret = []
                for i in range(n_dim[0]):
                    ret += _subcomp_port_gen(c_name, c_id + "__" + str(i),
                                             n_dim[1:], port_decls)
                return ret
コード例 #2
0
  def visit_For( s, node ):
    src      = []
    body     = []
    loop_var = s.visit( node.var )
    start    = s.visit( node.start )
    end      = s.visit( node.end )

    begin    = ' begin' if len( node.body ) > 1 else ''

    cmp_op   = '<' if node.step.value > 0 else '<'
    inc_op   = '+' if node.step.value > 0 else '-'

    step_abs = s.visit( node.step )
    step_abs = step_abs if node.step.value > 0 else step_abs[ 1 : ]

    for stmt in node.body:
      body.extend( s.visit( stmt ) )
    make_indent( body, 1 )

    for_begin = \
      'for ( int {v} = {s}; {v} {comp} {t}; {v} {inc}= {stp} ){begin}'.format(
      v = loop_var, s = start, t = end, stp = step_abs,
      comp = cmp_op, inc = inc_op, begin = begin
    )

    # Assemble for statement
    src.extend( [ for_begin ] )
    src.extend( body )

    if len( node.body ) > 1:
      src.extend( [ 'end' ] )

    return src
コード例 #3
0
  def rtlir_tr_struct_dtype( s, dtype ):
    dtype_name = dtype.get_name()
    field_decls = []

    for id_, _dtype in dtype.get_all_properties():

      if isinstance( _dtype, rdt.Vector ):
        decl = s.rtlir_tr_vector_dtype( _dtype )['decl'].format(**locals())
      elif isinstance( _dtype, rdt.PackedArray ):
        decl = s.rtlir_tr_packed_array_dtype( _dtype )['decl'].format(**locals())
      elif isinstance( _dtype, rdt.Struct ):
        decl = s.rtlir_tr_struct_dtype( _dtype )['decl'].format(**locals())
      else:
        assert False, \
          'unrecoganized field type {} of struct {}!'.format( _dtype, dtype_name )
      field_decls.append( decl + ';' )

    make_indent( field_decls, 1 )
    field_decl = '\n'.join( field_decls )

    file_info = dtype.get_file_info()

    return {
      'def' : \
"""\
typedef struct packed {{
{field_decl}
}} {dtype_name};
""".format( **locals() ),
      'const_decl' : '{dtype_name} {{id_}}'.format( **locals() ),
      'decl' : '{dtype_name} {{id_}}'.format( **locals() ),
      'raw_dtype' : dtype
    }
コード例 #4
0
 def rtlir_tr_upblk_decls(s, upblk_decls):
     ret = ''
     for idx, upblk_decl in enumerate(upblk_decls):
         make_indent(upblk_decl, 1)
         if idx != 0:
             ret += '\n'
         ret += '\n' + '\n'.join(upblk_decl)
     return ret
コード例 #5
0
ファイル: ImportPass.py プロジェクト: 2335229479/pymtl3
 def gen_line_trace_py(s, packed_ports):
     """Return the line trace method body that shows all interface ports."""
     ret = ['lt = ""']
     template = 'lt += "{my_name} = {{}}, ".format({full_name})'
     for name, v_name, port in packed_ports:
         my_name = name
         full_name = 's.mangled__' + s._verilator_name(name)
         ret.append(template.format(**locals()))
     ret.append('return lt')
     make_indent(ret, 2)
     return '\n'.join(ret)
コード例 #6
0
ファイル: ImportPass.py プロジェクト: 2335229479/pymtl3
 def gen_internal_line_trace_py(s, packed_ports):
     """Return the line trace method body that shows all CFFI ports."""
     ret = ['_ffi_m = s._ffi_m', 'lt = ""']
     template = \
       "lt += '{v_name} = {{}}, '.format(full_vector(s.mangled__{my_name}, _ffi_m.{v_name}))"
     for my_name, v_name, port in packed_ports:
         if v_name:
             my_name = s._verilator_name(my_name)
             v_name = s._verilator_name(v_name)
             ret.append(template.format(**locals()))
     ret.append('return lt')
     make_indent(ret, 2)
     return '\n'.join(ret)
コード例 #7
0
 def rtlir_tr_subcomp_decls(s, subcomp_decls):
     port_decls, wire_decls, conns = [], [], []
     for subcomp_decl in subcomp_decls:
         port_decls.extend(subcomp_decl["port_decls"])
         wire_decls.extend(subcomp_decl["wire_decls"])
         conns.extend(subcomp_decl["connections"])
     make_indent(wire_decls, 1)
     make_indent(conns, 1)
     return {
         "port_decls": "\n\n".join(port_decls),
         "wire_decls": "\n".join(wire_decls),
         "connections": "\n".join(conns)
     }
コード例 #8
0
ファイル: ImportPass.py プロジェクト: 2335229479/pymtl3
    def create_verilator_c_wrapper(s, m, config, packed_ports, cached):
        """Return the file name of generated C component wrapper.

    Create a C wrapper that calls verilator C API and provides interfaces
    that can be later called through CFFI.
    """
        component_name = config.get_top_module()
        dump_vcd = int(config.is_vl_trace_enabled())
        vcd_timescale = config.get_vl_trace_timescale()
        half_cycle_time = config.get_vl_trace_half_cycle_time()
        wrapper_name = config.get_c_wrapper_path()
        config.vprint("\n=====Generate C wrapper=====")

        # The wrapper template should be in the same directory as this file
        template_name = \
          os.path.dirname( os.path.abspath( __file__ ) ) + \
          os.path.sep + 'verilator_wrapper.c.template'

        # Generate port declarations for the verilated model in C
        port_defs = []
        for name, v_name, port in packed_ports:
            if v_name:
                port_defs.append(s.gen_signal_decl_c(v_name, port))
        port_cdefs = copy.copy(port_defs)
        make_indent(port_defs, 2)
        port_defs = '\n'.join(port_defs)

        # Generate initialization statements for in/out ports
        port_inits = []
        for name, v_name, port in packed_ports:
            if v_name:
                port_inits.extend(s.gen_signal_init_c(v_name, port))
        make_indent(port_inits, 1)
        port_inits = '\n'.join(port_inits)

        # Fill in the C wrapper template

        # Since we may run import with or without dump_vcd enabled, we need
        # to dump C wrapper regardless of whether the verilated model is
        # cached or not.
        # TODO: we can avoid dumping C wrapper if we attach some metadata to
        # tell if the wrapper was generated with or without `dump_vcd` enabled.
        with open(template_name, 'r') as template:
            with open(wrapper_name, 'w') as output:
                c_wrapper = template.read()
                c_wrapper = c_wrapper.format(**locals())
                output.write(c_wrapper)

        config.vprint(f"Successfully generated C wrapper {wrapper_name}!", 2)
        return port_cdefs
コード例 #9
0
    def visit_If(s, node):
        src = []
        body = []
        orelse = []

        # Grab condition, if-body, and orelse-body
        cond = s.visit(node.cond)
        for stmt in node.body:
            body.extend(s.visit(stmt))
        make_indent(body, 1)
        for stmt in node.orelse:
            orelse.extend(s.visit(stmt))

        # Assemble the statement, starting with if-body
        if_begin = f'if ( {cond} ) begin'
        src.extend([if_begin])
        src.extend(body)

        # if len( node.body ) > 1:
        src.extend(['end'])

        # If orelse-body is not empty, add it to the list of strings
        if node.orelse != []:

            # If an if statement is the only statement in the orelse-body
            if len(node.orelse) == 1 and isinstance(node.orelse[0], bir.If):
                # No indent will be added, also append if-begin to else-begin
                else_begin = f'else {orelse[0]}'
                orelse = orelse[1:]

            # Else indent orelse-body
            else:
                else_begin = 'else' + (' begin'
                                       if len(node.orelse) > 1 else '')
                make_indent(orelse, 1)

            src.extend([else_begin])
            src.extend(orelse)
            if len(node.orelse) > 1:
                src.extend(['end'])

        return src
コード例 #10
0
    def visit_For(s, node):
        node.start._top_expr = 1
        node.end._top_expr = 1
        node.step._top_expr = 1

        # Yosys-comptabile Verilog for loop
        src = []
        body = []
        loop_var = s.visit(node.var)
        start = s.visit(node.start)
        end = s.visit(node.end)

        loop_var = "__loopvar__" + s.blk.__name__ + "_" + loop_var
        if loop_var not in s.loopvars:
            s.loopvars.add(loop_var)

        begin = ' begin' if len(node.body) > 1 else ''

        cmp_op = '<' if node.step.value > 0 else '<'
        inc_op = '+' if node.step.value > 0 else '-'

        step_abs = s.visit(node.step)
        step_abs = step_abs if node.step.value > 0 else step_abs[1:]

        for stmt in node.body:
            body.extend(s.visit(stmt))
        make_indent(body, 1)

        for_begin = \
          'for ( {v} = {s}; {v} {comp} {t}; {v} = {v} {inc} {stp} ){begin}'.format(
          v = loop_var, s = start, t = end, stp = step_abs,
          comp = cmp_op, inc = inc_op, begin = begin
        )

        # Assemble for statement
        src.extend([for_begin])
        src.extend(body)

        if len(node.body) > 1:
            src.extend(['end'])

        return src
コード例 #11
0
    def visit_SeqUpblk(s, node):
        """Return the SV representation of statements inside it."""
        blk_name = node.name
        src = []
        body = []
        s.upblk_type = s.SEQUENTIAL

        s.check_res(node, blk_name)

        # Add name of the upblk to this always block
        src.append(f'always_ff @(posedge clk) begin : {blk_name}')

        for stmt in node.body:
            body.extend(s.visit(stmt))

        make_indent(body, 1)
        src.extend(body)
        src.append('end')
        s.upblk_type = s.NONE
        return src
コード例 #12
0
    def visit_CombUpblk(s, node):
        """Return the SV representation of statements inside it."""
        blk_name = node.name
        src = []
        body = []
        s.upblk_type = s.COMBINATIONAL

        s.check_res(node, blk_name)

        # Add name of the upblk to this always block
        src.extend(['always_comb begin : {blk_name}'.format(**locals())])

        for stmt in node.body:
            body.extend(s.visit(stmt))

        make_indent(body, 1)
        src.extend(body)
        src.extend(['end'])
        s.upblk_type = s.NONE
        return src
コード例 #13
0
 def rtlir_tr_port_decls(s, port_decls):
     ret = {"port_decls": [], "wire_decls": [], "connections": []}
     for port_decl in port_decls:
         ret["port_decls"] += port_decl["port_decls"]
         ret["wire_decls"] += port_decl["wire_decls"]
         ret["connections"] += port_decl["connections"]
     make_indent(ret["port_decls"], 1)
     make_indent(ret["wire_decls"], 1)
     make_indent(ret["connections"], 1)
     ret["port_decls"] = ",\n".join(ret["port_decls"])
     ret["wire_decls"] = "\n".join(ret["wire_decls"])
     ret["connections"] = "\n".join(ret["connections"])
     return ret
コード例 #14
0
 def rtlir_tr_interface_decls(s, ifc_decls):
     port_decls, wire_decls, connections = [], [], []
     for ifc_decl in ifc_decls:
         port_decls += ifc_decl["port_decls"]
         wire_decls += ifc_decl["wire_decls"]
         connections += ifc_decl["connections"]
     make_indent(port_decls, 1)
     make_indent(wire_decls, 1)
     make_indent(connections, 1)
     return {
         "port_decls": ",\n".join(port_decls),
         "wire_decls": "\n".join(wire_decls),
         "connections": "\n".join(connections),
     }
コード例 #15
0
 def rtlir_tr_port_decls( s, port_decls ):
   make_indent( port_decls, 1 )
   return ',\n'.join( port_decls )
コード例 #16
0
 def rtlir_tr_connections( s, connections ):
   make_indent( connections, 1 )
   return '\n'.join( connections )
コード例 #17
0
 def rtlir_tr_behavioral_freevars(s, freevars):
     make_indent(freevars, 1)
     return '\n'.join(freevars)
コード例 #18
0
 def rtlir_tr_upblk_py_srcs(s, upblk_py_srcs):
     ret = ''
     for upblk_py_src in upblk_py_srcs:
         make_indent(upblk_py_src, 1)
         ret += '\n' + '\n'.join(upblk_py_src)
     return ret
コード例 #19
0
 def rtlir_tr_behavioral_tmpvars( s, tmpvars ):
   make_indent( tmpvars, 1 )
   return '\n'.join( tmpvars )
コード例 #20
0
 def rtlir_tr_behavioral_tmpvars(s, tmpvars):
     _tmpvars = []
     for tmpvar in tmpvars:
         _tmpvars += tmpvar
     make_indent(_tmpvars, 1)
     return '\n'.join(_tmpvars)
コード例 #21
0
ファイル: ImportPass.py プロジェクト: 2335229479/pymtl3
    def create_py_wrapper(s, m, config, rtype, packed_ports, port_cdefs,
                          cached):
        """Return the file name of the generated PyMTL component wrapper."""
        config.vprint("\n=====Generate PyMTL wrapper=====")

        # Load the wrapper template
        template_name = \
          os.path.dirname( os.path.abspath( __file__ ) ) + \
          os.path.sep + 'verilator_wrapper.py.template'
        wrapper_name = config.get_py_wrapper_path()

        # Port definitions of verilated model
        make_indent(port_cdefs, 4)

        # Port definition in PyMTL style
        symbols, port_defs, connections = s.gen_signal_decl_py(rtype)
        make_indent(port_defs, 2)
        make_indent(connections, 2)
        # Wire definition in PyMTL style
        wire_defs = []
        for name, v_name, port in packed_ports:
            wire_defs.append(s.gen_wire_decl_py(name, port))
        make_indent(wire_defs, 2)

        # Set upblk inputs and outputs
        set_comb_input = s.gen_comb_input(packed_ports)
        set_comb_output = s.gen_comb_output(packed_ports)
        make_indent(set_comb_input, 3)
        make_indent(set_comb_output, 3)

        # Generate constraints for sequential block
        constraints = s.gen_constraints(packed_ports)
        make_indent(constraints, 4)
        constraint_str = '' if not constraints else \
    """\
constraint_list = [
{}
      ]

      s.add_constraints( *constraint_list )
""".format( '\n'.join( constraints ) )

        # Line trace
        line_trace = s.gen_line_trace_py(packed_ports)

        # Internal line trace
        in_line_trace = s.gen_internal_line_trace_py(packed_ports)

        # Fill in the python wrapper template
        if not cached:
            with open(template_name, 'r') as template:
                with open(wrapper_name, 'w') as output:
                    py_wrapper = template.read()
                    py_wrapper = py_wrapper.format(
                      component_name  = config.get_top_module(),
                      has_clk         = int(config.has_clk()),
                      clk             = 'inv_clk' if not config.has_clk() else \
                                        next(filter(lambda x: x[0]=='clk', packed_ports))[1],
                      lib_file        = config.get_shared_lib_path(),
                      port_cdefs      = ('  '*4+'\n').join( port_cdefs ),
                      port_defs       = '\n'.join( port_defs ),
                      wire_defs       = '\n'.join( wire_defs ),
                      connections     = '\n'.join( connections ),
                      set_comb_input  = '\n'.join( set_comb_input ),
                      set_comb_output = '\n'.join( set_comb_output ),
                      constraint_str  = constraint_str,
                      line_trace      = line_trace,
                      in_line_trace   = in_line_trace,
                      dump_vcd        = int(config.is_vl_trace_enabled())
                    )
                    output.write(py_wrapper)

        config.vprint(f"Successfully generated PyMTL wrapper {wrapper_name}!",
                      2)
        return symbols
コード例 #22
0
 def rtlir_tr_wire_decls( s, wire_decls ):
   make_indent( wire_decls, 1 )
   return '\n'.join( wire_decls )
コード例 #23
0
 def rtlir_tr_wire_decls(s, wire_decls):
     wires = []
     for wire_decl in wire_decls:
         wires += wire_decl
     make_indent(wires, 1)
     return '\n'.join(wires)
コード例 #24
0
 def rtlir_tr_interface_decls(s, ifc_decls):
     all_decls = sum(ifc_decls, [])
     make_indent(all_decls, 1)
     return ',\n'.join(all_decls)
コード例 #25
0
 def rtlir_tr_const_decls( s, const_decls ):
   make_indent( const_decls, 1 )
   return '\n'.join( const_decls )
コード例 #26
0
 def rtlir_tr_subcomp_ifc_port_decls(s, _ifc_port_decls):
     port_defs = [x['def'] for x in _ifc_port_decls]
     port_decls = [x['decl'] for x in _ifc_port_decls]
     make_indent(port_defs, 1)
     make_indent(port_decls, 2)
     return {'def': '\n'.join(port_defs), 'decl': ',\n'.join(port_decls)}