text: #!/usr/bin/env python3
  # Copyright lowRISC contributors.
  # Licensed under the Apache License, Version 2.0, see LICENSE for details.
  # SPDX-License-Identifier: Apache-2.0
  r"""FuseSoC wrapper for Top Module Generator
  
  This wrapper is called by FuseSoC. It extracts the arguments for topgen from the auto-generated
  GAPI file and creates a core file for the generated sources.
  """
  import sys
  import yaml
  import subprocess
  import os
  
  try:
      from yaml import CSafeLoader as YamlLoader, CSafeDumper as YamlDumper
  except ImportError:
      from yaml import SafeLoader as YamlLoader, SafeDumper as YamlDumper
  
  
  def _check_gapi(gapi):
      if 'cores' not in gapi:
          print("Key 'cores' not found in GAPI structure. "
                "Install a compatible version with "
                "'pip3 install --user -r python-requirements.txt'.")
          return False
      return True
  
  
  def write_core(core_filepath, generated_core):
      with open(core_filepath, 'w') as f:
          # FuseSoC requires this line to appear first in the YAML file.
          # Inserting this line through the YAML serializer requires ordered dicts
          # to be used everywhere, which is annoying syntax-wise on Python <3.7,
          # where native dicts are not sorted.
          f.write('CAPI=2:\n')
          yaml.dump(generated_core,
                    f,
                    encoding="utf-8",
                    default_flow_style=False,
                    sort_keys=False,
                    Dumper=YamlDumper)
      print("Core file written to %s" % (core_filepath, ))
  
  
  def main():
  
      # Extract arguments from GAPI file.
      gapi_filepath = sys.argv[1]
      with open(gapi_filepath) as f:
          gapi = yaml.load(f, Loader=YamlLoader)
  
      if not _check_gapi(gapi):
          sys.exit(1)
  
      files_root = ""
      if 'files_root' in gapi:
          files_root = gapi['files_root']
  
      topname = ""
      if 'parameters' in gapi and 'topname' in gapi['parameters']:
          topname = gapi['parameters']['topname']
  
      reg_only = ""
      if 'parameters' in gapi and 'reg-only' in gapi['parameters']:
          reg_only = gapi['parameters']['reg-only']
  
      # Call topgen.
      files_data = files_root + "/hw/" + topname + "/data/"
      files_out = os.getcwd()
      cmd = [files_root + "/util/topgen.py",  # "--verbose",
             "-t", files_data + topname + ".hjson",
             "-c", files_data,
             "-o", files_out]
      try:
          print("Running topgen.")
          subprocess.run(cmd,
                         check=True,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         universal_newlines=True)
  
      except subprocess.CalledProcessError as e:
          print("topgen failed: " + str(e))
          sys.exit(1)
  
      # Create core files.
      print("Creating core files.")
  
      # For some cores such IP package files, we need a separate dependency for the register file.
      # Combining this with the generated topgen core file below leads to cyclic dependencies. For
      # example, flash_ctrl depends on topgen but also on pwrmgr_pkg which depends on
      # pwrmgr_reg_pkg generated by topgen.
      if reg_only:
          for ip in ['alert_handler', 'clkmgr', 'flash_ctrl', 'padctrl', 'pinmux', 'pwrmgr',
                     'rstmgr', 'rv_plic']:
              core_filepath = os.path.abspath('generated-%s.core' % ip)
              name = 'lowrisc:ip:%s_reggen' % ip,
              files = ['ip/%s/rtl/autogen/%s_reg_pkg.sv' % (ip, ip),
                       'ip/%s/rtl/autogen/%s_reg_top.sv' % (ip, ip)]
              generated_core = {
                  'name': '%s' % name,
                  'filesets': {
                      'files_rtl': {
                          'depend': [
                              'lowrisc:ip:tlul',
                          ],
                          'files': files,
                          'file_type': 'systemVerilogSource'
                      },
                  },
                  'targets': {
                      'default': {
                          'filesets': [
                              'files_rtl',
                          ],
                      },
                  },
              }
              write_core(core_filepath, generated_core)
  
      else:
          core_filepath = os.path.abspath('generated-topgen.core')
          generated_core = {
              'name': "lowrisc:systems:generated-topgen",
              'filesets': {
                  'files_rtl': {
                      'depend': [
                          # flash_ctrl
                          'lowrisc:constants:top_pkg',
                          'lowrisc:prim:util',
                          'lowrisc:ip:lc_ctrl_pkg',
                          'lowrisc:ip:pwrmgr_pkg',
                          # rstmgr
                          'lowrisc:prim:clock_mux2',
                          # clkmgr
                          'lowrisc:prim:all',
                          'lowrisc:prim:clock_gating',
                          'lowrisc:prim:clock_buf',
                          'lowrisc:prim:clock_div',
                          # Top
                          # ast and sensor_ctrl not auto-generated, re-used from top_earlgrey
                          'lowrisc:systems:sensor_ctrl',
                          'lowrisc:systems:ast_wrapper_pkg',
                      ],
                      'files': [
                          # IPs
                          'ip/clkmgr/rtl/autogen/clkmgr_pkg.sv',
                          'ip/clkmgr/rtl/autogen/clkmgr.sv',
                          'ip/flash_ctrl/rtl/autogen/flash_ctrl_pkg.sv',
                          'ip/flash_ctrl/rtl/autogen/flash_ctrl.sv',
                          'ip/rstmgr/rtl/autogen/rstmgr_pkg.sv',
                          'ip/rstmgr/rtl/autogen/rstmgr.sv',
                          'ip/rv_plic/rtl/autogen/rv_plic.sv',
                          # Top
                          'rtl/autogen/%s_rnd_cnst_pkg.sv' % topname,
                          'rtl/autogen/%s_pkg.sv' % topname,
                          'rtl/autogen/%s.sv' % topname,
                      ],
                      'file_type': 'systemVerilogSource'
                  },
              },
              'targets': {
                  'default': {
                      'filesets': [
                          'files_rtl',
                      ],
                  },
              },
          }
          write_core(core_filepath, generated_core)
  
      return 0
  
  
  if __name__ == "__main__":
      main()
  