diff --git a/gen_c_config.py b/gen_c_config.py index e18ed76c861c6952cbb79ae6d175e13cf85d1d65..441e4a4347de86983f69ad8a0e8dc3a9aafd34b4 100755 --- a/gen_c_config.py +++ b/gen_c_config.py @@ -35,7 +35,7 @@ import os from argparse import ArgumentParser from args_logger import MyLogger -from py_args_lib import RAM, FIFO, Register, FPGALibrary, ceil_pow2, WIDTH_IN_BYTES +from py_args_lib import RAM, FIFO, Register, FPGALibrary, ceil_pow2, WORD_SIZE def gen_c_config(fpga, fpga_name, out_dir): @@ -55,15 +55,15 @@ def gen_c_config(fpga, fpga_name, out_dir): pname = peripheral.name() logger.debug('pname=%s', pname) count = peripheral.number_of_peripherals() - base = int(periph_info['base'] / WIDTH_IN_BYTES) + base = int(periph_info['base'] / WORD_SIZE) typ = periph_info['type'] if use_avalon: - span = max(int(8 / WIDTH_IN_BYTES), ceil_pow2(int(periph_info['span'] / WIDTH_IN_BYTES))) # span can be incorrect (bug in pyargslib?) + span = max(int(8 / WORD_SIZE), ceil_pow2(int(periph_info['span'] / WORD_SIZE))) # span can be incorrect (bug in pyargslib?) txt = '# peripheral={} start=0x{:04X} span=0x{:04X} count={:02} idx={} stop=0x{:04X}'.format( pname, base, span, count, p_num, base + count * span) else: - span = int(periph_info['span'] / WIDTH_IN_BYTES) # span can be incorrect (bug in pyargslib?) + span = int(periph_info['span'] / WORD_SIZE) # span can be incorrect (bug in pyargslib?) txt = '# peripheral={} start=0x{:04X} span=0x{:04X} type={} count={:02} idx={} stop=0x{:04X}'.format( pname, base, span, typ, count, p_num, base + count * span) @@ -79,7 +79,7 @@ def gen_c_config(fpga, fpga_name, out_dir): out.append('# RAM-SLAVE={:20}'.format(slave.name())) ram_base = base - ram_len = int(slave.address_length() / WIDTH_IN_BYTES) + ram_len = int(slave.address_length() / WORD_SIZE) ram_name = 'data' access = slave.access_mode() # width = slave.width() # Should be slave.user_width() ?? @@ -106,7 +106,7 @@ def gen_c_config(fpga, fpga_name, out_dir): else: out.append('# FIFO-SLAVE={:20}'.format(slave.name())) fifo_base = base - fifo_len = int(slave.address_length() / WIDTH_IN_BYTES) + fifo_len = int(slave.address_length() / WORD_SIZE) fifo_name = 'data' access = slave.access_mode() # width = slave.width() # Should be slave.user_width() ?? @@ -129,20 +129,20 @@ def gen_c_config(fpga, fpga_name, out_dir): out.append('# REG-SLAVE={} no.slaves={} len={} (base=0x{:X})'.format( slave.user_defined_name(), slave.number_of_slaves(), - int(slave.address_length() / WIDTH_IN_BYTES), - int(slave.base_address() / WIDTH_IN_BYTES))) - #int(slave.base_address() / WIDTH_IN_BYTES))) + int(slave.address_length() / WORD_SIZE), + int(slave.base_address() / WORD_SIZE))) + #int(slave.base_address() / WORD_SIZE))) else: out.append('# REG-SLAVE={} no.slaves={} len={} (base=0x{:X})'.format( slave.name(), slave.number_of_slaves(), - int(slave.address_length() / WIDTH_IN_BYTES), - int(slave.base_address() / WIDTH_IN_BYTES))) - #int(slave.base_address() / WIDTH_IN_BYTES))) + int(slave.address_length() / WORD_SIZE), + int(slave.base_address() / WORD_SIZE))) + #int(slave.base_address() / WORD_SIZE))) # Fields that have a non-unity 'number_of_fields' specifier may # become RAM at the start of the slave instances for ram in slave.rams: - ram_base = int(ram.base_address() / WIDTH_IN_BYTES) + base + ram_base = int(ram.base_address() / WORD_SIZE) + base ram_len = int(ram.number_of_fields()) ram_name = ram.name() access = ram.access_mode() @@ -169,16 +169,16 @@ def gen_c_config(fpga, fpga_name, out_dir): field_base = base if slave.rams: - field_base += int(slave.base_address() / WIDTH_IN_BYTES) + field_base += int(slave.base_address() / WORD_SIZE) # All other fields (with unity 'number_of_fields' attribute) - slave_length = int(slave.address_length() / WIDTH_IN_BYTES) + slave_length = int(slave.address_length() / WORD_SIZE) for i in range(0, num_slaves): for fld in slave.fields: bit_lo = fld.bit_offset() bit_hi = bit_lo + fld.width() - 1 # field_base = f.base_address - field_offset = int(fld.address_offset() / WIDTH_IN_BYTES) + field_offset = int(fld.address_offset() / WORD_SIZE) field_name = fld.name() access = fld.access_mode() @@ -236,7 +236,7 @@ if __name__ == '__main__': logger = my_logger.get_logger() logger.debug("Used arguments: {}".format(args)) - # Find and parse all *.fpga.yaml YAML files under root directory for RADIOHDL + # Find and parse all *.fpga.yaml YAML files under root directory for ARGS_WORK # For each FPGA file it extracts a list of the peripherals that are used by that FPGA # Here we select the FPGA YAML that matches up with the supplied fpga command line argument libRootDir = os.path.expandvars('$ARGS_WORK') diff --git a/gen_doc.py b/gen_doc.py index 69c36170830fb57b40900ecab93b12e25d804fde..874eaba6afce0d85f462dace732796a9b18579e3 100755 --- a/gen_doc.py +++ b/gen_doc.py @@ -267,7 +267,7 @@ class FPGADocumentation(object): periph_reg_table.add_row((slave.base_address(), '', slave.address_length(), slave.name(), slave.number_of_slaves())) periph_reg_table.add_hline() for ram in slave.rams: - periph_reg_table.add_row(('', ram.address_offset(), ram.number_of_fields() * WIDTH_IN_BYTES, '>> {} (RAM)'.format(ram.name()), slave.number_of_slaves())) + periph_reg_table.add_row(('', ram.address_offset(), ram.number_of_fields() * WORD_SIZE, '>> {} (RAM)'.format(ram.name()), slave.number_of_slaves())) periph_reg_table.add_hline() added_field_groups = [] @@ -416,7 +416,7 @@ class PeripheralDocumentation(object): if isinstance(slave, Register): # expand registers and fields for ram in slave.rams: - periph_reg_table.add_row((str(ram.base_address()), str(ram.number_of_fields() * WIDTH_IN_BYTES), ram.name() + ' (RAM)', str(slave.number_of_slaves()))) + periph_reg_table.add_row((str(ram.base_address()), str(ram.number_of_fields() * WORD_SIZE), ram.name() + ' (RAM)', str(slave.number_of_slaves()))) periph_reg_table.add_hline() periph_reg_table.add_row((str(slave.base_address()), str(slave.address_length()), slave.name(), str(slave.number_of_slaves()))) periph_reg_table.add_hline() diff --git a/gen_hdl.py b/gen_hdl.py index d36ae02bcf3dd466717ceb247f557f2f69b36b83..8149df7eb9fec07b54e5f331d573689ce0010d4f 100755 --- a/gen_hdl.py +++ b/gen_hdl.py @@ -46,7 +46,7 @@ def main(): lib_root_dir = os.path.expandvars('$ARGS_WORK') - # Find and parse all *.fpga.yaml YAML files under root directory for RADIOHDL + # Find and parse all *.fpga.yaml YAML files under root directory for $ARGS_WORK # For each FPGA file it extracts a list of the peripherals that are used by that FPGA # Here we select the FPGA YAML that matches up with the supplied fpga command line argument addr_size = 1 if use_avalon is True else 4 diff --git a/gen_slave.py b/gen_slave.py index 0fb451da8762a9bfb5ddd74060c42b0d3280a7cd..2a048f7747c761387db0e3c6d2ac0b999af3503f 100755 --- a/gen_slave.py +++ b/gen_slave.py @@ -43,7 +43,7 @@ logger = logging.getLogger('main.gen_slave') def word_wise(byte_address): - return max(1, int(byte_address / WIDTH_IN_BYTES)) + return max(1, int(byte_address / WORD_SIZE)) def tab_aligned(input_strings): @@ -120,7 +120,7 @@ class Slave(object): for slave in self.slaves: if not isinstance(slave, Register) or (isinstance(slave, Register) and getattr(slave, 'isIP', False)): continue - self.nof_dat = int(slave.base_address()/WIDTH_IN_BYTES + slave.address_length()/WIDTH_IN_BYTES*slave.number_of_slaves()) + self.nof_dat = int(slave.base_address()/WORD_SIZE + slave.address_length()/WORD_SIZE*slave.number_of_slaves()) if self.nof_dat > 1: self.dat_w = DEFAULT_WIDTH # parameterize @@ -242,8 +242,8 @@ class Slave(object): regGroup = slave # regGroup = self.registers[key] fields_dict = regGroup.fields - replace_dicts.update({regGroup.name(): {'<name>': self.periph_name, '<reg_ram>': 'reg', '<reg_name>': regGroup.name(), '<adr_w>': 'c_addr_w', '<dat_w>': 'c_dat_w','<nof_dat>' : int(regGroup.address_length()/WIDTH_IN_BYTES), - '<c_init_reg>': self.set_init_string(regGroup)[0], '<nof_slaves>' : regGroup.number_of_slaves(), '<addr_base>' : int(regGroup.base_address() / WIDTH_IN_BYTES), + replace_dicts.update({regGroup.name(): {'<name>': self.periph_name, '<reg_ram>': 'reg', '<reg_name>': regGroup.name(), '<adr_w>': 'c_addr_w', '<dat_w>': 'c_dat_w','<nof_dat>' : int(regGroup.address_length()/WORD_SIZE), + '<c_init_reg>': self.set_init_string(regGroup)[0], '<nof_slaves>' : regGroup.number_of_slaves(), '<addr_base>' : int(regGroup.base_address() / WORD_SIZE), '<c_clr_mask>': self.set_clr_mask(regGroup)[0]}}) else : self.replaceDict = {'<name>': slaveSettings.name(), '<lib>': self.prefix, '<adr_w>': ceil_log2(slaveSettings.address_length()), @@ -723,7 +723,7 @@ class Slave(object): sublines = [] with open(tmpl_file, 'r') as inst_file: for subline in inst_file: - for tag, replace_string in {'<reg_name>' : self.regGroup.name() + '_' + ram.name(), '<reg_ram>': 'ram', '<adr_w>' : str(ceil_log2(ram.number_of_fields())), '<nof_dat>' : str(ram.number_of_fields()), '<nof_slaves>' : self.regGroup.number_of_slaves(), '<addr_base>' : str(int(ram.base_address()/WIDTH_IN_BYTES)), '<dat_w>' : ram.width()}.items(): + for tag, replace_string in {'<reg_name>' : self.regGroup.name() + '_' + ram.name(), '<reg_ram>': 'ram', '<adr_w>' : str(ceil_log2(ram.number_of_fields())), '<nof_dat>' : str(ram.number_of_fields()), '<nof_slaves>' : self.regGroup.number_of_slaves(), '<addr_base>' : str(int(ram.base_address()/WORD_SIZE)), '<dat_w>' : ram.width()}.items(): subline = subline.replace(tag, str(replace_string)) if 'STD_LOGIC_VECTOR' not in subline: sublines.append(subline) diff --git a/py_args_lib/fpga.py b/py_args_lib/fpga.py index 478b7bf500995222492bf442959ed2692fe5b87c..aeae253cad3c56f16a371da3663bf255e986996d 100644 --- a/py_args_lib/fpga.py +++ b/py_args_lib/fpga.py @@ -27,7 +27,7 @@ import os import sys -import copy +from copy import deepcopy import logging import yaml import time @@ -44,7 +44,7 @@ class FPGA(object): """ def __init__(self, file_path_name=None, periph_lib=None, use_avalon_base_addr=None): self.file_path_name = file_path_name - self.root_dir = os.environ['RADIOHDL_WORK'] + self.root_dir = os.environ['ARGS_WORK'] if periph_lib is None: self.peri_lib = PeripheralLibrary(self.root_dir) else: @@ -103,10 +103,10 @@ class FPGA(object): self.fpga_name = self.fpga_config['fpga_name'] if "fpga_description" in self.fpga_config: - self.fpga_description = copy.deepcopy(self.fpga_config['fpga_description']) + self.fpga_description = deepcopy(self.fpga_config['fpga_description']) if "parameters" in self.fpga_config: - _parameters = copy.deepcopy(self.fpga_config['parameters']) + _parameters = deepcopy(self.fpga_config['parameters']) # keys with '.' in the name indicate the use of a structs # inside this class it is a dict in a dict @@ -147,7 +147,7 @@ class FPGA(object): component_prefix = peripheral_config.get('peripheral_group', None) number_of_peripherals = int(self._eval(peripheral_config.get('number_of_peripherals', 1))) - peripheral_from_lib = copy.deepcopy(self.peri_lib.find_peripheral(component_name, component_lib, self.fpga_name)) + peripheral_from_lib = deepcopy(self.peri_lib.find_peripheral(component_name, component_lib, self.fpga_name)) if peripheral_from_lib is None: logger.error("Peripheral component '%s' referenced in %s.fpga.yaml not found in peripheral library '%s'", component_name, self.fpga_name, component_lib if component_lib is not None else '') @@ -180,7 +180,7 @@ class FPGA(object): peripheral_from_lib.name('_'.join(peripheral_name)) if peripheral_from_lib.name() not in self.peripherals: - self.peripherals[peripheral_from_lib.name()] = copy.deepcopy(peripheral_from_lib) + self.peripherals[peripheral_from_lib.name()] = deepcopy(peripheral_from_lib) else: logger.error(" Duplicate found: use unique labels per instance in %s.fpga.yaml to distinguish " "between multiple instances of the same peripheral.\n" diff --git a/py_args_lib/peripheral.py b/py_args_lib/peripheral.py index 8b2e4959d861437af18bd2bc692b8d9f9f7dba97..6f6b174798922f128cd01db2ae622b2cb25eaa73 100644 --- a/py_args_lib/peripheral.py +++ b/py_args_lib/peripheral.py @@ -29,7 +29,7 @@ import os -from copy import deepcopy, copy +from copy import deepcopy from math import ceil import logging import yaml @@ -224,7 +224,7 @@ class Peripheral(BaseObject): continue field_name = field_info['field_name'] - logger.debug("%s, info= %s", field_name, str(field_info)) + logger.debug("field_info= %s", str(field_info)) try : field = Field(field_name, field_info) except ARGSNameError: @@ -357,8 +357,7 @@ class Peripheral(BaseObject): self.slaves.append(ram) def add_fifo(self, slave_nr, name, field, number_of_slaves): - """ add FIFO to peripheral - """ + """ add FIFO to peripheral """ fifo = deepcopy(self.init_slave('FIFO', name, field)) fifo.number_of_slaves(number_of_slaves) self.fifos['slave_{}'.format(slave_nr)] = fifo @@ -378,13 +377,11 @@ class Peripheral(BaseObject): return slave def eval_fields(self, fields): - # Evaluate the fields. - # ['number_of_fields', 'width', 'bit_offset', 'access_mode', 'side_effect', - # 'address_offset', 'reset_value', 'software_value', 'radix', 'field_description'] + """ Evaluate the fields """ for field in fields: # .values(): logger.debug("eval field %s", field.name()) - if [(field.name() == _field.name() and field.group_name() == _field.group_name())for _field in fields].count(True) > 1: + if [(field.name() == _field.name() and field.group_name() == _field.group_name()) for _field in fields].count(True) > 1: logger.error("Field name '%s' group_name '%s' is not unique within slave field list in *.peripheral.yaml", field.name(), field.group_name()) sys.exit() @@ -412,7 +409,7 @@ class Peripheral(BaseObject): fifo = slave fifo.number_of_slaves(val=self._eval(fifo.number_of_slaves())) logger.debug(" -FIFO depth (fields): %s", fifo.number_of_fields()) - fifo.address_length(val=ceil_pow2(self._eval(fifo.number_of_fields())) * WIDTH_IN_BYTES) # address_length in bytes + fifo.address_length(val=ceil_pow2(self._eval(fifo.number_of_fields())) * WORD_SIZE) # address_length in bytes logger.debug(" -FIFO depth (bytes): %s", fifo.address_length()) logger.debug(" -FIFO width (bits): %s", fifo.width()) @@ -420,7 +417,7 @@ class Peripheral(BaseObject): """Evaluate the parameters and the nof_inst of the peripheral in order to define the real address_length and width of the RAM. For example: address_length = c_nof_weights*c_nof_signal_paths - witdh = c_weights_w*N_COMPLEX """ + witdh = c_weights_w*c_nof_complex """ for slave in self.slaves: # Evaluate the fields and see if there are field that have to be repeated. @@ -430,10 +427,10 @@ class Peripheral(BaseObject): continue self.eval_fields([ram]) - if ram.width() < DEFAULT_WIDTH: - ram.width(DEFAULT_WIDTH) - if ram.user_width() < DEFAULT_WIDTH: - ram.user_width(DEFAULT_WIDTH) + if ram.width() < DEFAULT_FIELD_WIDTH: + ram.width(DEFAULT_FIELD_WIDTH) + if ram.user_width() < DEFAULT_FIELD_WIDTH: + ram.user_width(DEFAULT_FIELD_WIDTH) ram.number_of_slaves(val=self._eval(ram.number_of_slaves())) @@ -446,7 +443,7 @@ class Peripheral(BaseObject): logger.debug(" -RAM depth (fields): %s", ram.number_of_fields()) # Here the variables are used to evaluate the true value for the depth # parameter(taking int account the nof_inst as well) - ram.address_length(val=ceil_pow2(self._eval(ram.number_of_fields())) * WIDTH_IN_BYTES) # address_length in bytes + ram.address_length(val=ceil_pow2(self._eval(ram.number_of_fields())) * WORD_SIZE) # address_length in bytes logger.debug(" -RAM depth (bytes): %d", ram.address_length()) logger.debug(" -RAM width (bits): %s", ram.width()) @@ -475,7 +472,7 @@ class Peripheral(BaseObject): # Evaluate the fields and see if there are field that have to be repeated. fields_eval = [] for field in register.fields: - if field.number_of_fields() > 1 and field.number_of_fields() < REG_MAX_FIELDS: + if field.number_of_fields() > 1: for i in range(field.number_of_fields()): _field = deepcopy(field) _field.name("{}{}".format(field.name(), i)) @@ -487,13 +484,11 @@ class Peripheral(BaseObject): if _field.address_offset() != UNASSIGNED_ADDRESS: # field is manually assigned # TODO-PD check, only bit size check is done if address offset is set? - if _field.group_name() is None or (field.bit_offset() + _field.number_of_fields() * _field.width()) >= DEFAULT_WIDTH: # not part of a field group - _field.address_offset(field.address_offset() + i * WIDTH_IN_BYTES) # duplicate across addresses + if _field.group_name() is None or (field.bit_offset() + _field.number_of_fields() * _field.width()) >= DEFAULT_FIELD_WIDTH: # not part of a field group + _field.address_offset(field.address_offset() + i * WORD_SIZE) # duplicate across addresses fields_eval.append(_field) - elif field.number_of_fields() >= REG_MAX_FIELDS: - register.rams.append(field) - else : + else: fields_eval.append(field) self.eval_fields(fields_eval) @@ -509,8 +504,8 @@ class Peripheral(BaseObject): # set base addresses for reg fields implemented as RAM base_addr = 0 for field in register.rams: - base_addr = ceil(base_addr / (ceil_pow2(field.number_of_fields()) * WIDTH_IN_BYTES)) * ceil_pow2(field.number_of_fields()) * WIDTH_IN_BYTES # lowest possible base_addr - base_addr = base_addr + ceil_pow2(field.number_of_fields()) * WIDTH_IN_BYTES * register.number_of_slaves() # new base address + base_addr = ceil(base_addr / (ceil_pow2(field.number_of_fields()) * WORD_SIZE)) * ceil_pow2(field.number_of_fields()) * WORD_SIZE # lowest possible base_addr + base_addr = base_addr + ceil_pow2(field.number_of_fields()) * WORD_SIZE * register.number_of_slaves() # new base address field.base_address(base_addr) # ### Assigned Address and bits to register fields @@ -526,11 +521,6 @@ class Peripheral(BaseObject): group_address = UNASSIGNED_ADDRESS last_group = None for field in fields_eval: - # skip address and bit placement for fields resulting in RAM blocks, addresses already set above - if field.number_of_fields() >= REG_MAX_FIELDS: - logger.warning("Field '%s' number_of_fields >= 32, a dual port RAM will be instantiated within the Register module", field.name()) - continue - # new field group or single field if field.group_name() != last_group or field.group_name() is None: if field.group_name() is not None: @@ -540,7 +530,7 @@ class Peripheral(BaseObject): occupied_bits = list(range(field.bit_offset(), field.bit_offset() + field.width())) if field.bit_offset() != UNASSIGNED_BIT else [] while (lowest_free_addr) in occupied_addresses: - lowest_free_addr = lowest_free_addr + WIDTH_IN_BYTES + lowest_free_addr = lowest_free_addr + WORD_SIZE if len(set(occupied_bits)) < len(occupied_bits) or any([bit > (DATA_WIDTH - 1) or bit < 0 for bit in occupied_bits]): logger.error('*.peripheral.yaml: Manually assigned bits for field %s is outside of data width or contains bit collisions', @@ -572,7 +562,7 @@ class Peripheral(BaseObject): free_bit = 0 while any([i in occupied_bits for i in range(free_bit, free_bit + field.width() + 1)]): # bit is occupied free_bit = free_bit + 1 # try next bit - if free_bit == DEFAULT_WIDTH: # 31 didn't work + if free_bit == DEFAULT_FIELD_WIDTH: # 31 didn't work logger.error('*.peripheral.yaml: No suitable gap available for automatic bit offset assignment of field%s', field.name()) logger.error("Check peripheral.yaml file. Field group may be overstuffed or manual bit assignment may have precluded space for other fields") @@ -598,7 +588,7 @@ class Peripheral(BaseObject): register.base_address(base_addr) base_addr = base_addr + register.address_length() * register.number_of_slaves() - self.reg_len = base_addr + self.reg_len = base_addr def eval_peripheral(self): """Evaluate name, label, nof_inst and the parameters to determine the true size of @@ -682,7 +672,7 @@ class PeripheralLibrary(object): self.library = collections.OrderedDict() self.nof_peripherals = 0 # number of peripherals - exclude = set([path_string(os.path.expandvars('$RADIOHDL_BUILD_DIR'))]) + exclude = set([path_string(os.path.expandvars('$ARGS_BUILD_DIR'))]) if root_dir is not None: for root, dirs, files in os.walk(self.root_dir, topdown=True): # topdown=False): if 'tools' in root: diff --git a/py_args_lib/peripheral_lib/constants.py b/py_args_lib/peripheral_lib/constants.py index a6acaf4a44aa7ab8ececcce01bd228372469a6b7..0c5531b27a95b81595a1dc84c02b8dca64e29f25 100644 --- a/py_args_lib/peripheral_lib/constants.py +++ b/py_args_lib/peripheral_lib/constants.py @@ -33,50 +33,62 @@ c_word_w = 32 c_nof_complex = 2 -BYTE_WIDTH = c_byte_w -WORD_WIDTH = c_word_w -N_COMPLEX = c_nof_complex +BYTE_WIDTH = c_byte_w # = 8 bits +WORD_WIDTH = c_word_w # = 32 bits +WORD_SIZE = c_word_w // c_byte_w # = 4 bytes VALID_SCHEMA_NAME = ['args'] -VALID_SCHEMA_TYPES = ['system', 'peripheral'] - -VALID_SLAVE_TYPES = ['REG', 'RAM', 'FIFO', 'REG_IP'] - -VALID_ACCESS_MODES = ['RO', 'WO', 'RW', 'FR', 'FW'] - -VALID_REG_ACCESS_MODES = ['RO', 'RW'] -VALID_RAM_ACCESS_MODES = ['RO', 'RW'] -VALID_FIFO_ACCESS_MODES = ['RO', 'WO'] -VALID_REGIP_ACCESS_MODES = ['WO'] - -VALID_SIDE_EFFECTS = ['CLR', 'PR', 'PW', 'MON'] - -VALID_FIELD_KEYS = ['width', 'bit_offset', 'side_effect', 'number_of_fields', 'address_offset', 'access_mode', 'reset_value', 'radix', - 'field_description', 'user_width', 'software_value'] -VALID_DEFAULT_KEYS = ['width', 'address_offset', 'access_mode', 'reset_value', 'field_description', 'number_of_fields', 'reset_value', 'side_effect'] -VALID_RADIXS = ['UNSIGNED', 'SIGNED', 'HEXADECIMAL'] - -DEFAULT_NUMBER_OF_PERIPHERALS = 1 -DEFAULT_NUMBER_OF_SLAVES = 1 - -UNASSIGNED_ADDRESS = 16384 -UNASSIGNED_BIT = 32 - -DEFAULT_WIDTH = c_word_w -WIDTH_IN_BYTES = int(c_word_w / c_byte_w) -DEFAULT_BIT_OFFSET = UNASSIGNED_BIT -DEFAULT_ACCESS_MODE = 'RW' -DEFAULT_SIDE_EFFECT = None -DEFAULT_ADDRESS_OFFSET = UNASSIGNED_ADDRESS -DEFAULT_NUMBER_OF_FIELDS = 1 -RESET_VALUE = 0 -DEFAULT_SOFTWARE_VALUE = 0 -DEFAULT_RADIX = 'SIGNED' -DEFAULT_DESCRIPTION = 'NONE' -DATA_WIDTH = 32 - -DEFAULT_ADDRESS_LENGTH = 1 - -REG_MAX_FIELDS = 32 +VALID_SCHEMA_TYPES = ['fpga', 'peripheral'] + +VALID_SLAVE_TYPES = ['REG', 'RAM', 'FIFO', 'REG_IP'] # EK: TODO Remove REG_IP + +VALID_FIELD_ACCESS_MODES = ['RO', 'WO', 'RW'] # Read only, Write only, Read/Write. For FIFO use RO = read from FIFO, WO = write to FIFO. + +VALID_FIELD_SIDE_EFFECTS = ['CLR', 'PR', 'PW', 'MON'] # EK: TODO Remove MON + +VALID_FIELD_KEYS = ['field_description', + 'width', + 'user_width', + 'bit_offset', + 'access_mode', + 'side_effect', + 'address_offset', + 'number_of_fields', + 'reset_value', + 'software_value', + 'radix'] # EK: TODO field_name is missing in this list ? Use same order as in ARGS doc. + +VALID_DEFAULT_FIELD_KEYS = ['field_description', + 'width', + 'access_mode', + 'side_effect', + 'address_offset', + 'number_of_fields', + 'reset_value'] # EK: TODO change to MANDATORY_FIELD_KEYS to have smaller list ? Current list is incomplete. + +VALID_FIELD_RADIXS = ['UNSIGNED', 'SIGNED', 'HEXADECIMAL'] + + +UNASSIGNED_ADDRESS = 16384 # EK: TODO why is this needed ? Should be -1 for undefined, or just default 0 ? +UNASSIGNED_BIT = 32 # EK: TODO why is this needed ? Name may be bad choice, use WORD_WIDTH instead? + +DEFAULT_NUMBER_OF_PERIPHERALS = 1 +DEFAULT_NUMBER_OF_SLAVES = 1 +DEFAULT_SLAVE_DESCRIPTION = 'NONE' +DEFAULT_ADDRESS_LENGTH = 1 + +DEFAULT_FIELD_WIDTH = WORD_WIDTH +DEFAULT_FIELD_USER_WIDTH = WORD_WIDTH +DEFAULT_FIELD_BIT_OFFSET = UNASSIGNED_BIT # EK: TODO should be 0 ? +DEFAULT_FIELD_ACCESS_MODE = 'RW' +DEFAULT_FIELD_SIDE_EFFECT = None +DEFAULT_FIELD_ADDRESS_OFFSET = UNASSIGNED_ADDRESS # EK: TODO should be 0 ? +DEFAULT_FIELD_NUMBER_OF_FIELDS = 1 +DEFAULT_FIELD_RESET_VALUE = 0 +DEFAULT_FIELD_SOFTWARE_VALUE = 0 +DEFAULT_FIELD_RADIX = 'SIGNED' +DEFAULT_FIELD_DESCRIPTION = 'NONE' + +DATA_WIDTH = 32 # EK: TODO purpose ? use WORD_WIDTH instead ? diff --git a/py_args_lib/peripheral_lib/field.py b/py_args_lib/peripheral_lib/field.py index 876864ebf166e7337237bcfa73cc51aab2852a4a..d448f487c3397bda645e23b7adf6224cc235a963 100644 --- a/py_args_lib/peripheral_lib/field.py +++ b/py_args_lib/peripheral_lib/field.py @@ -42,7 +42,10 @@ class Field(BaseObject): self.name(name) - self._valid_dict = {'width' : {'max': 32, 'min': 1}, + self._valid_dict = {'field_name' : {}, + 'field_description' : {}, + 'width' : {'max': 32, 'min': 1}, + 'user_width' : {'max': 2048, 'min': 32}, 'bit_offset' : {'max': UNASSIGNED_BIT, 'min': 0}, 'access_mode' : {}, 'side_effect' : {}, @@ -50,21 +53,18 @@ class Field(BaseObject): 'number_of_fields' : {'max': 262144, 'min': 1}, 'reset_value' : {'max': 131071}, 'software_value' : {}, - 'radix' : {}, - 'field_description' : {}, - 'field_name' : {}, - 'user_width' : {'max': 2048, 'min': 32}} - - self._args.update({'width' : DEFAULT_WIDTH, - 'bit_offset' : DEFAULT_BIT_OFFSET, - 'access_mode' : DEFAULT_ACCESS_MODE, - 'side_effect' : DEFAULT_SIDE_EFFECT, - 'address_offset' : DEFAULT_ADDRESS_OFFSET, - 'number_of_fields' : DEFAULT_NUMBER_OF_FIELDS, - 'reset_value' : RESET_VALUE, - 'software_value' : DEFAULT_SOFTWARE_VALUE, - 'radix' : DEFAULT_RADIX, - 'field_description': DEFAULT_DESCRIPTION, + 'radix' : {}} + + self._args.update({'field_description': DEFAULT_FIELD_DESCRIPTION, + 'width' : DEFAULT_FIELD_WIDTH, + 'bit_offset' : DEFAULT_FIELD_BIT_OFFSET, + 'access_mode' : DEFAULT_FIELD_ACCESS_MODE, + 'side_effect' : DEFAULT_FIELD_SIDE_EFFECT, + 'address_offset' : DEFAULT_FIELD_ADDRESS_OFFSET, + 'number_of_fields' : DEFAULT_FIELD_NUMBER_OF_FIELDS, + 'reset_value' : DEFAULT_FIELD_RESET_VALUE, + 'software_value' : DEFAULT_FIELD_SOFTWARE_VALUE, + 'radix' : DEFAULT_FIELD_RADIX, 'group_name' : None}) if settings is not None: @@ -73,10 +73,10 @@ class Field(BaseObject): for key, val in settings.items(): if key in self._valid_dict: # self._valid_keys: - if key == 'access_mode' and val.upper() not in VALID_ACCESS_MODES: + if key == 'access_mode' and val.upper() not in VALID_FIELD_ACCESS_MODES: logger.error("Field.__init__(), Not a valid acces_mode '%s'", val) self.success = False - elif key == 'side_effect' and val.upper() not in VALID_SIDE_EFFECTS: + elif key == 'side_effect' and val.upper() not in VALID_FIELD_SIDE_EFFECTS: logger.error("Field.__init__(), Not a valid side_effect '%s'", val) self.success = False else: @@ -132,7 +132,7 @@ class Field(BaseObject): val: if not None and a valid mode set access_mode of field return: actual access_mode of field """ if val is not None: - if val.upper() in VALID_ACCESS_MODES: + if val.upper() in VALID_FIELD_ACCESS_MODES: return self.set_kv('access_mode', val.upper()) else: logger.error("unknown access_mode '%s'", val) @@ -149,7 +149,7 @@ class Field(BaseObject): vals = val.split(',') for _val in vals: _val = _val.strip() - if _val.upper() not in VALID_SIDE_EFFECTS: + if _val.upper() not in VALID_FIELD_SIDE_EFFECTS: logger.error("unknown side_effect '%s'", _val) self.success = False return False @@ -191,7 +191,7 @@ class Field(BaseObject): val: if not None set default value of field return: active radix value of field """ if val is not None: - if val.upper() in VALID_RADIXS: + if val.upper() in VALID_FIELD_RADIXS: return self.set_kv('radix', val.upper()) else: logger.error("unknown radix '%s'", val) @@ -217,7 +217,7 @@ class Field(BaseObject): def base_address(self, val=None): """ set/get base_address in bytes """ if val is not None: - if mod(val, WIDTH_IN_BYTES): # don't need check here if tool calcs are correct + if mod(val, WORD_SIZE): # don't need check here if tool calcs are correct logger.error("Base address for field {} is not word aligned".format(field.name())) self.set_kv('base_addr', val) return @@ -238,7 +238,7 @@ class Field(BaseObject): return True # may not have been evaluated from parameter yet, skip if check_alignment: - if mod(_val, WIDTH_IN_BYTES): + if mod(_val, WORD_SIZE): logger.error("Address offset for field %s is not word aligned (%s=%s)", self.name(), yaml_key, str(_val)) sys.exit() diff --git a/py_args_lib/peripheral_lib/fifo.py b/py_args_lib/peripheral_lib/fifo.py index af569f8cd3872609787fe6a38fc79c0f4d458e86..1201a1bf5e9312a1560285dbe900b8e11e569ed5 100644 --- a/py_args_lib/peripheral_lib/fifo.py +++ b/py_args_lib/peripheral_lib/fifo.py @@ -25,7 +25,7 @@ ############################################################################### import logging -from constants import VALID_FIFO_ACCESS_MODES, WIDTH_IN_BYTES +from constants import WORD_SIZE from common_func import ceil_pow2 from field import Field from args_errors import ARGSModeError @@ -42,34 +42,6 @@ class FIFO(Field): self.set_kv('type', 'FIFO') self.name(name) self.description = "" - if self.access_mode() not in VALID_FIFO_ACCESS_MODES: - logger.error("'%s' not a valid access mode for slaves of type FIFO. Valid modes include %s", self.access_mode(), VALID_FIFO_ACCESS_MODES) - raise ARGSModeError - - self.tx_fifo_vacancy = Field(name="fifo_status", - settings={'width': 32, - 'access_mode': "RO", - 'address_offset': 0x8, - 'reset_value': 0, - 'field_description': "Transmit Data FIFO Vacancy (TDFV). Width N equal to C_S_AXI_DATA_WIDTH" - }) - self.rx_fifo_occupancy = Field(name="fifo_status", - settings={'width': 16, - 'access_mode': "RO", - 'address_offset': 0x1C, - 'reset_value': 0, - 'field_description': "Receive Data FIFO Occupancy (RDFO). Number of locations in use for data storage" - }) - self.rx_length = Field(name="fifo_status", - settings={'width': 23, - 'access_mode': "RO", - 'address_offset': 0x24, - 'reset_value': 0, - 'field_description': "Receive Length Register (RLR). The number of bytes of the corresponding receive data stored in the receive data FIFO" - }) - - def set_mon_fields(): - """ fifo_fields are set based on FIFO access mode if side effect 'MON' is configured """ def number_of_slaves(self, val=None): """ set/get number of slaves """ @@ -81,7 +53,7 @@ class FIFO(Field): def update_address_length(self): """ update total address_length of Register in bytes """ n_fields = ceil_pow2(self.number_of_fields()) - self.set_kv('address_length', n_fields * WIDTH_IN_BYTES) + self.set_kv('address_length', n_fields * WORD_SIZE) def address_length(self, val=None): """ set/get address_length of register in bytes @@ -90,4 +62,4 @@ class FIFO(Field): """ if val is not None: return self.set_kv('address_length', val) - return self._as_int('address_length', default=WIDTH_IN_BYTES) + return self._as_int('address_length', default=WORD_SIZE) diff --git a/py_args_lib/peripheral_lib/ram.py b/py_args_lib/peripheral_lib/ram.py index b8f25cd6376708a893c3924af1eaa1daa03a3276..755867cd9d5f965dac9523f80066b71b581853e3 100644 --- a/py_args_lib/peripheral_lib/ram.py +++ b/py_args_lib/peripheral_lib/ram.py @@ -69,7 +69,7 @@ class RAM(Field): """ update total address_length of Register in bytes """ n_fields = ceil_pow2(self.number_of_fields()) self.user_depth(n_fields * self.width() / self.user_width()) - self.set_kv('address_length', n_fields * WIDTH_IN_BYTES) + self.set_kv('address_length', n_fields * WORD_SIZE) def address_length(self, val=None): """ set/get address_length of register in bytes @@ -77,4 +77,4 @@ class RAM(Field): return: address_length of register """ if val is not None: return self.set_kv('address_length', val) - return self._as_int('address_length', default=WIDTH_IN_BYTES) + return self._as_int('address_length', default=WORD_SIZE) diff --git a/py_args_lib/peripheral_lib/register.py b/py_args_lib/peripheral_lib/register.py index 58422da4829d2930baff6aa8e46a3c8710f516c1..211573df2ec4816a7f1c81e74d88df818ddf8bd4 100644 --- a/py_args_lib/peripheral_lib/register.py +++ b/py_args_lib/peripheral_lib/register.py @@ -53,13 +53,13 @@ class Register(BaseObject): self._args.update({'number_of_slaves' : DEFAULT_NUMBER_OF_SLAVES, 'address_length' : DEFAULT_ADDRESS_LENGTH, 'dual_clock' : False, - 'slave_description': DEFAULT_DESCRIPTION}) + 'slave_description': DEFAULT_SLAVE_DESCRIPTION}) # self.update_address_length() - self.isIP = False + self.isIP = False # EK: TODO remove platform specific isIP self.slave_span = None - self.protocol = 'LITE' + self.protocol = 'LITE' # EK: TODO remove AXI specific protocol field def number_of_slaves(self, val=None): """ set/get number of slaves """ @@ -87,11 +87,11 @@ class Register(BaseObject): n_bytes = 0 if any(self.fields): - n_bytes += max(max([_field.address_offset() for _field in self.fields]) + WIDTH_IN_BYTES, self.slave_span if self.slave_span is not None else 0) + n_bytes += max(max([_field.address_offset() for _field in self.fields]) + WORD_SIZE, self.slave_span if self.slave_span is not None else 0) if any(self.rams): - #n_bytes += max(max([_field.address_offset() for _field in self.rams]) + WIDTH_IN_BYTES, self.slave_span if self.slave_span is not None else 0) - n_bytes += ceil_pow2(self.rams[0].number_of_fields()) * WIDTH_IN_BYTES + #n_bytes += max(max([_field.address_offset() for _field in self.rams]) + WORD_SIZE, self.slave_span if self.slave_span is not None else 0) + n_bytes += ceil_pow2(self.rams[0].number_of_fields()) * WORD_SIZE self.set_kv('address_length', n_bytes) @@ -100,7 +100,7 @@ class Register(BaseObject): val: if not None set address_length of register return: address_length of register """ if val is not None: - if mod(val, WIDTH_IN_BYTES): # dont need this if properly calcd + if mod(val, WORD_SIZE): # dont need this if properly calcd logger.error("Invalid address length for register {}, not word aligned".format(self.name())) sys.exit() return self.set_kv('address_length', val) @@ -109,4 +109,4 @@ class Register(BaseObject): def base_address(self, val=None): if val is not None: return self.set_kv('base_address', val) - return self._as_int('base_address', default=0) \ No newline at end of file + return self._as_int('base_address', default=0) diff --git a/uniboard_rom_system_info.py b/uniboard_rom_system_info.py index 1ad0f3563e4ca43670b37da829aaba7cbf3de3bf..03b00b0d40813794b9d0995818f35614af342118 100755 --- a/uniboard_rom_system_info.py +++ b/uniboard_rom_system_info.py @@ -82,23 +82,23 @@ class MemoryMapper(object): self.map.append({'name': name, 'base_address': base_address, 'end_address': end_address, - 'size': size * WIDTH_IN_BYTES, + 'size': size * WORD_SIZE, 'nof_instances': nof_instances, 'hide_in_reg_file': hide_in_reg_file}) logger.debug("add(): %08x, %08x, %d, %s, %d, %s", - base_address, end_address, (size * WIDTH_IN_BYTES), name, nof_instances, str(hide_in_reg_file)) + base_address, end_address, (size * WORD_SIZE), name, nof_instances, str(hide_in_reg_file)) else: _base_address = self._find_start_addr(size*nof_instances) self.map.append({'name': name, 'base_address': _base_address, 'end_address': _base_address+(size*nof_instances), - 'size': size * WIDTH_IN_BYTES, + 'size': size * WORD_SIZE, 'nof_instances': nof_instances, 'hide_in_reg_file': hide_in_reg_file}) logger.debug("add(): %08x, %08x, %d, %s, %d, %s", - _base_address, _base_address+(size*nof_instances), size * WIDTH_IN_BYTES, name, nof_instances, str(hide_in_reg_file)) + _base_address, _base_address+(size*nof_instances), size * WORD_SIZE, name, nof_instances, str(hide_in_reg_file)) def _find_start_addr(self, size): """ look for the next address where the size (in bytes) will fit """ @@ -436,4 +436,4 @@ if __name__ == "__main__": logger.error('TRACEBACK:\n%s', traceback.format_exc()) logger.error('Aborting NOW') sys.exit("ERROR") - sys.exit("Normal Exit") \ No newline at end of file + sys.exit("Normal Exit")