class ModuleTracePort(JinjaTempl):
    def __init__(self, scfg: StructureConfig):
        super().__init__(trim_blocks=True, lstrip_blocks=True)
        probes = scfg.digital_probes + scfg.analog_probes + [scfg.time_probe] + [scfg.dec_cmp]

        #####################################################
        # Define module ios
        #####################################################

        self.module_ifc = SVAPI()
        module = ModuleInst(api=self.module_ifc, name="trace_port_gen")
        # Add probe signals
        module.add_inputs(probes)

        # Add master clk
        module.add_input(scfg.emu_clk)

        module.generate_header()

        #####################################################
        # CPU sim control section - add dump statements
        #####################################################

        self.probe_dumps = SVAPI()
        self.probe_dumps.indent()
        self.probe_dumps.writeln(f'initial begin')
        self.probe_dumps.indent()
        self.probe_dumps.writeln('#0;')
        for probe in probes:
            self.probe_dumps.writeln(f'$dumpvars(0, {probe.name});')
        self.probe_dumps.dedent()
        self.probe_dumps.writeln(f'end')

        #####################################################
        # FPGA sim control section - Instantiate ila core
        #####################################################

        # Instantiate ila core
        self.ila_wiz_inst = SVAPI()
        ila_wiz = ModuleInst(api=self.ila_wiz_inst, name="ila_0")
        for k, signal in enumerate(probes): # Add probe signals
            ila_wiz.add_input(DigitalSignal(name=f'probe{k}', abspath=None, width=signal.width), connection=signal)
        ila_wiz.add_input(DigitalSignal(name='clk', abspath=None, width=1), connection=scfg.emu_clk) # Add master clk
        ila_wiz.generate_instantiation()


    TEMPLATE_TEXT = '''
class TemplLAUNCH_ILA_TCL(JinjaTempl):
    def __init__(self, pcfg: EmuConfig, scfg: StructureConfig, ltxfile_path,
                 server_addr: str):
        super().__init__(trim_blocks=False, lstrip_blocks=False)
        pcfg = pcfg
        scfg = scfg

        # set server address
        self.server_addr = server_addr

        # set the paths to the LTX file
        self.ltx_file = back2fwd(ltxfile_path)

        # set the JTAG frequency.  sometimes it is useful to try a slower frequency than default if there
        # are problems with the debug hub clock
        self.jtag_freq = str(int(pcfg.cfg.jtag_freq))

        # set the "short" device name which is used to distinguish the FPGA part from other USB devices
        self.device_name = pcfg.board.short_part_name

        # Set aliases for probes
        self.probe_aliases = SVAPI()
        for probe in scfg.digital_probes + scfg.analog_probes + [
                scfg.time_probe
        ]:
            self.probe_aliases.writeln(
                f'set {probe.name} [get_hw_probes "trace_port_gen_i/{probe.name}" -of_objects $ila_0_i]'
            )

        # Set radix for probes
        self.probe_radix = SVAPI()
        for digital_probe in (scfg.digital_probes + [scfg.time_probe]):
            signed = 'SIGNED' if digital_probe.signed else 'UNSIGNED'
            self.probe_radix.writeln(
                f'set_property DISPLAY_RADIX {signed} ${digital_probe.name}')

        for analog_probe in scfg.analog_probes:
            self.probe_radix.writeln(
                f'set_property DISPLAY_RADIX SIGNED ${analog_probe.name}')

    TEMPLATE_TEXT = '''\
示例#3
0
class TemplLAUNCH_FPGA_SIM(JinjaTempl):
    def __init__(self, pcfg: EmuConfig, scfg: StructureConfig, bitfile_path,
                 ltxfile_path, server_addr: str):
        super().__init__(trim_blocks=False, lstrip_blocks=False)
        pcfg = pcfg
        scfg = scfg

        # set server address
        self.server_addr = server_addr

        # set the paths to the BIT and LTX file
        self.bit_file = back2fwd(bitfile_path)
        self.ltx_file = back2fwd(ltxfile_path)

        # set the JTAG frequency.  sometimes it is useful to try a slower frequency than default if there
        # are problems with the debug hub clock
        self.jtag_freq = str(int(pcfg.cfg.jtag_freq))

        # save some parameters from the board configuration
        self.device_name = pcfg.board.short_part_name
        self.no_rev_check = pcfg.board.no_rev_check

        # Set aliases for VIOs
        self.ctrl_io_aliases = SVAPI()
        for io in scfg.digital_ctrl_inputs + scfg.digital_ctrl_outputs + \
                  scfg.analog_ctrl_inputs + scfg.analog_ctrl_outputs:
            self.ctrl_io_aliases.writeln(
                f'set {io.name} [get_hw_probes "sim_ctrl_gen_i/{io.name}" -of_objects $vio_0_i]'
            )

        # Set radix for VIOs
        self.ctrl_io_radix = SVAPI()
        for digital_in in scfg.digital_ctrl_inputs:
            signed = 'SIGNED' if digital_in.signed else 'UNSIGNED'
            self.ctrl_io_radix.writeln(
                f'set_property OUTPUT_VALUE_RADIX {signed} ${digital_in.name}')

        for digital_out in scfg.digital_ctrl_outputs:
            signed = 'SIGNED' if digital_out.signed else 'UNSIGNED'
            self.ctrl_io_radix.writeln(
                f'set_property INPUT_VALUE_RADIX {signed} ${digital_out.name}')

        for analog_in in scfg.analog_ctrl_inputs:
            self.ctrl_io_radix.writeln(
                f'set_property OUTPUT_VALUE_RADIX SIGNED ${analog_in.name}')

        for analog_out in scfg.analog_ctrl_outputs:
            self.ctrl_io_radix.writeln(
                f'set_property INPUT_VALUE_RADIX SIGNED ${analog_out.name}')

        # Set aliases for probes
        self.probe_aliases = SVAPI()
        for probe in scfg.digital_probes + scfg.analog_probes + [
                scfg.time_probe
        ]:
            self.probe_aliases.writeln(
                f'set {probe.name} [get_hw_probes "trace_port_gen_i/{probe.name}" -of_objects $ila_0_i]'
            )

        # Set radix for probes
        self.probe_radix = SVAPI()
        for digital_probe in (scfg.digital_probes + [scfg.time_probe]):
            signed = 'SIGNED' if digital_probe.signed else 'UNSIGNED'
            self.probe_radix.writeln(
                f'set_property DISPLAY_RADIX {signed} ${digital_probe.name}')

        for analog_probe in scfg.analog_probes:
            self.probe_radix.writeln(
                f'set_property DISPLAY_RADIX SIGNED ${analog_probe.name}')

    TEMPLATE_TEXT = '''\
示例#4
0
class ModuleEmuClks(JinjaTempl):
    def __init__(self, scfg: StructureConfig, pcfg: EmuConfig):
        super().__init__(trim_blocks=True, lstrip_blocks=True)

        gated_clks = []

        #####################################################
        # Create module interface
        #####################################################
        self.module_ifc = SVAPI()

        module = ModuleInst(api=self.module_ifc, name="gen_emu_clks")
        module.add_input(scfg.emu_clk_2x)
        module.add_output(scfg.emu_clk)

        for derived_clk in scfg.clk_derived:
            if derived_clk.abspath_gated_clk is not None:
                gated_clks.append(derived_clk.name)

        # add IOs for default oscillator if used
        self.use_default_oscillator = scfg.use_default_oscillator
        if scfg.use_default_oscillator:
            module.add_input(
                DigitalSignal(name=f'clk_val_default_osc', width=1,
                              abspath=''))
            module.add_output(
                DigitalSignal(name=f'clk_default_osc', width=1, abspath=''))

        for gated_clk in gated_clks:
            module.add_input(
                DigitalSignal(name=f'clk_val_{gated_clk}', width=1,
                              abspath=''))
            module.add_output(
                DigitalSignal(name=f'clk_{gated_clk}', width=1, abspath=''))

        module.generate_header()

        #####################################################
        # Generate other clks
        #####################################################
        self.generated_clks = SVAPI()

        if gated_clks:
            for gated_clk in gated_clks:
                self.generated_clks.gen_signal(DigitalSignal(
                    name=f'clk_unbuf_{gated_clk}', width=1, abspath=''),
                                               default_value=0)
            self.generated_clks.writeln(f'always @(posedge emu_clk_2x) begin')
            self.generated_clks.indent()
            for gated_clk in gated_clks:
                self.generated_clks.writeln(
                    f"if (emu_clk_unbuf == 1'b0) begin")
                self.generated_clks.indent()
                self.generated_clks.writeln(
                    f'clk_unbuf_{gated_clk} <= clk_val_{gated_clk};')
                self.generated_clks.dedent()
                self.generated_clks.writeln(f'end else begin')
                self.generated_clks.indent()
                self.generated_clks.writeln(
                    f"clk_unbuf_{gated_clk} <= clk_unbuf_{gated_clk};")
                self.generated_clks.dedent()
                self.generated_clks.writeln(f'end')
            self.generated_clks.dedent()
            self.generated_clks.writeln(f'end')
            self.generated_clks.writeln(f'')
            self.generated_clks.writeln(f'`ifndef SIMULATION_MODE_MSDSL')
            self.generated_clks.indent()
            for k, gated_clk in enumerate(gated_clks):
                self.generated_clks.writeln(
                    f'BUFG buf_{k} (.I(clk_unbuf_{gated_clk}), .O(clk_{gated_clk}));'
                )
            self.generated_clks.dedent()
            self.generated_clks.writeln(f'`else')
            self.generated_clks.indent()
            for gated_clk in gated_clks:
                self.generated_clks.writeln(
                    f'assign clk_{gated_clk} = clk_unbuf_{gated_clk};')
            self.generated_clks.dedent()
            self.generated_clks.writeln(f'`endif')

    TEMPLATE_TEXT = '''
示例#5
0
class ModuleTimeManager(JinjaTempl):
    def __init__(self, scfg: StructureConfig, pcfg: EmuConfig,
                 plugin_includes: list):
        super().__init__(trim_blocks=True, lstrip_blocks=True)

        self.num_dt_reqs = scfg.num_dt_reqs
        self.dt_value = pcfg.cfg.dt

        #####################################################
        # Add plugin specific includes
        #####################################################

        self.plugin_includes = SVAPI()
        for plugin in plugin_includes:
            for include_statement in plugin.include_statements:
                self.plugin_includes.writeln(f'{include_statement}')

        #####################################################
        # Create module interface
        #####################################################
        self.module_ifc = SVAPI()

        module = ModuleInst(api=self.module_ifc, name="gen_time_manager")
        module.add_input(scfg.emu_clk)
        module.add_input(scfg.reset_ctrl)
        module.add_output(scfg.time_probe)

        module.add_output(
            DigitalSignal(name=f'emu_dt',
                          abspath='',
                          width=pcfg.cfg.dt_width,
                          signed=False))

        # add inputs for external timestep requests
        dt_reqs = []
        for derived_clk in scfg.clk_derived:
            if derived_clk.abspath_dt_req is not None:
                dt_req = DigitalSignal(name=f'dt_req_{derived_clk.name}',
                                       abspath='',
                                       width=pcfg.cfg.dt_width,
                                       signed=False)
                module.add_input(dt_req)
                dt_reqs.append(dt_req)

        # add input for anasymod control dt request signal
        dt_req = DigitalSignal(name=f'dt_req_stall',
                               abspath='',
                               width=pcfg.cfg.dt_width,
                               signed=False)
        module.add_input(dt_req)
        dt_reqs.append(dt_req)

        # add input for dt request signal, in case a default oscillator is used
        if scfg.use_default_oscillator:
            dt_req = DigitalSignal(name=f'dt_req_default_osc',
                                   abspath='',
                                   width=pcfg.cfg.dt_width,
                                   signed=False)
            module.add_input(dt_req)
            dt_reqs.append(dt_req)

        module.generate_header()

        # generate a bit of code to take the minimum of the timestep requests
        self.codegen = SVAPI()
        self.codegen.indent()

        # take minimum of the timestep requests
        if len(dt_reqs) == 0:
            # Convert dt value to integer considering dt_scale
            dt_as_int = int(float(pcfg.cfg.dt) / float(pcfg.cfg.dt_scale))

            # Represent as binary and expand to dt_width
            dt_as_bin = bin(dt_as_int).replace('b',
                                               '').zfill(pcfg.cfg.dt_width)

            # assign to the emulator timestep output
            self.codegen.writeln(
                f"assign emu_dt = {pcfg.cfg.dt_width}'b{dt_as_bin};")
        else:
            prev_min = None
            for k, curr_sig in enumerate(dt_reqs):
                if k == 0:
                    prev_min = curr_sig.name
                else:
                    # create a signal to hold temporary min result
                    curr_min = f'__dt_req_min_{k - 1}'
                    self.codegen.writeln(
                        f'(* dont_touch = "true" *) logic [((`DT_WIDTH)-1):0] {curr_min};'
                    )
                    # take the minimum of the previous minimum and the current signal
                    curr_min_val = self.vlog_min(curr_sig.name, prev_min)
                    self.codegen.writeln(
                        f'assign {curr_min} = {curr_min_val};')
                    # mark the current minimum as the previous minimum for the next
                    # iteration of the loop
                    prev_min = curr_min
            # assign to the emulator timestep output
            self.codegen.writeln(f'assign emu_dt = {prev_min};')

    @staticmethod
    def vlog_min(a, b):
        return f'((({a}) < ({b})) ? ({a}) : ({b}))'

    TEMPLATE_TEXT = '''\
class ModuleVIOSimCtrl(JinjaTempl):
    def __init__(self, scfg: StructureConfig, plugin_includes: list):
        super().__init__(trim_blocks=True, lstrip_blocks=True)

        ctrl_inputs = scfg.analog_ctrl_inputs + scfg.digital_ctrl_inputs
        ctrl_outputs = scfg.analog_ctrl_outputs + scfg.digital_ctrl_outputs

        #####################################################
        # Add plugin specific includes
        #####################################################

        self.plugin_includes = SVAPI()
        for plugin in plugin_includes:
            for include_statement in plugin.include_statements:
                self.plugin_includes.writeln(f'{include_statement}')

        #####################################################
        # Define module ios
        #####################################################
        self.module_ifc = SVAPI()

        module = ModuleInst(api=self.module_ifc, name="sim_ctrl_gen")
        module.add_inputs(ctrl_outputs)
        module.add_outputs(ctrl_inputs)
        module.add_input(scfg.emu_clk)

        module.generate_header()

        #####################################################
        # PC sim control section
        #####################################################

        ## Custom control IOs for pc sim control module
        self.pc_sim_crtl_ifc = SVAPI()

        # Only generate instantiation if there is any ctrl signal available, that is not a special control signal
        has_custom_ctrl_signal = False
        for ctrl_signal in (ctrl_outputs + ctrl_inputs):
            if ctrl_signal.name not in scfg.special_ctrl_ios:
                has_custom_ctrl_signal = True
                break

        if has_custom_ctrl_signal:
            sim_ctrl_module = ModuleInst(api=self.pc_sim_crtl_ifc,
                                         name="sim_ctrl")
            for ctrl_output in ctrl_outputs:
                if ctrl_output.name not in scfg.special_ctrl_ios:
                    sim_ctrl_module.add_input(ctrl_output,
                                              connection=ctrl_output)
            for ctrl_input in ctrl_inputs:
                if ctrl_input.name not in scfg.special_ctrl_ios:
                    sim_ctrl_module.add_output(ctrl_input,
                                               connection=ctrl_input)

            sim_ctrl_module.generate_instantiation()

        # set number of clk cycles for initial reset
        self.rst_clkcycles = scfg.cfg.rst_clkcycles

        #####################################################
        # FPGA sim control section - Instantiate vio wizard
        #####################################################

        self.vio_wiz_inst = SVAPI()
        vio_wiz = ModuleInst(api=self.vio_wiz_inst, name="vio_0")

        for k, input in enumerate(ctrl_outputs):
            if isinstance(input, AnalogCtrlOutput):
                width = '`LONG_WIDTH_REAL'
            elif isinstance(input, DigitalCtrlOutput):
                width = input.width
            else:
                raise Exception(
                    f"Provided signal type:{type(input)} is not supported!")

            vio_i = DigitalSignal(name=f'probe_in{k}',
                                  width=width,
                                  abspath=None)
            vio_wiz.add_input(io_obj=vio_i, connection=input)

        for k, output in enumerate(ctrl_inputs):
            if isinstance(output, AnalogCtrlInput):
                width = '`LONG_WIDTH_REAL'
            elif isinstance(output, DigitalCtrlInput):
                width = output.width
            else:
                raise Exception(
                    f"Provided signal type:{type(output)} is not supported!")

            vio_o = DigitalSignal(name=f'probe_out{k}',
                                  width=width,
                                  abspath=None)
            vio_wiz.add_output(io_obj=vio_o, connection=output)

        vio_wiz.add_input(io_obj=DigitalSignal(name='clk',
                                               width=1,
                                               abspath=None),
                          connection=scfg.emu_clk)
        vio_wiz.generate_instantiation()

    TEMPLATE_TEXT = '''\
示例#7
0
class ModuleRegMapSimCtrl(JinjaTempl):
    def __init__(self, scfg):
        super().__init__(trim_blocks=True, lstrip_blocks=True)

        crtl_inputs = scfg.analog_ctrl_inputs + scfg.digital_ctrl_inputs
        ctrl_outputs = scfg.analog_ctrl_outputs + scfg.digital_ctrl_outputs

        #####################################################
        # Define module ios
        #####################################################
        self.module_ifc = SVAPI()
        module = ModuleInst(api=self.module_ifc, name="reg_map")

        # Add clock
        clk = DigitalSignal(name='clk', width=1, abspath=None)
        module.add_input(io_obj=clk)

        o_ctrl = DigitalSignal(name='o_ctrl', width=32, abspath=None)
        module.add_input(io_obj=o_ctrl)
        o_data = DigitalSignal(name='o_data', width=32, abspath=None)
        module.add_output(io_obj=o_data)
        i_ctrl = DigitalSignal(name='i_ctrl', width=32, abspath=None)
        module.add_input(io_obj=i_ctrl)
        i_data = DigitalSignal(name='i_data', width=32, abspath=None)
        module.add_input(io_obj=i_data)

        # Add I/Os to Design (probes and Conrol Parameters)
        module.add_outputs(io_objs=crtl_inputs, connections=crtl_inputs)
        module.add_inputs(io_objs=ctrl_outputs, connections=ctrl_outputs)

        module.generate_header()

        #####################################################
        # Initialize Default Values for ControlInfrastructure Parameters
        #####################################################

        self.init_ctrlios = SVAPI()

        for parameter in crtl_inputs:
            default_signal = deepcopy(parameter)
            default_signal.name = str(default_signal.name) + '_def'
            self.init_ctrlios.gen_signal(io_obj=default_signal)
            self.init_ctrlios.assign_to(io_obj=default_signal, exp=default_signal.init_value)

        #####################################################
        # Combo mux for Probes section
        #####################################################

        # instantiation of register map module
        self.probes_combomux_cases = SVAPI()

        self.probes_combomux_cases.indent(quantity=3)
        for probe in ctrl_outputs:
            if probe.o_addr is not None:
                self.probes_combomux_cases.writeln(f"'d{probe.o_addr}: o_data_reg = {probe.name};")

        #####################################################
        # Combo mux for Probes section
        #####################################################

        # instantiation of register map module
        self.params_regmap = SVAPI()

        for param in crtl_inputs:
            # create a reg signal
            reg_signal = deepcopy(param)
            reg_signal.name = f'{param.name}_reg'
            self.params_regmap.gen_signal(reg_signal)

            # assign to the reg signal
            self.params_regmap.writeln(f'assign {param.name} = {param.name}_reg;')

            # update the reg signal
            self.params_regmap.writeln(f'''\
always @(posedge clk) begin
    if (i_rst == 'b1) begin
        {param.name}_reg <= {param.name}_def; // use VIO defaults
    end else if ((i_valid == 1'b1) && (i_addr == 'd{param.i_addr})) begin
        {param.name}_reg <= i_data;
    end else begin
        {param.name}_reg <= {param.name}_reg;
    end
end''')

    TEMPLATE_TEXT = '''
示例#8
0
class ModuleTop(JinjaTempl):
    """
    This is the generator for top.sv.
    """
    def __init__(self, target):
        super().__init__(trim_blocks=True, lstrip_blocks=True)
        scfg = target.str_cfg
        """ :type: StructureConfig """

        pcfg = target.prj_cfg
        """ :type: EmuConfig """

        self.result_path_raw = back2fwd(target.result_path_raw)

        #####################################################
        # Add plugin specific includes
        #####################################################

        self.plugin_includes = SVAPI()
        for plugin in target.plugins:
            for include_statement in plugin.include_statements:
                self.plugin_includes.writeln(f'{include_statement}')

        #####################################################
        # Create module interface
        #####################################################
        self.module_ifc = SVAPI()

        module = ModuleInst(api=self.module_ifc, name='top')
        module.add_inputs(scfg.clk_i)
        if ((target.cfg.fpga_sim_ctrl is not None)
                and (target.cfg.fpga_sim_ctrl == FPGASimCtrl.UART_ZYNQ)
                and (not pcfg.board.is_ultrascale)):
            module.add_inouts(TemplZynqGPIO.EXT_IOS)
        module.generate_header()

        #####################################################
        # Manage clks
        #####################################################

        # Add clk in signals for simulation case
        self.clk_in_sim_sigs = SVAPI()

        for clk_i in scfg.clk_i:
            self.clk_in_sim_sigs.gen_signal(io_obj=clk_i)

        # Add dbg clk signals
        self.dbg_clk_sigs = SVAPI()
        self.dbg_clk_sigs.gen_signal(io_obj=scfg.dbg_clk)

        # Instantiation of clk_gen wrapper
        self.clk_gen_ifc = SVAPI()
        clk_gen = ModuleInst(api=self.clk_gen_ifc, name='clk_gen')
        clk_gen.add_inputs(scfg.clk_i, connections=scfg.clk_i)
        clk_gen.add_output(scfg.emu_clk_2x, connection=scfg.emu_clk_2x)
        clk_gen.add_output(scfg.dbg_clk, connection=scfg.dbg_clk)
        clk_gen.add_outputs(scfg.clk_independent,
                            connections=scfg.clk_independent)
        clk_gen.generate_instantiation()

        # Absolute path assignments for derived clks
        self.derived_clk_assigns = SVAPI()
        for k, clk in enumerate(scfg.clk_derived):
            self.derived_clk_assigns.writeln(f'// derived clock: {clk.name}')
            if clk.abspath_emu_dt is not None:
                self.derived_clk_assigns.writeln(
                    f'assign {clk.abspath_emu_dt} = emu_dt;')
            if clk.abspath_emu_clk is not None:
                self.derived_clk_assigns.writeln(
                    f'assign {clk.abspath_emu_clk} = emu_clk;')
            if clk.abspath_emu_rst is not None:
                self.derived_clk_assigns.writeln(
                    f'assign {clk.abspath_emu_rst} = emu_rst;')
            if clk.abspath_dt_req is not None:
                self.derived_clk_assigns.writeln(
                    f'assign dt_req_{clk.name} = {clk.abspath_dt_req};')
            if clk.abspath_gated_clk is not None:
                self.derived_clk_assigns.writeln(
                    f'assign clk_val_{clk.name} = {clk.abspath_gated_clk_req};'
                )
                self.derived_clk_assigns.writeln(
                    f'assign {clk.abspath_gated_clk} = clk_{clk.name};')

        self.num_dt_reqs = scfg.num_dt_reqs
        self.num_gated_clks = scfg.num_gated_clks

        #####################################################
        # Manage Ctrl Module
        #####################################################

        # provide information if default oscillator was used for template evaluation
        self.use_default_oscillator = scfg.use_default_oscillator

        ctrl_ios = scfg.analog_ctrl_inputs + scfg.analog_ctrl_outputs + scfg.digital_ctrl_inputs + \
                          scfg.digital_ctrl_outputs

        ## Instantiate all ctrl signals
        self.inst_itl_ctlsigs = SVAPI()
        for ctrl_io in ctrl_ios:
            self.inst_itl_ctlsigs.gen_signal(io_obj=ctrl_io)

        ## Instantiate ctrl module
        self.sim_ctrl_inst_ifc = SVAPI()
        sim_ctrl_inst = ModuleInst(api=self.sim_ctrl_inst_ifc,
                                   name='sim_ctrl_gen')
        sim_ctrl_inst.add_inputs(
            scfg.analog_ctrl_outputs + scfg.digital_ctrl_outputs,
            connections=scfg.analog_ctrl_outputs + scfg.digital_ctrl_outputs)
        sim_ctrl_inst.add_outputs(
            scfg.analog_ctrl_inputs + scfg.digital_ctrl_inputs,
            connections=scfg.analog_ctrl_inputs + scfg.digital_ctrl_inputs)

        ## Wire through Zynq connections if needed
        if ((target.cfg.fpga_sim_ctrl is not None)
                and (target.cfg.fpga_sim_ctrl == FPGASimCtrl.UART_ZYNQ)
                and (not pcfg.board.is_ultrascale)):
            sim_ctrl_inst.add_inouts(TemplZynqGPIO.EXT_IOS,
                                     connections=TemplZynqGPIO.EXT_IOS)

        # add master clk to ctrl module
        emu_clk_sig = DigitalSignal(name='emu_clk', width=1, abspath=None)
        sim_ctrl_inst.add_input(emu_clk_sig, emu_clk_sig)
        sim_ctrl_inst.generate_instantiation()

        ## Assign custom ctrl signals via abs paths into design
        self.assign_custom_ctlsigs = SVAPI()
        for ctrl_input in scfg.digital_ctrl_inputs + scfg.analog_ctrl_inputs:
            if ctrl_input.abs_path is not None:
                self.assign_custom_ctlsigs.assign_to(
                    io_obj=ctrl_input.abs_path, exp=ctrl_input.name)

        for ctrl_output in scfg.digital_ctrl_outputs + scfg.analog_ctrl_outputs:
            self.assign_custom_ctlsigs.assign_to(io_obj=ctrl_output.name,
                                                 exp=ctrl_output.abs_path)

        ######################################################
        # Manage trace port Module
        ######################################################

        probes = scfg.digital_probes + scfg.analog_probes + [
            scfg.time_probe
        ] + [scfg.dec_cmp]

        ## Instantiate all probe signals
        self.inst_probesigs = SVAPI()
        for probe in probes:
            self.inst_probesigs.gen_signal(probe)

        ## Instantiate traceport module
        self.num_probes = len(probes)
        self.trap_inst_ifc = SVAPI()
        trap_inst = ModuleInst(api=self.trap_inst_ifc, name='trace_port_gen')
        trap_inst.add_inputs(probes, connections=probes)
        trap_inst.add_input(scfg.emu_clk, connection=scfg.emu_clk)
        trap_inst.generate_instantiation()

        ## Assign probe signals via abs paths into design except for time probe
        self.assign_probesigs = SVAPI()
        for probe in scfg.digital_probes + scfg.analog_probes:
            self.assign_probesigs.assign_to(io_obj=probe, exp=probe.abs_path)

        ######################################################
        # Manage emulation clks Module
        ######################################################

        ## Instantiate all emulation clk signals
        self.inst_emu_clk_sigs = SVAPI()

        clk_io_pairs = []
        for derived_clk in scfg.clk_derived:
            if derived_clk.abspath_gated_clk is None:
                continue
            clk_val = digsig(f'clk_val_{derived_clk.name}')
            clk = digsig(f'clk_{derived_clk.name}')
            self.inst_emu_clk_sigs.gen_signal(clk_val)
            self.inst_emu_clk_sigs.gen_signal(clk)
            clk_io_pairs.append((clk_val, clk))

        # add default oscillator signals, in case default oscillator was used
        if self.use_default_oscillator:
            clk_val = digsig(f'clk_val_default_osc')
            clk = digsig(f'clk_default_osc')
            self.inst_emu_clk_sigs.gen_signal(clk_val)
            self.inst_emu_clk_sigs.gen_signal(clk)
            clk_io_pairs.append((clk_val, clk))

        ## Instantiate gen emulation clk module
        self.emu_clks_inst_ifc = SVAPI()

        emu_clks_inst = ModuleInst(api=self.emu_clks_inst_ifc,
                                   name="gen_emu_clks")
        emu_clks_inst.add_input(scfg.emu_clk_2x, connection=scfg.emu_clk_2x)
        emu_clks_inst.add_output(scfg.emu_clk, connection=scfg.emu_clk)

        for clk_val, clk in clk_io_pairs:
            emu_clks_inst.add_input(clk_val, connection=clk_val)
            emu_clks_inst.add_output(clk, connection=clk)

        emu_clks_inst.generate_instantiation()

        ######################################################
        # Manage default oscillator module
        ######################################################

        emu_dt = digsig('emu_dt', width=pcfg.cfg.dt_width)
        dt_req_default_osc = DigitalSignal(name=f'dt_req_default_osc',
                                           abspath='',
                                           width=pcfg.cfg.dt_width,
                                           signed=False)

        if scfg.use_default_oscillator:
            # instantiate API
            self.def_osc_api = SVAPI()

            # generate clock and reset signals

            # instantiate the default oscillator
            def_osc_inst = ModuleInst(api=self.def_osc_api,
                                      name='osc_model_anasymod',
                                      inst_name='def_osc_i')

            emu_dt_req = digsig('emu_dt_req', width=pcfg.cfg.dt_width)

            def_osc_inst.add_output(scfg.emu_clk, connection=scfg.emu_clk)
            def_osc_inst.add_output(scfg.reset_ctrl,
                                    connection=scfg.reset_ctrl)
            def_osc_inst.add_output(emu_dt, connection=emu_dt)
            def_osc_inst.add_output(emu_dt_req, connection=dt_req_default_osc)
            def_osc_inst.add_output(digsig('cke'),
                                    connection=digsig('clk_val_default_osc'))
            def_osc_inst.generate_instantiation()
        else:
            self.def_osc_api = None

        ######################################################
        # Manage time manager Module
        ######################################################

        ## Instantiate all time manager signals
        self.inst_timemanager_sigs = SVAPI()

        self.inst_timemanager_sigs.gen_signal(emu_dt)

        dt_reqs = []
        for derived_clk in scfg.clk_derived:
            if derived_clk.abspath_dt_req is None:
                continue
            dt_req_sig = digsig(f'dt_req_{derived_clk.name}',
                                width=pcfg.cfg.dt_width)
            self.inst_timemanager_sigs.gen_signal(dt_req_sig)
            dt_reqs.append(dt_req_sig)

        # add input for anasymod control dt request signal
        dt_req_stall = DigitalSignal(name=f'dt_req_stall',
                                     abspath='',
                                     width=pcfg.cfg.dt_width,
                                     signed=False)
        dt_reqs.append(dt_req_stall)

        # add input for dt request signal, in case a default oscillator is used
        if scfg.use_default_oscillator:
            dt_reqs.append(dt_req_default_osc)

        ## Instantiate time manager module
        self.time_manager_inst_ifc = SVAPI()
        time_manager_inst = ModuleInst(api=self.time_manager_inst_ifc,
                                       name='gen_time_manager')
        time_manager_inst.add_input(scfg.emu_clk, connection=scfg.emu_clk)
        time_manager_inst.add_input(scfg.reset_ctrl,
                                    connection=scfg.reset_ctrl)
        time_manager_inst.add_output(scfg.time_probe, scfg.time_probe)
        time_manager_inst.add_output(emu_dt, emu_dt)
        for dt_req_sig in dt_reqs:
            time_manager_inst.add_input(dt_req_sig, connection=dt_req_sig)

        time_manager_inst.generate_instantiation()

        ######################################################
        # Control module
        ######################################################

        self.ctrl_anasymod_inst_ifc = SVAPI()

        ctrl_anasymod_inst = ModuleInst(api=self.ctrl_anasymod_inst_ifc,
                                        name='ctrl_anasymod',
                                        inst_name='ctrl_anasymod_i')

        ctrl_anasymod_inst.add_input(scfg.emu_ctrl_data,
                                     connection=scfg.emu_ctrl_data)
        ctrl_anasymod_inst.add_input(scfg.emu_ctrl_mode,
                                     connection=scfg.emu_ctrl_mode)
        ctrl_anasymod_inst.add_input(scfg.time_probe,
                                     connection=scfg.time_probe)
        ctrl_anasymod_inst.add_input(scfg.dec_thr_ctrl,
                                     connection=scfg.dec_thr_ctrl)
        ctrl_anasymod_inst.add_input(scfg.emu_clk, connection=scfg.emu_clk)
        ctrl_anasymod_inst.add_input(scfg.reset_ctrl,
                                     connection=scfg.reset_ctrl)
        ctrl_anasymod_inst.add_output(scfg.dec_cmp, connection=scfg.dec_cmp)
        ctrl_anasymod_inst.add_output(dt_req_stall, connection=dt_req_stall)

        ctrl_anasymod_inst.generate_instantiation()

        # indicate whether TSTOP_MSDSL should be used
        self.use_tstop = target.cfg.tstop is not None

        #####################################################
        # Instantiate testbench
        #####################################################
        self.tb_inst_ifc = SVAPI()
        tb_inst = ModuleInst(api=self.tb_inst_ifc, name='tb')
        tb_inst.add_inputs(scfg.clk_independent,
                           connections=scfg.clk_independent)
        tb_inst.generate_instantiation()

        #####################################################
        # CPU debug mode
        #####################################################
        self.dump_debug_signals = SVAPI()
        if pcfg.cfg.cpu_debug_mode:
            dbg_mods_list = pcfg.cfg.cpu_debug_hierarchies
            if isinstance(dbg_mods_list, list):
                for dbg_module in dbg_mods_list:
                    if isinstance(dbg_module, list):
                        self.dump_debug_signals.writeln(
                            f'$dumpvars({dbg_module[0]}, {dbg_module[1]});')
                    elif isinstance(dbg_module, int) and len(
                            dbg_mods_list
                    ) == 2:  # only one single debug module was provided
                        self.dump_debug_signals.writeln(
                            f'$dumpvars({dbg_mods_list[0]}, {dbg_mods_list[1]});'
                        )
                        break
                    else:
                        raise Exception(
                            f'ERROR: unexpected format for cpu_debug_hierarchies attribute of '
                            f'project_config: {dbg_mods_list}, expecting a list including <depth>, '
                            f'<path_to_module> or a lists of such a list.')
            elif not dbg_mods_list:
                self.dump_debug_signals.writeln(f'$dumpvars(0, top.tb_i);')
            else:
                raise Exception(
                    f'ERROR: unexpected format for cpu_debug_hierarchies attribute of '
                    f'project_config: {dbg_mods_list}, expecting tuple, list or None'
                )

    TEMPLATE_TEXT = '''