Beispiel #1
0
  def generate_code(self, code_entity_list, language = VHDL_Code):
    """ Final VHDL generation, once the evaluation scheme has been optimized"""
    # registering scheme as function implementation
    #self.implementation.set_scheme(scheme)
    # main code object
    code_object = self.get_main_code_object()

    # list of ComponentObject which are entities on which self depends
    common_entity_list = []
    generated_entity = []

    self.result = code_object
    code_str = ""
    while len(code_entity_list) > 0:
      code_entity = code_entity_list.pop(0)
      if code_entity in generated_entity:
        continue
      entity_code_object = NestedCode(
        self.vhdl_code_generator, static_cst=False,
        uniquifier="{0}_".format(self.entity_name),
        code_ctor=VHDLCodeObject,
        shared_symbol_list=[MultiSymbolTable.EntitySymbol, MultiSymbolTable.ProtectedSymbol],
      )
      if self.is_main_entity(code_entity):
        self.vhdl_code_generator.disable_debug = not self.debug_flag
      else:
        self.vhdl_code_generator.disable_debug = True
      result = code_entity.add_definition(self.vhdl_code_generator, language, entity_code_object, static_cst = False)
      result.add_library("ieee")
      result.add_header("ieee.std_logic_1164.all")
      result.add_header("ieee.std_logic_arith.all")
      result.add_header("ieee.std_logic_misc.all")
      result.add_header("STD.textio.all")
      result.add_header("ieee.std_logic_textio.all")
      code_str += result.get(self.vhdl_code_generator, headers = True)

      generated_entity.append(code_entity)

      # adding the entities encountered during code generation
      # for future generation
      # TODO: document
      extra_entity_list = [
            comp_object.get_code_entity() for comp_object in
                entity_code_object.get_entity_list()
      ]
      Log.report(Log.Info, "appending {} extra entit(y/ies)\n".format(len(extra_entity_list)))
      code_entity_list += extra_entity_list

    Log.report(Log.Verbose, "Generating VHDL code in " + self.output_file)
    output_stream = open(self.output_file, "w")
    output_stream.write(code_str)
    output_stream.close()
    if self.debug_flag:
      Log.report(Log.Verbose, "Generating Debug code in {}".format(self.debug_file))
      debug_code_str = self.debug_code_object.get(None)
      debug_stream = open(self.debug_file, "w")
      debug_stream.write(debug_code_str)
      debug_stream.close()
Beispiel #2
0
    def __init__(
            self,
            # Naming
            base_name=ArgDefault("unknown_entity", 2),
            entity_name=ArgDefault(None, 2),
            output_file=ArgDefault(None, 2),
            # Specification
            io_precisions=ArgDefault([ML_Binary32], 2),
            abs_accuracy=ArgDefault(None, 2),
            libm_compliant=ArgDefault(True, 2),
            # Optimization parameters
            backend=ArgDefault(VHDLBackend(), 2),
            fast_path_extract=ArgDefault(True, 2),
            # Debug verbosity
            debug_flag=ArgDefault(False, 2),
            language=ArgDefault(VHDL_Code, 2),
            arg_template=DefaultEntityArgTemplate):
        # selecting argument values among defaults
        base_name = ArgDefault.select_value([base_name])
        Log.report(
            Log.Info, "pre entity_name: %s %s " %
            (entity_name, arg_template.entity_name))
        entity_name = ArgDefault.select_value(
            [arg_template.entity_name, entity_name])
        Log.report(Log.Info, "entity_name: %s " % entity_name)
        Log.report(
            Log.Info,
            "output_file: %s %s " % (arg_template.output_file, output_file))
        Log.report(Log.Info, "debug_file:  %s " % arg_template.debug_file)
        output_file = ArgDefault.select_value(
            [arg_template.output_file, output_file])
        debug_file = arg_template.debug_file
        # Specification
        io_precisions = ArgDefault.select_value([io_precisions])
        abs_accuracy = ArgDefault.select_value([abs_accuracy])
        # Optimization parameters
        backend = ArgDefault.select_value([arg_template.backend, backend])
        fast_path_extract = ArgDefault.select_value(
            [arg_template.fast_path_extract, fast_path_extract])
        # Debug verbosity
        debug_flag = ArgDefault.select_value([arg_template.debug, debug_flag])
        language = ArgDefault.select_value([arg_template.language, language])
        auto_test = arg_template.auto_test
        auto_test_std = arg_template.auto_test_std

        self.precision = arg_template.precision
        self.pipelined = arg_template.pipelined

        # io_precisions must be a list
        #     -> with a single element
        # XOR -> with as many elements as function arity (input + output arities)
        self.io_precisions = io_precisions

        ## enable the generation of numeric/functionnal auto-test
        self.auto_test_enable = (auto_test != False or auto_test_std != False)
        self.auto_test_number = auto_test
        self.auto_test_range = arg_template.auto_test_range
        self.auto_test_std = auto_test_std

        # enable/disable automatic exit once functional test is finished
        self.exit_after_test = arg_template.exit_after_test

        # enable post-generation RTL elaboration
        self.build_enable = arg_template.build_enable
        # enable post-elaboration simulation
        self.execute_trigger = arg_template.execute_trigger

        self.language = language

        # Naming logic, using provided information if available, otherwise deriving from base_name
        # base_name is e.g. exp
        # entity_name is e.g. expf or expd or whatever
        self.entity_name = entity_name if entity_name else generic_naming(
            base_name, self.io_precisions)

        self.output_file = output_file if output_file else self.entity_name + ".vhd"
        self.debug_file = debug_file if debug_file else "{}_dbg.do".format(
            self.entity_name)

        # debug version
        self.debug_flag = debug_flag
        # debug display
        self.display_after_gen = arg_template.display_after_gen
        self.display_after_opt = arg_template.display_after_opt

        # TODO: FIX which i/o precision to select
        # TODO: incompatible with fixed-point formats
        # self.sollya_precision = self.get_output_precision().get_sollya_object()

        self.abs_accuracy = abs_accuracy if abs_accuracy else S2**(
            -self.get_output_precision().get_precision())

        # target selection
        self.backend = backend

        # register control
        self.reset_pipeline = arg_template.reset_pipeline
        self.recirculate_pipeline = arg_template.recirculate_pipeline

        # optimization parameters
        self.fast_path_extract = fast_path_extract

        self.implementation = CodeEntity(self.entity_name)

        self.vhdl_code_generator = VHDLCodeGenerator(
            self.backend,
            declare_cst=False,
            disable_debug=not self.debug_flag,
            language=self.language)
        uniquifier = self.entity_name
        self.main_code_object = NestedCode(self.vhdl_code_generator,
                                           static_cst=False,
                                           uniquifier="{0}_".format(
                                               self.entity_name),
                                           code_ctor=VHDLCodeObject)
        if self.debug_flag:
            self.debug_code_object = CodeObject(self.language)
            self.debug_code_object << debug_utils_lib
            self.vhdl_code_generator.set_debug_code_object(
                self.debug_code_object)

        # pass scheduler instanciation
        self.pass_scheduler = PassScheduler()
        # recursive pass dependency
        pass_dep = PassDependency()
        for pass_uplet in arg_template.passes:
            pass_slot_tag, pass_tag = pass_uplet.split(":")
            pass_slot = PassScheduler.get_tag_class(pass_slot_tag)
            pass_class = Pass.get_pass_by_tag(pass_tag)
            pass_object = pass_class(self.backend)
            self.pass_scheduler.register_pass(pass_object,
                                              pass_dep=pass_dep,
                                              pass_slot=pass_slot)
            # linearly linking pass in the order they appear
            pass_dep = AfterPassById(pass_object.get_pass_id())

        # TODO/FIXME: can be overloaded
        if self.reset_pipeline:
            self.reset_signal = self.implementation.add_input_signal(
                "reset", ML_StdLogic)
        self.recirculate_signal_map = {}