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)
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)
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)
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
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
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
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()