예제 #1
0
파일: rdl.py 프로젝트: rainliu20/regenerate
    def save(self, reg_list):
        """
        Converts the extracted data into register and bit field values, and
        loads the new data into the database.
        """
        lookup = {'rw': BitField.READ_WRITE,
                  'w': BitField.WRITE_ONLY,
                  'r': BitField.READ_ONLY}

        for (reg_name, addr_txt, field_list) in reg_list:
            register = Register()
            register.address = int(addr_txt, 16)
            register.register_name = reg_name
            register.token = reg_name
            self.dbase.add_register(register)

            for item in field_list:
                field = BitField()
                field.field_name = item.name
                field.field_type = lookup.get(item.software_access,
                                              BitField.READ_ONLY)
                field.start_position = item.start
                field.stop_position = item.stop
                field.reset_value = item.reset
                field.description = item.description
                register.add_bit_field(field)
예제 #2
0
    def save(self, reg_list):
        """
        Converts the extracted data into register and bit field values, and
        loads the new data into the database.
        """
        lookup = {'rw': BitField.TYPE_READ_WRITE,
                  'w': BitField.TYPE_WRITE_ONLY,
                  'r': BitField.TYPE_READ_ONLY}

        name_count = {}
        for reg in reg_list:
            for item in reg.field_list:
                if item.name in name_count:
                    name_count[item.name] = name_count[item.name] + 1
                else:
                    name_count[item.name] = 1
        duplicates = set([key for key in name_count if name_count[key] > 1])
        current_duplicates = {}

        offset = self.dbase.data_bus_width / 8

        for reg in reg_list:
            register = Register()
            register.address = reg.address
            register.register_name = reg.reg_name
            register.token = reg.token
            if not reg.description:
                register.description = reg.description
            else:
                register.description = reg.reg_name
            register.width = self.dbase.data_bus_width
            
            for item in reg.field_list:
                if item.name.startswith("OBSOLETE"):
                    continue

                delta = (register.address % offset) * 8

                if item.name in duplicates:
                    if item.name in current_duplicates:
                        index = current_duplicates[item.name] + 1
                    else:
                        index = 1
                    current_duplicates[item.name] = index
                    name = "%s_%d" % (item.name, index)
                else:
                    name = item.name
                width = (item.stop - item.start) + 1

                field = BitField()
                field.field_name = name
                field.field_type = lookup.get(item.software_access,
                                              BitField.READ_ONLY)
                field.start_position = item.start - delta
                field.stop_position = item.stop - delta
                field.reset_value = item.reset
                field.volatile = item.volatile
                field.description = item.description
                register.add_bit_field(field)
            self.dbase.add_register(register)
예제 #3
0
    def save(self, reg_list):
        """
        Converts the extracted data into register and bit field values, and
        loads the new data into the database.
        """
        lookup = {
            '"rw"': BitField.TYPE_READ_WRITE,
            '"w"': BitField.TYPE_WRITE_ONLY,
            '"r"': BitField.TYPE_READ_ONLY
        }

        for (reg_name, addr_txt, width, field_list) in reg_list:
            register = Register()
            register.address = int(addr_txt, 16)
            register.register_name = reg_name
            register.width = width
            register.token = reg_name
            self.dbase.add_register(register)

            for item in field_list:
                field = BitField()
                field.field_name = item.name
                try:
                    field.field_type = lookup[item.software_access]
                except IndexError:
                    field.field_type = BitField.TYPE_READ_ONLY

                field.start_position = item.start
                field.stop_position = item.stop
                field.reset_value = item.reset
                field.description = item.description
                register.add_bit_field(field)
예제 #4
0
class IpXactParser(object):
    """
    Parses the XML file, loading up the register database.
    """

    def __init__(self, dbase):
        self._db = dbase
        self._reg = None
        self._field = None
        self._fld_start = 0
        self._fld_width = 0
        self._token_list = []
        self._in_maps = False
        self._block_offset = 0
        self._block_list = [0]
        self._in_field_reset = False
        self._in_reg_reset = False
        self._reg_reset = (False, 0)

    def import_data(self, input_file):
        """
        Parses the specified input file.
        """
        parser = xml.parsers.expat.ParserCreate()
        parser.StartElementHandler = self.start_element
        parser.EndElementHandler = self.end_element
        parser.CharacterDataHandler = self.characters
        with open(input_file) as f:
            parser.ParseFile(f)
        #crossreference(self._db)

    def start_element(self, tag, attrs):
        """
        Called every time an XML element begins
        """
        self._token_list = []
        mname = 'start_' + tag.replace(":", "_")
        if hasattr(self, mname):
            method = getattr(self, mname)
            method(attrs)

    def end_element(self, tag):
        """
        Called every time an XML element end
        """
        text = ''.join(self._token_list)
        fields = tag.split(":")
        if len(field) == 1:
            t = tag
        else:
            t = field[1]

        mname = 'end_' + t
        if hasattr(self, mname):
            method = getattr(self, mname)
            method(text)

    def characters(self, data):
        """
        Called with segments of the character data. This is not predictable
        in how it is called, so we must collect the information for assembly
        later.
        """
        self._token_list.append(data)

    def start_register(self, attrs):
        self._reg = Register()

    def end_register(self, text):
        self._db.add_register(self._reg)
        self._reg = None
        self._reg_reset = (False, 0)

    def end_addressOffset(self, text):
        if self._reg:
            self._reg.address = int(text, 0) + self._block_offset

    def end_dim(self, text):
        if self._reg:
            self._reg.dimension = int(text, 0)

    def end_addressBlock(self, text):
        self._block_offset = self._block_list.pop()

    def end_baseAddress(self, text):
        self._block_list.append(self._block_offset)
        self._block_offset = self._block_offset + int(text, 0)

    def end_size(self, text):
        size = int(text, 0)
        if self._reg:
            self._reg.width = size

    def start_reset(self, attrs):
        if self._field:
            self._in_field_reset = True
        elif self._reg:
            self._in_reg_reset = True

    def end_reset(self, text):
        self._in_field_reset = False
        self._in_reg_reset = False

    def end_value(self, text):
        if self._in_field_reset:
            if self._field:
                self._field.reset_value = int(text, 16)
                self._field.reset_type = BitField.RESET_NUMERIC
        elif self._in_reg_reset:
            self._reg_reset = (True, int(text, 16))

    def start_field(self, attrs):
        self._field = BitField()

    def end_field(self, text):
        if not self._field.field_name.startswith("RESERVED"):
            self._field.start_position = self._fld_start
            self._field.stop_position = self._fld_start + self._fld_width - 1
            self._reg.add_bit_field(self._field)
            if self._reg_reset[0]:
                self._field.reset_value = (
                    self._reg_reset[1] >> self._fld_start) & (
                        (1 << self._field.width) - 1)
                self._field.reset_type = BitField.RESET_NUMERIC

        self._field = None

    def end_access(self, text):
        if self._field:
            if self._field.field_type not in (BitField.TYPE_WRITE_1_TO_SET, 
                                              BitField.TYPE_WRITE_1_TO_CLEAR_SET):
                self._field.field_type = text2field.get(text,
                                                        BitField.TYPE_READ_ONLY)

    def end_modifiedWriteValue(self, text):
        if self._field:
            self._field.field_type = text2write.get(text,
                                                    BitField.TYPE_WRITE_1_TO_CLEAR_SET)

    def end_name(self, text):
        if self._field:
            self._field.field_name = text.upper()
        elif self._reg:
            self._reg.register_name = text.replace('_', ' ')
            self._reg.token = text.upper()
        elif not self._in_maps and not self._db.descriptive_title:
            self._db.descriptive_title = text.strip()

    def end_description(self, text):
        if self._field:
            self._field.description = text.strip()
        elif self._reg:
            self._reg.description = text.strip()

    def end_bitOffset(self, text):
        self._fld_start = int(text, 0)

    def end_bitWidth(self, text):
        self._fld_width = int(text, 0)

    def start_memoryMaps(self, attrs):
        self._in_maps = True

    def end_memoryMaps(self, text):
        self._in_maps = False
예제 #5
0
class RegParser(object):
    """
    Parses the XML file, loading up the register database.
    """

    def __init__(self, dbase):
        self.__db = dbase
        self.__reg = None
        self.__field = None
        self.__in_ports = False
        self.__current_val = 0
        self.__current_token = ''
        self.__reset_type = 0
        self.__reset_parameter = ""
        self.__token_list = []
        self.save_id = None

    def parse(self, input_file):
        """
        Parses the specified input file.
        """
        parser = xml.parsers.expat.ParserCreate()
        parser.StartElementHandler = self.start_element
        parser.EndElementHandler = self.end_element
        parser.CharacterDataHandler = self.characters
        parser.ParseFile(input_file)

    def start_element(self, tag, attrs):
        """
        Called every time an XML element begins
        """
        self.__token_list = []
        mname = 'start_' + tag
        if hasattr(self, mname):
            method = getattr(self, mname)
            method(attrs)

    def end_element(self, tag):
        """
        Called every time an XML element end
        """
        text = ''.join(self.__token_list)
        mname = 'end_' + tag
        if hasattr(self, mname):
            method = getattr(self, mname)
            method(text)

    def characters(self, data):
        """
        Called with segments of the character data. This is not predictable
        in how it is called, so we must collect the information for assembly
        later.
        """
        self.__token_list.append(data)

    def start_module(self, attrs):
        """
        Called when the module tag is first encounterd. Pulls off the ID tag
        if it exists, and pulls out the description
        """
        self.__db.module_name = attrs['name']
        if 'owner' in attrs:
            self.__db.owner = attrs['owner']
        if 'organization' in attrs:
            self.__db.organization = attrs['organization']
        self.__db.internal_only = bool(int(attrs.get('internal', "0")))
        if 'id' in attrs:
            self.save_id = cnv_str(attrs, 'id').upper()
        array = attrs.get('array', "mem")
        self.__db.coverage = bool(int(attrs.get('coverage', "1")))
        self.__db.array_is_reg = array == "reg"
        self.__db.descriptive_title = cnv_str(attrs, 'title')

    def start_base(self, attrs):
        """
        Called when the base tag is encountered. Attributes are:

           offset (optional)
           addr_width
           data_width
        """
        self.__db.address_bus_width = cnv_int(attrs, 'addr_width', 32)
        self.__db.data_bus_width = cnv_int(attrs, 'data_width', 32)

    def start_signal(self, attrs):
        """
        Called when the signal tag is encountered. Attributes are:

           enb
           static
           side_effect
           type
        """
        self.__field.use_output_enable = cnv_bool(attrs, 'enb')
        self.__field.output_is_static = cnv_bool(attrs, 'static')
        self.__field.output_has_side_effect = cnv_bool(attrs, 'side_effect')
        self.__field.volatile = cnv_bool(attrs, 'volatile')
        self.__field.can_randomize = cnv_bool(attrs, 'random')
        self.__field.is_error_field = cnv_bool(attrs, 'error_field')
        self.__field.field_type = ID_TO_TYPE[attrs.get('field_type', 'RO')]

    def start_input(self, attrs):
        """
        Called when the input tag is encountered. Attributes are;

          function
          load
        """
        self.__field.control_signal = cnv_str(attrs, 'load')

    def start_register(self, attrs):
        """
        Called when the register tag is encountered. Attributes are:

          nocode
          dont_test
          hide
        """
        self.__reg = Register()
        self.__reg.do_not_generate_code = cnv_bool(attrs, 'nocode')
        self.__reg.do_not_test = cnv_bool(attrs, 'dont_test')
        self.__reg.do_cover = cnv_bool(attrs, 'dont_cover')
        self.__reg.hide = cnv_bool(attrs, 'hide')

    def start_ports(self, attrs):
        """
        Called when the ports tag is encountered.
        """
        self.__in_ports = True

    def start_value(self, attrs):
        """
        Called when the value tag is encountered. Attributes are:

          val
          token
        """
        self.__current_val = attrs['val']
        self.__current_token = attrs.get('token', '')

    def start_range(self, attrs):
        """
        Called when the range tag is encountered. Attributes are:

          start
          stop
        """
        self.__field = BitField(cnv_int(attrs, 'stop'),
                                cnv_int(attrs, 'start'))
        self.__reg.add_bit_field(self.__field)

    def start_be(self, attrs):
        """
        Called when the be tag is encountered. Attributes are:

          active
        """
        self.__db.be_level = cnv_int(attrs, 'active')

    def start_reset(self, attrs):
        """
        Called with the reset tag is encountered. If it is a ports definition,
        then it refers to a global reset, and the attributes are:

          active

        If not, then it refers to the reset value of a bit field, in which
        case the attribute is:

          type

        if type is not specified, the it is assumed to be RESET_NUMERIC
        """
        if self.__in_ports:
            self.__db.reset_active_level = cnv_int(attrs, 'active')
        else:
            try:
                self.__reset_type = int(attrs.get('type', "0"))
                self.__reset_parameter = attrs.get('parameter', '')
            except ValueError:
                self.__reset_type = BitField.RESET_NUMERIC

    def end_register(self, text):
        """
        Called when the register tag is terminated.
        """
        self.__reg = None

    def end_ports(self, text):
        """
        Called when the ports tag is terminated.
        """
        self.__in_ports = False

    def end_range(self, text):
        """
        Called when the range tag is terminated.
        """
        self.__field = None

    def end_reset(self, text):
        """
        Called when the register tag is terminated. If we are in a port
        definition, then the text contains the reset signal name.
        """
        if self.__in_ports:
            self.__db.reset_name = text
        elif self.__reset_type == 1:
            self.__field.reset_input = text.strip()
            self.__field.reset_type = BitField.RESET_INPUT
        elif self.__reset_type == 2:
            self.__field.reset_parameter = self.__reset_parameter
            self.__field.reset_value = int(text, 16)
            self.__field.reset_type = BitField.RESET_PARAMETER
        else:
            self.__field.reset_value = int(text, 16)
            self.__field.reset_type = BitField.RESET_NUMERIC

    def end_token(self, text):
        """
        Called when the token tag is terminated. The text is the
        register token value.
        """
        self.__reg.token = text

    def end_dimension(self, text):
        """
        Called when the token tag is terminated. The text is the
        register token value.
        """
        try:
            self.__reg.dimension = int(text)
        except ValueError:
            self.__reg.dimension = 1

    def end_uuid(self, text):
        """
        Called when the token tag is terminated. The text is the
        register token value.
        """
        if self.__field:
            self.__field.uuid = text
        else:
            self.__reg.uuid = text

    def end_ram_size(self, text):
        """
        Called when the token tag is terminated. The text is the
        register token value.
        """
        self.__reg.ram_size = int(text)

    def end_mneumonic(self, text):
        """
        Called when the token tag is terminated. The text is the
        register token value.
        """
        self.__reg.token = text

    def end_address(self, text):
        """
        Called when the register tag is terminated. The address is the
        text value (base 10). At this point, the register can be added to
        the database, since the address is used as the key.
        """
        self.__reg.address = int(text)
        self.__db.add_register(self.__reg)

    def end_signal(self, text):
        """
        Called when the signal tag is terminated. The text value is assigned
        to the field's output signal
        """
        self.__field.output_signal = text

    def end_value(self, text):
        """
        Called when the value tag is terminated. The value, token and text
        value are added to the field's value list.
        """
        self.__field.values.append((self.__current_val, self.__current_token,
                                    text))

    def end_input(self, text):
        """
        Called when the input tag is terminated. The text value is assigned
        to the field's input signal
        """
        self.__field.input_signal = text

    def end_width(self, text):
        """
        Called when the width tag is terminated. The text value is assigned
        as the register's width. This is assumed to be base 10.
        """
        self.__reg.width = int(text)

    def end_name(self, text):
        """
        Called when the name tag is terminated. If a field is active, then
        the text value is assigned to the field. Otherwise, it is assigned to
        the register.
        """
        if self.__field:
            self.__field.field_name = text
        else:
            self.__reg.register_name = text

    def end_description(self, text):
        """
        Called when the description tag is terminated. If a field is active,
        then the text value is assigned to the field. Otherwise, it is
        assigned to the register.
        """
        if self.__field:
            self.__field.description = text
        else:
            self.__reg.description = text

    def end_overview(self, text):
        """
        Called when the overview tag is terminated. The text value is assigned
        to the database's overview_text
        """
        self.__db.overview_text = text

    def end_addr(self, text):
        """
        Called when the addr tag is terminated. The text value is assigned
        to the database's address_bus_name
        """
        self.__db.address_bus_name = text

    def end_data_in(self, text):
        """
        Called when the data_in tag is terminated. The text value is assigned
        to the database's write_data_name
        """
        self.__db.write_data_name = text

    def end_data_out(self, text):
        """
        Called when the data_out tag is terminated. The text value is assigned
        to the database's read_data_name
        """
        self.__db.read_data_name = text

    def end_be(self, text):
        """
        Called when the be tag is terminated. The text value is assigned
        to the database's byte_strobe_name
        """
        self.__db.byte_strobe_name = text

    def end_wr(self, text):
        """
        Called when the wr tag is terminated. The text value is assigned
        to the database's write_strobe_name
        """
        self.__db.write_strobe_name = text

    def end_ack(self, text):
        """
        Called when the ack tag is terminated. The text value is assigned
        to the database's acknowledge_name
        """
        self.__db.acknowledge_name = text

    def end_rd(self, text):
        """
        Called when the rd tag is terminated. The text value is assigned
        to the database's read_strobe_name
        """
        self.__db.read_strobe_name = text

    def end_clk(self, text):
        """
        Called when the clk tag is terminated. The text value is assigned
        to the database's clock_name
        """
        self.__db.clock_name = text
예제 #6
0
class IpXactParser(object):
    """
    Parses the XML file, loading up the register database.
    """

    def __init__(self, dbase):
        self._db = dbase
        self._reg = None
        self._field = None
        self._fld_start = 0
        self._fld_width = 0
        self._token_list = []
        self._in_maps = False

    def import_data(self, input_file):
        """
        Parses the specified input file.
        """
        parser = xml.parsers.expat.ParserCreate()
        parser.StartElementHandler = self.start_element
        parser.EndElementHandler = self.end_element
        parser.CharacterDataHandler = self.characters
        f = open(input_file)
        parser.ParseFile(f)

    def start_element(self, tag, attrs):
        """
        Called every time an XML element begins
        """
        self._token_list = []
        mname = 'start_' + tag.replace(":", "_")
        if hasattr(self, mname):
            method = getattr(self, mname)
            method(attrs)

    def end_element(self, tag):
        """
        Called every time an XML element end
        """
        text = ''.join(self.__token_list)
        mname = 'end_' + tag.replace(":", "_")
        if hasattr(self, mname):
            method = getattr(self, mname)
            method(text)

    def characters(self, data):
        """
        Called with segments of the character data. This is not predictable
        in how it is called, so we must collect the information for assembly
        later.
        """
        self.__token_list.append(data)

    def start_spirit_register(self, attrs):
        self._reg = Register()

    def end_spirit_register(self, text):
        self._db.add_register(self._reg)
        self._reg = None

    def end_spirit_addressOffset(self, text):
        if self._reg:
            self._reg.address = int(text)

    def end_spirit_size(self, text):
        size = int(text)
        if self._reg:
            self._reg.width = size

    def start_spirit_field(self, attrs):
        self._field = BitField()

    def end_spirit_field(self, text):
        self._field.start_position = self._fld_start
        self._field.stop_position = self._fld_start + self._fld_width - 1
        self._reg.add_bit_field(self._field)
        self._field = None

    def end_spirit_access(self, text):
        if self._field:
            self._field.field_type = text2field.get(text,
                                                     BitField.TYPE_READ_ONLY)

    def end_spirit_name(self, text):
        if self._field:
            self._field.field_name = text.upper()
        elif self._reg:
            self._reg.register_name = text.upper()
            self._reg.token = text.upper()
        elif not self._in_maps:
            self._db.descriptive_title = text

    def end_spirit_description(self, text):
        if self._field:
            self._field.description = " ".join(text.split())
        elif self._reg:
            self._reg.description = " ".join(text.split())

    def end_spirit_bitOffset(self, text):
        self._fld_start = int(text)

    def end_spirit_bitWidth(self, text):
        self._fld_width = int(text)

    def start_spirit_memoryMaps(self, attrs):
        self._in_maps = True

    def end_spirit_memoryMaps(self, text):
        self._in_maps = False
예제 #7
0
    def import_data(self, filename):
        """
        Opens, parses, and extracts data from the input file.
        """
        next_addr = 0
        field = None
        field_list = []
        reg_list = []
        col = {}
        name2addr = {}

        input_file = open(filename, "rU")

        titles = input_file.readline().split(",")
        for (i,name) in enumerate(titles):
            col[name] = i

        r_addr_col = col.get(REG_ADDR, -1)
        r_descr_col = col.get(REG_DESCR, -1)
        r_name_col = col.get(REG_NAME, -1)
        r_width_col = col.get(REG_WIDTH, -1)
        f_name_col = col.get(FIELD_NAME, -1)
        f_start_col = col.get(FIELD_OFFSET, -1)
        f_width_col = col.get(FIELD_WIDTH, -1)
        f_reset_col = col.get(FIELD_RESET, -1)
        f_type_col = col.get(FIELD_ACCESS, -1)
        f_descr_col = col.get(FIELD_DESCR, -1)

        for line in input_file:
            data = line.split(",")

            if is_blank(data):
                continue

            if r_name_col != -1:
                r_name = data[r_name_col].strip()
            else:
                r_name = "REG%04x" % r_addr

            r_token = r_name.upper().replace(" ", "_")

            if r_width_col != -1:
                r_width = parse_hex_value(data[r_width_col])
            else:
                r_width = 32
                
            if r_descr_col == -1:
                r_descr = ""
            else:
                r_descr = data[r_descr_col].strip()

            if data[r_addr_col].strip() == "":
                r_addr = name2addr.get(r_name, next_addr)
            else:
                r_addr = parse_hex_value(data[r_addr_col])
            
            next_addr = r_addr + r_width/8

            name2addr[r_name] = r_addr

            if f_start_col != -1:
                f_start = parse_hex_value(data[f_start_col])

                if f_width_col != -1:
                    width = parse_hex_value(data[col[FIELD_WIDTH]])
                    if width == 0:
                        f_stop = f_start
                    else:
                        f_stop = f_start + width - 1
                else:
                    f_stop = f_start

                if f_descr_col != -1:
                    f_descr = data[f_descr_col]
                else:
                    f_descr = ""
                    
                if f_name_col != -1:
                    f_name = data[f_name_col].strip()
                elif f_stop == f_start:
                    f_name = "BIT%d" % f_stop
                else:
                    f_name = "BITS_%d_%d" % (f_stop, f_start)

                if f_reset_col != -1:
                    f_reset = parse_hex_value(data[col[FIELD_RESET]])
                else:
                    f_reset = 0

                if f_type_col == -1:
                    if data[f_type_col] == "RW":
                        f_type = BitField.READ_WRITE
                    else:
                        f_type = BItField.READ_ONLY
                else:
                    f_type = BitField.READ_ONLY

            if r_addr in self.dbase.get_keys():
                reg = self.dbase.get_register(r_addr)
            else:
                reg = Register()
                reg.address = r_addr
                reg.description = r_descr
                reg.token = r_token
                reg.width = r_width
                reg.register_name = r_name
                self.dbase.add_register(reg)
            field = BitField()
            field.field_name = f_name
            field.description = f_descr
            field.start_position = f_start
            field.stop_position = f_stop
            field.field_type = f_type
            reg.add_bit_field(field)

        input_file.close()