diff --git a/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml b/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml
index 0d668dcae46c907d2581e0db7ddcb0b94b0e0ca2..e469236bd5b6548e83bddd54c8540430b77f8933 100644
--- a/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml
+++ b/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml
@@ -9,30 +9,30 @@ bf_unit:
     g_nof_signal_paths:            64  
     g_nof_subbands:                24  
     g_nof_input_streams:           16
-    g_nof_signal_paths_per_stream: 4
+    g_nof_signal_paths_per_stream: 4   # PD: 64/16 = 4, g_nof_signal_paths/g_nof_input_streams 
 
   ram_bf_weights:
     width: g_weights_w * cm.c_nof_complex
     depth: g_nof_weights * g_nof_signal_paths  # 256*64 = 16384
     mode : RW   
     descr: >
-      Contains the weights. 
-      The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part.
+      "Contains the weights. 
+      The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
     
   ram_ss_ss_wide:
     width: cm.ceil_log2(g_nof_subbands * g_nof_signal_paths_per_stream)
     depth: g_nof_weights * g_nof_input_streams * g_nof_signal_paths_per_stream  # 256*16*4, nof_weights*nof_input_streams*nof_signal_paths_per_stream = 256*16*4=16384
     mode : RW   
     descr: >
-      Contains the addresses to select from the stored subbands.
+      "Contains the addresses to select from the stored subbands."
   
   ram_st_sst_bf: 
     width: 56
     depth: g_nof_weights * cm.c_nof_complex  # 256*2 = 512
     mode : RO   
     descr: >
-      Contains the weights.
-      The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part.
+      "Contains the weights.
+      The real and the imaginary parts are concatenated: W_real in Lower part. W_imag in Higher part."
   
   reg_st_sst_bf:
     Treshold:
@@ -41,10 +41,10 @@ bf_unit:
       offset : 0x0
       default: 0
       descr  : > 
-        When the treshold register is set to 0 the statistics will be auto-correlations.
+        "When the treshold register is set to 0 the statistics will be auto-correlations.
         In case the treshold register is set to a non-zero value, it allows to create a sample & hold function
         for the a-input of the multiplier. 
-        The a-input of the multiplier is updated every treshold clockcycle. Thereby cross statistics can be created.
+        The a-input of the multiplier is updated every treshold clockcycle. Thereby cross statistics can be created."
   
   peripheral_description: |
-    This is the beamformer unit
+    "This is the beamformer unit"
diff --git a/tools/oneclick/prestudy/YAML/fringe_stop/peripheral.yaml b/tools/oneclick/prestudy/YAML/fringe_stop/peripheral.yaml
index 00b208bdf49336da9204a058d0429adbc652d815..a7ecc64638ac9745f584fc6bb593243f9a009033 100644
--- a/tools/oneclick/prestudy/YAML/fringe_stop/peripheral.yaml
+++ b/tools/oneclick/prestudy/YAML/fringe_stop/peripheral.yaml
@@ -8,17 +8,17 @@ fringe_stop:
     depth: 256
     mode : RW
     descr: >
-      Contains the step size for all nof_channels channels.
+      "Contains the step size for all nof_channels channels."
 
   ram_fringe_stop_offset:
     width: 10
     depth: 256
     mode : RW
     descr: >
-      Contains the offset for all nof_channels channels.
+      "Contains the offset for all nof_channels channels."
 
   peripheral_description: |
-    The fringe stopping peripheral is based on piecewise linear coefficients. The coefficients are indicated as offset and step.
+    "The fringe stopping peripheral is based on piecewise linear coefficients. The coefficients are indicated as offset and step.
     The offset and step are used to calculate an index that is used to select a certain phase from a look-up table. The look-up
     table contains a series of complex values that are based on a sinewave. The length of the look-up table is determined by the
     width of the offset RAM (offset_w). If offset_w = 10 then the length of the look-up table is 2^offset_w=1024. In that case
@@ -46,12 +46,14 @@ fringe_stop:
     the page that is NOT accessible for the software and vice-versa. This means that the values that are written to the RAMs
     will only be actually used in the following sync-interval:
     
-             _             T0                _              T1               _              T2
-     sync __| |_____________________________| |_____________________________| |________________________
-            |     VHDL uses data T0         |     VHDL uses data T1         |     VHDL uses data T2
-            |     Software writes data T1   |     Software writes data T2   |     Software writes data T3
-            |                               |                               |
-        page_swap                       page_swap                       page_swap
+    
+    A|         _             T0              _             T1              _            T2 
+    A| sync __| |___________________________| |___________________________| |________________________
+    A|        |    VHDL uses data T0        |    VHDL uses data T1        |    VHDL uses data T2 
+    A|        |    Software writes data T1  |    Software writes data T2  |    Software writes data T3
+    A|        |                             |                             | 
+    A|    page_swap                     page_swap                     page_swap 
+    
     
     The software should be sure to write the next set of data before the sync_interval expires. Keeping track of the
     synchronization with the sync-pulse can be done, using one of the BSN Monitors in the system. In the Apertif system
@@ -63,24 +65,29 @@ fringe_stop:
     This RAM contains the offset values for all channels, ranging from Channel 0 to Channel Max-1. The width of the RAM is
     defined by the offset_w.
     
-    RAM_ADDRESS    RAM_CONTENT
-       0x0       Offset_Channel_0
-       0x1       Offset_Channel_1
-       0x2       Offset_Channel_2
-       0x3       Offset_Channel_3
-       ..              ..
-       ..        Offset_Channel_Max-1
+    +-----------------------------------------+
+    | RAM_address     | RAM_content           | 
+    |-----------------------------------------|
+    |   0x0           | Offset_Channel_0      |
+    |   0x1           | Offset_Channel_1      |
+    |   0x2           | Offset_Channel_2      |
+    |   0x3           | Offset_Channel_3      |
+    |   ..            |       ..              |
+    |   ..            | Offset_Channel_Max-1  |
+    +-----------------------------------------+
     
     RAM_FRINGE_STOP_STEP
     This RAM contains the step size values for all channels, ranging from Channel 0 to Channel Max-1. The width of the RAM is
     specified by the step_w.
     
-    RAM_ADDRESS    RAM_CONTENT
-       0x0        Step_Channel_0
-       0x1        Step_Channel_1
-       0x2        Step_Channel_2
-       0x3        Step_Channel_3
-       ..              ..
-       ..         Step_Channel_Max-1
-
-
+    +-----------------------------------------+
+    | RAM_address     | RAM_content           | 
+    |-----------------------------------------|
+    |   0x0           | Step_Channel_0        |
+    |   0x1           | Step_Channel_1        |
+    |   0x2           | Step_Channel_2        |
+    |   0x3           | Step_Channel_3        |
+    |   ..            |       ..              |
+    |   ..            | Step_Channel_Max-1    |
+    +-----------------------------------------+"
+    
diff --git a/tools/oneclick/prestudy/YAML/mm_menu.py b/tools/oneclick/prestudy/YAML/mm_menu.py
new file mode 100755
index 0000000000000000000000000000000000000000..58082a442519531704824e5ca76473ab7f8a30f9
--- /dev/null
+++ b/tools/oneclick/prestudy/YAML/mm_menu.py
@@ -0,0 +1,143 @@
+#! /usr/bin/env python
+
+###############################################################################
+#
+# Copyright (C) 2016
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author  Date
+#   PD    mrt 2017
+#
+###############################################################################
+
+
+import os
+import sys
+import argparse
+import yaml
+import traceback
+from subprocess import CalledProcessError
+from py_mm_lib import *
+
+
+def main():
+    """ main function """
+    while True:
+        menu_choice = show_menu().lower()
+        if menu_choice == 'q':
+            break
+        elif menu_choice == '1':
+            filename = get_filename()
+            show_overview(filename)
+        elif menu_choice == '2':
+            filename = get_filename()
+            generate_system_rom(filename)
+        elif menu_choice == '3':
+            filename = get_filename()
+            generate_report(filename)
+        else:
+            pass
+
+
+def show_menu():
+    """ show main menu """
+    menu = []
+    menu.append("OneClick menu")
+    menu.append("------------------------")
+    menu.append("1  show config file overview")
+    menu.append("2  generate system-rom")
+    menu.append("3  make documentation")
+    menu.append("Q  quit")
+    menu.append("select menu nr: ")
+    nr = raw_input('\n'.join(menu))
+    return nr
+
+
+def get_filename():
+    return raw_input("wich file: ")
+
+
+def generate_report(filename):
+    try:
+        config = yaml.load(open(filename, "r"))
+        name = config.keys()[0]
+        settings = config[name]
+        documentation = Documentation(name)
+        if settings['type'] == 'system':
+            system = System(filename)
+            documentation.add(name, system)
+        elif settings['type'] == 'peripheral':
+            peripheral = Peripheral(filename)
+            peripheral.eval_peripheral()
+            documentation.add(name, peripheral)
+        documentation.generate_pdf()
+    except IOError:
+        logger.error("config file '{}' does not exist".format(filename))
+    except CalledProcessError:
+        pass
+
+
+def show_overview(filename):
+    try:
+        config = yaml.load(open(filename, "r"))
+        name = config.keys()[0]
+        settings = config[name]
+        if settings['type'] == 'system':
+            system = System(filename)
+            system.show_overview()
+        elif settings['type'] == 'peripheral':
+            peripheral = Peripheral(filename)
+            peripheral.eval_peripheral()
+            peripheral.show_overview()
+    except IOError:
+        logger.error("config file '{}' does not exist".format(filename))
+
+def generate_system_rom(filename):
+    """ generate system_rom reg and txt file """
+    system_rom = SystemRom()
+    system_rom.read_system(filename)
+    system_rom.generate_reg()
+    system_rom.generate_txt()
+
+
+if __name__ == "__main__":
+    # setup first log system before importing other user libraries
+    PROGRAM_NAME = sys.argv[0].split('/')[-1].split('.')[0]
+    mylogger.set_logfile_name(name=PROGRAM_NAME)
+    mylogger.set_stdout_log_level('DEBUG')
+    mylogger.set_file_log_level('DEBUG')
+
+    # Parse command line arguments
+    # parser = argparse.ArgumentParser(description='System and peripheral config command line parser arguments')
+    # parser.add_argument('-p','--peripheral', nargs='*', default=None, help='peripheral names separated by commas')
+    # parser.add_argument('-s','--system', nargs='*', default=None, help='system names separated by commas')
+    # parser.add_argument('-r','--run', action='store_true', default=False, help='run command')
+    # parser.add_argument('-v','--verbosity', type=int, default=0, help='verbosity >= 0 for more info')
+    # args = parser.parse_args()
+    # logger.debug("Used arguments: {}".format(args))
+
+    try:
+        main()
+    except:
+        logger.error('Program fault, reporting and cleanup')
+        logger.error('Caught %s', str(sys.exc_info()[0]))
+        logger.error(str(sys.exc_info()[1]))
+        logger.error('TRACEBACK:\n%s', traceback.format_exc())
+        logger.error('Aborting NOW')
+        sys.exit("ERROR")
+    sys.exit("Normal Exit")
+
diff --git a/tools/oneclick/prestudy/YAML/mms_diag_block_gen/peripheral.yaml b/tools/oneclick/prestudy/YAML/mms_diag_block_gen/peripheral.yaml
index ebfc568fd7ae0bf8b4f6164223987c27ee454865..92d3fa6ce44366f8ae7ab3d069c073e10cba4b0c 100644
--- a/tools/oneclick/prestudy/YAML/mms_diag_block_gen/peripheral.yaml
+++ b/tools/oneclick/prestudy/YAML/mms_diag_block_gen/peripheral.yaml
@@ -15,7 +15,7 @@ mms_diag_block_gen:
       offset   : 0x0
       default  : 0
       descr    : >
-        Bit 0: enable the block generator Bit 1: enable the blok generator on PPS
+        "Bit 0: enable the block generator Bit 1: enable the blok generator on PPS"
 
     Samples_per_packet:
       width  : 16
@@ -23,7 +23,7 @@ mms_diag_block_gen:
       offset : 0x1
       default: 256
       descr  : >
-        This register specifies the number samples in a packet
+        "This register specifies the number samples in a packet"
 
     Blocks_per_sync:
       width  : 16
@@ -31,7 +31,7 @@ mms_diag_block_gen:
       offset : 0x2
       default: 781250
       descr  : >
-        This register specifies the number of packets in a sync period
+        "This register specifies the number of packets in a sync period"
 
     Gapsize:
       width  : 16
@@ -39,7 +39,7 @@ mms_diag_block_gen:
       offset : 0x3
       default: 80
       descr  : >
-        This register specifies the gap in number of clock cycles between two consecutive packets
+        "This register specifies the gap in number of clock cycles between two consecutive packets"
 
     Mem_low_address:
       width  : 8
@@ -47,7 +47,7 @@ mms_diag_block_gen:
       offset : 0x4
       default: 0
       descr  : >
-        This register specifies the starting address for reading from the waveform memory
+        "This register specifies the starting address for reading from the waveform memory"
 
     Mem_high_address:
       width  : 8
@@ -55,14 +55,14 @@ mms_diag_block_gen:
       offset : 0x5
       default: 0
       descr  : >
-        This register specifies the last address to be read when from the waveform memory
+        "This register specifies the last address to be read when from the waveform memory"
     BSN_init_low:
       width  : 32
       mode   : RW
       offset : 0x6
       default: 0
       descr  : >
-        This register specifies the lower(LSB) 32 bits [31:0] of the initialization BSN
+        "This register specifies the lower(LSB) 32 bits [31:0] of the initialization BSN"
 
     BSN_init_high:
       width  : 32
@@ -70,15 +70,14 @@ mms_diag_block_gen:
       offset : 0x7
       default: 0
       descr  : >
-        This register specifies the higher(MSB) 32 bits [63:32] of the initialization BSN
-
+        "This register specifies the higher(MSB) 32 bits [63:32] of the initialization BSN"
   ram_diag_bg:
     width: g_buf_dat_w
     depth: 2**g_buf_addr_w * g_nof_streams
     mode : RW
     descr: >
-      Contains the Waveform data for the data-streams to be send
+      "Contains the Waveform data for the data-streams to be send"
 
   peripheral_description: |
-    Block generator
+    "Block generator"
 
diff --git a/tools/oneclick/prestudy/YAML/mms_diag_data_buffer/peripheral.yaml b/tools/oneclick/prestudy/YAML/mms_diag_data_buffer/peripheral.yaml
index cbf4c95e1b51f762e6512d1d8efdab015824a1e2..babe7edc18edf8639cc07e23805c1697c9ce7ef0 100644
--- a/tools/oneclick/prestudy/YAML/mms_diag_data_buffer/peripheral.yaml
+++ b/tools/oneclick/prestudy/YAML/mms_diag_data_buffer/peripheral.yaml
@@ -15,8 +15,8 @@ mms_diag_data_buffer:
       offset : 0x0
       default: 0
       descr  : >
-        Sync_cnt contains the nof times the buffer (ST) has received a sync pulse since the last MM read
-        (cleared when the last data word from the buffer is read)
+        "Sync_cnt contains the nof times the buffer (ST) has received a sync pulse since the last MM read
+        (cleared when the last data word from the buffer is read)"
 
     Word_cnt:
       width  : 32
@@ -24,7 +24,7 @@ mms_diag_data_buffer:
       offset : 0x1
       default: 0
       descr  : >
-        Word_cnt indicates the number of word currently (ST) written in the buffer. Cleared on (ST) re-write of buffer.
+        "Word_cnt indicates the number of word currently (ST) written in the buffer. Cleared on (ST) re-write of buffer."
 
     Valid_cnt_arm_ena:
       width  : 32
@@ -32,9 +32,9 @@ mms_diag_data_buffer:
       offset : 0x2
       default: 0
       descr  : >
-        Valid_cnt contains the number of valid cycles since the last sync pulse. Cleared on every sync pulse.
+        "Valid_cnt contains the number of valid cycles since the last sync pulse. Cleared on every sync pulse.
         Arm_enable: Write to this register to arm the system.
-        After the system is armed the next syn pulse will trigger the acquisition of data.
+        After the system is armed the next syn pulse will trigger the acquisition of data."
 
     Reg_sync_delay:
       width  : 32
@@ -42,8 +42,8 @@ mms_diag_data_buffer:
       offset : 0x3
       default: 0
       descr  : >
-        Reg_sync_delay contains the number of valid cycles to delay/wait after an armed-syncpulse,
-        before the data is written to the databuffer.
+        "Reg_sync_delay contains the number of valid cycles to delay/wait after an armed-syncpulse,
+        before the data is written to the databuffer."
 
     Version:
       width  : 32
@@ -51,17 +51,26 @@ mms_diag_data_buffer:
       offset : 0x7
       default: 0
       descr  : >
-        Version contains the version number of the databuffer peripheral.
+        "Version contains the version number of the databuffer peripheral."
 
   ram_diag_data_buffer:
     width: g_data_w
     depth: g_nof_streams * 2**cm.ceil_log2(g_buf_nof_data)
     mode : RW
     descr: >
-      Contains the data that is being captured.
+      "Contains the data that is being captured."
+
+  reg_rx_sequece:
+    Name??:
+      width  : 32
+      mode   : RW
+      offset : 0x0
+      default: 0
+      descr  : >
+        "Name?? description."
 
   peripheral_description: |
-    Peripheral diag_data_buffer
+    "Peripheral diag_data_buffer
     
     Memory map RAM_DIAG_DATA_BUFFER
     
@@ -71,46 +80,39 @@ mms_diag_data_buffer:
     The diag_data_buffer can store multiple streams in parallel. For example
     1024 data words for 16 streams the memory map becomes:      16
     
+    
     streamNr = 0:
+    +------------------------------------------------------------+
+    |   byte 3   |   byte 2   |   byte 1   |   byte 0   |   wi   |
+    |------------------------------------------------------------|
+    |                   data_0[31:0]                    |  0     |
+    |                   data_1[31:0]                    |  1     |
+    |                   ...                             |  ..    |
+    |                data_1023[31:0]                    |  1023  |
+    +------------------------------------------------------------+
+    
+    
+    streamNr = 1:                                                                    
+    +------------------------------------------------------------+
+    |   byte 3   |   byte 2   |   byte 1   |   byte 0   |   wi   |
+    |------------------------------------------------------------|
+    |                   data_0[31:0]                    |  1024  |
+    |                   data_1[31:0]                    |  1025  |
+    |                   ...                             |  ..    |
+    |                data_1023[31:0]                    |  2047  |
+    +------------------------------------------------------------+
+    
+    
+    streamNr = 15:                                                                   
+    +------------------------------------------------------------+
+    |   byte 3   |   byte 2   |   byte 1   |   byte 0   |   wi   |
+    |------------------------------------------------------------|
+    |                   data_0[31:0]                    |  15360 |
+    |                   data_1[31:0]                    |  15361 |
+    |                   ...                             |  ..    |
+    |                data_1023[31:0]                    |  16383 |
+    +------------------------------------------------------------+
     
-     31                                                                    0  wi
-    |-----------------|-----------------|-----------------|-----------------|
-    |                                 data_0[31:0]                          | 0
-    |-----------------------------------------------------------------------|
-    |                                 data_1[31:0]                          | 1
-    |-----------------------------------------------------------------------|
-    |                                 ...                                   | ..
-    |-----------------------------------------------------------------------|
-    |                              data_1023[31:0]                          | 1023
-    |-----------------------------------------------------------------------|
-    
-    streamNr = 1:
-    
-     31                                                                    0  wi
-    |-----------------|-----------------|-----------------|-----------------|
-    |                                 data_0[31:0]                          | 1024
-    |-----------------------------------------------------------------------|
-    |                                 data_1[31:0]                          | 1025
-    |-----------------------------------------------------------------------|
-    |                                 ...                                   | ..
-    |-----------------------------------------------------------------------|
-    |                              data_1023[31:0]                          | 2047
-    |-----------------------------------------------------------------------|
-    
-    
-    
-    streamNr = 15:
-    
-     31                                                                    0  wi
-    |-----------------|-----------------|-----------------|-----------------|
-    |                                 data_0[31:0]                          | 15360
-    |-----------------------------------------------------------------------|
-    |                                 data_1[31:0]                          | 15361
-    |-----------------------------------------------------------------------|
-    |                                 ...                                   | ..
-    |-----------------------------------------------------------------------|
-    |                              data_1023[31:0]                          | 16383
-    |-----------------------------------------------------------------------|
     
     Remarks:
     - The data buffer stores valid data samples until it is full.
@@ -120,26 +122,22 @@ mms_diag_data_buffer:
     - The actual data width depends on the generic g_data_w in
       diag_data_buffer.vhd. The value of unused MSBits is undefined.
     
+    
     Memory map REG_DIAG_DATA_BUFFER (one for each stream like the RAM above)
     
-     31                                                                     0  wi
-    |-----------------|-----------------|-----------------|-----------------|
-    |                             sync_cnt[31:0]                            | 0 RO (Version 0 and 1)
-    |-----------------------------------------------------------------------|
-    |                             word_cnt[31:0]                            | 1 RO (Version 0 and 1)
-    |-----------------------------------------------------------------------|
-    |                   R = valid_cnt[31:0] W = arm_enable                  | 2 RW (Version 1 only)
-    |-----------------------------------------------------------------------|
-    |                          reg_sync_delay[31:0]                         | 3 RW (Version 1 only)
-    |-----------------------------------------------------------------------|
-    |                                RESERVED                               | 4    (Version 1 only)
-    |-----------------------------------------------------------------------|
-    |                                RESERVED                               | 5    (Version 1 only)
-    |-----------------------------------------------------------------------|
-    |                                RESERVED                               | 6    (Version 1 only)
-    |-----------------------------------------------------------------------|
-    |                             version[31:0]                             | 7 RO (Version 1 only)
-    |-----------------------------------------------------------------------|
+    +----------------------------------------------------------------------------+
+    |   byte 3   |   byte 2   |   byte 1   |   byte 0   |  wi                    |
+    |----------------------------------------------------------------------------|
+    |                  sync_cnt[31:0]                   | 0 RO (Version 0 and 1) |
+    |                  word_cnt[31:0]                   | 1 RO (Version 0 and 1) |
+    |        R = valid_cnt[31:0] W = arm_enable         | 2 RW (Version 1 only)  |
+    |               reg_sync_delay[31:0]                | 3 RW (Version 1 only)  | 
+    |                     RESERVED                      | 4    (Version 1 only)  |
+    |                     RESERVED                      | 5    (Version 1 only)  |
+    |                     RESERVED                      | 6    (Version 1 only)  |
+    |                  version[31:0]                    | 7 RO (Version 1 only)  |
+    +----------------------------------------------------------------------------+
+    
     
     There are 3 modes of operation of the data_buffer.
     Version 0 supports Mode 1 and Mode 2
@@ -174,4 +172,4 @@ mms_diag_data_buffer:
       armed the next syn pulse will truigger the acquisition of data.
     - reg_sync_delay contains the number of valid cycles to delay/wait after an armed-syncpulse,
       before the data is written to the databuffer.
-    - version contains the version number of the databuffer peripheral.
+    - version contains the version number of the databuffer peripheral."
\ No newline at end of file
diff --git a/tools/oneclick/prestudy/YAML/mms_dp_bsn_align/peripheral.yaml b/tools/oneclick/prestudy/YAML/mms_dp_bsn_align/peripheral.yaml
index 9d652c1363edb3f9dd8a4b411e49058c831fdd2a..d9231ee15d015de1a6145b309ec011ee47ee990f 100644
--- a/tools/oneclick/prestudy/YAML/mms_dp_bsn_align/peripheral.yaml
+++ b/tools/oneclick/prestudy/YAML/mms_dp_bsn_align/peripheral.yaml
@@ -4,7 +4,7 @@ mms_dp_bsn_align:
   nof_inst: 1
 
   parameters:
-    g_nof_input: 4
+    g_nof_input: 2
 
   reg_dp_bsn_align:
     Enable:
@@ -14,8 +14,8 @@ mms_dp_bsn_align:
       default: 0
       repeat : g_nof_input
       descr  : >
-        Input enable register for input 0. If set to 0 the input is discarded from alignment.
-        If set to 1 the corresopnding input is taken into account.
+        "Input enable register for input 0. If set to 0 the input is discarded from alignment.
+        If set to 1 the corresopnding input is taken into account."
 
   peripheral_description: |
-    This is the BSN aligner
+    "This is the BSN aligner"
diff --git a/tools/oneclick/prestudy/YAML/mms_dp_fifo_fill/peripheral.yaml b/tools/oneclick/prestudy/YAML/mms_dp_fifo_fill/peripheral.yaml
index d8d82a127c344ca6f9a07157391f32d60be915ca..7a1e3d1c40b5d33143ca4ad664f667027449483e 100644
--- a/tools/oneclick/prestudy/YAML/mms_dp_fifo_fill/peripheral.yaml
+++ b/tools/oneclick/prestudy/YAML/mms_dp_fifo_fill/peripheral.yaml
@@ -14,7 +14,7 @@ mms_dp_fifo_fill:
       default: 0
       repeat : g_nof_streams
       descr  : >
-        Register reflects the currently used nof words on the fifo.
+        "Register reflects the currently used nof words on the fifo."
 
     fifo_status:
       width:  2
@@ -32,8 +32,8 @@ mms_dp_fifo_fill:
       default: 0
       repeat : g_nof_streams
       descr  : >
-        Register contains the maximum number of words that have been in the fifo.
-        Will be cleared after it has been read.
+        "Register contains the maximum number of words that have been in the fifo.
+        Will be cleared after it has been read."
 
   peripheral_description: |
-    This is the MM slave version of the dp_fifo_fill component.
+    "This is the MM slave version of the dp_fifo_fill component."
diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py b/tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py
index 466784ccfb0dde49fa694642ac4a1eb5fde54a38..772ab65362c5fff0d772641b38640846bb0f0868 100644
--- a/tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py
+++ b/tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py
@@ -1,9 +1,16 @@
 """ init file for py_mm_lib
-""" 
+"""
 
 import os
+cwd = os.getcwd()
+print(cwd)
+
 from my_logger import MyLogger
+
 mylogger = MyLogger(os.path.join(os.getcwd(), 'log'))
 logger = mylogger.logger
 
-from peripheral import PeripheralLibrary
+from peripheral import PeripheralLibrary, Peripheral
+from system import System
+from documentation import Documentation
+from system_rom import SystemRom
\ No newline at end of file
diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/documentation.py b/tools/oneclick/prestudy/YAML/py_mm_lib/documentation.py
new file mode 100755
index 0000000000000000000000000000000000000000..eacede762403ba33715e5799404ea3dc9fd54f01
--- /dev/null
+++ b/tools/oneclick/prestudy/YAML/py_mm_lib/documentation.py
@@ -0,0 +1,273 @@
+
+###############################################################################
+#
+# Copyright (C) 2016
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author  Date
+#   PD    feb 2017
+#
+###############################################################################
+
+"""
+Make automatic documentation
+
+"""
+
+import sys
+import os
+import argparse
+import subprocess
+import traceback
+import logging
+from pylatex import Document, Section, Subsection, Command, Package, Tabular, MultiColumn, MultiRow, SmallText, LargeText
+from pylatex.utils import italic, bold, NoEscape, verbatim, escape_latex
+
+from peripheral import PeripheralLibrary, Peripheral
+from system import System
+
+import common as cm
+
+logger = logging.getLogger('main.documentation')
+
+class Documentation(object):
+    """ make documentation for system or peripheral(s)
+    """
+    def __init__(self, document_name):
+        self.root_dir  = os.path.expandvars('$RADIOHDL/tools/oneclick/prestudy/YAML')
+        self.document_name = document_name
+        self.config = {}
+
+        geometry_options = {"tmargin": "1cm", "lmargin": "2.5cm"}
+        self.doc = Document(geometry_options=geometry_options)
+        #doc.packages.append(Package(u'listings'))
+        #doc.append(NoEscape(r'\lstset{columns=flexible}'))
+        #doc.append(NoEscape(r'\lstset{keepspaces=true}'))
+        #doc.append(NoEscape(r'\lstset{basicstyle=\ttfamily\color{blue}}'))
+        self.add_title()
+
+    def generate_pdf(self):
+        self.doc.generate_pdf('{}'.format(self.document_name), clean_tex=False)
+        #self.doc.generate_tex()
+
+    def add_title(self):
+        """ add title to document """
+
+        self.doc.preamble.append(Command('title', 'MM Documentation for {}'.format(self.document_name)))
+        self.doc.preamble.append(Command('author', 'oneclick-mm-documentation-script'))
+        self.doc.preamble.append(Command('date', NoEscape(r'\today')))
+
+
+        self.doc.append(NoEscape(r'\maketitle'))
+
+    def add(self, header, data):
+        """ add section (data) to the document with header as section name """
+        _type = type(data)
+        if _type == str:
+            self.add_text(header, data)
+        elif _type == dict:
+            self.add_dict(header, data)
+        elif _type == Peripheral:
+            self.add_peripheral(header, data)
+        elif _type == System:
+            self.add_system(header, data)
+        else:
+            pass
+
+    def add_text(self, header, text):
+        """ add text to the document """
+        self.add_section(header, text)
+
+    def add_dict(self, header, data):
+        """ add a dict to the document """
+        for key, val in data.items():
+            self.add(key, val)
+
+    def add_peripheral(self, header, data):
+        """ add a peripheral to the document """
+        self.add_section(data.get_name(), data.get_description() )
+
+    def add_system(self, header, data):
+        """ add a system to the document """
+        self.doc.append(Command('begin', 'huge'))
+        self.doc.append(NoEscape("{} description.".format(header)))
+        self.doc.append(Command('end', 'huge'))
+
+        self.add("", data.system['description'])
+
+        self.doc.append(Command('begin', 'huge'))
+        self.doc.append(NoEscape("Peripherals."))
+        self.doc.append(Command('end', 'huge'))
+
+        for key, val in sorted(data.peripherals.items()):
+            _header = key.strip()
+            _text = val.get_description()
+            self.add(_header, _text)
+
+    def add_section(self, heading='', text=''):
+        with self.doc.create(Section('%s' % heading)) as sec:
+            lines = text.splitlines(True)
+            n_lines = len(lines)
+            block_data = []
+            line_nr = 0
+            while line_nr < n_lines:
+                if lines[line_nr].startswith('+--'):
+                    block_data = []
+                    block_data.append(lines[line_nr])
+                    line_nr += 1
+                    while line_nr < n_lines:
+                        block_data.append(lines[line_nr])
+                        if lines[line_nr].startswith('+--'):
+                            logger.debug("append table")
+                            self.add_table(sec, block_data)
+                            line_nr += 1
+                            break
+                        line_nr += 1
+
+                elif lines[line_nr].startswith('A|'):
+                    block_data = []
+                    block_data.append(lines[line_nr][2:])
+                    line_nr += 1
+                    while line_nr < n_lines:
+                        block_data.append(lines[line_nr][2:])
+                        if not lines[line_nr].startswith('A|'):
+                            logger.debug("append AscciiArt")
+                            self.add_ascii_art(sec, block_data)
+                            break
+                        line_nr += 1
+                else:
+                    self.add_line(sec, lines[line_nr])
+                    line_nr += 1
+        return
+
+
+    def add_line(self, doc, line, add=True):
+        n_spaces = 0
+        _line = []
+        text = []
+        if line[0] == '"':
+            line = line[1:]
+        if line[-1] == '"':
+            line = line[:-1]
+        for ch_nr, ch in enumerate(line):
+            if ch == ' ':
+                n_spaces += 1
+
+            else:
+                if n_spaces == 1:
+                    text.append(' ')
+                elif n_spaces:
+                    if text:
+                        _line.append('%s' % ''.join(text))
+                        text = []
+                    _line.append(NoEscape(r'\hspace{%fcm}' % (n_spaces * 0.184)))
+                n_spaces = 0
+                text.append(ch)
+        if text:
+            _line.append('%s' % ''.join(text))
+        #_line.append('\n')
+        if add:
+            for i in _line:
+                doc.append(i)
+            return
+        return _line
+
+
+    def add_ascii_art(self, doc, data):
+        doc.append(Command('begin', 'small'))
+        doc.append(Command('begin', 'verbatim'))
+        doc.append(NoEscape(''.join(data)))
+        doc.append(Command('end', 'verbatim'))
+        doc.append(Command('end', 'small'))
+
+
+    def add_table(self, doc, data):
+        table = None
+        table_column_pos = []
+        table_n_columns = 0
+
+        # get vertical line positions of second line
+        pos = 0
+        while pos >= 0:
+            pos = data[1].find('|', pos)
+            if pos > -1:
+                table_column_pos.append(pos)
+                pos += 1
+
+        # make table
+        table_n_columns = len(table_column_pos) - 1
+        #table = Tabular('c'.join('|'*len(table_column_pos)))
+        tabular = ['|']
+        p1 = table_column_pos[0]
+        for p2 in table_column_pos[1:]:
+            cols = p2 - p1
+            tabular.append('p{%fcm}|' % (cols * 0.16))
+            p1 = p2
+
+        table = Tabular(''.join(tabular))
+        #table.add_hline()
+
+        for line_nr, line in enumerate(data):
+            logger.debug("%s, %d", line, len(line))
+            if line.startswith('+---'): # or line.startswith('|---'):
+                table.add_hline()
+                continue
+            if line.startswith('|---'):
+                continue
+
+
+            if line_nr == 1:
+                row_data = [bold(i) for i in line.strip()[1:-1].split('|')]
+            else:
+                row_data = [i for i in line.strip()[1:-1].split('|')]
+
+            logger.debug("%s", str(row_data))
+            row_n_cols = len(row_data)
+            # if all colums used add data
+            if row_n_cols == table_n_columns:
+                if len(table) > 1:
+                    table.add_hline()
+                table.add_row(row_data)
+            else:
+                row_cells = []
+                row_data_index = 0
+                pos = table_column_pos[0] + 1
+                last_index = 0
+                while pos >= 0:
+                    pos = line.find('|', pos)
+                    if pos > -1:
+                        for index, tcp in enumerate(table_column_pos):
+                            if pos == tcp:
+                                #rint "same pos, %d" % pos
+                                #if (index - last_index) == 1:
+                                #    row_cells.append(row_data[row_data_index])
+                                #else:
+                                cols = index - last_index
+                                text = row_data[row_data_index]
+                                if len(row_data[row_data_index][:2].strip()) == 0:
+                                    row_cells.append(MultiColumn(cols, align='|c|', data=SmallText(text)))
+                                else:
+                                    row_cells.append(MultiColumn(cols, align='|l|', data=SmallText(text)))
+                                last_index = index
+                                row_data_index += 1
+                        pos += 1
+                    else:
+                        table.add_hline()
+                        table.add_row(row_cells)
+        doc.append(table)
+        doc.append('\n')
+        return table
diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py b/tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py
index fb686cbc68d31db6676c2f22455aa648e9875e98..b0c2aa9ea21152d32ad881cbd10027956b539248 100755
--- a/tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py
+++ b/tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py
@@ -1,3 +1,4 @@
+
 ###############################################################################
 #
 # Copyright (C) 2016
@@ -19,23 +20,22 @@
 #
 # Author  Date
 #   HJ    jan 2017  Original
-#   EK    feb 2017  
-#   PD    feb 2017  
+#   EK    feb 2017
+#   PD    feb 2017
 #
 ###############################################################################
 
 
-###############################################################################
-
 import os
 import sys
-import copy
-import yaml
 import logging
+import yaml
+
 import common as cm
 
 logger = logging.getLogger('main.peripheral')
 
+
 class Field(object):
     """ A field defines data at certain address or an array of addresses
     """
@@ -45,33 +45,39 @@ class Field(object):
         self.valid_modes = ["RO", "WO", "RW", "WP", "RR"]
         if mode in self.valid_modes:
             self.mode = mode
-        else: 
-            logger.warning("Field(), unknown mode '{}'".format(mode))
+        else:
+            logger.warning("Field(), unknown mode '%s'", mode)
             self.mode = ""
-            
+
         self.offset  = offset
         self.default = default
-        self.descr   = descr  
+        self.descr   = descr
         self.repeat  = repeat
 
 
 class Register(object):
     """ A register consists of Fields
     """
-    def __init__(self, name, fields = [], nof_inst = 1):
-        self.name     = name        
-        self.fields   = fields
+    def __init__(self, name, fields = None, nof_inst = 1):
+        self.name     = name
+        self.fields   = {} if fields is None else fields
         self.nof_inst = nof_inst
         self.depth    = self.nof_inst * cm.ceil_pow2(len(fields))
-        
-    def add_field(self, name, width, mode, offset, default, descr): 
-        self.fields.append(Field(name, width, mode, offset, default, descr))
-        self.depth = self.nof_inst * cm.ceil_pow2(len(fields))
-    
+
+    def add_field(self, name, width, mode, offset, default, descr):
+        """ add fields to Register
+        """
+        self.fields[name] = Field(name, width, mode, offset, default, descr)
+        self.depth = self.nof_inst * cm.ceil_pow2(len(self.fields))
+
     def set_depth(self):
+        """ set depth of Register
+        """
         self.depth = self.nof_inst * cm.ceil_pow2(len(self.fields))
-    
+
     def set_nof_inst(self, nof_inst):
+        """ set number of instances
+        """
         self.nof_inst = nof_inst
 
 
@@ -87,31 +93,47 @@ class RAM(Field):
 class FIFO(Field):
     """ A FIFO is a specific set of Fields
     """
-    def __init__(self, name, width, mode, default, depth): 
+    def __init__(self, name, width, mode, default, depth):
         Field.__init__(self, name, width, mode, 0, default)
-        fifo_fields = []
-        fifo_fields.append(Field(fifo_status,        4, "RO", 0x0, 0, "fifo status register. Bit 0: Fifo Full Bit 1: Fifo Empty"))
-        fifo_fields.append(Field(fifo_used_w,       32, "RO", 0x4, 0, "fifo used words register."))
-        fifo_fields.append(Field(fifo_read_reg,  width, "RO", 0x8, 0, "fifo read register."))
-        fifo_fields.append(Field(fifo_write_reg, width, "WO", 0xC, 0, "fifo write register."))        
-        self.Register = Register("FIFO Register", fifo_fields)   
-        self.depth = depth
+        fifo_fields = {}
+        fifo_fields["fifo_status"] =    Field(name="fifo_status",
+                                              width=4,
+                                              mode="RO",
+                                              offset=0x0,
+                                              default=0,
+                                              descr="fifo status register. Bit 0: Fifo Full Bit 1: Fifo Empty")
 
+        fifo_fields["fifo_used_w"] =    Field(name="fifo_used_w",
+                                              width=32,
+                                              mode="RO",
+                                              offset=0x4,
+                                              default=0,
+                                              descr="fifo used words register.")
+
+        fifo_fields["fifo_read_reg"]  = Field(name="fifo_read_reg",
+                                              width=width,
+                                              mode="RO",
+                                              offset=0x8,
+                                              default=0,
+                                              descr="fifo read register.")
+
+        fifo_fields["fifo_write_reg"] = Field(name="fifo_write_reg",
+                                              width=width,
+                                              mode="WO",
+                                              offset=0xC,
+                                              default=0,
+                                              descr="fifo write register.")
+
+        self.register = Register("FIFO Register", fifo_fields)
+        self.depth = depth
 
-class Parameter(object):
-    """ A Parameter defines a name and value
-    """
-    def __init__(self, name, value):
-        self.name  = name        
-        self.value = value
-      
 
 class Peripheral(object):
     """ A Peripheral consists of 1 or more MM slaves. The slave can be a
     Register, RAM or FIFO.
-        
+
     The Peripheral has parameters to configure the MM slaves.
-        
+
     A Peripheral has two levels of supporting multiple instances:
     1) At system level a peripheral can be used more than once. The individual
        peripherals are then distinghuised by defining a unique label per
@@ -121,166 +143,229 @@ class Peripheral(object):
        via nof_inst. Dependent on the specific definition of the peripheral,
        the nof_inst then either replicates some fields in a register or it
        replicates some or all MM slaves nof_inst times.
-           
+
     The Peripheral evaluates the nof_inst and parameters to set the
     dimensions of the MM slaves.
     """
-    def __init__(self, name, nof_inst, descr, label = ""):
-        self.name        = name
+    def __init__(self, filename):
         self.postfix     = ""
-        self.label       = label  # the label is used to make it unique in case multiple instances are required in a system
-        self.nof_inst    = nof_inst
-        self.descr       = descr 
+        self.label       = "" # the label is used to make it unique in case multiple
+                              # instances are required in a system
+        self.name        = ""
+        self.config      = {}  # read config from file
         self.parameters  = {}
-        self.registers   = []
-        self.rams        = []
-        self.fifos       = []   
-        
-    def set_name(self, name):              
-        self.name = name  
+        self.registers   = {}
+        self.rams        = {}
+        self.fifos       = {}
+
+        try:
+            _config = yaml.load(open(filename, "r"))
+        except IOError:
+            logger.error("config file '{}' does not exist".format(filename))
+            return
+
+        self.name   = _config.keys()[0]
+        self.config = _config[self.name]
+
+        self.nof_inst = int(self.config["nof_inst"])
+
+        for key, val in self.config.items():
+            if "ram_" in key:
+                self.add_ram(key,
+                             val["width"],
+                             val["mode"],
+                             val["depth"],
+                             val["descr"])
+            if "reg_" in key:
+                fields = {}
+                for reg_key, reg_val in val.items():
+                    logger.debug("key=%s, val=%s", reg_key, str(reg_val))
+
+                    repeat = reg_val.get('repeat', None)  # print "YES!"
+                    fields[reg_key] = Field(reg_key,
+                                            reg_val["width"],
+                                            reg_val["mode"],
+                                            reg_val["offset"],
+                                            reg_val["default"],
+                                            reg_val["descr"],
+                                            repeat)
+
+                self.add_register(key, fields)
+
+            if "parameters" in key:
+                self.parameters.update(val)
+
+    def set_name(self, name):
+        """ set name of peripheral
+        """
+        self.name = name
 
     def set_nof_inst(self, nof_inst):
+        """ set number of instances
+        """
         self.nof_inst = nof_inst
-    
-    def set_label(self, label):              
-        self.label = label  
 
-    def add_parameter(self, name, value):              
-        self.parameters.append(Parameter(name, value))  
+    def set_label(self, label):
+        """ set label of instance
+        """
+        self.label = label
 
-    def add_register(self, name, fields):              
-        self.registers.append(Register(name, fields, self.nof_inst))      
+    def add_parameter(self, name, value):
+        """ add parameter to  peripheral
+        """
+        self.parameters[name] = value
 
-    def add_RAM(self, name, width, mode, depth, descr):              
-        self.rams.append(RAM(name, width, mode, depth, self.nof_inst, descr))      
+    def add_register(self, name, fields):
+        """ add register to peripheral
+        """
+        _name = "{}{}".format(name, self.postfix)
+        self.registers[_name] = Register(_name, fields, self.nof_inst)
 
-    def eval_RAM(self):
-        """Evaluate the parameters and the nof_inst of the peripheral in order to define the real depth and width of the RAM.
-           For example: depth = c_nof_weights*c_nof_signal_paths 
-                        witdh = c_weights_w*c_nof_complex """ 
+    def add_ram(self, name, width, mode, depth, descr):
+        """ add RAM to peripheral
+        """
+        _name = "{}{}".format(name, self.postfix)
+        self.rams[_name] = RAM(_name, width, mode, depth, self.nof_inst, descr)
+
+    def eval_ram(self):
+        """Evaluate the parameters and the nof_inst of the peripheral in order to define the
+           real depth and width of the RAM.
+           For example: depth = c_nof_weights*c_nof_signal_paths
+                        witdh = c_weights_w*c_nof_complex """
         for parameter in self.parameters:
-            exec("%s = %d" % (parameter, self.parameters[parameter])) # Here the parameters of the peripheral are promoted to real python variables 
-        for ram in self.rams:
-            ram.name  = ram.name + self.postfix
-            logger.debug("  -RAM depth str: {}".format(ram.depth))
-            ram.depth = self.nof_inst * cm.ceil_pow2(eval(str(ram.depth))) # Here the variables are used to evaluate the true value for the depth parameter(taking int account the nof_inst as well)
-            logger.debug("  -RAM depth eval: {}".format(ram.depth))
-            logger.debug("  -RAM width str: {}".format(ram.width))
-            ram.width = eval(str(ram.width)) # Here the variables are used to evaluate the true value for the width parameter.
-            logger.debug("  -RAM width eval: {}".format(ram.width))
-            logger.debug("  {} depth: {}".format(ram.name, ram.depth))
-            logger.debug("  {} width: {}".format(ram.name, ram.width))
+            # Here the parameters of the peripheral are promoted to real python variables
+            exec("%s = %d" % (parameter, self.parameters[parameter]))
+        for ram in self.rams.values():
+            logger.debug("  -RAM depth str: %s", ram.depth)
+            # Here the variables are used to evaluate the true value for the depth
+            # parameter(taking int account the nof_inst as well)
+            ram.depth = self.nof_inst * cm.ceil_pow2(eval(str(ram.depth)))
+            logger.debug("  -RAM depth eval: %d", ram.depth)
+            
+            logger.debug("  -RAM width str: %s", ram.width)
+            # Here the variables are used to evaluate the true value for the width parameter.
+            ram.width = eval(str(ram.width))
+            logger.debug("  -RAM width eval: %d", ram.width)
+            
+            logger.debug("  %s depth: %d", ram.name, ram.depth)
+            logger.debug("  %s width: %d", ram.name, ram.width)
 
     def eval_register(self):
-        """Evaluate the register depth based on the evaluation of the fields, nof registers and the nof_inst."""
+        """Evaluate the register depth based on the evaluation of the fields,
+           nof registers and the nof_inst."""
         for parameter in self.parameters:
-            exec("%s = %d" % (parameter, self.parameters[parameter])) # Here the parameters of the peripheral are promoted to real python variables 
-        for register in self.registers:
-            # Evaluate the fields and see if there are field that have to be repeated. 
-            for field in register.fields:
+            # Here the parameters of the peripheral are promoted to real python variables
+            exec("%s = %d" % (parameter, self.parameters[parameter]))
+        for register in self.registers.values():
+            # Evaluate the fields and see if there are field that have to be repeated.
+            for field in register.fields.values():
                 field.repeat = eval(str(field.repeat))
             fields_eval = []
             offset = 0
-            for field in register.fields:
-                if field.repeat == None:           # If no repeat is required, just copy. 
+            for field in register.fields.values():
+                if field.repeat is None:           # If no repeat is required, just copy.
                     fields_eval.append(field)
                 else:
-                    for f in range(field.repeat):  # Repeat the field as many times as required. Keep track of the offset.  
-                        fields_eval.append(Field(field.name + str(f), field.width, field.mode, offset, field.default, field.descr))  
+                    # Repeat the field as many times as required. Keep track of the offset.
+                    for i in range(field.repeat):
+                        fields_eval.append(Field(field.name + str(i),
+                                                 field.width,
+                                                 field.mode,
+                                                 offset,
+                                                 field.default,
+                                                 field.descr))
                         offset = offset + 1
             register.fields = fields_eval                  # Update the fields with evaluated fields
-            register.name = register.name + self.postfix   # Create the name
-            register.set_nof_inst(self.nof_inst)            
-            register.set_depth()                            # Estimate the new depth after evaluation of the fields and nof_inst
-            logger.debug("  {} depth: {}".format(register.name, register.depth))
-    
+            register.set_nof_inst(self.nof_inst)
+            register.set_depth()  # Estimate the new depth after evaluation of the fields and nof_inst
+            logger.debug("  %s depth: %d", register.name, register.depth)
+
     def eval_peripheral(self):
-        """Evaluate name, label, nof_inst and the parameters to determine the true size of the RAMs and the register width and the name of the peripheral, registers and RAMS """
+        """Evaluate name, label, nof_inst and the parameters to determine the true size of
+           the RAMs and the register width and the name of the peripheral, registers and RAMS """
         if self.label:
-           self.postfix = "_" + self.label
-        self.set_name(self.name + self.postfix)
-        logger.debug(" Evaluating peripheral '{}'".format(self.name))
-        self.eval_RAM()
+            self.postfix = "_{}".format(self.label)
+        self.set_name("{}{}".format(self.name, self.postfix))
+        logger.debug(" Evaluating peripheral '%s'", self.name)
+        self.eval_ram()
         self.eval_register()
- 
- 
+
+    def get_name(self):
+        """ returns name of peripheral """
+        return self.name
+
+    def get_description(self):
+        """ return peripheral description """
+        return self.config['peripheral_description']
+
+    def show_overview(self, header=True):
+        """ print system overview
+        """
+        if header:
+            logger.info("--------------------")
+            logger.info("PERIPHERAL OVERVIEW:")
+            logger.info("--------------------")
+
+        logger.info("Peripheral name:     %s", self.name)
+        logger.info("  Number of instances: %d", self.nof_inst)
+        logger.info("  RAMs and registers:")
+        for ram in self.rams.values():
+            logger.info("    %-20s  width=%d  depth=%d", ram.name, ram.width, ram.depth)
+        for reg in self.registers.values():
+            logger.info("    %-20s  depth=%d", reg.name, reg.depth)
+            for field in reg.fields:
+                logger.info("      %-20s width=%3d  mode=%s  offset=0x%02x", field.name, field.width, field.mode, field.offset)
+        logger.info("  parameters:")
+        for param_key, param_val in self.parameters.items():
+            logger.info("      %-20s  %s", param_key, str(param_val))
+
+
 class PeripheralLibrary(object):
     """ List of all information for peripheral config files in the root dir
     """
     def __init__(self, root_dir, file_name='peripheral.yaml'):
         """Store the dictionaries from all file_name files in root_dir."""
         self.root_dir   = root_dir
-        self.file_name  = file_name                                     # all peripheral files have the same file_name
-        self.file_paths = cm.find_all_file_paths(root_dir, file_name)   # list of all directory paths of peripheral files that are available in the root_dir tree
+        # all peripheral files have the same file_name
+        self.file_name  = file_name
+        # list of all directory paths of peripheral files that are available in the root_dir tree
+        self.file_paths = cm.find_all_file_paths(root_dir, file_name)
         if len(self.file_paths) == 0:
             sys.exit('Error : No %s file found in %s directory tree.' % (file_name, root_dir))
-        self.file_path_names = []                                       # list of all directory paths + file_name of the available peripheral files
+        # list of all directory paths + file_name of the available peripheral files
+        self.file_path_names = []
         for path in self.file_paths:
             self.file_path_names.append(os.path.join(path, self.file_name))
-        self.peripheral_configs     = self.read_all_peripheral_files()  # list of peripheral configurations that are read from the available peripheral files
-        self.nof_peripheral_configs = len(self.peripheral_configs)      # number of peripheral configurations
-        self.peripherals            = self.create_all_peripherals()
-        self.nof_peripherals        = len(self.peripherals)             # number of peripherals
+        # list of peripheral configurations that are read from the available peripheral files
+        self.peripherals     = self.read_all_peripheral_files()
+        self.nof_peripherals = len(self.peripherals)  # number of peripherals
         #print self.peripherals
-        
+
     def read_all_peripheral_files(self, file_path_names=None):
         """Read the peripheral information from all peripheral files that were found in the root_dir tree."""
+        peripherals = {}
         if file_path_names is None:
             file_path_names = self.file_path_names
-        read_peripherals = {}
-        for fp in self.file_path_names:
-            read_peripherals.update(self.read_peripheral_file(fp))
-        return read_peripherals
-
-    def read_peripheral_file(self, file_path_name=None):
-        """Read the peripheral information from the file_path_name file."""
-        if file_path_name is None:
-            file_path_name = self.file_path_names[0]
-
-        with open(file_path_name, "r") as myfile:
-            peripheral_yaml_config = myfile.read()
-        peripheral_config = yaml.load(peripheral_yaml_config)
-        return peripheral_config
-
-    def create_all_peripherals(self, peripheral_configs=None):
-        """Create peripheral objects from all peripheral configurations."""
-        if peripheral_configs is None:
-            peripheral_configs = self.peripheral_configs
-        peripherals = {}
-        
-        for peripheral_name, peripheral_config in peripheral_configs.items():
-            peripherals[peripheral_name] = self.create_peripheral(peripheral_name, peripheral_config)
+        for fpn in self.file_path_names:
+            peripheral = Peripheral(fpn)
+            peripherals[peripheral.name] = peripheral
         return peripherals
 
-    def create_peripheral(self, peripheral_name, peripheral_config):
-        """Create a peripheral object based on the information in the peripheral_config"""
-        peripheral = Peripheral(peripheral_name, peripheral_config["nof_inst"], peripheral_config["peripheral_description"])
-
-        for key, val in peripheral_config.items():
-            if "ram_" in key: 
-                peripheral.add_RAM(key, val["width"], val["mode"], val["depth"], val["descr"])
-            if "reg_" in key:       
-                fields = []
-                for reg_key, reg_val in val.items():   
-#                    print reg_key
-#                    print reg_val
-#                    print reg_key.values()
-#                    print reg_key.values()[0]
-                    repeat = None
-                    if "repeat" in reg_val:
-                        repeat = reg_val['repeat']  # print "YES!"
-                    
-                    fields.append(Field(reg_key, reg_val["width"], reg_val["mode"], reg_val["offset"], reg_val["default"], reg_val["descr"], repeat))
-                
-                peripheral.add_register(key, fields)
-            
-            if "parameters" in key:
-                peripheral.parameters.update(val)
-
-        return peripheral  
-    
-    def find_peripheral(self, name, peripheral_library=None): 
+    def find_peripheral(self, name, peripheral_library=None):
+        """ find peripheral in peripheral_library and return it
+        """
         if peripheral_library is None:
             return self.peripherals.get(name, None)
-        return peripheral_library.get(name, None)           
+        return peripheral_library.get(name, None)
+
+    def show_overview(self, header=True):
+        """ print system overview
+        """
+        if header:
+            logger.info("---------------------")
+            logger.info("PERIPHERALS OVERVIEW:")
+            logger.info("---------------------")
         
+        for peripheral in self.peripherals.values():
+            peripheral.show_overview(header=False)
+
diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/system.py b/tools/oneclick/prestudy/YAML/py_mm_lib/system.py
new file mode 100755
index 0000000000000000000000000000000000000000..beaf909cc312535d3f6adbf3ef7ffc14b05740c9
--- /dev/null
+++ b/tools/oneclick/prestudy/YAML/py_mm_lib/system.py
@@ -0,0 +1,132 @@
+###############################################################################
+#
+# Copyright (C) 2016
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author  Date
+#   HJ    jan 2017  Original
+#   EK    feb 2017
+#   PD    feb 2017
+#
+###############################################################################
+
+import os
+import copy
+import logging
+import yaml
+
+import common as cm
+from peripheral import PeripheralLibrary
+
+logger = logging.getLogger('main.system')
+
+
+class System(object):
+    """ A System consist of a set of one or more Peripherals.
+    """
+    def __init__(self, file_path_name=None):
+        self.file_path_name  = file_path_name
+        self.root_dir        = os.path.join(os.environ['RADIOHDL'], "tools/oneclick/prestudy/YAML")
+        self.peri_lib        = PeripheralLibrary(self.root_dir, "peripheral.yaml")
+        self.system          = {}
+        self.peripherals     = {}
+        self.valid_file_type = False
+
+        if file_path_name is None:
+            logger.debug("No system configuration file specified")
+            self.system_config = None
+            self.system        = None
+        else:
+            # list of peripheral configurations that are read from the available peripheral files
+            self.system_config = self.read_system_file(file_path_name)
+            self.create_system()
+
+    def is_valid(self):
+        """ return False or True if the given file is a valid system file """
+        return self.valid_file_type
+
+    def read_system_file(self, file_path_name=None):
+        """Read the system information from the file_path_name file."""
+        if file_path_name is None:
+            file_path_name = self.file_path_name[0]
+
+        system_config = yaml.load(open(file_path_name, 'r'))
+        if system_config.values()[0]['type'] != 'system':
+            return {}
+        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")
+        logger.debug("Instantiating the peripherals from the peripheral Library")
+        self.system_name = self.system_config.keys()[0]
+        config = self.system_config[self.system_name]
+
+        for key, val in config.items():
+            if key == 'peripherals':
+                for peripheral_name, peripheral_config in val.items():
+                    if '.' in peripheral_name:
+                        peripheral_key, label = peripheral_name.split('.')
+                        logger.debug("splitted %s in key=%s, label=%s", peripheral_name, peripheral_key, label)
+                    else:
+                        peripheral_key = peripheral_name
+                        label = ''
+
+                    # (Deep)Copy the peripheral from the library in order to avoid creating a reference
+                    peripheral_from_lib = copy.deepcopy(self.peri_lib.find_peripheral(peripheral_key))
+                    if peripheral_from_lib is None:
+                        logger.warning("peripheral_key %s not found in library", peripheral_key)
+                        continue
+
+                    logger.debug(" Finding %s", peripheral_from_lib.name)
+                    peripheral_from_lib.set_label(label)
+                    for parameter_key, parameter_val in peripheral_config.items():
+                        if parameter_key == "nof_inst":
+                            peripheral_from_lib.set_nof_inst(parameter_val)
+                        elif parameter_key in peripheral_from_lib.parameters:
+                            logger.debug("  Parameter %s default value: %s is overwritten with new value: %s",
+                                        parameter_key, str(peripheral_from_lib.parameters[parameter_key]), str(parameter_val))
+                            peripheral_from_lib.parameters[parameter_key] = parameter_val
+                        else:
+                            logger.warning("  !!! Parameter %s does not exist on peripheral: %s !!!",
+                                        parameter_key, peripheral_from_lib.name)
+
+                    #peripheral_name2 = "{}.{}".format(peripheral_key, peripheral_from_lib.label)
+                    if peripheral_name not in self.peripherals:
+                        self.peripherals[peripheral_name] = peripheral_from_lib
+                    else:
+                        logger.warning("  Duplicate found: use unique labels per instance to distinguish between multiple instances of the same peripheral.")
+                        logger.warning("  Cannot add a second instance of peripheral: %s label(%s)",
+                                    peripheral_from_lib.name, peripheral_from_lib.label)
+            else:
+                self.system[key] = val
+
+        logger.debug("Start evaluating the peripherals")
+        for peripheral_name, peripheral_config in self.peripherals.items():
+            peripheral_config.eval_peripheral()
+        return
+
+    def show_overview(self):
+        """ print system overview
+        """
+        logger.info("----------------")
+        logger.info("SYSTEM OVERVIEW:")
+        logger.info("----------------")
+        logger.info("System name '%s'", self.system_name)
+        for peripheral in self.system_config[self.system_name]['slave_index_order']:
+            self.peripherals[peripheral].show_overview(header=False)
diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/system_rom.py b/tools/oneclick/prestudy/YAML/py_mm_lib/system_rom.py
new file mode 100644
index 0000000000000000000000000000000000000000..9dc5656001bc8ffa7a8c9bcfc202d22e67e29582
--- /dev/null
+++ b/tools/oneclick/prestudy/YAML/py_mm_lib/system_rom.py
@@ -0,0 +1,96 @@
+
+###############################################################################
+#
+# Copyright (C) 2016
+# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
+# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+# Author  Date
+#   PD    feb 2017
+#
+###############################################################################
+
+"""
+Generate system rom files
+
+"""
+
+import sys
+import os
+import argparse
+import subprocess
+import traceback
+import logging
+from math import ceil
+
+from peripheral import PeripheralLibrary, Peripheral
+from system import System
+
+import common as cm
+
+logger = logging.getLogger('main.system_rom')
+
+class SystemRom(object):
+    def __init__(self):
+        self.filename = None
+        self.system = None
+        self.mm_reg_list = []
+        self.mm_ram_list = []
+        self.word_size = 32  # number of bits
+
+    def read_system(self, filename):
+        """ read system configuration file """
+        self.filename = filename
+        system = System(self.filename)
+        if system.is_valid():
+            self.system = system
+            return True
+        return False
+
+    def calc_offsets(self):
+        """ calculate register offsets """
+        slave_order = self.system.system['slave_index_order']
+        peripherals = self.system.peripherals
+        reg_info_start_address = self.system.system['reg_system_info']['locked_start_address']
+        rom_info_start_address = self.system.system['rom_system_info']['locked_start_address']
+        reg_addr = 0x0000
+        for name in slave_order:
+            peripheral = peripherals[name]
+            for key, val in peripheral.rams.items():
+                width = int(val['with'])
+                depth = int(val['depth'])
+                n_words = int(ceil(float(width) / self.word_size))
+                n_addresses = n_words * depth
+                self.mm_reg_list.append([key, reg_addr, n_words, depth])
+                reg_addr += n_addresses
+            '''
+            for rkey, rval in peripheral.registers.items():
+                for fkey, fval in rval.items():
+                    width = int(val['with'])
+                    n_words = int(ceil(float(width) / self.word_size))
+                    n_addresses = n_words * depth
+                    self.mm_reg_list.append([key, reg_addr, n_words, depth])
+                    reg_addr += n_addresses
+            '''
+        print(self.mm_reg_list)
+
+
+    def generate_reg(self):
+        pass
+
+    def generate_txt(self):
+        pass
+
diff --git a/tools/oneclick/prestudy/YAML/system.py b/tools/oneclick/prestudy/YAML/system.py
deleted file mode 100755
index 0b687afaaeeaf5a21e0d1c8502b11e6719877b57..0000000000000000000000000000000000000000
--- a/tools/oneclick/prestudy/YAML/system.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/env python
-###############################################################################
-#
-# Copyright (C) 2016
-# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Author  Date
-#   HJ    jan 2017  Original
-#   EK    feb 2017  
-#   PD    feb 2017  
-#
-###############################################################################
-
-
-###############################################################################
-
-import os
-import sys
-import copy
-import yaml
-import argparse
-import traceback
-
-from py_mm_lib import *
-
-
-import common as cm
-        
-
-class System(object):
-    """ A System consist of a set of one or more Peripherals.
-    """
-    def __init__(self, file_path_name=None):
-        self.file_path_name = file_path_name
-        self.root_dir       = os.path.join(os.environ['RADIOHDL'], "tools/oneclick/prestudy/YAML")        
-        self.peri_lib       = PeripheralLibrary(self.root_dir, "peripheral.yaml")        
-        self.peripherals    = {}  # TODO: make dict
-        
-        if file_path_name is None: 
-            logger.debug("No system configuration file specified")
-            self.system_config = None
-            self.system        = None
-        else:
-            self.system_config = self.read_system_file(file_path_name)        # list of peripheral configurations that are read from the available peripheral files
-            self.system        = self.create_system(self.system_config)
-
-    def read_system_file(self, file_path_name=None):
-        """Read the system information from the file_path_name file."""
-        if file_path_name is None:
-            file_path_name = self.file_path_names[0]
-
-        with open(file_path_name, "r") as myfile:
-            system_yaml_config = myfile.read()
-        system_config = yaml.load(system_yaml_config)
-        #print system_config
-        return system_config
-
-    def create_system(self, system_config=None):
-        """Create a system object based on the information in the system_config"""
-        logger.debug("Creating system") 
-        logger.debug("Instantiating the peripherals from the peripheral Library") 
-        self.system_name = system_config.keys()[0]
-        
-        for peripheral_name, peripheral_config in system_config[self.system_name]['peripherals'].items():
-            if '.' in peripheral_name:
-                peripheral_key, label = peripheral_name.split('.')
-                logger.debug("splitted {} in key={}, label={}".format(peripheral_name, peripheral_key, label))
-            else:
-                peripheral_key = peripheral_name
-                label = ''
-                
-            peripheral_from_lib = copy.deepcopy(self.peri_lib.find_peripheral(peripheral_key))  # (Deep)Copy the peripheral from the library in order to avoid creating a reference
-            if peripheral_from_lib is None:
-                logger.warning("peripheral_key {} not found in library".format(peripheral_key))
-                continue
-                
-            logger.debug(" Finding {}".format(peripheral_from_lib.name)) 
-            peripheral_from_lib.set_label(label)
-            for parameter_key, parameter_val in peripheral_config.items():
-                if parameter_key == "nof_inst":
-                    peripheral_from_lib.set_nof_inst(parameter_val)
-                elif parameter_key in peripheral_from_lib.parameters:
-                    logger.debug("  Parameter {} default value: {} is overwritten with new value: {}".format(
-                                parameter_key, peripheral_from_lib.parameters[parameter_key], parameter_val))
-                    peripheral_from_lib.parameters[parameter_key] = parameter_val
-                else:
-                    logger.warning("  !!! Parameter {} does not exist on peripheral: {} !!!".format(
-                                   parameter_key, peripheral_from_lib.name))
-                  
-            #peripheral_name2 = "{}.{}".format(peripheral_key, peripheral_from_lib.label)
-            if peripheral_name not in self.peripherals:
-                self.peripherals[peripheral_name] = peripheral_from_lib
-            else:
-                logger.warning("  Duplicate found: use unique labels per instance to distinguish between multiple instances of the same peripheral.")
-                logger.warning("  Cannot add a second instance of peripheral: {} label({})".format(peripheral_from_lib.name, peripheral_from_lib.label))
-
-        logger.debug("Start evaluating the peripherals")           
-        for peripheral_name, peripheral_config in self.peripherals.items():
-            peripheral_config.eval_peripheral()
-
-    def log_system_overview(self):
-        logger.info("----------------")
-        logger.info("SYSTEM OVERVIEW:")
-        logger.info("----------------")
-        logger.info("System name '{}'".format(self.system_name))
-        for peripheral_name, peripheral_config in self.peripherals.items():
-            logger.info("{} ({}):".format(peripheral_config.name, peripheral_config.nof_inst))
-            logger.info("  RAMs and registers:")
-            for ram in peripheral_config.rams:
-                logger.info("    {} {} {}".format(ram.name, ram.width, ram.depth))
-            for reg in peripheral_config.registers:
-                logger.info("    {} {}".format(reg.name, reg.depth))
-                for field in reg.fields:                
-                    logger.info("      {} {} {} {}".format(field.name, field.width, field.mode, field.offset))
-            logger.info("  parameters:")
-            for param in peripheral_config.parameters:
-                logger.info("      {} {}".format(param, peripheral_config.parameters[param]))
-            
-            
-def get_arguments():
-    """ Parse command line arguments
-    """
-    # Parse command line arguments
-    parser = argparse.ArgumentParser(description='System and peripheral config command line parser arguments')
-    parser.add_argument('-p','--peripheral', nargs='*', default=None, help='peripheral names separated by commas')
-    parser.add_argument('-s','--system', nargs='*', default=None, help='system names separated by commas')
-    parser.add_argument('-r','--run', action='store_true', default=False, help='run command')
-    parser.add_argument('-v','--verbosity', type=int, default=0, help='verbosity >= 0 for more info')
-    args = parser.parse_args()
-    logger.debug("Used arguments: {}".format(args))
-    return args
-
-
-if __name__ == '__main__':
-    
-    # setup first log system before importing other user libraries
-    program_name = sys.argv[0].split('/')[-1].split('.')[0]
-    mylogger.set_logfile_name(name=program_name)
-    mylogger.set_stdout_log_level('INFO')
-    mylogger.set_file_log_level('DEBUG')
-
-    try:
-        # Mode
-        # 0 = Read YAML info from one system configuration file
-        # 1 = Read YAML info from all system and peripheral configuration files in the root directory
-        mode = 0
-        
-        # Parse command line arguments
-        args = get_arguments()
-        
-        # Read the peripheral configuration files from the root in the current directory and the sub directories
-        #hdl = HdlConfig(toolroot_dir=os.path.expandvars('$RADIOHDL/tools/oneclick/prestudy/YAML'), libfile_name='hdllib.cfg', toolfile_name=cli_args.toolfile_name)
-        
-        if mode == 0:   
-            root_dir  = os.path.expandvars('$RADIOHDL/tools/oneclick/prestudy/YAML')
-
-            #peri_lib = PeripheralLibrary(root_dir, "peripheral.yaml")
-
-            system = System(os.path.join(root_dir, "system.yaml")) 
-
-            system.log_system_overview()
-    except:
-        logger.error('Program fault, reporting and cleanup')
-        logger.error('Caught %s', str(sys.exc_info()[0]))
-        logger.error(str(sys.exc_info()[1]))
-        logger.error('TRACEBACK:\n%s', traceback.format_exc())
-        logger.error('Aborting NOW')
-        sys.exit("ERROR")
diff --git a/tools/oneclick/prestudy/YAML/system.yaml b/tools/oneclick/prestudy/YAML/system.yaml
index 5aa6647f5345af1d408c6e25f85bc865b2e4fea2..23dbb49b1c1ea8d4d7a75c8876b972127a9f3422 100644
--- a/tools/oneclick/prestudy/YAML/system.yaml
+++ b/tools/oneclick/prestudy/YAML/system.yaml
@@ -2,19 +2,35 @@
 demo:
   type: system
 
+  description: |
+    "DEMO system for testing mm tools
+    Now with extra line ??"
+
   board_select: unb1
 
   bus_select : qsys
-
+  
   reg_system_info:
-    locked_address: 0
+    locked_start_address: 0
 
   rom_system_info:
-    locked_address: 0x20
-
+    locked_start_address: 0x20
+
+  slave_index_order: [fringe_stop, 
+                      mms_diag_block_gen.input, 
+                      mms_diag_block_gen.mesh,
+                      mms_diag_block_gen.proc,
+                      bf_unit,
+                      mms_diag_block_gen.output,
+                      mms_diag_data_buffer.input_pre,
+                      mms_diag_data_buffer.input_post,
+                      mms_diag_data_buffer.mesh,
+                      mms_diag_data_buffer.proc,
+                      mms_dp_bsn_align.input,
+                      mms_dp_fifo_fill]
 
   peripherals:
-
+  # use '- peripheral_name' to set address order'
     fringe_stop:
       nof_inst: 1
 
@@ -27,12 +43,12 @@ demo:
       nof_inst     : 1
       g_nof_streams: 8
       g_buf_addr_w : 8
-
+  
     mms_diag_block_gen.proc:
       nof_inst     : 1
       g_nof_streams: 12
       g_buf_addr_w : 7
-
+  
     bf_unit:
       nof_inst           : 3
       g_weights_w        : 3
@@ -41,40 +57,40 @@ demo:
       g_nof_subbands     : 12
       g_nof_signal_paths_per_stream: 2
       g_nof_input_streams: 8
-
+  
     mms_diag_block_gen.output:
       nof_inst     : 1
       g_nof_streams: 2
-
+  
     mms_diag_data_buffer.input_pre:
       nof_inst      : 1
       g_nof_streams : 12
       g_data_w      : 16
       g_buf_nof_data: 8192
-
+  
     mms_diag_data_buffer.input_post:
       nof_inst      : 1
       g_nof_streams : 12
       g_data_w      : 16
       g_buf_nof_data: 8192
-
+  
     mms_diag_data_buffer.mesh:
       nof_inst      : 1
       g_nof_streams : 8
       g_data_w      : 16
       g_buf_nof_data: 8
-
+  
     mms_diag_data_buffer.proc:
       nof_inst      : 1
       g_nof_streams : 12
       g_data_w      : 16
       g_buf_nof_data: 128
-
+  
     mms_dp_bsn_align.input:
       nof_inst   : 1
       g_nof_input: 3
-
+  
     mms_dp_fifo_fill:
       nof_inst     : 1
       g_nof_streams: 3
-
+      
\ No newline at end of file