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,