Ejemplo n.º 1
0
def get_module_instance(module_dir: str) -> AsWindowModule:
    module = AsWindowModule()

    toplevel_file = "hardware/vhdl/as_feature_counter.vhd"
    module.files = []
    module.dependencies = []
    module.processing_delay = 0
    module.show_in_browser = True
    module.dev_status = AsWindowModule.DevStatus.STABLE
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "Pipeline Module"

    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Ejemplo n.º 2
0
def get_module_instance(module_dir: str) -> AsWindowModule:
    module = AsWindowModule()

    toplevel_file = "hardware/vhdl/as_edge_threshold.vhd"
    module.files = []
    module.dependencies = []

    module.processing_delay = 1
    module.show_in_browser = True
    module.dev_status = AsWindowModule.DevStatus.BETA
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "Pipeline Window Filter"

    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Ejemplo n.º 3
0
def get_module_instance(module_dir: str) -> AsWindowModule:
    module = AsWindowModule()

    toplevel_file = "hardware/hdl/vhdl/pipeline/as_pipeline_flush.vhd"
    module.files = []
    module.dependencies = ["helpers"]

    module.show_in_browser = False
    module.dev_status = AsWindowModule.DevStatus.BETA
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "Internal Submodules"

    # Automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
def get_module_instance(module_dir: str) -> AsWindowModule:

    module = AsWindowModule()
    toplevel_file = "hardware/hdl/vhdl/as_2d_conv_filter_internal.vhd"
    module.files = []
    module.dependencies = ["as_generic_filter_module"]
    module.processing_delay = 2
    module.show_in_browser = True
    module.dev_status = AsWindowModule.DevStatus.BETA
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "Pipeline Window Filter"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Ejemplo n.º 5
0
def get_module_instance(module_dir: str) -> AsWindowModule:

    module = AsWindowModule()
    toplevel_file = "hardware/hdl/vhdl/as_cnn_pooling_filter.vhd"

    module.files = ["hardware/hdl/vhdl/as_pooling_operator.vhd"]

    module.dependencies = ["as_generic_filter", "helpers"]
    module.processing_delay = 3
    module.show_in_browser = False
    module.dev_status = AsWindowModule.DevStatus.ALPHA
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "AI Accelerator Window Filter"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Ejemplo n.º 6
0
def get_module_instance(module_dir: str) -> AsWindowModule:
    module = AsWindowModule()

    toplevel_file = "hardware/vhdl/as_edge_nms.vhd"
    module.files = []
    module.dependencies = ["as_generic_filter"]

    # Module delay in clock cycles.
    # Number of clock cycles before a result pixel is
    # generated on the output of this module. (default = 0, valid: delay >= 0)
    module.processing_delay = 1
    module.show_in_browser = True
    module.dev_status = AsWindowModule.DevStatus.STABLE
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "Pipeline Window Filter"

    # Automatic module discovery is skipped accordingly.
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
Ejemplo n.º 7
0
def get_module_instance(module_dir: str) -> AsWindowModule:
    module = AsWindowModule()

    toplevel_file = "hardware/hdl/vhdl/pipeline/as_pipeline_row.vhd"
    module.files = [
        "hardware/hdl/vhdl/pipeline/as_line_buffer.vhd",
        "hardware/hdl/vhdl/pipeline/as_shift_line.vhd",
        "hardware/hdl/vhdl/pipeline/as_fifo.vhd",
    ]
    module.dependencies = ["as_generic_filter", "DUAL_BRAM_READ_FIRST"]

    module.show_in_browser = False
    module.dev_status = AsWindowModule.DevStatus.BETA
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "Internal Submodules"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    return module
def get_module_instance(module_dir: str) -> AsWindowModule:

    module = AsWindowModule()
    toplevel_file = "hardware/hdl/vhdl/as_cnn_serial_convolution.vhd"
    module.files = [
        "hardware/hdl/vhdl/as_wallace_adder_tree_generic.vhd",
        "hardware/hdl/vhdl/as_weighted_summand_generator.vhd",
        "hardware/hdl/vhdl/as_cnn_quantizer.vhd",
        "hardware/hdl/vhdl/as_carry_safe_adder.vhd",
        "hardware/hdl/vhdl/as_carry_safe_operator.vhd",
    ]
    module.dependencies = ["as_cnn_helpers", "as_generic_filter", "helpers"]
    module.processing_delay = 11

    module.show_in_browser = True
    module.dev_status = AsWindowModule.DevStatus.BETA
    module.module_type = AsWindowModule.ModuleTypes.HARDWARE
    module.module_category = "AI Accelerator Window Filter"

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    def assign_trained_values(self, weights: list, biases: list,
                              quant_mults: list):
        filter_count = self.get_generic("FILTER_COUNT").get_value()
        kernel_size = self.get_generic("KERNEL_SIZE").get_value()
        # Depth of pipeline in module: 4 + (filter_count - 1)
        self.processing_delay += filter_count - 1

        # Generate kernel weight value string
        channel_count = self.get_generic("CHANNEL_COUNT").get_value()
        kernel_str = weights_to_string_for_serial_filter(
            weights, channel_count, filter_count)

        # Calculate quantization BIAS extension from weights
        weights_per_filter = len(weights) // filter_count
        biases = tuple(biases)
        biases_new = []
        for f_idx in range(filter_count):
            biases_new.append(
                calc_extended_quantized_bias(
                    weights[weights_per_filter * f_idx:weights_per_filter *
                            (f_idx + 1)],
                    biases[f_idx],
                ))

        # Convert values to strings
        if filter_count == 1:
            kernel_str = "(0 => " + kernel_str[1:]
            qmult_str = "(0 => {})".format(quant_mults[0])
            biases_str = "(0 => {})".format(biases_new[0])
        else:
            qmult_str = str(tuple(quant_mults))
            biases_str = str(tuple(biases_new))

        kernel_const_name = self.name + "_kernel_values"
        biases_const_name = self.name + "_bias_values"
        quant_mults_const_name = self.name + "_quantization_factors"

        # Create constants for each value type
        kernel_value_const = Constant(
            kernel_const_name,
            kernel_const_name,
            "t_generic_filter_array",
            kernel_str,
            "(0 to {filter_count}, 0 to {channel_count}, 0 to {kernel_values})"
            .format(
                filter_count=filter_count - 1,
                channel_count=channel_count - 1,
                kernel_values=(kernel_size**2) - 1,
            ),
        )
        biases_value_const = Constant(
            biases_const_name,
            biases_const_name,
            "t_integer_array",
            biases_str,
            Port.DataWidth(0, "to", filter_count - 1),
        )
        quant_mult_const = Constant(
            quant_mults_const_name,
            quant_mults_const_name,
            "t_real_array",
            qmult_str,
            Port.DataWidth(0, "to", filter_count - 1),
        )
        self.parent.add_constant(kernel_value_const)
        self.parent.add_constant(biases_value_const)
        self.parent.add_constant(quant_mult_const)

        # Assign constants to the generics
        self.set_generic_value("KERNEL_VALUES", kernel_const_name)
        self.set_generic_value("BIAS_VALUES", biases_const_name)
        self.set_generic_value("QUANTIZATION_MULTIPLIERS",
                               quant_mults_const_name)

    module.assign_trained_values = assign_trained_values.__get__(module)

    return module
Ejemplo n.º 9
0
def get_module_instance(module_dir: str) -> AsWindowModule:
    """! @brief This function specifies an ASTERICS window module for use
    in a 2D Window Pipeline subsystem.
    It is called by the module library to define the meta data required by
    Automatics to automatically analyze the module
    and further meta data to use it correctly."""

    # Instantiate 'module' as a new ASTERICS window module
    module = AsWindowModule()

    # Pre-Discovery configuration:
    # Here, certain configuration options can be used:

    # Add a custom interface template, defined above, as a possible interface
    # of this module:
    # module.add_local_interface_template(<InterfaceClass>())

    # Here the toplevel file for the module has to be defined.
    # Example, for the file:
    # "modules/as_memwriter/hardware/hdl/vhdl/writer/as_memwriter.vhd"
    # The path to spedify is: "hdl/vhdl/writer/as_memwriter.vhd"
    toplevel_file = "path/to/toplevel/toplevel_filename.vhd"

    # Here all other required files in the module's folder need to be specified.
    # The search path starts at the module's folder, as with the toplevel.
    module.files = [
        "hardware/hdl/vhdl/common_file.vhd",
        "hardware/hdl/vhdl/library.vhd",
        "hardware/hdl/vhdl/extra_component.vhd",
        "hardware/hdl/verilog/vendor_lib.v",
        "hardware/hdl/vhdl/subfolder/shared_component.vhd",
    ]

    # If this module uses files from other modules or from a shared module
    # such as the files in the "as_misc" folder (not technically a module),
    # these have to be declared here.
    # Only the module name has to be listed here
    # (not the folder name, the module name!).
    module.dependencies = ["as_memwriter", "as_lib", "helpers"]

    # Additionally, for window modules, the internal data delay in pixel clocks
    # must be specified. The default value, if this value is not set in this
    # script, is 1 pixel clock.
    module.processing_delay = 1

    # as_automatics now automatically parses the toplevel file and discovers
    # ports, generics, existing interfaces and register interfaces
    module.discover_module(module_dir + "/" + toplevel_file)

    # Custom Interfaces:
    # Your module may implement a new interface that the generator could
    # manage automatically. There are two places where you can specify a new
    # Interface: In this file, above the definition of the function
    # "get_module_instance", or in the user script.
    # To add the defined interface to Automatics, you may use one of two methods
    # Use: 'AsModule.add_global_interface_template(InterfaceClassName())'
    # for interfaces used in more than one module.
    # If the interface is exclusive to this or very few modules, use:
    # 'module.add_local_interface_template(InterfaceClassName())
    # in every module witht the interface.

    # Module configuration:
    # Here you can add/modify configuration parameters for interfaces, generics,
    # ports, register interfaces and the module itself.
    # Here is a list of possible configuration options along with a brief
    # explanation of what they do. For more detailed information, check
    # the chapter about Automatics in the ASTERICS manual.

    # Rules for ports:
    # Ports need to be assigned rules.
    # These rules tell Automatics what to do with the ports when it
    # comes time to build a system. When the generator integrates a module
    # into a system it will match up interfaces of modules and their ports.
    # Depending on the condition, which ports are available, Automatics
    # needs to choose which rules to follow.

    # Valid rule conditions:
    # Conditions for comparing two ports of interfaces:
    #  - "any_present" (this is always true)
    #  - "both_present"
    #  - "sink_missing"
    # Conditions for ports not part of an interface:
    #  - "single_port"
    #  - "external_port"

    # Valid rule-actions:
    # "connect":
    #     Only applicable on the condition "both_present".
    #     Connects the two ports to each other
    # "make_external":
    #     Only applicable on the condition "single_port" or "external_port".
    #     The generator will connect the port through to the toplevel
    #     of the ASTERICS IP-Core.
    # "error"
    #     Applicable for any condition.
    #     Raises an error message and stops as_automatics.
    # "warning"
    #     Applicable for any condition.
    #     Prints a warning message, continuing the process.
    # "note"
    #     Applicable for any condition.
    #     Prints a n information message to the console output and build log.
    # "set_value(<value>)"
    #     Applicable to the conditions "single_port",
    #     "sink_missing", "any_present".
    #     Sets the port to the user defined <value>.
    #     This can be a VHDL signal name, VHDL keyword,
    #     number or data representation (eg. '1', X"F00BA5", open, reg_03).
    #     The "value" given will be directly copied into the VHDL source code.
    # "bundle_and"
    #     Applicable to all conditions.
    #     Similar to "make_external", but bundles all ports with the same
    #     rule and name of all ASTERICS modules in this system.
    #     The signals are bundled together using a single big AND gate.
    # "bundle_or"
    #     This rule behaves exactly like "bundle_and", except that for
    #     this rule the signals are bundled using a big OR gate.
    # "fallback_port(<port name>)"
    #     Applicable to "sink_missing",
    #     depending on the ports data direction.
    #     This action defines another port the port may be connected to, if its
    #     counterpart is missing.
    # "fallback_signal(<signal name>)"
    #     Applicable to "sink_missing".
    #     This action defines a signal that the port may be connected to, if its
    #     counterpart is missing.
    # "none"
    #     The default rule action: Do nothing.

    # By default all ports are assigned a minimal ruleset:
    #   1. "both_present" -> "connect"
    #   2. "sink_missing" -> "note"

    # Use the following functions to modify the rulesets of ports to fit
    # your needs:

    # Use this line to add a rule to a port, one rule action at a time.
    # module.port_rule_add("<Port name>", "<rule_condition>", "<rule_action>")

    # Use this line to replace all rule actions for a single condition with
    # a new rule action.
    # module.port_rule_overwrite("<Port name>", "<rule_condition>",
    #                            "<new_rule_action>")

    # Use this line to remove a rule condition from a port
    # module.port_rule_remove("<Port name>", "<rule_condition>")

    # Use this line to remove all rules from a port
    # module.get("<Port Name>").set_ruleset([])

    # More configuration functions:

    # Configure generics:
    # "to_external"-attribute: Default value is "False", setting this to "True"
    # will cause Automatics to propagate this Generic to toplevel, if no
    # value is set in the user script.
    # module.make_generic_external("<generic name>")

    # "link_to"-attribute: The generic will be set to the generic provided.
    # Automatics will search each higher level module for matching generics.
    # Using this attribute you can set a custom generic to any of the external
    # or standard toplevel generics (such as AXI specific generics).
    # module.link_generic("<generic name>", "<generic to link to>")

    # You can define a function that is used to check the values the generic
    # is "allowed" to take on:
    # module.get_generic(<Generic name>).set_value_check(<function>)
    # The function can be any Python function that takes one value and returns
    # True or False. It is recommended to use lambda expressions for brevity
    # Example: Allow only values between 16 and 256 for generic "DIN_WIDTH"
    # func = lambda value: (value > 15) and (value < 257)
    # module.get_generic("DIN_WIDTH").set_value_check(func)
    # This function will check the value that
    # the generic is set to in the user script.

    # In case you want to have your module automatically instantiated, you have
    # the option to define an additional configuration function here, that is
    # run only if this module is added by way of automatic instantiation.
    # This has the benefit that at the time the function is run, additional
    # information is available, most noteably the object of the instantiating
    # module. Furthermore, the function is run after all user specified
    # connection methods have been run - the processing system is mostly
    # built already.
    # Here is an example definition of the configuration function - for a real
    # use case example, see the specification file of the as_regmgr module in
    # "modules/as_misc/hardware/automatics/as_regmgr_spec.py"
    #
    # def auto_inst_config(this_module, instantiated_from):
    #     # Add first Generic of instantiating module to this module
    #     this_module.set_generic(instantiated_from.generics[0])

    return module