def __init__(self, scfg: StructureConfig):
        super().__init__(trim_blocks=True, lstrip_blocks=True)

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

        module = ModuleInst(api=self.module_ifc, name="clk_gen")
        module.add_inputs(scfg.clk_i)
        module.add_output(scfg.dbg_clk)
        module.add_output(scfg.emu_clk_2x)
        module.add_outputs(scfg.clk_independent)
        module.generate_header()

        #####################################################
        # Instantiate clk wizard
        #####################################################
        self.clk_wiz_inst = SVAPI()

        clk_wiz = ModuleInst(api=self.clk_wiz_inst, name='clk_wiz_0')
        clk_wiz.add_inputs(scfg.clk_i, connections=scfg.clk_i)

        # handled by emu clk generator
        for k, port in enumerate([scfg.emu_clk_2x] + [scfg.dbg_clk] +
                                 scfg.clk_independent):
            clk_wiz.add_output(DigitalSignal(abspath=None,
                                             width=1,
                                             name=f'clk_out{k + 1}'),
                               connection=port)

        clk_wiz.add_input(DigitalSignal(abspath=None, width=1, name='reset'),
                          connection=r"1'b0")
        clk_wiz.add_output(DigitalSignal(abspath=None, width=1, name='locked'),
                           DigitalSignal(abspath=None, width=1, name='locked'))

        clk_wiz.generate_instantiation()

        #####################################################
        # Create independent clks for simulation case
        #####################################################

        self.emu_clk = scfg.emu_clk
        self.independent_clks = scfg.clk_independent
    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()
Beispiel #3
0
    def __init__(self,
                 ps_vlnv='xilinx.com:ip:processing_system7:5.5',
                 gpio_vlnv='xilinx.com:ip:axi_gpio:2.0',
                 design_name='zynq_gpio',
                 ultra_ps_vlnv='xilinx.com:ip:zynq_ultra_ps_e:3.3',
                 is_ultrascale=False):
        # call the super constructor
        super().__init__(trim_blocks=False, lstrip_blocks=False)

        # save settings
        self.design_name = design_name
        self.ps_vlnv = ps_vlnv
        self.gpio_vlnv = gpio_vlnv
        self.ultra_ps_vlnv = ultra_ps_vlnv
        self.is_ultrascale = is_ultrascale

        # save IO that are used by the emulator
        self.o_ctrl = DigitalSignal(name='o_ctrl', width=32, abspath=None)
        self.o_data = DigitalSignal(name='o_data', width=32, abspath=None)
        self.i_ctrl = DigitalSignal(name='i_ctrl', width=32, abspath=None)
        self.i_data = DigitalSignal(name='i_data', width=32, abspath=None)
Beispiel #4
0
class TemplZynqGPIO(JinjaTempl):
    def __init__(self,
                 ps_vlnv='xilinx.com:ip:processing_system7:5.5',
                 gpio_vlnv='xilinx.com:ip:axi_gpio:2.0',
                 design_name='zynq_gpio',
                 ultra_ps_vlnv='xilinx.com:ip:zynq_ultra_ps_e:3.3',
                 is_ultrascale=False):
        # call the super constructor
        super().__init__(trim_blocks=False, lstrip_blocks=False)

        # save settings
        self.design_name = design_name
        self.ps_vlnv = ps_vlnv
        self.gpio_vlnv = gpio_vlnv
        self.ultra_ps_vlnv = ultra_ps_vlnv
        self.is_ultrascale = is_ultrascale

        # save IO that are used by the emulator
        self.o_ctrl = DigitalSignal(name='o_ctrl', width=32, abspath=None)
        self.o_data = DigitalSignal(name='o_data', width=32, abspath=None)
        self.i_ctrl = DigitalSignal(name='i_ctrl', width=32, abspath=None)
        self.i_data = DigitalSignal(name='i_data', width=32, abspath=None)

        # generate text

    TEMPLATE_TEXT = '''\
############################
# Create the block diagram #
############################

# Initialize

create_bd_design "{{subst.design_name}}"

# Instantiate IPs

{% if subst.is_ultrascale %}
create_bd_cell -type ip -vlnv {{subst.ultra_ps_vlnv}} zynq_ultra_ps_e_0
{% else %}
create_bd_cell -type ip -vlnv {{subst.ps_vlnv}} processing_system7_0
{% endif %}
create_bd_cell -type ip -vlnv {{subst.gpio_vlnv}} axi_gpio_0
create_bd_cell -type ip -vlnv {{subst.gpio_vlnv}} axi_gpio_1

# Configure IPs

set_property \\
    -dict [list \\
        CONFIG.C_IS_DUAL {1} \\
        CONFIG.C_ALL_OUTPUTS {1} \\
        CONFIG.C_ALL_INPUTS_2 {1} \\
    ] \\
    [get_bd_cells axi_gpio_0]

set_property \\
    -dict [list \\
        CONFIG.C_IS_DUAL {1} \\
        CONFIG.C_ALL_OUTPUTS {1} \\
        CONFIG.C_ALL_OUTPUTS_2 {1} \\
    ] \\
    [get_bd_cells axi_gpio_1]

# Create ports

create_bd_port -dir O -from 31 -to 0 o_ctrl 
create_bd_port -dir I -from 31 -to 0 o_data
create_bd_port -dir O -from 31 -to 0 i_ctrl 
create_bd_port -dir O -from 31 -to 0 i_data

# Wire up IPs

{% if not subst.is_ultrascale %}
connect_bd_net \\
    [get_bd_pins processing_system7_0/FCLK_CLK0] \\
    [get_bd_pins processing_system7_0/M_AXI_GP0_ACLK]
{% endif %}

connect_bd_net \\
    [get_bd_ports o_ctrl] \\
    [get_bd_pins axi_gpio_0/gpio_io_o]

connect_bd_net \\
    [get_bd_ports o_data] \\
    [get_bd_pins axi_gpio_0/gpio2_io_i]

connect_bd_net \\
    [get_bd_ports i_ctrl] \\
    [get_bd_pins axi_gpio_1/gpio_io_o]

connect_bd_net \\
    [get_bd_ports i_data] \\
    [get_bd_pins axi_gpio_1/gpio2_io_o]

####################
# Apply automation #
####################   

# processing system automation

{% if subst.is_ultrascale %}
apply_bd_automation \\
    -rule xilinx.com:bd_rule:zynq_ultra_ps_e \\
    -config { \\
        apply_board_preset "1" \\
    } \\
    [get_bd_cells zynq_ultra_ps_e_0]
{% else %}
apply_bd_automation \\
    -rule xilinx.com:bd_rule:processing_system7 \\
    -config { \\
        make_external "FIXED_IO, DDR" \\
        apply_board_preset "1" \\
        Master "Disable" \\
        Slave "Disable" \\
    } \\
    [get_bd_cells processing_system7_0]
{% endif %}

# axi_gpio_0 automation

{% if subst.is_ultrascale %}
apply_bd_automation \\
    -rule xilinx.com:bd_rule:axi4 \\
    -config { \\
        Clk_master {Auto} \\
        Clk_slave {Auto} \\
        Clk_xbar {Auto} \\
        Master {/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD} \\
        Slave {/axi_gpio_0/S_AXI} \\
        ddr_seg {Auto} \\
        intc_ip {New AXI Interconnect} \\
        master_apm {0}\\
    } \\
    [get_bd_intf_pins axi_gpio_0/S_AXI]
{% else %}
apply_bd_automation \\
    -rule xilinx.com:bd_rule:axi4 \\
    -config { \\
        Clk_master {/processing_system7_0/FCLK_CLK0 (100 MHz)} \\
        Clk_slave {Auto} \\
        Clk_xbar {Auto} \\
        Master {/processing_system7_0/M_AXI_GP0} \\
        Slave {/axi_gpio_0/S_AXI} \\
        intc_ip {New AXI Interconnect} \\
        master_apm {0}\\
    } \\
    [get_bd_intf_pins axi_gpio_0/S_AXI]
{% endif %}

# axi_gpio_1 automation

{% if subst.is_ultrascale %}
apply_bd_automation \\
    -rule xilinx.com:bd_rule:axi4 \\
    -config { \\
        Clk_master {Auto} \\
        Clk_slave {Auto} \\
        Clk_xbar {Auto} \\
        Master {/zynq_ultra_ps_e_0/M_AXI_HPM0_FPD} \\
        Slave {/axi_gpio_1/S_AXI} \\
        ddr_seg {Auto} \\
        intc_ip {New AXI Interconnect} \\
        master_apm {0}\\
    } \\
    [get_bd_intf_pins axi_gpio_1/S_AXI]
{% else %}
apply_bd_automation \\
    -rule xilinx.com:bd_rule:axi4 \\
    -config { \\
        Clk_master {/processing_system7_0/FCLK_CLK0 (100 MHz)} \\
        Clk_slave {Auto} \\
        Clk_xbar {Auto} \\
        Master {/processing_system7_0/M_AXI_GP0} \\
        Slave {/axi_gpio_1/S_AXI} \\
        intc_ip {New AXI Interconnect} \\
        master_apm {0}\\
    } \\
    [get_bd_intf_pins axi_gpio_1/S_AXI]
{% endif %}

# other automation

{% if subst.is_ultrascale %}
apply_bd_automation \\
    -rule xilinx.com:bd_rule:axi4 \\
    -config { \\
        Clk_master {Auto} \\
        Clk_slave {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} \\
        Clk_xbar {/zynq_ultra_ps_e_0/pl_clk0 (99 MHz)} \\
        Master {/zynq_ultra_ps_e_0/M_AXI_HPM1_FPD} \\
        Slave {/axi_gpio_0/S_AXI} \\
        ddr_seg {Auto} \\
        intc_ip {/ps8_0_axi_periph} \\
        master_apm {0}\\
    } \\
    [get_bd_intf_pins zynq_ultra_ps_e_0/M_AXI_HPM1_FPD]
{% endif %}

validate_bd_design
'''

    # save external IOs that need to be wired to the top
    EXT_IOS = [
        DigitalSignal(name='DDR_addr', width=15, abspath=None),
        DigitalSignal(name='DDR_ba', width=3, abspath=None),
        DigitalSignal(name='DDR_cas_n', width=1, abspath=None),
        DigitalSignal(name='DDR_ck_n', width=1, abspath=None),
        DigitalSignal(name='DDR_ck_p', width=1, abspath=None),
        DigitalSignal(name='DDR_cke', width=1, abspath=None),
        DigitalSignal(name='DDR_cs_n', width=1, abspath=None),
        DigitalSignal(name='DDR_dm', width=4, abspath=None),
        DigitalSignal(name='DDR_dq', width=32, abspath=None),
        DigitalSignal(name='DDR_dqs_n', width=4, abspath=None),
        DigitalSignal(name='DDR_dqs_p', width=4, abspath=None),
        DigitalSignal(name='DDR_odt', width=1, abspath=None),
        DigitalSignal(name='DDR_ras_n', width=1, abspath=None),
        DigitalSignal(name='DDR_reset_n', width=1, abspath=None),
        DigitalSignal(name='DDR_we_n', width=1, abspath=None),
        DigitalSignal(name='FIXED_IO_ddr_vrn', width=1, abspath=None),
        DigitalSignal(name='FIXED_IO_ddr_vrp', width=1, abspath=None),
        DigitalSignal(name='FIXED_IO_mio', width=54, abspath=None),
        DigitalSignal(name='FIXED_IO_ps_clk', width=1, abspath=None),
        DigitalSignal(name='FIXED_IO_ps_porb', width=1, abspath=None),
        DigitalSignal(name='FIXED_IO_ps_srstb', width=1, abspath=None)
    ]
    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')
Beispiel #6
0
    def _read_simctrlfile(self):
        """
        Read all lines from simulation control file simctrl.yaml and store in structure config attributes.
        """

        if os.path.isfile(self._simctrl_file_path):
            try:
                sigs = yaml.safe_load(open(self._simctrl_file_path, "r"))
            except yaml.YAMLError as exc:
                raise Exception(exc)
        else:
            print('No simctrl.yaml file existing, no additional probes will be available for this simulation.')
            return

        if sigs is None:
            print('No signals specified in simctrl.yaml.')
            return
        # Add analog probes to structure config
        if 'analog_probes' in sigs:
            print(f'Analog Probes: {list(sigs["analog_probes"].keys())}')
            for name, analog_probe in sigs['analog_probes'].items():
                self.analog_probes.append(AnalogProbe.from_dict(name, analog_probe))
            else:
                print(f'No Analog Probes provided.')

        # Add digital probes to structure config
        if 'digital_probes' in sigs:
            print(f'Digital Probes: {list(sigs["digital_probes"].keys())}')
            for name, digital_probe in sigs['digital_probes'].items():
                self.digital_probes.append(DigitalSignal.from_dict(name, digital_probe))
        else:
            print(f'No Digital Probes provided.')

        # Add digital ctrl inputs to structure config
        if sigs.get('digital_ctrl_inputs', None) is not None:
            print(f'Digital Ctrl Inputs: {list(sigs["digital_ctrl_inputs"].keys())}')
            for name, d_ctrl_in in sigs['digital_ctrl_inputs'].items():
                d_ctrl_i = DigitalCtrlInput.from_dict(name, d_ctrl_in)
                d_ctrl_i.i_addr = self._assign_i_addr()
                self.digital_ctrl_inputs.append(d_ctrl_i)
        else:
            print(f'No Digital Ctrl Input provided.')

        # Add digital ctrl outputs to structure config
        if sigs.get('digital_ctrl_outputs', None) is not None:
            print(f'Digital Ctrl Outputs: {list(sigs["digital_ctrl_outputs"].keys())}')
            for name, d_ctrl_out in sigs['digital_ctrl_outputs'].items():
                d_ctrl_o = DigitalCtrlOutput.from_dict(name, d_ctrl_out)
                d_ctrl_o.o_addr = self._assign_o_addr()
                self.digital_ctrl_outputs.append(d_ctrl_o)
        else:
            print(f'No Digital Ctrl Outputs provided.')

        # Add analog ctrl inputs to structure config
        if sigs.get('analog_ctrl_inputs', None) is not None:
            print(f'Analog Ctrl Inputs: {list(sigs["analog_ctrl_inputs"].keys())}')
            for name, a_ctrl_in in sigs['analog_ctrl_inputs'].items():
                a_ctrl_i = AnalogCtrlInput.from_dict(name, a_ctrl_in)
                a_ctrl_i.i_addr = self._assign_i_addr()
                self.analog_ctrl_inputs.append(a_ctrl_i)
        else:
            print(f'No Analog Ctrl Input provided.')

        # Add analog ctrl outputs to structure config
        if sigs.get('analog_ctrl_outputs', None) is not None:
            print(f'Analog Ctrl Outputs: {list(sigs["analog_ctrl_outputs"].keys())}')
            for name, a_ctrl_out in sigs['analog_ctrl_outputs'].items():
                a_ctrl_o = AnalogCtrlOutput.from_dict(name, a_ctrl_out)
                a_ctrl_o.o_addr = self._assign_o_addr()
                self.analog_ctrl_outputs.append(a_ctrl_o)
        else:
            print(f'No Analog Ctrl Outputs provided.')
Beispiel #7
0
    def __init__(self, prj_cfg: EmuConfig, simctrl_path, can_use_default_oscillator=True):
        # Internal variables
        self.i_addr_counter = 0
        self.o_addr_counter = 0

        # Path to clks.yaml file
        self._clks_file_path = os.path.join(prj_cfg.root, 'clks.yaml')
        # Path to simctrl.yaml file
        self._simctrl_file_path = simctrl_path

        self.cfg = Config(prj_cfg=prj_cfg)
        self.cfg.update_config()

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

        self.emu_clk = ClkIndependent(name='emu_clk', freq=float(prj_cfg.cfg.emu_clk_freq))
        self.emu_clk_2x = ClkIndependent(name='emu_clk_2x', freq=float(prj_cfg.cfg.emu_clk_freq) * 2) # multiplied by two, as emu_clk_2x is twice as fast as emu_clk
        self.dbg_clk = ClkIndependent(name='dbg_hub_clk', freq=float(prj_cfg.board.dbg_hub_clk_freq))

        # add clk_in
        self.clk_i_num = len(prj_cfg.board.clk_pin)

        # clk_in names cannot be changed
        if self.clk_i_num == 2:
            self.clk_i = [DigitalSignal(abspath=None, width=1, name='clk_in1_p'), DigitalSignal(abspath=None, width=1, name='clk_in1_n')]
        elif self.clk_i_num == 1:
            self.clk_i = [DigitalSignal(abspath=None, width=1, name='clk_in1')]
        else:
            raise ValueError(
                f"Wrong number of pins for boards param 'clk_pin', expecting 1 or 2, provided:{self.clk_i_num}")

        # Add independent clks, that will be implemented via clk_wiz IP core for FPGA
        self.clk_independent = []
        """ type : [ClkIndependent]"""

        # Add derived clks; those are aligned with emu_clk
        self.clk_derived = []
        """ type : [ClkDerived]"""

        # Number of gated clks
        self.num_gated_clks = 0

        # Number of dt requests
        self.num_dt_reqs = 0

        self._read_clksfile()

        # add a default derived clock if needed
        if (self.num_dt_reqs == 0) and can_use_default_oscillator:
            self.use_default_oscillator = True
        else:
            self.use_default_oscillator = False

        # make note of whether this is an UltraScale board
        self.is_ultrascale = prj_cfg.board.is_ultrascale

        #########################################################
        # Simulation control interfaces
        #########################################################

        # CtrlIOs
        self.digital_ctrl_inputs = []
        self.digital_ctrl_outputs = []
        self.analog_ctrl_inputs = []
        self.analog_ctrl_outputs = []
        self.analog_probes = []
        self.digital_probes = []

        # annotate special control signals that should not
        # be routed to sim_ctrl
        self.special_ctrl_ios = set()

        # Add time signal representing current simulated time
        self.time_probe = DigitalSignal(
            name='emu_time',
            width=prj_cfg.cfg.time_width,
            abspath=''
        )

        # Add DigitalCtrlInput for reset
        self.reset_ctrl = DigitalCtrlInput(
            abspath=None,
            name='emu_rst',
            width=1)
        self.reset_ctrl.i_addr = self._assign_i_addr()
        self.digital_ctrl_inputs += [self.reset_ctrl]
        self.special_ctrl_ios.add(self.reset_ctrl.name)

        # Add DigitalCtrlInput for control signal 'emu_dec_thr' to manage decimation
        # ratio for capturing probe samples
        self.dec_thr_ctrl = DigitalCtrlInput(
            abspath=None,
            name='emu_dec_thr',
            width=int(prj_cfg.cfg.dec_bits)
        )
        self.dec_thr_ctrl.i_addr = self._assign_i_addr()
        self.digital_ctrl_inputs += [self.dec_thr_ctrl]
        self.special_ctrl_ios.add(self.dec_thr_ctrl.name)

        # Add DigitalCtrlInput for control signal 'emu_time_tgt' to run for
        # a specific amount of time
        self.emu_ctrl_data = DigitalCtrlInput(
            name='emu_ctrl_data',
            width=int(prj_cfg.cfg.time_width),
            abspath = None
        )
        self.emu_ctrl_data.i_addr = self._assign_i_addr()
        self.digital_ctrl_inputs += [self.emu_ctrl_data]
        self.special_ctrl_ios.add(self.emu_ctrl_data.name)

        # Add DigitalCtrlInput for control signal 'emu_ctrl_mode' to run for
        # a specific amount of time
        self.emu_ctrl_mode = DigitalCtrlInput(
            name='emu_ctrl_mode',
            width=2,
            abspath = None
        )
        self.emu_ctrl_mode.i_addr = self._assign_i_addr()
        self.digital_ctrl_inputs += [self.emu_ctrl_mode]
        self.special_ctrl_ios.add(self.emu_ctrl_mode.name)

        # Add DigitalCtrlOutput for reading the emulation time
        self.emu_time_vio = DigitalCtrlOutput(
            name='emu_time_vio',
            width=prj_cfg.cfg.time_width,
            abspath = 'emu_time'
        )
        self.emu_time_vio.i_addr = self._assign_o_addr()
        self.digital_ctrl_outputs += [self.emu_time_vio]
        self.special_ctrl_ios.add(self.emu_time_vio.name)

        # Add DigitalSignal for control of signal 'emu_dec_cmp' to trigger sampling
        # for the ila depending on 'emu_dec_thr'
        self.dec_cmp = DigitalSignal(
            name='emu_dec_cmp',
            abspath='emu_dec_cmp_probe',
            width=1
        )

        self._read_simctrlfile()
Beispiel #8
0
    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};')
    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()
Beispiel #10
0
    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''')
Beispiel #11
0
    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'
                )
Beispiel #12
0
def digsig(name, width=1, signed=False):
    # convenience function to return a digital signal
    return DigitalSignal(name=f'{name}',
                         width=width,
                         signed=signed,
                         abspath='')
    def __init__(self, scfg: StructureConfig):
        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

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

        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)
        if not scfg.is_ultrascale:
            module.add_inouts(TemplZynqGPIO.EXT_IOS)
        module.generate_header()

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

        #####################################################
        # 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 custom ctrl signal available
        ctrl_signals = ctrl_outputs + ctrl_inputs
        custom_ctrl_signals = []
        for ctrl_signal in ctrl_signals:
            if not ctrl_signal.name in scfg.special_ctrl_ios:
                custom_ctrl_signals.append(ctrl_signal)

        if len(custom_ctrl_signals) != 0:
            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
        #####################################################

        # instantiation of register map module

        self.reg_map_inst = SVAPI()

        reg_map = ModuleInst(api=self.reg_map_inst, name="reg_map")

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

        reg_map.add_input(io_obj=self.zynq_gpio.o_ctrl,
                          connection=self.zynq_gpio.o_ctrl)
        reg_map.add_output(io_obj=self.zynq_gpio.o_data,
                           connection=self.zynq_gpio.o_data)
        reg_map.add_input(io_obj=self.zynq_gpio.i_ctrl,
                          connection=self.zynq_gpio.i_ctrl)
        reg_map.add_input(io_obj=self.zynq_gpio.i_data,
                          connection=self.zynq_gpio.i_data)

        reg_map.add_outputs(io_objs=ctrl_inputs, connections=ctrl_inputs)
        reg_map.add_inputs(io_objs=ctrl_outputs, connections=ctrl_outputs)

        reg_map.generate_instantiation()

        # instantiation of bd

        self.bd_inst = SVAPI()

        bd = ModuleInst(api=self.bd_inst, name=self.zynq_gpio.design_name)

        bd.add_output(io_obj=self.zynq_gpio.o_ctrl,
                      connection=self.zynq_gpio.o_ctrl)
        bd.add_input(io_obj=self.zynq_gpio.o_data,
                     connection=self.zynq_gpio.o_data)
        bd.add_output(io_obj=self.zynq_gpio.i_ctrl,
                      connection=self.zynq_gpio.i_ctrl)
        bd.add_output(io_obj=self.zynq_gpio.i_data,
                      connection=self.zynq_gpio.i_data)

        if not scfg.is_ultrascale:
            bd.add_inouts(io_objs=TemplZynqGPIO.EXT_IOS,
                          connections=TemplZynqGPIO.EXT_IOS)

        bd.generate_instantiation()