예제 #1
0
    def __init__(self, root, cfg_file, active_target, build_root=None):

        self._valid_ila_values = [1024, 2048, 4096, 8192, 16384, 32768, 65536, 131072]

        self.root = root

        # define and create build root
        self.build_root_base = build_root if build_root is not None else os.path.join(root, 'build')

        # define build root for functional models
        self.build_root_functional_models = os.path.join(self.build_root_base, 'models')

        self.build_root = os.path.join(self.build_root_base, active_target)
        if not os.path.exists(self.build_root):
            mkdir_p(self.build_root)

        self.cfg_file = cfg_file

        # Initialize config  dict
        self.cfg = Config(cfg_file=self.cfg_file)

        # Update config options by reading from config file
        self.cfg.update_config()

        # Try to initialize Inicio config_dict
        # TODO: add more reasonable defaults
        try:
            from inicio import config_dict
            self.cfg_dict = config_dict()
        except:
            self.cfg_dict = {
                'TOOLS_xilinx': '',
                'INICIO_TOOLS': '',
                'TOOLS_iverilog': '',
                'TOOLS_gtkwave': ''
            }

        # FPGA board configuration
        self.board = self._fetch_board()

        # Vivado configuration
        self.vivado_config = VivadoConfig(parent=self)

        # GtkWave configuration
        self.gtkwave_config = GtkWaveConfig(parent=self)

        # SimVision configuration
        self.simvision_config = SimVisionConfig(parent=self)

        # Icarus configuration
        self.icarus_config = IcarusConfig(parent=self)

        # Xcelium configuration
        self.xcelium_config = XceliumConfig(parent=self)
예제 #2
0
    def wait_on_and_dump_trace(self, result_file=None, emu_time_scaled=True):
        """
        Wait until the trace unit stopped recording data. Transmit this data to the host PC, store by default to the raw
        result file path, or a custom path provided by the user, and convert analog values from fixed-point to float.
        Finally store it to a .vcd file in the default location.

        :param result_file: Optionally, it is possible to provide a custom result file path.
        """

        if result_file is not None:
            # Expand provided path, paths relative to project root are also supported
            result_path = expand_path(result_file,
                                      rel_path_reference=self.pcfg.root)

            # Create raw result path by adding _raw to the filename
            result_path_raw = os.path.join(
                os.path.dirname(result_path),
                os.path.basename(os.path.splitext(result_path)[0]) + '_raw' +
                os.path.splitext(result_path)[1])
            print(f'Simulation results will be stored in:{result_path}')
        else:
            result_path = self.result_path
            result_path_raw = self.result_path_raw

        if not result_path:
            raise Exception(
                f'ERROR: provided result_file:{result_file} is not valid!')

        # wait until trace buffer is full
        self.sendline(
            f'wait_on_hw_ila -timeout {self.record_timeout} $ila_0_i')

        # transmit and dump trace buffer data to a CSV file
        self.sendline('current_hw_ila_data [upload_hw_ila_data $ila_0_i]')

        if not os.path.isdir(os.path.dirname(result_path_raw)):
            mkdir_p(os.path.dirname(result_path_raw))

        self.sendline(
            f'write_hw_ila_data -csv_file -force {{{result_path_raw}}} [current_hw_ila_data]'
        )

        # Convert to .vcd and from fixed-point to float
        ConvertWaveform(result_path_raw=result_path_raw,
                        result_type_raw=self.result_type_raw,
                        result_path=result_path,
                        str_cfg=self.scfg,
                        float_type=self.float_type,
                        dt_scale=self.pcfg.cfg.dt_scale,
                        emu_time_scaled=emu_time_scaled)
예제 #3
0
    def build(self):
        """
        Generate bitstream for FPGA target
        """

        shutil.rmtree(
            self._prj_cfg.build_root
        )  # Remove target specific build dir to make sure there is no legacy
        mkdir_p(self._prj_cfg.build_root)
        self._setup_targets(target=self.act_fpga_target, gen_structures=True)

        # Check if active target is an FPGA target
        target = getattr(self, self.act_fpga_target)

        VivadoEmulation(target=target).build()
        statpro.statpro_update(statpro.FEATURES.anasymod_build_vivado)
예제 #4
0
    def emulate(self, server_addr=None, convert_waveform=True):
        """
        Program bitstream to FPGA and run simulation/emulation on FPGA

        :param server_addr: Address of Vivado hardware server used for communication to FPGA board
        """

        if server_addr is None:
            server_addr = self.args.server_addr

        # create target object, but don't generate instrumentation structure again in case target object does not exist yet
        if not hasattr(self, self.act_fpga_target):
            self._setup_targets(target=self.act_fpga_target)

        # check if bitstream was generated for active fpga target
        target = getattr(self, self.act_fpga_target)
        if not os.path.isfile(getattr(target, 'bitfile_path')):
            raise Exception(
                f'Bitstream for active FPGA target was not generated beforehand; please do so before running emulation.'
            )

        # create sim result folders
        if not os.path.exists(os.path.dirname(target.cfg.vcd_path)):
            mkdir_p(os.path.dirname(target.cfg.vcd_path))

        if not os.path.exists(os.path.dirname(target.result_path_raw)):
            mkdir_p(os.path.dirname(target.result_path_raw))

        # run the emulation
        VivadoEmulation(target=target).run_FPGA(
            start_time=self.args.start_time,
            stop_time=self.args.stop_time,
            server_addr=server_addr)

        statpro.statpro_update(statpro.FEATURES.anasymod_emulate_vivado)

        # post-process results
        if convert_waveform:
            ConvertWaveform(result_path_raw=target.result_path_raw,
                            result_type_raw=target.cfg.result_type_raw,
                            result_path=target.cfg.vcd_path,
                            str_cfg=target.str_cfg,
                            float_type=self.float_type,
                            dt_scale=self._prj_cfg.cfg.dt_scale)
예제 #5
0
파일: msdsl.py 프로젝트: xlchan/msdsl
    def models(self):
        """
        Call gen.py to generate analog models.
        """
        # make model directory, removing the old one if necessary
        rm_rf(self.cfg.model_dir)
        mkdir_p(self.cfg.model_dir)

        # run generator script
        gen_script = os.path.join(self._prj_root, 'gen.py')

        if 'PYTHON_MSDSL' in os.environ:
            python_name = os.environ['PYTHON_MSDSL']
        else:
            python_name = which('python')

        call([
            python_name, gen_script, '-o', self.cfg.model_dir, '--dt',
            str(self.dt)
        ])
예제 #6
0
    def build(self, *args, **kwargs):
        """
        Generate bitstream for FPGA target
        """

        shutil.rmtree(
            self._prj_cfg.build_root
        )  # Remove target specific build dir to make sure there is no legacy
        mkdir_p(self._prj_cfg.build_root)
        self._setup_targets(target=self.act_fpga_target, gen_structures=True)

        # Check if active target is an FPGA target
        target = getattr(self, self.act_fpga_target)

        VivadoEmulation(target=target).build()

        # Build firmware for ctrl infrastructure if needed
        if target.cfg.fpga_sim_ctrl == FPGASimCtrl.UART_ZYNQ:
            self._build_firmware(*args, **kwargs)

        statpro.statpro_update(statpro.FEATURES.anasymod_build_vivado)
예제 #7
0
    def launch(self, server_addr=None, debug=False):
        """
        Program bitstream to FPGA, setup control infrastructure and wait for interactive commands.

        :param server_addr: Address of Vivado hardware server used for communication to FPGA board
        :param debug: Enable or disable debug mode when running an interactive simulation
        """

        if server_addr is None:
            server_addr = self.args.server_addr

        # create target object, but don't generate instrumentation structure again in case target object does not exist yet
        if not hasattr(self, self.act_fpga_target):
            self._setup_targets(target=self.act_fpga_target, debug=debug)

        # check if bitstream was generated for active fpga target
        target = getattr(self, self.act_fpga_target)
        if not os.path.isfile(getattr(target, 'bitfile_path')):
            raise Exception(
                f'Bitstream for active FPGA target was not generated beforehand; please do so before running emulation.'
            )

        # create sim result folders
        if not os.path.exists(os.path.dirname(target.cfg.vcd_path)):
            mkdir_p(os.path.dirname(target.cfg.vcd_path))

        if not os.path.exists(os.path.dirname(target.result_path_raw)):
            mkdir_p(os.path.dirname(target.result_path_raw))

        # launch the emulation
        ctrl_handle = VivadoEmulation(target=target).launch_FPGA(
            server_addr=server_addr)
        statpro.statpro_update(statpro.FEATURES.anasymod_emulate_vivado)

        # Return ctrl handle for interactive control
        return ctrl_handle
예제 #8
0
    def models(self):
        """
        Call gen.py to generate analog models.
        """
        # make model directory, removing the old model directory if necessary
        rm_rf(self._build_root)

        # run generator script
        if 'PYTHON_MSDSL' in os.environ:
            python_name = os.environ['PYTHON_MSDSL']
        else:
            python_name = which('python')
        for generator_source in self.generator_sources:
            # make model directory if necessary
            mkdir_p(
                os.path.join(self._build_root, generator_source.fileset,
                             generator_source.name))
            for file in generator_source.files:
                call([
                    python_name, file, '-o',
                    os.path.join(self._build_root, generator_source.fileset,
                                 generator_source.name), '--dt',
                    str(self.dt)
                ])
예제 #9
0
    def build(self, *args, **kwargs):
        """
        Generate bitstream for FPGA target
        """

        shutil.rmtree(
            self._prj_cfg.build_root
        )  # Remove target specific build dir to make sure there is no legacy
        mkdir_p(self._prj_cfg.build_root)
        self._setup_targets(target=self.act_fpga_target, gen_structures=True)

        # Check if active target is an FPGA target
        target = getattr(self, self.act_fpga_target)

        VivadoEmulation(target=target).build()

        # Build firmware for ctrl infrastructure if needed, first
        # waiting a short time for outputs from Vivado to sync
        # to disk.  This seems to be an issue with NFS.
        if target.cfg.fpga_sim_ctrl == FPGASimCtrl.UART_ZYNQ:
            time.sleep(1)
            self._build_firmware(*args, **kwargs)

        statpro.statpro_update(statpro.FEATURES.anasymod_build_vivado)
예제 #10
0
    def simulate(self, unit=None, id=None, convert_waveform=True, flags=None):
        """
        Run simulation on a pc target.  'flags' contains a list of simulator-specific
        flags, as a sort of escape hatch for features that are not yet supported
        natively through anasymod.
        """
        # Remove target-specific build dir to make sure there are no old files.
        # However, don't fail when certain files can't be removed, because that
        # might indicate that a waveform window is open
        shutil.rmtree(self._prj_cfg.build_root, ignore_errors=True)
        mkdir_p(self._prj_cfg.build_root)
        self._setup_targets(target=self.act_cpu_target, gen_structures=True)

        target = getattr(self, self.act_cpu_target)

        # create sim result folder
        if not os.path.exists(os.path.dirname(target.cfg.vcd_path)):
            mkdir_p(os.path.dirname(target.cfg.vcd_path))

        if not os.path.exists(os.path.dirname(target.result_path_raw)):
            mkdir_p(os.path.dirname(target.result_path_raw))

        # pick simulator
        sim_cls = {
            'icarus': IcarusSimulator,
            'vivado': VivadoSimulator,
            'xrun': XceliumSimulator
        }[self.args.simulator_name]

        # run simulation

        sim = sim_cls(target=target, flags=flags)

        if self.args.simulator_name == "xrun":
            sim.unit = unit
            sim.id = id

        sim.simulate()
        statpro.statpro_update(statpro.FEATURES.anasymod_sim +
                               self.args.simulator_name)

        # post-process results
        if convert_waveform:
            ConvertWaveform(result_path_raw=target.result_path_raw,
                            result_type_raw=target.cfg.result_type_raw,
                            result_path=target.cfg.vcd_path,
                            str_cfg=target.str_cfg,
                            float_type=self.float_type,
                            debug=self._prj_cfg.cfg.cpu_debug_mode,
                            dt_scale=self._prj_cfg.cfg.dt_scale)
예제 #11
0
 def _update_build_root(self, active_target):
     self.build_root = os.path.join(self.build_root_base, active_target)
     if not os.path.exists(self.build_root):
         mkdir_p(self.build_root)