diff --git a/gen_doc.py b/gen_doc.py index 95bb850d4acdfc9dbe0714cf29d62d00cd8a03d5..0288d45db7a5958b545451063cb75f19c368d5cf 100755 --- a/gen_doc.py +++ b/gen_doc.py @@ -46,14 +46,13 @@ from math import ceil from py_args_lib import * -#import common as cm def gen_reg_tables(subsection, group_fields): """ Takes a list of fields belonging to a field group and a register subsection - Returns the subsection with fully formatted variable width tables for a field group + Returns the subsection with fully formatted variable width tables for a field group - Needs to support field splitting in the case when field width exceeds 16 + Needs to support field splitting in the case when field width exceeds 16 """ c_max_chars = 64 @@ -61,76 +60,79 @@ def gen_reg_tables(subsection, group_fields): last_bit_boundary = 0 bit_bounds = [32] i = 0 - # iterate through fields and break whenever max chars has been exceeded - #print("New field group") + # iterate through fields and break whenever max chars has been exceeded + # print("New field group") for field in group_fields[::-1]: i = i+1 - field_name = field.name() if field.group_name() == 'None' else field.name().split(field.group_name() + '_')[-1] + field_name = field.name() if field.group_name() is None else field.name().split(field.group_name() + '_')[-1] char_sum = char_sum + len(field_name) - if char_sum > c_max_chars: + if char_sum > c_max_chars: char_sum = len(field_name) bit_bounds.append(last_bit_boundary) last_bit_boundary = field.bit_offset() if (bit_bounds[-1]-last_bit_boundary) > 16: - bit_bounds.append(bit_bounds[-1]-16)# still limit to max of 16 - last_bit_boundary = bit_bounds[-1] - #print("field {} upper {} lower {}".format(field.name(), str(field.bit_offset() + field.width() -1), str(field.bit_offset()))) - #print(*bit_bounds) - if bit_bounds[-1] != 0 : bit_bounds.append(0) - - bit_bounds = [32,16,0] if len(bit_bounds) < 3 else bit_bounds + bit_bounds.append(bit_bounds[-1]-16) # still limit to max of 16 + last_bit_boundary = bit_bounds[-1] + # print("field {} upper {} lower {}".format(field.name(), str(field.bit_offset() + field.width() -1), str(field.bit_offset()))) + # print(*bit_bounds) + if bit_bounds[-1] != 0: + bit_bounds.append(0) + + bit_bounds = [32, 16, 0] if len(bit_bounds) < 3 else bit_bounds nof_tables = len(bit_bounds) - - # generate columns for fields, mostly useful for gaps, can make it less bulky than the column dictionary - for i in range(1, nof_tables): # starts from second bound + + # generate columns for fields, mostly useful for gaps, can make it less bulky than the column dictionary + for i in range(1, nof_tables): # starts from second bound col_list = [] - nof_cols = bit_bounds[i-1]-bit_bounds[i]+1 # nof bits + bit label column - group_table = Tabular('|c'*nof_cols+'|') + nof_cols = bit_bounds[i-1]-bit_bounds[i]+1 # nof bits + bit label column + group_table = Tabular('|c'*nof_cols+'|') group_table.add_hline() group_table.add_row((MultiColumn(nof_cols, align='|c|', data='Addr: {}h'.format(str(hex(field.address_offset()))[2:])),)) group_table.add_hline() # group_table.add_row(('Bit',*range(bit_bounds[i-1]-1,bit_bounds[i]-1,-1))) - row = ['Bit'] + [str(bit) for bit in range(bit_bounds[i-1]-1,bit_bounds[i]-1,-1)] + row = ['Bit'] + [str(bit) for bit in range(bit_bounds[i-1]-1, bit_bounds[i]-1, -1)] group_table.add_row(row) group_table.add_hline() - gap_bit = bit_bounds[i-1] -1 # next available bit, inclusive + gap_bit = bit_bounds[i-1] - 1 # next available bit, inclusive end_bit = bit_bounds[i] - #print("Table {} bounding {} and {}".format(str(i),str(gap_bit+1), str(end_bit))) + # print("Table {} bounding {} and {}".format(str(i),str(gap_bit+1), str(end_bit))) for field in group_fields[::-1]: - field_name = field.name() if field.group_name() == 'None' else field.name().split(field.group_name() + '_')[-1] - upper_bit = field.bit_offset() + field.width() -1 # inclusive + field_name = field.name() if field.group_name() is None else field.name().split(field.group_name() + '_')[-1] + upper_bit = field.bit_offset() + field.width() - 1 # inclusive # print("field {} has upper bit {} gap bit is {}".format(field_name,str(upper_bit), str(gap_bit))) if upper_bit < gap_bit: gap_width = min(gap_bit - upper_bit, nof_cols-1) col_list.append(MultiColumn(gap_width, align='|c|', data='RES')) - gap_bit = max(upper_bit, bit_bounds[i]-1)#gap_bit-(nof_cols-1)) - #print("added gap before field {} of width {}".format(field_name, str(gap_width))) - if gap_bit == (end_bit-1): break; + gap_bit = max(upper_bit, bit_bounds[i]-1) # gap_bit-(nof_cols-1)) + # print("added gap before field {} of width {}".format(field_name, str(gap_width))) + if gap_bit == (end_bit-1): + break - #print("field {} bit offset {} should be more or equal to {} and upper bit {} should be less than {}".format(field_name, str(field.bit_offset()), str(bit_bounds[i]), str(upper_bit), str(bit_bounds[i-1]))) - if field.bit_offset() >= end_bit and upper_bit < bit_bounds[i-1]: # field fully contained + # print("field {} bit offset {} should be more or equal to {} and upper bit {} should be less than {}".format(field_name, str(field.bit_offset()), str(bit_bounds[i]), str(upper_bit), str(bit_bounds[i-1]))) + if field.bit_offset() >= end_bit and upper_bit < bit_bounds[i-1]: # field fully contained col_list.append(MultiColumn(field.width(), align='|c|', data=field_name)) - #print("added complete field {} of width {}".format(field_name, str(field.width()))) + # print("added complete field {} of width {}".format(field_name, str(field.width()))) gap_bit = field.bit_offset()-1 - elif upper_bit >= end_bit and field.bit_offset() < end_bit: # upper partial + elif upper_bit >= end_bit and field.bit_offset() < end_bit: # upper partial col_list.append(MultiColumn(upper_bit - bit_bounds[i]+1, align='|c|', data=field_name)) - #print("added upper partial for field {} of width {}".format(field_name, str(upper_bit - bit_bounds[i]+1))) - gap_bit = bit_bounds[i]-1# end of table + # print("added upper partial for field {} of width {}".format(field_name, str(upper_bit - bit_bounds[i]+1))) + gap_bit = bit_bounds[i] - 1 # end of table break - elif upper_bit >= bit_bounds[i-1] and field.bit_offset() < bit_bounds[i-1]:# lower partial field - col_list.append(MultiColumn(bit_bounds[i-1]-field.bit_offset(),align='|c|',data=field_name)) - #print("added lower partial for field {} of width {}".format(field_name, str(bit_bounds[i-1]-field.bit_offset()))) + elif upper_bit >= bit_bounds[i-1] and field.bit_offset() < bit_bounds[i-1]: # lower partial field + col_list.append(MultiColumn(bit_bounds[i-1]-field.bit_offset(), align='|c|', data=field_name)) + # print("added lower partial for field {} of width {}".format(field_name, str(bit_bounds[i-1]-field.bit_offset()))) gap_bit = field.bit_offset()-1 - if field.bit_offset() == (bit_bounds[i]): break + if field.bit_offset() == (bit_bounds[i]): + break - if gap_bit != (bit_bounds[i]-1): # bottom gap - gap_width = max(0,gap_bit - (bit_bounds[i]-1)) + if gap_bit != (bit_bounds[i] - 1): # bottom gap + gap_width = max(0, gap_bit - (bit_bounds[i]-1)) col_list.append(MultiColumn(gap_width, align='|c|', data='RES')) - #print("added gap after field {} of width {}".format(field_name, str(gap_width))) + # print("added gap after field {} of width {}".format(field_name, str(gap_width))) row = ['Name'] + col_list group_table.add_row(row) - # group_table.add_row(('Name',*col_list,))# add + # group_table.add_row(('Name',*col_list,))# add group_table.add_hline() subsection.append(group_table) subsection.append(NewLine()) @@ -139,15 +141,24 @@ def gen_reg_tables(subsection, group_fields): return subsection + def main(): + # find all "*.fpga.yaml" files + if args.fpga: + fpga_libs = FPGALibrary(os.path.expandvars('$RADIOHDL_WORK')).library + + # find all "*.peripheral.yaml" files + if args.peripheral: + periph_libs = PeripheralLibrary(os.path.expandvars('$RADIOHDL_WORK')).library + try: - for fpganame in args.system: + for fpganame in args.fpga: doc = FPGADocumentation(fpganame, fpga_libs[fpganame]) doc.fill() doc.make_pdf() del doc time.sleep(0.5) - + for peripheralname in args.peripheral: doc = PeripheralDocumentation(peripheralname, periph_libs[peripheralname]) doc.fill() @@ -156,30 +167,35 @@ def main(): time.sleep(0.5) except IOError: - logger.error("config file '{}' does not exist".format(filename)) + logger.error("config file '{}' does not exist".format('??')) # filename)) # class SamePage(Environment): # """ A class to wrap a section in same page environment """ # packages = [Package('MiniPage')] - # escape = False # not sure + # escape = False # not sure + class FPGADocumentation(object): def __init__(self, fpga_name, fpga_lib): self.fpga_name = fpga_name - self.out_dir = os.path.expandvars('$HDL_BUILD_DIR/ARGS/{}'.format(self.fpga_name)) + # self.out_dir = os.path.expandvars('$HDL_ARGS_DIR/{}'.format(self.fpga_name)) + self.out_dir = os.path.join(os.getenv('HDL_ARGS_DIR'), self.fpga_name, 'doc') try: - os.stat(os.path.expandvars('$HDL_BUILD_DIR/ARGS/{}'.format(self.fpga_name))) + os.stat(self.out_dir) except: - os.mkdir(os.path.expandvars('$HDL_BUILD_DIR/ARGS/{}'.format(self.fpga_name))) + logger.debug("$HDL_ARGS_DIR = %s", os.getenv('HDL_ARGS_DIR')) + logger.debug("%s does not exist in args dir, make it now", self.out_dir) + os.makedirs(self.out_dir) + self.fpga = fpga_lib['fpga'] self.fpga_lib = fpga_lib # self.fpga_filename = "./systems/{}.fpga.yaml".format(fpganame) # self.config = yaml.load(open(self.fpga_filename, "r")) - + geometry_options = {"tmargin": "1cm", "lmargin": "2.5cm"} self.doc = Document(geometry_options=geometry_options) - self.doc.packages.add(Package('hyperref','bookmarks'))#(Command('usepackage','bookmarks','hyperref')) + self.doc.packages.add(Package('hyperref','bookmarks')) # (Command('usepackage','bookmarks','hyperref')) self.doc.preamble.append(Command('title', 'ARGS Documentation for FPGA design \'{}\''.format(self.fpga_name))) self.doc.preamble.append(Command('author', 'ARGS script gen_doc.py')) self.doc.preamble.append(Command('date', NoEscape(r'\today'))) @@ -194,11 +210,10 @@ class FPGADocumentation(object): self.doc.append(NewLine()) self.doc.append(Command('tableofcontents')) self.doc.append(NewPage()) - #self.doc = Documentation(self.config['fpga_name']) + # self.doc = Documentation(self.config['fpga_name']) # self.system = System(self.fpga_filename) # self.fpga = fpga - - + def __del__(self): del self.doc del self.fpga @@ -214,11 +229,11 @@ class FPGADocumentation(object): self.doc.append(NewLine()) fpga_system_table = Tabular('|c|c|c|c|c|') fpga_system_table.add_hline() - fpga_system_table.add_row(('Hex','Range (Bytes)','Slave Port','Protocol','Port No.')) + fpga_system_table.add_row(('Hex', 'Range (Bytes)', 'Slave Port', 'Protocol', 'Port No.')) fpga_system_table.add_hline() for slave_port, slave_dict in self.fpga.address_map.items(): - fpga_system_table.add_row((str(hex(slave_dict['base'])),str(slave_dict['span']),slave_port,slave_dict['type'], slave_dict['port_index'])) + fpga_system_table.add_row((str(hex(slave_dict['base'])), str(slave_dict['span']), slave_port, slave_dict['type'], slave_dict['port_index'])) fpga_system_table.add_hline() self.doc.append(fpga_system_table) @@ -236,24 +251,24 @@ class FPGADocumentation(object): # # self.doc.append(peri_class.get_kv('peripheral_description').replace('"', '')) # self.doc.append(peri_class.get_description().replace('"', '')) # self.doc.append(NewLine()) - + # #self.doc.append(MediumText(bold("slave ports."))) - - # for val_info, val_type in ((peri_class.registers, 'Registers'), - # (peri_class.rams, 'Rams'), + + # for val_info, val_type in ((peri_class.registers, 'Registers'), + # (peri_class.rams, 'Rams'), # (peri_class.fifos, 'Fifos')): - + # if len(val_info) == 0: # continue # #self.doc.add(text=val_type, size="medium") - + # added_val_types = [] # for key, val in sorted(val_info.items()): # if val.name() in added_val_types: # continue # added_val_types.append(val.name()) - + # with self.doc.create(Subsection("{} slave.".format(val.name().lower()), numbering=True)): # if val.get_kv('slave_description') is not None: # self.doc.append(val.get_kv('slave_description').replace('"', '')) @@ -266,34 +281,35 @@ class FPGADocumentation(object): # with self.doc.create(Subsubsection("{} field.".format("{}".format(real_name)), numbering=True)): # self.doc.append(field_val.get_kv('field_description').replace('"', '') ) # #self.doc.append(NewLine()) - + def make_pdf(self): - stdout = sys.stdout # keep a handle on the real standard output + stdout = sys.stdout # keep a handle on the real standard output sys.stdout = StringIO() try: self.doc.generate_pdf(os.path.join(self.out_dir, self.fpga_name), clean_tex=True) time.sleep(0.5) except CalledProcessError: pass + sys.stdout = stdout def peripheral_fill(self, periph, periph_name): self.doc.append(NewPage()) periph_subsection = Section(periph_name, numbering=True) - periph_subsection.append(periph.get_description().replace('""','')) + periph_subsection.append(periph.get_description().replace('""', '')) periph_reg_section = Subsection("{} register slave".format(periph_name), numbering=False) periph_reg_table = Tabular('|c|c|c|c|') periph_reg_table.add_hline() - periph_reg_table.add_row(('Base Address','Range','Register group', 'Number of Slaves')) + periph_reg_table.add_row(('Base Address', 'Range', 'Register group', 'Number of Slaves')) periph_reg_table.add_hline() # slave_subsections = ("{} slaves".format(periph_name), numbering=False) # slave_subsections = [] # slave_subsections.append(NewLine()) # slave_subsections.append(MediumText(bold("Slave Ports for peripheral " + periph_name + "\n"))) slave_subsections = Subsection("Slave Ports for peripheral \'{}\'".format(periph_name), numbering=False) - for slave in periph.slaves: + for slave in periph.slaves: + + # self.doc.add(text=val_type, size="medium") - #self.doc.add(text=val_type, size="medium") - # added_val_types = [] # for key, val in sorted(val_info.items()): # if val.name() in added_val_types: @@ -309,66 +325,67 @@ class FPGADocumentation(object): slave_subsection.append("Number of Slaves: {}".format(str(slave.number_of_slaves()))) slave_subsection.append(NewLine()) slave_subsection.append(NewLine()) - + # if val_type == 'Registers': - if isinstance(slave, Register): # expand registers and fields + 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()), 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_row((str(slave.base_address()), str(slave.address_length()), slave.name(), str(slave.number_of_slaves()))) periph_reg_table.add_hline() added_field_groups = [] # with self.doc.create(Subsection("{} Register Fields".format(val.name().lower()), numbering=True)): # if val.get_kv('slave_description') is not None: # slave_subsection.append(val.get_kv('slave_description').replace('"', '')) - - # generate register table i.e. by word + + # generate register table i.e. by word group_address = -1 group_list = [] for field in slave.fields: - if field.address_offset() != group_address: + if field.address_offset() != group_address: group_address = field.address_offset() group_list.append(field) # addr_name = field.group_name() if field.group_name() != "None" else field.name() - + # slave_table.add_row(str(hex(field.address_offset())), addr_name) # slave_table.add_hline() c_max_rows = 30 - nof_cols = ceil(len(group_list)/c_max_rows) # register table has max length of 40 + nof_cols = ceil(len(group_list)/c_max_rows) # register table has max length of 40 nof_rows = min(len(group_list), c_max_rows) slave_table = Tabular('|c|c|'*nof_cols) slave_table.add_hline() # slave_table.add_row((*['Hex','Field Group']*nof_cols)) - slave_table.add_row(['Hex','Field Group']*nof_cols) + slave_table.add_row(['Hex', 'Field Group']*nof_cols) slave_table.add_hline() - for i in range(nof_rows): + for i in range(nof_rows): row = [] for j in range(nof_cols): if i+c_max_rows*j < len(group_list): - field.group_name() if field.group_name() != "None" else field.name() + field.group_name() if field.group_name() is not None else field.name() row.extend([str(hex(group_list[i+c_max_rows*j].address_offset())), group_list[i+c_max_rows*j].name()]) - else : - row.extend(['','']) + else : + row.extend(['', '']) # slave_table.add_row(*row) slave_table.add_row(row) slave_table.add_hline() slave_subsection.append(slave_table) slave_subsection.append(NewPage()) - + group_address = -1 for field in slave.fields: # if field.group_name() is None or field.group_name() != last_group: # base on group_address instead # print("field {} address {} bit{}".format(field.name(), str(field.address_offset()), str(field.bit_offset()))) - if field.address_offset() != group_address: + if field.address_offset() != group_address: group_address = field.address_offset() # group_page = MiniPage() - group_subsection = Subsection('{} {}'.format(str(hex(field.address_offset())), field.name() if field.group_name() == 'None' else field.group_name()),numbering=False) - group_fields = [field for field in slave.fields if field.address_offset() == group_address ] - if len(group_fields)>10: slave_subsection.append(NewPage()) + group_subsection = Subsection('{} {}'.format(str(hex(field.address_offset())), field.name() if field.group_name() == 'None' else field.group_name()), numbering=False) + group_fields = [field for field in slave.fields if field.address_offset() == group_address] + if len(group_fields) > 10: + slave_subsection.append(NewPage()) group_subsection = gen_reg_tables(group_subsection, group_fields) for field in group_fields[::-1]: - field_name = field.name() if field.group_name() == 'None' else field.name().split(field.group_name() + '_')[-1] + field_name = field.name() if field.group_name() is None else field.name().split(field.group_name() + '_')[-1] bit_string = "Bit {}".format(str(field.bit_offset())) if field.width() == 1 else "Bits {}:{}".format(str(field.bit_offset()+field.width()-1), str(field.bit_offset())) group_subsection.append(bold("{}\t\t{} ({}):".format(bit_string, field_name, field.access_mode()))) group_subsection.append("\t\t{}".format(field.field_description())) @@ -376,7 +393,7 @@ class FPGADocumentation(object): group_subsection.append(NewLine()) # group_page.append(group_subsection) slave_subsection.append(group_subsection) - else: # RAM or FIFO + else: # RAM or FIFO slave_subsection.append("Data width: {}".format(slave.width())) slave_subsection.append(NewLine()) if isinstance(slave, RAM): @@ -385,7 +402,8 @@ class FPGADocumentation(object): slave_subsections.append(slave_subsection) periph_reg_section.append(periph_reg_table) self.doc.append(periph_subsection) - if any([isinstance(slave, Register) for slave in periph.slaves]): self.doc.append(periph_reg_section) + if any([isinstance(slave, Register) for slave in periph.slaves]): + self.doc.append(periph_reg_section) # for i in range(len(slave_subsections)): # self.doc.append(slave_subsections[i]) self.doc.append(slave_subsections) @@ -395,24 +413,25 @@ class FPGADocumentation(object): class PeripheralDocumentation(object): - def __init__(self, periph_lib_name, periph_lib): # accepts an item from periph_libs + def __init__(self, periph_lib_name, periph_lib): # accepts an item from periph_libs self.periph_lib_name = periph_lib_name self.periph_lib = periph_lib - self.out_dir = os.path.expandvars('$HDL_BUILD_DIR/ARGS/{}'.format(self.periph_lib_name)) - try: - os.stat(os.path.expandvars('$HDL_BUILD_DIR/ARGS')) - except: - os.mkdir(os.path.expandvars('$HDL_BUILD_DIR/ARGS')) + + self.out_dir = os.path.join(os.getenv('HDL_ARGS_DIR'), self.periph_lib_name, 'doc') + try: - os.stat(os.path.expandvars('$HDL_BUILD_DIR/ARGS/{}'.format(self.periph_lib_name))) + os.stat(self.out_dir) except: - os.mkdir(os.path.expandvars('$HDL_BUILD_DIR/ARGS/{}'.format(self.periph_lib_name))) + # logger.debug("$HDL_ARGS_DIR = %s", os.getenv('HDL_ARGS_DIR')) + logger.debug("%s does not exist in args dir, make it now", self.out_dir) + os.makedirs(self.out_dir) + # self.peripheral_filename = "./peripherals/{}.peripheral.yaml".format(peripheralname) # self.config = yaml.load(open(self.peripheral_filename, "r")) - + geometry_options = {"tmargin": "1cm", "lmargin": "2.5cm"} - self.doc = Document(font_size='small',geometry_options=geometry_options) - self.doc.packages.add(Package('hyperref','bookmarks')) + self.doc = Document(font_size='small', geometry_options=geometry_options) + self.doc.packages.add(Package('hyperref', 'bookmarks')) self.doc.preamble.append(Command('title', 'ARGS Documentation for Peripheral Library \'{}\''.format(self.periph_lib_name))) self.doc.preamble.append(Command('author', 'ARGS script gen_doc.py')) self.doc.preamble.append(Command('date', NoEscape(r'\today'))) @@ -431,7 +450,6 @@ class PeripheralDocumentation(object): self.doc.append(Command('tableofcontents')) self.doc.append(NewPage()) - def fill(self): # with self.doc.create(Section("{} library.".format(self.config['hdl_library_name']))): # with self.doc.create(Section("{} library".format(self.periph_lib_name))): @@ -452,15 +470,15 @@ class PeripheralDocumentation(object): continue added_instances.append(periph_name) - + # with self.doc.create(Section(periph_name, numbering=True)): # with self.doc.create(Subsection(periph_name, numbering=True)): # self.doc.append(peri_class.get_kv('peripheral_description').replace('"', '')) self.doc.append(NewPage()) periph_subsection = Section(periph_name, numbering=True) - periph_subsection.append(periph.get_description().replace('""','')) + periph_subsection.append(periph.get_description().replace('""', '')) - # Peripheral System Map Table + # Peripheral System Map Table periph_subsection.append(NewLine()) periph_subsection.append(NewLine()) periph_subsection.append(MediumText(bold('Local Slave Port Map'))) @@ -469,45 +487,45 @@ class PeripheralDocumentation(object): periph_system_table = Tabular('|c|c|c|c|') # periph_system_table.add_row((MultiColumn(4,data=MediumText(bold('System Map'))),)) periph_system_table.add_hline() - periph_system_table.add_row(('Hex','Range (Bytes)','Slave Port','Protocol')) + periph_system_table.add_row(('Hex', 'Range (Bytes)', 'Slave Port', 'Protocol')) periph_system_table.add_hline() - # peripheral system address map + # peripheral system address map dummyFPGA = FPGA(None) dummyFPGA.peripherals.update({periph_name: periph}) dummyFPGA.create_address_map() # for slave in periph.slaves: for slave_port, slave_dict in dummyFPGA.address_map.items(): - periph_system_table.add_row((str(hex(slave_dict['base'])),str(slave_dict['span']),slave_port,slave_dict['type'])) + periph_system_table.add_row((str(hex(slave_dict['base'])), str(slave_dict['span']), slave_port, slave_dict['type'])) periph_system_table.add_hline() periph_subsection.append(periph_system_table) # self.doc.append(periph.get_description().replace('""','')) # self.doc.append(NewLine()) - - #self.doc.append(MediumText(bold("slave ports."))) - # for val_info, val_type in ((periph.registers, 'Registers'), - # (periph.rams, 'Rams'), + # self.doc.append(MediumText(bold("slave ports."))) + + # for val_info, val_type in ((periph.registers, 'Registers'), + # (periph.rams, 'Rams'), # (periph.fifos, 'Fifos')): periph_reg_section = Subsection("{} register slave".format(periph_name), numbering=False) periph_reg_table = Tabular('|c|c|c|c|') periph_reg_table.add_hline() - periph_reg_table.add_row(('Base Address','Range','Register group', 'Number of Slaves')) + periph_reg_table.add_row(('Base Address', 'Range', 'Register group', 'Number of Slaves')) periph_reg_table.add_hline() # slave_subsections = ("{} slaves".format(periph_name), numbering=False) # slave_subsections = [] # slave_subsections.append(NewLine()) # slave_subsections.append(MediumText(bold("Slave Ports for peripheral " + periph_name + "\n"))) slave_subsections = Subsection("Slave Ports for peripheral \'{}\'".format(periph_name), numbering=False) - for slave in periph.slaves: + for slave in periph.slaves: - # if len(val_info) == 0: # not sure what this is for + # if len(val_info) == 0: # not sure what this is for # continue #self.doc.add(text=val_type, size="medium") - + # added_val_types = [] # for key, val in sorted(val_info.items()): # if val.name() in added_val_types: @@ -523,63 +541,64 @@ class PeripheralDocumentation(object): slave_subsection.append("Number of Slaves: {}".format(str(slave.number_of_slaves()))) slave_subsection.append(NewLine()) slave_subsection.append(NewLine()) - + # if val_type == 'Registers': - if isinstance(slave, Register): # expand registers and fields + 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_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_row((str(slave.base_address()), str(slave.address_length()), slave.name(), str(slave.number_of_slaves()))) periph_reg_table.add_hline() added_field_groups = [] # with self.doc.create(Subsection("{} Register Fields".format(val.name().lower()), numbering=True)): # if val.get_kv('slave_description') is not None: # slave_subsection.append(val.get_kv('slave_description').replace('"', '')) - - # generate register table i.e. by word + + # generate register table i.e. by word group_address = -1 group_list = [] for field in slave.fields: - if field.address_offset() != group_address: + if field.address_offset() != group_address: group_address = field.address_offset() group_list.append(field) # addr_name = field.group_name() if field.group_name() != "None" else field.name() - + # slave_table.add_row(str(hex(field.address_offset())), addr_name) # slave_table.add_hline() c_max_rows = 30 - nof_cols = ceil(len(group_list)/c_max_rows) # register table has max length of c_max_rows + nof_cols = ceil(len(group_list)/c_max_rows) # register table has max length of c_max_rows nof_rows = min(len(group_list), c_max_rows) slave_table = Tabular('|c|c|'*nof_cols) slave_table.add_hline() - slave_table.add_row(['Hex','Field Group']*nof_cols) + slave_table.add_row(['Hex', 'Field Group']*nof_cols) # slave_table.add_row((*['Hex','Field Group']*nof_cols)) slave_table.add_hline() - for i in range(nof_rows): + for i in range(nof_rows): row = [] for j in range(nof_cols): if i+c_max_rows*j < len(group_list): - field.group_name() if field.group_name() != "None" else field.name() + field.group_name() if field.group_name() is not None else field.name() row.extend([str(hex(group_list[i+c_max_rows*j].address_offset())), group_list[i+c_max_rows*j].name()]) - else : - row.extend(['','']) + else : + row.extend(['', '']) slave_table.add_row(row) # slave_table.add_row(*row) slave_table.add_hline() slave_subsection.append(slave_table) slave_subsection.append(NewPage()) - + group_address = -1 for field in slave.fields: # if field.group_name() is None or field.group_name() != last_group: # base on group_address instead # print("field {} address {} bit{}".format(field.name(), str(field.address_offset()), str(field.bit_offset()))) - if field.address_offset() != group_address: + if field.address_offset() != group_address: group_address = field.address_offset() # group_page = MiniPage() group_subsection = Subsection('{} {}'.format(str(hex(field.address_offset())), field.name() if field.group_name() == 'None' else field.group_name()),numbering=False) - group_fields = [field for field in slave.fields if field.address_offset() == group_address ] - if len(group_fields)>10: slave_subsection.append(NewPage()) + group_fields = [field for field in slave.fields if field.address_offset() == group_address] + if len(group_fields) > 10: + slave_subsection.append(NewPage()) group_subsection = gen_reg_tables(group_subsection, group_fields) for field in group_fields[::-1]: field_name = field.name() if field.group_name() == 'None' else field.name().split(field.group_name() + '_')[-1] @@ -590,7 +609,7 @@ class PeripheralDocumentation(object): group_subsection.append(NewLine()) # group_page.append(group_subsection) slave_subsection.append(group_subsection) - else: # RAM or FIFO + else: # RAM or FIFO slave_subsection.append("Data width: {}".format(slave.width())) slave_subsection.append(NewLine()) if isinstance(slave, RAM): @@ -599,7 +618,8 @@ class PeripheralDocumentation(object): slave_subsections.append(slave_subsection) periph_reg_section.append(periph_reg_table) self.doc.append(periph_subsection) - if any([isinstance(slave, Register) for slave in periph.slaves]): self.doc.append(periph_reg_section) + if any([isinstance(slave, Register) for slave in periph.slaves]): + self.doc.append(periph_reg_section) # for i in range(len(slave_subsections)): # self.doc.append(slave_subsections[i]) self.doc.append(slave_subsections) @@ -608,7 +628,7 @@ class PeripheralDocumentation(object): self.doc.append(NewPage()) def make_pdf(self): - stdout = sys.stdout # keep a handle on the real standard output + stdout = sys.stdout # keep a handle on the real standard output sys.stdout = StringIO() try: # self.doc.generate_pdf('{}'.format(self.periph_lib_name), clean_tex=False, silent=True) @@ -619,7 +639,6 @@ class PeripheralDocumentation(object): sys.stdout = stdout - if __name__ == "__main__": # setup first log system before importing other user libraries PROGRAM_NAME = __file__.split('/')[-1].split('.')[0] @@ -628,22 +647,18 @@ if __name__ == "__main__": # Parse command line arguments parser = argparse.ArgumentParser(description="System and peripheral config command line parser arguments") - parser.add_argument('-s','--system', nargs='*', default=[], help="system names separated by spaces") - parser.add_argument('-p','--peripheral', nargs='*', default=[], help="peripheral names separated by spaces") - parser.add_argument('-v','--verbosity', default='INFO', help="verbosity level can be [ERROR | WARNING | INFO | DEBUG]") + parser.add_argument('-f', '--fpga', nargs='*', default=[], help="fpga system names separated by spaces") + parser.add_argument('-p', '--peripheral', nargs='*', default=[], help="peripheral names separated by spaces") + parser.add_argument('-v', '--verbosity', default='INFO', help="verbosity level can be [ERROR | WARNING | INFO | DEBUG]") args = parser.parse_args() - if not args.peripheral and not args.system: - parser.print_help() - else: - if args.system: - fpga_libs = FPGALibrary(os.path.expandvars('$RADIOHDL_WORK')).library - if args.peripheral: - periph_libs = PeripheralLibrary(os.path.expandvars('$RADIOHDL_WORK')).library - unit_logger.set_stdout_log_level(args.verbosity) logger.debug("Used arguments: {}".format(args)) + if not args.peripheral and not args.fpga: + parser.print_help() + sys.exit(1) + try: main() except: @@ -653,4 +668,5 @@ 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 diff --git a/init_args.sh b/init_args.sh index 63b351bffa3422d10f4865bd4510fffad51f9c10..e1e0b1e7f75563dd3a75ff7ba3eac4dbf0191517 100644 --- a/init_args.sh +++ b/init_args.sh @@ -34,5 +34,20 @@ if [[ "$_" == "${0}" ]]; then exit fi +# Figure out where this script is located and set environment variables accordingly +export ARGS_GEAR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + # Figure out where this script is located and set environment variables accordingly export RADIOHDL_WORK="$GIT/hdl" + +# setup paths to build and config dir if not already defined by the user. +export HDL_BUILD_DIR=${HDL_BUILD_DIR:-${RADIOHDL_WORK}/build} + +# args uses this dir for output +export HDL_ARGS_DIR=${HDL_ARGS_DIR:-${HDL_BUILD_DIR}/args} + +if ! [[ -e HDL_ARGS_DIR ]]; then + echo "make args dir" + mkdir ${HDL_BUILD_DIR}/args +fi + diff --git a/py_args_lib/fpga.py b/py_args_lib/fpga.py index 65a47711158553002cfb412e48eb120f40395e2b..768a3671020d868f7153faeac7d7bb2fa9816221 100644 --- a/py_args_lib/fpga.py +++ b/py_args_lib/fpga.py @@ -21,6 +21,7 @@ # HJ jan 2017 Original # EK feb 2017 # PD feb 2017 +# PD nov 2019 # ############################################################################### @@ -30,7 +31,6 @@ import logging import yaml import time import collections -import common as cm from py_args_lib import * from peripheral_lib import * import numpy as np @@ -39,11 +39,11 @@ logger = logging.getLogger('main.fpga') class FPGA(object): - """ A System consist of a set of one or more Peripherals. + """ A FPGA System consist of a set of one or more Peripherals. """ def __init__(self, file_path_name=None, periph_lib=None): self.file_path_name = file_path_name - self.root_dir = os.environ['RADIOHDL'] + self.root_dir = os.environ['RADIOHDL_WORK'] if periph_lib is None: self.peri_lib = PeripheralLibrary(self.root_dir) else: @@ -81,7 +81,6 @@ class FPGA(object): self.valid_file_type = True return system_config - def create_system(self): """ Create a system object based on the information in the system_config """ logger.debug("Creating system") @@ -110,7 +109,7 @@ class FPGA(object): for parameter_set_nr, parameter_set in enumerate(_parameters): name = parameter_set['name'] value = parameter_set['value'] - if '.' in name: # struct notation with dot + if '.' in name: # struct notation with dot _struct, _name = name.split('.') self.parameters[_struct][_name] = self._eval(str(value)) else: @@ -126,20 +125,19 @@ class FPGA(object): value = parameter_set['value'] logger.debug("eval of name=%s and value=%s not posible", name, value) - logger.debug("parameters={}".format(self.parameters)) for peripheral_config in config['peripherals']: # (Deep)Copy the peripheral from the library in order to avoid creating a reference component_name = peripheral_config['peripheral_name'] if '/' not in peripheral_config['peripheral_name'] else peripheral_config['peripheral_name'].split('/')[1] component_lib = None if '/' not in peripheral_config['peripheral_name'] else peripheral_config['peripheral_name'].split('/')[0] - component_prefix = peripheral_config.get('peripheral_group',None) + 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)) if peripheral_from_lib is None: - logger.error("Peripheral component '{}' referenced in {}.fpga.yaml not found in " - "peripheral library {}".format(component_name, self.fpga_name, '\'' + component_lib + '\'' if component_lib is not None else '')) + logger.error("Peripheral component '{}' referenced in {}.fpga.yaml not found in peripheral library {}" + .format(component_name, self.fpga_name, '\'' + component_lib + '\'' if component_lib is not None else '')) sys.exit() logger.debug(" Finding %s", peripheral_from_lib.name()) @@ -151,7 +149,6 @@ class FPGA(object): value = parameter_set['value'] peripheral_from_lib.parameter(key=name, val=self._eval(value)) - if 'slave_port_names' in peripheral_config: logger.debug("slave_port_names={}".format(peripheral_config['slave_port_names'])) for slave_nr, slave_port_name in enumerate(peripheral_config['slave_port_names']): @@ -169,9 +166,9 @@ class FPGA(object): self.peripherals[peripheral_from_lib.name()] = copy.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" - " Cannot add a second instance of peripheral: %s", - self.fpga_name, peripheral_from_lib.name()) + "between multiple instances of the same peripheral.\n" + " Cannot add a second instance of peripheral: %s", + self.fpga_name, peripheral_from_lib.name()) sys.exit() logger.debug("Start evaluating the peripherals") @@ -208,14 +205,14 @@ class FPGA(object): Configurable ranges are 4k, 8k, 16k, 32k, 64k i.e. 2^(12,13,14,15,16) There is a maximum of one register group per peripheral """ - print("[fpga.py] create_address_map('{:s}')".format(self.fpga_name)) + logger.debug("[fpga.py] create_address_map('{:s}')".format(self.fpga_name)) # Largest peripheral will determine spacing between peripheral base addresses - largest_addr_range = 4096 # minimal allowed address-decode spacing with Xilinx interconnect + largest_addr_range = 4096 # minimal allowed address-decode spacing with Xilinx interconnect for peripheral in self.peripherals.values(): if peripheral.reg_len > largest_addr_range: largest_addr_range = peripheral.reg_len - peripheral_spacing = cm.ceil_pow2(largest_addr_range) + peripheral_spacing = ceil_pow2(largest_addr_range) lowest_free_addr = 0 for peripheral in self.peripherals.values(): @@ -225,7 +222,7 @@ class FPGA(object): if len(p_nam) > 20: p_nam = p_nam[0:20] pad = ' ' * (21-len(peripheral.name())) - print('** PERIPHERAL: {} {}base_addr=0x{:08x} [occupied size=0x{:x}]'.format(p_nam, pad, lowest_free_addr, peripheral.reg_len)) + logger.debug('** PERIPHERAL: {:21s} base_addr=0x{:08x} [occupied size=0x{:04x}]'.format(p_nam, lowest_free_addr, peripheral.reg_len)) # assigned_reg = False # _nof_regs = sum([isinstance(slave, Register) for slave in peripheral.slaves]) # _minus_regs = _nof_regs - 1 if _nof_regs > 0 else 0 @@ -234,27 +231,31 @@ class FPGA(object): assigned_reg = False for slave in peripheral.slaves: if isinstance(slave, Register) and not getattr(slave, 'isIP', False): - if assigned_reg == False: #calc for entire register slave port - reg_span = cm.ceil_pow2(max(peripheral.reg_len, 4096)) + if assigned_reg is False: # calc for entire register slave port + reg_span = ceil_pow2(max(peripheral.reg_len, 4096)) lowest_free_addr = int(np.ceil(lowest_free_addr/reg_span)*reg_span) register_base = lowest_free_addr else : self.nof_lite = self.nof_lite - 1 lowest_free_addr = register_base + (slave.base_address() if not any(slave.rams) else slave.rams[0].base_address()) - ram_span = slave.base_address() - slave.rams[0].base_address() if any(slave.rams) else 0 + ram_span = slave.base_address() - slave.rams[0].base_address() if any(slave.rams) else 0 slave_span = slave.address_length()*slave.number_of_slaves()+ram_span slave_port_name = peripheral.name() + '_' + slave.name() + (('_' + str(periph_num)) if peripheral.number_of_peripherals() > 1 else '') - self.address_map[slave_port_name] = {'base':lowest_free_addr,'span':slave_span,'type':'LITE','port_index':self.nof_lite,'peripheral':peripheral,'periph_num':periph_num,'slave':slave} + self.address_map[slave_port_name] = {'base': lowest_free_addr, 'span': slave_span, 'type': 'LITE', + 'port_index': self.nof_lite, 'peripheral': peripheral, + 'periph_num': periph_num, 'slave': slave} logger.info("Register for %s has span 0x%x", peripheral.name(), slave_span) lowest_free_addr = lowest_free_addr + int(slave_span) self.nof_lite = self.nof_lite + 1 assigned_reg = True elif isinstance(slave, Register) and getattr(slave, 'isIP', False): - slave_span = cm.ceil_pow2(max(slave.address_length()*slave.number_of_slaves(), 4096)) #slave.address_length()*slave.number_of_slaves()# + slave_span = ceil_pow2(max(slave.address_length()*slave.number_of_slaves(), 4096)) # slave.address_length()*slave.number_of_slaves()# lowest_free_addr = int(np.ceil(lowest_free_addr/slave_span)*slave_span) - slave_port_name = peripheral.name() + '_' + slave.name() #+ '_reg_ip' - self.address_map[slave_port_name] = {'base':lowest_free_addr, 'span':slave_span, 'type':slave.protocol, 'port_index':eval("self.nof_{}".format(slave.protocol.lower())),'peripheral':peripheral,'periph_num':periph_num,'slave':slave} + slave_port_name = peripheral.name() + '_' + slave.name() # + '_reg_ip' + self.address_map[slave_port_name] = {'base': lowest_free_addr, 'span': slave_span, 'type': slave.protocol, + 'port_index': eval("self.nof_{}".format(slave.protocol.lower())), + 'peripheral': peripheral, 'periph_num': periph_num, 'slave': slave} if slave.protocol.lower() == 'lite': self.nof_lite = self.nof_lite + 1 else : @@ -263,24 +264,28 @@ class FPGA(object): elif isinstance(slave, RAM): slave_type = 'ram' - size_in_bytes = np.ceil(slave.width()/8)*slave.address_length()*cm.ceil_pow2(slave.number_of_slaves()) - slave_span = cm.ceil_pow2(max(size_in_bytes, 4096)) + size_in_bytes = np.ceil(slave.width()/8)*slave.address_length()*ceil_pow2(slave.number_of_slaves()) + slave_span = ceil_pow2(max(size_in_bytes, 4096)) logger.info("Slave %s has span 0x%x", peripheral.name() + '_' + slave.name() , slave_span) # slave_name = slave.name() + ('_{}'.format(slave_no) if slave.number_of_slaves() >1 else '') lowest_free_addr = int(np.ceil(lowest_free_addr/slave_span)*slave_span) - slave_port_name = peripheral.name() + '_' + slave.name() + '_' + slave_type+ (('_' + str(periph_num)) if peripheral.number_of_peripherals() > 1 else '') - self.address_map[slave_port_name] = {'base':lowest_free_addr,'span':slave_span,'type':'FULL','port_index':self.nof_full,'peripheral':peripheral,'periph_num':periph_num,'slave':slave} + slave_port_name = peripheral.name() + '_' + slave.name() + '_' + slave_type + (('_' + str(periph_num)) if peripheral.number_of_peripherals() > 1 else '') + self.address_map[slave_port_name] = {'base': lowest_free_addr, 'span': slave_span, 'type': 'FULL', + 'port_index': self.nof_full, 'peripheral': peripheral, + 'periph_num': periph_num, 'slave': slave} self.nof_full = self.nof_full + 1 lowest_free_addr = lowest_free_addr + slave_span elif isinstance(slave, FIFO): slave_type = 'fifo' - size_in_bytes = np.ceil(slave.width()/8)*slave.address_length() - slave_span = cm.ceil_pow2(max(size_in_bytes, 4096)) + size_in_bytes = np.ceil(slave.width()/8)*slave.address_length() + slave_span = ceil_pow2(max(size_in_bytes, 4096)) for i in range(slave.number_of_slaves()): lowest_free_addr = int(np.ceil(lowest_free_addr/slave_span)*slave_span) slave_port_name = peripheral.name() + '_' + slave.name() + '_' + slave_type+ (('_' + str(periph_num)) if peripheral.number_of_peripherals() > 1 else '') + ('_{}'.format(i) if slave.number_of_slaves() > 1 else '') - self.address_map[slave_port_name] = {'base':lowest_free_addr,'span':slave_span,'type':'FULL','port_index':self.nof_full,'access':slave.access_mode(),'peripheral':peripheral,'periph_num':periph_num,'slave':slave} + self.address_map[slave_port_name] = {'base': lowest_free_addr, 'span': slave_span, 'type': 'FULL', + 'port_index': self.nof_full, 'access': slave.access_mode(), + 'peripheral': peripheral, 'periph_num': periph_num, 'slave': slave} self.nof_full = self.nof_full + 1 lowest_free_addr = lowest_free_addr + slave_span @@ -291,20 +296,21 @@ class FPGA(object): def show_overview(self): """ print system overview """ - logger.info("----------------") - logger.info("SYSTEM OVERVIEW:") - logger.info("----------------") - logger.info("System name '%s'", self.fpga_name) - logger.info("- System parameters:") + logger.info("----------------------") + logger.info(" FPGA SYSTEM OVERVIEW ") + logger.info("----------------------") + logger.info("FPGA name '%s'", self.fpga_name) + logger.info("- system parameters:") for key, val in iter(self.parameters.items()): if isinstance(val, dict): for _key, _val in val.items(): logger.info(" %-25s %s", "{}.{}".format(key, _key), str(_val)) else: logger.info(" %-20s %s", key, str(val)) - logger.info("- System Address Map:") + logger.info("- FPGA Address Map:") for slave_name, attributes in self.address_map.items(): - logger.info(" %-30s 0x%x, range %dkB at port MSTR_%s[%d]", slave_name, attributes['base'], attributes['span']/1024, attributes['type'],attributes['port_index']) + logger.info(" %-30s 0x%x, range %dkB at port MSTR_%s[%d]", + slave_name, attributes['base'], attributes['span']/1024, attributes['type'], attributes['port_index']) logger.info("- Peripherals:") for peripheral in sorted(self.peripherals): self.peripherals[peripheral].show_overview(header=False) @@ -321,27 +327,27 @@ class FPGALibrary(object): self.nof_peripherals = 0 tic = time.time() if root_dir is not None: - for root, dirs, files in os.walk(self.root_dir, topdown = True): + for root, dirs, files in os.walk(self.root_dir, topdown=True): if 'tools' not in root: for name in files: - if self.file_extension in name: + if name.endswith(self.file_extension): try : - library_config = yaml.load(open(os.path.join(root,name),'r')) + library_config = yaml.load(open(os.path.join(root, name), 'r')) except: logger.error('Failed parsing YAML in {}. Check file for YAML syntax errors'.format(name)) print('ERROR:\n' + sys.exc_info()[1]) sys.exit() if not isinstance(library_config, dict): - logger.warning('File {} is not readable as a dictionary, it will not be' - ' included in the FPGA library of peripherals'.format(name)) + logger.warning('File %s is not readable as a dictionary, it will not be' + ' included in the FPGA library of peripherals', name) continue lib_name = name.replace(self.file_extension, '') - logger.info("Found fpga.yaml file {}".format(lib_name)) + logger.info("Found fpga.yaml file %s", lib_name) if lib_name in self.library: - logger.warning("{} library already exists in FPGALibrary, being overwritten".format(lib_name)) - self.library[lib_name] = {'file_path':root, 'file_path_name':os.path.join(root,name), 'peripherals':{}} + logger.warning("%s library already exists in FPGALibrary, being overwritten", lib_name) + self.library[lib_name] = {'file_path': root, 'file_path_name': os.path.join(root, name), 'peripherals': {}} toc = time.time() - logger.debug("FPGALibrary os.walk took %.4f seconds" %(toc-tic)) + logger.debug("FPGALibrary os.walk took %.4f seconds", toc-tic) self.read_all_fpga_files() def read_all_fpga_files(self, file_path_names=None): @@ -358,8 +364,8 @@ class FPGALibrary(object): tic = time.time() fpga = FPGA(fpn, periph_lib=periph_lib) toc = time.time() - logger.debug("fpga creation for %s took %.4f seconds" %(fpn, toc-tic)) + logger.debug("fpga creation for %s took %.4f seconds", fpn, toc-tic) fpga.show_overview() - self.library[fpga.fpga_name].update({'fpga':fpga}) + self.library[fpga.fpga_name].update({'fpga': fpga}) for lib, peripheral in fpga.peripherals.items(): - self.library[fpga.fpga_name]['peripherals'].update({lib:peripheral}) + self.library[fpga.fpga_name]['peripherals'].update({lib: peripheral}) diff --git a/py_args_lib/peripheral.py b/py_args_lib/peripheral.py index 01e90990d279a33a7cd4095cf07d71b569b2956b..0e8a8b9c498a6ae01c944ea9f1b7efe6508202db 100644 --- a/py_args_lib/peripheral.py +++ b/py_args_lib/peripheral.py @@ -33,8 +33,6 @@ from math import ceil import logging import yaml import collections -#from constants import * -from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2, unique, path_string from peripheral_lib import * logger = logging.getLogger('main.peripheral') @@ -184,7 +182,7 @@ class Peripheral(BaseObject): for parameter_set_nr, parameter_set in enumerate(_parameters): name = parameter_set['name'] value = parameter_set['value'] - if '.' in name: # struct notation with dot + if '.' in name: # struct notation with dot _struct, _name = name.split('.') self._parameters[_struct][_name] = self._eval(str(value)) else: @@ -212,7 +210,7 @@ class Peripheral(BaseObject): for slave_nr, slave_info in enumerate(slave_ports): # logger.debug("slave_prefix=%s, slave_name=%s, slave_postfix=%s", # slave_info['slave_prefix'], slave_info['slave_name'], slave_info['slave_postfix']) - logger.debug("slave_name=%s slave_type=%s", slave_info.get('slave_name',None), slave_info.get('slave_type',None)) + logger.debug("slave_name=%s slave_type=%s", slave_info.get('slave_name', None), slave_info.get('slave_type', None)) # make full name, dot sepperated # slave_name = [] # for name in ('slave_prefix', 'slave_name', 'slave_postfix'): @@ -228,7 +226,7 @@ class Peripheral(BaseObject): sys.exit() i = 0 - _slave_type = slave_info.get('slave_type', '').lower() + _slave_type = slave_info.get('slave_type', '').upper() if _slave_type in VALID_SLAVE_TYPES: number_of_slaves = slave_info.get('number_of_slaves', DEFAULT_NUMBER_OF_SLAVES) @@ -236,15 +234,19 @@ class Peripheral(BaseObject): if 'fields' in slave_info: # for field_info in slave_info['fields']: # list of addresses defaults = {} + logger.debug("slave_info['fields'] = %s", str(slave_info['fields'])) for field_group in slave_info['fields']: - if isinstance(field_group, dict): # labelled field group - (group_label, v), = field_group.items() + if isinstance(field_group, dict): # labelled field group + logger.debug('field_group=%s', field_group) + (group_label, v) = field_group.items() field_group = v elif len(field_group) > 1: # unlabelled field group group_label = "reg{}".format(i) i = i + 1 else : - group_label = None # only one field in group + group_label = None # only one field in group + + logger.debug('group_label=%s', str(group_label)) for field_info in field_group: # logger.debug("field_info=%s", str(field_info)) @@ -259,8 +261,11 @@ class Peripheral(BaseObject): continue field_name = field_info['field_name'] + logger.debug("%s, info= %s", field_name, str(field_info)) try : - field = Field(field_name, _slave_type) + #PD print(f'field_name={field_name} _slave_type={_slave_type}') + #field = Field(field_name, _slave_type) + field = Field(field_name, field_info) except ARGSNameError: logger.error("Invalid name '{}' for field in {}.peripheral.yaml".format(field_name, self.lib)) sys.exit() @@ -299,8 +304,8 @@ class Peripheral(BaseObject): self.add_ram(slave_nr, slave_name, field, number_of_slaves) else: self.add_fifo(slave_nr, slave_name, field, number_of_slaves) - else: # slave_type is REG or REG_IP - logger.debug('adding register %s', slave_name) + else: # slave_type is REG or REG_IP + logger.debug('adding register %s\n', slave_name) self.add_register(slave_nr, slave_name, fields, number_of_slaves, slave_info['slave_type'].upper() == 'REG_IP', slave_info.get('slave_protocol', None),slave_info.get('slave_span', None)) if 'slave_description' in slave_info.keys(): self.slaves[-1].update_args({'slave_description': slave_info['slave_description']}) @@ -322,22 +327,22 @@ class Peripheral(BaseObject): 1) trying to parse values of known parameter into the value 2) eval the value, known imported function are also evaluated """ - - _val = str(val) # first replace all knowns parameter names with its assigned value for key1, val1 in self._parameters.items(): - logger.debug("key1={}, val1={}".format(key1, val1)) + #logger.debug("key={}, val={}".format(key1, val1)) # if val is a dict, in vhdl it's a struct if isinstance(val1, dict): for key2, val2 in val1.items(): key = "{}.{}".format(key1, key2) - #logger.debug("replace %s with %s", key, str(val2)) - _val = _val.replace(key, str(val2)) + if key in _val: + logger.debug("replace %s with %s", key, str(val2)) + _val = _val.replace(key, str(val2)) else: - #logger.debug("replace %s with %s", key1, str(val1)) - _val = _val.replace(key1, str(val1)) - #logger.debug("_val={}".format(_val)) + if key1 in _val: + logger.debug("replace %s with %s", key1, str(val1)) + _val = _val.replace(key1, str(val1)) + # logger.debug("_val={}".format(_val)) if val is None: logger.error("key set to invalid value {} in {}.peripheral.yaml".format(_val, self.lib)) sys.exit() @@ -371,11 +376,11 @@ class Peripheral(BaseObject): """ add register to peripheral """ - register = self.init_slave('Register', name, fields) + register = deepcopy(self.init_slave('Register', name, fields)) register.number_of_slaves(number_of_slaves) register.isIP = isIP register.slave_span = slave_span - if protocol is not None and protocol.upper() in ['LITE','FULL']: + if protocol is not None and protocol.upper() in ['LITE', 'FULL']: register.protocol = protocol.upper() # else : # logger.error("{}.peripheral.yaml: Invalid user setting {} for slave {}".format(self.lib, protocol, name)) @@ -388,7 +393,7 @@ class Peripheral(BaseObject): """ logger.debug("name is %s", name) - ram = self.init_slave('RAM', name, settings) + ram = deepcopy(self.init_slave('RAM', name, settings)) ram.number_of_slaves(number_of_slaves) self.rams['slave_{}'.format(slave_nr)] = ram self.slaves.append(ram) @@ -397,7 +402,7 @@ class Peripheral(BaseObject): """ add FIFO to peripheral """ # fifo = FIFO(name, field) - fifo = self.init_slave('FIFO', name, field) + fifo = deepcopy(self.init_slave('FIFO', name, field)) fifo.number_of_slaves(number_of_slaves) self.fifos['slave_{}'.format(slave_nr)] = fifo self.slaves.append(fifo) @@ -420,13 +425,13 @@ class Peripheral(BaseObject): # ['number_of_fields', 'width', 'bit_offset', 'access_mode', 'side_effect', # 'address_offset', 'reset_value', 'software_value', 'radix', 'field_description'] - for field in fields: #.values(): - logger.debug("eval field %s", field.name()) + for field in fields: # .values(): + logger.debug("eval_fields= %s", field.name()) if [(field.name() == _field.name() and field.group_name() == _field.group_name())for _field in fields].count(True) > 1: logger.error("Field name '{}' group_name '{}' is not unique within slave field list in {}.peripheral.yaml".format(field.name(), field.group_name(), self.lib)) sys.exit() - if field.group_name() != "None": - field.name(field.group_name() + '_' +field.name()) + if field.group_name() is not None: + field.name(field.group_name() + '_' + field.name()) field.width(val=self._eval(field.width(), int)) field.bit_offset(val=self._eval(field.bit_offset(), int)) field.access_mode(val=self._eval(field.access_mode())) @@ -437,7 +442,6 @@ class Peripheral(BaseObject): field.software_value(val=self._eval(field.software_value(), int)) field.radix(val=self._eval(field.radix())) - def eval_fifo(self): """ Evaluate the paramters and the nof_inst of the peripheral """ @@ -452,11 +456,10 @@ class Peripheral(BaseObject): fifo = slave fifo.number_of_slaves(val=self._eval(fifo.number_of_slaves())) logger.debug(" -FIFO depth str: %s", fifo.number_of_fields()) - fifo.address_length(val = ceil_pow2(self._eval(fifo.number_of_fields()))) + fifo.address_length(val=ceil_pow2(self._eval(fifo.number_of_fields()))) logger.debug(" -FIFO depth eval: %s", fifo.address_length()) logger.debug(" -FIFO width str: %s", fifo.width()) - def eval_ram(self): """Evaluate the parameters and the nof_inst of the peripheral in order to define the real address_length and width of the RAM. @@ -474,7 +477,7 @@ class Peripheral(BaseObject): self.eval_fields([ram]) if ram.width() < DEFAULT_WIDTH: ram.width(DEFAULT_WIDTH) - if ram.user_width() <DEFAULT_WIDTH: + if ram.user_width() < DEFAULT_WIDTH: ram.user_width(DEFAULT_WIDTH) ram.number_of_slaves(val=self._eval(ram.number_of_slaves())) @@ -508,7 +511,6 @@ class Peripheral(BaseObject): logger.debug(" %s depth: %d", ram.name(), ram.address_length()) logger.debug(" %s width: %d", ram.name(), ram.user_width()) - def eval_register(self): """Evaluate the register address_length based on the evaluation of the fields, nof registers and the nof_inst.""" @@ -528,6 +530,7 @@ class Peripheral(BaseObject): register = slave else : continue + logger.debug("evaluate %s", register.name()) # register.number_of_slaves(val=self._eval(register.number_of_slaves())) # Evaluate the fields and see if there are field that have to be repeated. @@ -537,18 +540,23 @@ class Peripheral(BaseObject): for i in range(field.number_of_fields()): _field = deepcopy(field) _field.name("{}{}".format(field.name(), i)) - if _field.bit_offset() != UNASSIGNED_BIT and _field.group_name() != "None" and i > 0:# if fields repeated within the same group and bit offset is set, reset to 0 from the 2nd repeated field - _field.bit_offset(field.bit_offset()+i*_field.width()) # duplicate within the field group - if _field.address_offset() != UNASSIGNED_ADDRESS and i > 0: # field is manually assigned - if _field.group_name() == 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) # duplicate across addresses + + if i > 0: + if _field.bit_offset() != UNASSIGNED_BIT and _field.group_name() is not None: # if fields repeated within the same group and bit offset is set, reset to 0 from the 2nd repeated field + # TODO-PD check size, max = 32 bit + _field.bit_offset(field.bit_offset() + i * _field.width()) # duplicate within the field group + + 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 + fields_eval.append(_field) elif field.number_of_fields() >= 32: register.rams.append(field) else : fields_eval.append(field) - self.eval_fields(fields_eval) self.eval_fields(register.rams) register.number_of_slaves(val=self._eval(register.number_of_slaves())) @@ -561,11 +569,11 @@ class Peripheral(BaseObject): # set base addresses for reg fields implemented as RAM 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 = 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 field.base_address(base_addr) - base_addr = base_addr + ceil_pow2(field.number_of_fields()*WIDTH_IN_BYTES)*register.number_of_slaves() # new base address + base_addr = base_addr + ceil_pow2(field.number_of_fields() * WIDTH_IN_BYTES) * register.number_of_slaves() # new base address - #### Assigned Address and bits to register fields + # ### Assigned Address and bits to register fields # 1st pass for manually set address fields occupied_addresses = [] for field in fields_eval: @@ -580,36 +588,40 @@ class Peripheral(BaseObject): 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() >= 32: - logger.warning("Field %s number_of_fields >= 32, a dual port RAM will be instantiated within the Register module") - continue; + 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() == "None": - if field.group_name() != "None": + if field.group_name() != last_group or field.group_name() is None: + if field.group_name() is not None: field_group = [_field for _field in fields_eval if _field.group_name() == field.group_name()] - occupied_bits = [bit for _field in field_group for bit in range(_field.bit_offset(), _field.bit_offset()+_field.width()) if _field.bit_offset() != UNASSIGNED_BIT] + occupied_bits = [bit for _field in field_group for bit in range(_field.bit_offset(), _field.bit_offset()+_field.width()) if _field.bit_offset() != UNASSIGNED_BIT] else : 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 - 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 {} is outside of data width or contains bit collisions".format(self.lib, field.name() if field.group_name() == "None" else "group " + field.group_name())) + + if len(set(occupied_bits)) < len(occupied_bits) or any([bit > (DATA_WIDTH-1) or bit < 0 for bit in occupied_bits]): + logger.error('%s.peripheral.yaml: Manually assigned bits for field %s is outside of data width or contains bit collisions', + self.lib, field.name() if field.group_name() is None else "group " + field.group_name()) logger.error("{}".format(str(occupied_bits))) sys.exit() # track beginning of group address - if field.group_name() != "None": - if field.group_name() == last_group: # for all subsequent fields in field group + if field.group_name() is not None: + if field.group_name() == last_group: # for all subsequent fields in field group field.address_offset(group_address) - else : # new group, do for first field in group, checks addresses within group and determines group_address or sets as unassigned + else: # new group, do for first field in group, checks addresses within group and determines group_address or sets as unassigned last_group = field.group_name() # get unique list of addresses for fields with matching group name and address not equal to unassigned address group_addresses = list(set([_field.address_offset() for _field in field_group if _field.address_offset() != UNASSIGNED_ADDRESS])) if len(group_addresses) == 1: group_address = group_addresses[0] elif len(group_addresses) > 1: - logger.error("{}.peripheral.yaml: Manually set addresses within field group \"{}\"are conflicting, please change in configuration file".format(self.lib, field.group_name())) + logger.error('%s.peripheral.yaml: Manually set addresses within field group %s %s are conflicting, please change in configuration file', + self.lib, field.group_name(), type(field.group_name())) sys.exit() - else: # address not assigned + else: # address not assigned group_address = UNASSIGNED_ADDRESS if field.address_offset() == UNASSIGNED_ADDRESS: @@ -618,10 +630,11 @@ class Peripheral(BaseObject): if field.bit_offset() == UNASSIGNED_BIT: 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 - logger.error("{}.peripheral.yaml: No suitable gap available for automatic bit offset assignment of field{}".format(self.lib, field.name())) + 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 + logger.error('%s.peripheral.yaml: No suitable gap available for automatic bit offset assignment of field%s', + self.lib, field.name()) logger.error("Check peripheral.yaml file. Field group may be overstuffed or manual bit assignment may have precluded space for other fields") break field.bit_offset(free_bit) @@ -744,24 +757,25 @@ class PeripheralLibrary(object): # all peripheral files have the same double file extension ".peripheral.yaml" self.file_extension = file_extension self.library = collections.OrderedDict() - self.nof_peripherals = 0 # number of peripherals + self.nof_peripherals = 0 # number of peripherals - exclude = set([path_string(os.path.expandvars('$HDL_BUILD_DIR')), path_string(os.path.join(os.path.expandvars('$RADIOHDL'),'tools'))]) + exclude = set([path_string(os.path.expandvars('$HDL_BUILD_DIR'))]) if root_dir is not None: - for root, dirs, files in os.walk(self.root_dir, topdown=True):#topdown=False): + for root, dirs, files in os.walk(self.root_dir, topdown=True): # topdown=False): dirs[:] = [d for d in dirs if path_string(root+d) not in exclude and '.svn' not in d] for name in files: - if self.file_extension in name and name[0]!='.': + if self.file_extension in name and name[0] != '.': try : - library_config = yaml.load(open(os.path.join(root,name), 'r')) + library_config = yaml.load(open(os.path.join(root, name), 'r')) except : logger.error('Failed parsing YAML in {}. Check file for YAML syntax errors'.format(name)) print('\nERROR:\n') print(sys.exc_info()[1]) sys.exit() if not isinstance(library_config, dict): - logger.warning('File {} is not readable as a dictionary, it will not be' - ' included in the RadioHDL library of ARGS peripherals'.format(name)) + logger.warning('File %s is not readable as a dictionary, it will not be' + ' included in the RadioHDL library of ARGS peripherals', + name) continue else: try: @@ -769,18 +783,20 @@ class PeripheralLibrary(object): library_config['peripherals'] library_config['hdl_library_name'] except KeyError: - logger.warning('File {0} will not be included in the RadioHDL library. ' - '{0} is missing schema_type and/or peripherals and/or hdl_library_name key'.format(name)) + logger.warning('File %s will not be included in the RadioHDL library.' + '%s is missing schema_type and/or peripherals and/or hdl_library_name key', + name, name) continue - lib_name = library_config['hdl_library_name']#name.replace(file_extension, '') + lib_name = library_config['hdl_library_name'] # name.replace(file_extension, '') if lib_name != name.split('.')[0]: - logger.error("File {} has mismatching filename \'{}\' and hdl_library_name \'{}\'".format(os.path.join(root,name), name.split('.')[0], lib_name)) + logger.error("File %s has mismatching filename '%s' and hdl_library_name '%s'", + os.path.join(root, name), name.split('.')[0], lib_name) sys.exit() - if self.library.get(lib_name, None) is None: # check peripheral library name is unique - self.library.update({lib_name: {'file_path':root,'file_path_name':os.path.join(root,name), 'peripherals':collections.OrderedDict(), 'description':library_config.get('hdl_library_description', "") }}) + if self.library.get(lib_name, None) is None: # check peripheral library name is unique + self.library.update({lib_name: {'file_path': root, 'file_path_name': os.path.join(root, name), 'peripherals': collections.OrderedDict(), 'description': library_config.get('hdl_library_description', "")}}) else : logger.error("More than one instance of args peripheral library '{}' found under {}".format(lib_name, root_dir)) - logger.error("\nConflicting files:\n\t{}\n\t{}".format(self.library[lib_name]['file_path_name'], os.path.join(root,name))) + logger.error("\nConflicting files:\n\t%s\n\t%s", self.library[lib_name]['file_path_name'], os.path.join(root, name)) sys.exit() # list of peripheral configurations that are read from the available peripheral files @@ -797,7 +813,7 @@ class PeripheralLibrary(object): library_config = yaml.load(open(fpn, 'r')) for peripheral_config in library_config['peripherals']: lib = library_config['hdl_library_name'] - peripheral_config['lib'] = library_config['hdl_library_name'] #TODO: get rid of need for this + peripheral_config['lib'] = library_config['hdl_library_name'] # TODO: get rid of need for this try : peripheral = deepcopy(Peripheral(peripheral_config)) except ARGSNameError: diff --git a/py_args_lib/peripheral_lib/__init__.py b/py_args_lib/peripheral_lib/__init__.py index 224519d0579a47dc454a50c117e369f617724fba..2fdf1d26b4880b012003914ace7d172768d69a75 100644 --- a/py_args_lib/peripheral_lib/__init__.py +++ b/py_args_lib/peripheral_lib/__init__.py @@ -7,6 +7,7 @@ cwd = os.path.dirname(os.path.realpath(__file__)) sys.path.append(cwd) from constants import * +from common_func import * from base_object import BaseObject from field import Field from register import Register diff --git a/py_args_lib/peripheral_lib/constants.py b/py_args_lib/peripheral_lib/constants.py index 7596b04d8555b8a2fa3912d3689a1e01506717a9..0476b9f5958542b5ef4498e4658f41e719a9b324 100644 --- a/py_args_lib/peripheral_lib/constants.py +++ b/py_args_lib/peripheral_lib/constants.py @@ -4,7 +4,10 @@ this constants can be used in the yaml files """ -from common import c_word_w, c_byte_w +c_byte_w = 8 +c_word_w = 32 +c_nof_complex = 2 + VALID_SCHEMA_NAME = ['args'] VALID_SCHEMA_TYPES = ['system', 'peripheral'] diff --git a/py_args_lib/peripheral_lib/field.py b/py_args_lib/peripheral_lib/field.py index 0e74088bf0f2ce75e78e099b73f50e033f132bed..5c9264bf38bf80dd3985e9181e0cc39edafe63a3 100644 --- a/py_args_lib/peripheral_lib/field.py +++ b/py_args_lib/peripheral_lib/field.py @@ -27,7 +27,7 @@ import logging import sys from constants import * -from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2 +from common_func import ceil_pow2, ceil_log2 from base_object import BaseObject from numpy import mod @@ -72,7 +72,7 @@ class Field(BaseObject): if settings is not None: # print(name) - # print(settings) + # logger.debug(f"settings=%s", str(settings)) for key, val in settings.items(): if key in self._valid_dict: # self._valid_keys: @@ -103,6 +103,8 @@ class Field(BaseObject): if val is not None: self.set_kv('group_name', val) return + if self.get_kv('group_name') is None: + return None return self._as_str('group_name') def width(self, val=None): @@ -239,7 +241,8 @@ class Field(BaseObject): if check_alignment: if mod(_val, WIDTH_IN_BYTES): - logger.error("Address offset for field {} is not word aligned".format(self.name())) + logger.error("Address offset for field %s is not word aligned (%s=%s)", + self.name(), yaml_key, str(_val)) sys.exit() if _min is not None: diff --git a/py_args_lib/peripheral_lib/fifo.py b/py_args_lib/peripheral_lib/fifo.py index b53c6a27f8c8b99f555207130f38815edb160a96..0cabf804fe824a3c10dc10e0417a2da89aec9d8b 100644 --- a/py_args_lib/peripheral_lib/fifo.py +++ b/py_args_lib/peripheral_lib/fifo.py @@ -26,8 +26,8 @@ from math import ceil import logging -from constants import * -from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2 +from constants import c_word_w, c_nof_complex +from common_func import ceil_pow2, ceil_log2 from base_object import BaseObject from field import Field from register import Register diff --git a/py_args_lib/peripheral_lib/ram.py b/py_args_lib/peripheral_lib/ram.py index 7e1772de18c9cf6e6b27ce52ff43ff3f3b2f809b..abeaeb0d262d452b80f2145073f85537a170c975 100644 --- a/py_args_lib/peripheral_lib/ram.py +++ b/py_args_lib/peripheral_lib/ram.py @@ -27,7 +27,7 @@ from math import ceil import logging from constants import * -from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2 +from common_func import ceil_pow2, ceil_log2 from base_object import BaseObject from field import Field diff --git a/py_args_lib/peripheral_lib/register.py b/py_args_lib/peripheral_lib/register.py index c04678e12e511b68e1c2aa53a8c8a371e2728392..9f18391c0b1cb177f4f69823907dfae70b5fdb93 100644 --- a/py_args_lib/peripheral_lib/register.py +++ b/py_args_lib/peripheral_lib/register.py @@ -28,12 +28,13 @@ from math import ceil from numpy import mod import logging from constants import * -from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2 +from common_func import ceil_pow2, ceil_log2 from base_object import BaseObject from field import Field logger = logging.getLogger('main.periph.register') + class Register(BaseObject): """ A register consists of Fields """ @@ -53,7 +54,7 @@ class Register(BaseObject): 'dual_clock' : False, 'slave_description': DEFAULT_DESCRIPTION}) - #self.update_address_length() + # self.update_address_length() self.isIP = False self.slave_span = None @@ -73,7 +74,7 @@ class Register(BaseObject): if field.success: # self.fields[name] = field self.fields.append(field) - #self.update_address_length() + # self.update_address_length() return True return False @@ -96,14 +97,13 @@ 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, WIDTH_IN_BYTES): # 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) return self._as_int('address_length', default=1) - - def base_address(self, val = None): + 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=1) \ No newline at end of file diff --git a/py_args_lib/unit_logger.py b/py_args_lib/unit_logger.py index cc0d88d5dd163b53ec68a52887ef14cc37b31f0c..1aacb87ddf474258fa77bfad045f75bdced2dd49 100644 --- a/py_args_lib/unit_logger.py +++ b/py_args_lib/unit_logger.py @@ -5,6 +5,8 @@ import time # first start main logging before including checkhardware_lib # backup log files + + class UnitLogger(object): def __init__(self, log_path, file_name=None): self.log_levels = {'DEBUG' : logging.DEBUG,