예제 #1
0
def verilate_model(filename, model_name, vcd_file, lint):

    # verilator commandline template

    compile_cmd = ('verilator -cc {source} -top-module {model_name} '
                   '--Mdir {obj_dir} {flags}')

    # verilator commandline options

    source = filename
    obj_dir = 'obj_dir_' + model_name
    flags = ' '.join([
        '-Wno-lint' if not lint else '',
        '-Wno-UNOPTFLAT',
        '--unroll-count 1000000',
        '--unroll-stmts 1000000',
        '--trace' if vcd_file else '',
    ])

    # remove the obj_dir because issues with staleness

    if os.path.exists(obj_dir):
        shutil.rmtree(obj_dir)

    # create the verilator compile command

    compile_cmd = compile_cmd.format(**vars())

    # try compilation

    try:
        print(compile_cmd)
        result = check_output(compile_cmd, stderr=STDOUT, shell=True)
        print(result)

    # handle verilator failure

    except CalledProcessError as e:
        error_msg = """
      Module did not Verilate!

      Command:
      {command}

      Error:
      {error}
    """

        # Source:
        # \x1b[31m {source} \x1b[0m

        raise VerilatorCompileError(
            error_msg.format(command=e.cmd, error=e.output))
예제 #2
0
def verilate_model( filename, model_name, vcd_en, lint ):

  # verilator commandline template

  compile_cmd = ( 'verilator -cc {source} -top-module {model_name} '
                  '--Mdir {obj_dir} {flags}' )

  # verilator commandline options

  source  = filename
  obj_dir = 'obj_dir_' + model_name
  flags   = ' '.join([
              '-Wno-lint' if not lint else '',
              '-Wno-UNOPTFLAT',
              '--unroll-count 1000000',
              '--unroll-stmts 1000000',
              '--assert',
              '--trace' if vcd_en else '',
            ])

  # remove the obj_dir because issues with staleness

  if os.path.exists( obj_dir ):
    shutil.rmtree( obj_dir )

  # create the verilator compile command

  compile_cmd = compile_cmd.format( **vars() )

  # try compilation

  try:
    # print( compile_cmd )
    result = check_output( compile_cmd, stderr=STDOUT, shell=True )
    # print( result )

  # handle verilator failure

  except CalledProcessError as e:
    # error_msg = """
    #   Module did not Verilate!
    #
    #   Command:
    #   {command}
    #
    #   Error:
    #   {error}
    # """

    # We remove the final "Error: Command Failed" line to make the output
    # more succinct.

    split_output = e.output.splitlines()
    error = '\n'.join(split_output[:-1])

    if not split_output[-1].startswith("%Error: Command Failed"):
      error += "\n"+split_output[-1]

    error_msg = """
See "Errors and Warnings" section in the manual located here
http://www.veripool.org/projects/verilator/wiki/Manual-verilator
for more details on various Verilator warnings and error messages.

{error}"""

    raise VerilatorCompileError( error_msg.format(
      command = e.cmd,
      error   = error
    ))
예제 #3
0
def create_shared_lib( model_name, c_wrapper_file, lib_file,
                       vcd_en, vlinetrace ):

  # We need to find out where the verilator include directories are
  # globally installed. We first check the PYMTL_VERILATOR_INCLUDE_DIR
  # environment variable, and if that does not exist then we fall back on
  # using pkg-config.

  verilator_include_dir = os.environ.get('PYMTL_VERILATOR_INCLUDE_DIR')
  if verilator_include_dir is None:
    cmd = ['pkg-config', '--variable=includedir', 'verilator']

    try:

      verilator_include_dir = check_output( cmd, stderr=STDOUT ).strip()

    except OSError as e:

      error_msg = """
Error trying to find verilator include directories. The
PYMTL_VERILATOR_INCLUDE_DIR environment variable was not set,
so we attempted to use pkg-config to find where verilator was
installed, but it looks like we had trouble finding or executing
pkg-config itself. Try running the following command on your own
to debug the issue.

Command:
{command}

Error:
[Errno {errno}] {strerror}
      """

      raise VerilatorCompileError( error_msg.format(
        command  = ' '.join( cmd ),
        errno    = e.errno,
        strerror = e.strerror,
      ))

    except CalledProcessError as e:

      error_msg = """
Error trying to find verilator include directories. The
PYMTL_VERILATOR_INCLUDE_DIR environment variable was not set,
so we attempted to use pkg-config to find where verilator was
installed, but it looks like pkg-config had trouble finding
the verilator.pc file installed by verilator. Is a recent
version of verilator installed? Older versions of verilator
did not have pkg-config support. Try running the following
command on your own to debug the issue.

Command:
{command}

Error:
{error}
      """

      raise VerilatorCompileError( error_msg.format(
        command = ' '.join( e.cmd ),
        error   = e.output,
      ))

  include_dirs = [
    verilator_include_dir,
    verilator_include_dir+"/vltstd",
  ]

  # Compile standard Verilator code if libverilator.a does not exist.
  # Originally, I was also including verilated_dpi.cpp in this library,
  # but for some reason that screws up line tracing. Somehow there is
  # some kind of global state or something that is shared across the
  # shared libraries or something. I was able to fix it by recompiling
  # verilated_dpi if linetracing is enabled. Actually, the line tracing
  # doesn't work -- if you use this line tracing approach, so we are back
  # to always recomping everyting every time for now.

  # if not os.path.exists( "libverilator.a" ):
  #
  #   compile(
  #     flags        = "-O3 -c",
  #     include_dirs = include_dirs,
  #     output_file  = "verilator.o",
  #     input_files  = [ verilator_include_dir+"/verilated.cpp" ]
  #   )
  #
  #   compile(
  #     flags        = "-O3 -c",
  #     include_dirs = include_dirs,
  #     output_file  = "verilator_vcd_c.o",
  #     input_files  = [ verilator_include_dir+"/verilated_vcd_c.cpp" ]
  #   )
  #
  #   # compile(
  #   #   flags        = "-O3 -c",
  #   #   include_dirs = include_dirs,
  #   #   output_file  = "verilator_dpi.o",
  #   #   input_files  = [ verilator_include_dir+"/verilated_dpi.cpp" ]
  #   # )
  #
  #   make_lib(
  #     output_file  = "libverilator.a",
  #     # input_files  = [ "verilator.o", "verilator_vcd_c.o", "verilator_dpi.o" ]
  #     input_files  = [ "verilator.o", "verilator_vcd_c.o" ]
  #    )

  obj_dir_prefix = "obj_dir_{m}/V{m}".format( m=model_name )

  # We need to find a list of all the generated classes. We look in the
  # Verilator makefile for that.

  cpp_sources_list = []

  with open( obj_dir_prefix+"_classes.mk" ) as mkfile:
    found = False
    for line in mkfile:
      if line.startswith("VM_CLASSES_FAST += "):
        found = True
      elif found:
        if line.strip() == "":
          found = False
        else:
          filename = line.strip()[:-2]
          cpp_file = "obj_dir_{m}/{f}.cpp".format( m=model_name, f=filename )
          cpp_sources_list.append( cpp_file )

  # Compile this module

  cpp_sources_list += [
    obj_dir_prefix+"__Syms.cpp",
    verilator_include_dir+"/verilated.cpp",
    verilator_include_dir+"/verilated_dpi.cpp",
    c_wrapper_file,
  ]

  if vcd_en:
    cpp_sources_list += [
      verilator_include_dir+"/verilated_vcd_c.cpp",
      obj_dir_prefix+"__Trace.cpp",
      obj_dir_prefix+"__Trace__Slow.cpp",
    ]

  compile(
    # flags        = "-O1 -fstrict-aliasing -fPIC -shared -L. -lverilator",
    flags        = "-O1 -fstrict-aliasing -fPIC -shared",
    include_dirs = include_dirs,
    output_file  = lib_file,
    input_files  = cpp_sources_list,
  )