From 3bbce6ace56b326f2f47862cae0a45e99da29b4e Mon Sep 17 00:00:00 2001 From: Pieter Donker <donker@astron.nl> Date: Thu, 2 Mar 2017 12:19:29 +0000 Subject: [PATCH] Task #893 backup --- .../prestudy/YAML/bf_unit/peripheral.yaml | 79 ++-- .../prestudy/YAML/fringe_stop/peripheral.yaml | 157 +++---- .../prestudy/YAML/make_documentation.py | 87 ++++ .../YAML/mms_diag_block_gen/peripheral.yaml | 110 +++-- .../YAML/mms_diag_data_buffer/peripheral.yaml | 304 +++++++------ .../YAML/mms_dp_bsn_align/peripheral.yaml | 19 +- .../YAML/mms_dp_fifo_fill/peripheral.yaml | 43 +- tools/oneclick/prestudy/YAML/peripheral.py | 416 ------------------ .../prestudy/YAML/py_mm_lib/__init__.py | 9 + .../prestudy/YAML/py_mm_lib/my_logger.py | 77 ++++ .../prestudy/YAML/py_mm_lib/peripheral.py | 286 ++++++++++++ tools/oneclick/prestudy/YAML/system.py | 182 ++++++++ tools/oneclick/prestudy/YAML/system.yaml | 102 ++++- 13 files changed, 1148 insertions(+), 723 deletions(-) create mode 100755 tools/oneclick/prestudy/YAML/make_documentation.py delete mode 100644 tools/oneclick/prestudy/YAML/peripheral.py create mode 100644 tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py create mode 100644 tools/oneclick/prestudy/YAML/py_mm_lib/my_logger.py create mode 100755 tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py create mode 100755 tools/oneclick/prestudy/YAML/system.py diff --git a/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml b/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml index ccaf2e2360..0d668dcae4 100644 --- a/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml +++ b/tools/oneclick/prestudy/YAML/bf_unit/peripheral.yaml @@ -1,35 +1,50 @@ --- -peripheral_name: bf_unit +bf_unit: + type : peripheral + nof_inst: 1 + + parameters: + g_weights_w: 16 + g_nof_weights: 256 + g_nof_signal_paths: 64 + g_nof_subbands: 24 + g_nof_input_streams: 16 + g_nof_signal_paths_per_stream: 4 -nof_inst: 1 - -parameters: - g_weights_w: 16 - g_nof_weights: 256 - g_nof_signal_paths: 64 - g_nof_subbands: 24 - g_nof_input_streams: 16 - g_nof_signal_paths_per_stream: 4 - -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." + 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. + + 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. -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." - -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." - -reg_st_sst_bf: - - Treshold: { width: 32, mode: "RW", offset: 0x0, default: 0, descr: "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."} - -peripheral_description: "This is the beamformer unit" \ No newline at end of file + 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. + + reg_st_sst_bf: + Treshold: + width : 32 + mode : RW + offset : 0x0 + default: 0 + descr : > + 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. + + peripheral_description: | + 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 ee2c04a4d3..00b208bdf4 100644 --- a/tools/oneclick/prestudy/YAML/fringe_stop/peripheral.yaml +++ b/tools/oneclick/prestudy/YAML/fringe_stop/peripheral.yaml @@ -1,85 +1,86 @@ --- -peripheral_name: fringe_stop +fringe_stop: + type : peripheral + nof_inst: 1 -nof_inst: 1 + ram_fringe_stop_step: + width: 17 + depth: 256 + mode : RW + descr: > + Contains the step size for all nof_channels channels. -ram_fringe_stop_step: - width: 17 - depth: 256 - mode: RW - descr: "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" + ram_fringe_stop_offset: + width: 10 + depth: 256 + mode : RW + descr: > + 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 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 - the look-up table contains 1024 complex values that make one sine-wave period. - - The index is determined as follows: - - index(t) = (offset + step*t) MOD 2^offset_w + peripheral_description: | + 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 + the look-up table contains 1024 complex values that make one sine-wave period. + + The index is determined as follows: + + index(t) = (offset + step*t) MOD 2^offset_w + + Where t ranges from 0 to Tmax-1. Tmax is the number of samples that fit in the control interval (the sync interval). + The fringe stop peripheral is capable to process 1 or more channels in series (nof_channels). + + Accumulation Register + The accumulation register that maintains the accumulated step value is flushed by the sync pulse in the system. + The accumulation register in the Apertif case is 31 bit wide. For the additon of the offset and the accumulated step the + 10 (offset_w) highest bit of the accumulated value are used --> offset(9:0) + step_accumulated(30:21). + + RAMs + The fringe stop interface is facilitated by two RAMs: + + -RAM_FRINGE_STOP_OFFSET + -RAM_FRINGE_STOP_STEP - Where t ranges from 0 to Tmax-1. Tmax is the number of samples that fit in the control interval (the sync interval). - The fringe stop peripheral is capable to process 1 or more channels in series (nof_channels). - - Accumulation Register - The accumulation register that maintains the accumulated step value is flushed by the sync pulse in the system. - The accumulation register in the Apertif case is 31 bit wide. For the additon of the offset and the accumulated step the - 10 (offset_w) highest bit of the accumulated value are used --> offset(9:0) + step_accumulated(30:21). - - RAMs - The fringe stop interface is facilitated by two RAMs: + Both RAMs are implemented as dual-page RAMs.The page swap is triggered by the sync-pulse. The VHDL is always accessing + 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: - -RAM_FRINGE_STOP_OFFSET - -RAM_FRINGE_STOP_STEP - - Both RAMs are implemented as dual-page RAMs.The page swap is triggered by the sync-pulse. The VHDL is always accessing - 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 - - 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 - the BSN Monitor at the input of the beamformer can be used. - - The depth of both RAMs is determined by the number of unique channels that ought to be processed. - - RAM_FRINGE_STOP_OFFSET - 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_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 - + _ 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 + + 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 + the BSN Monitor at the input of the beamformer can be used. + + The depth of both RAMs is determined by the number of unique channels that ought to be processed. + + RAM_FRINGE_STOP_OFFSET + 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_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 + diff --git a/tools/oneclick/prestudy/YAML/make_documentation.py b/tools/oneclick/prestudy/YAML/make_documentation.py new file mode 100755 index 0000000000..0a5cce3150 --- /dev/null +++ b/tools/oneclick/prestudy/YAML/make_documentation.py @@ -0,0 +1,87 @@ +#! /usr/bin/env python +""" +Make automatic documentation + +""" + +import sys +import os +import argparse +import subprocess +import traceback + +from py_mm_lib import * + +import common as cm + + +def main(): + root_dir = os.path.expandvars('$RADIOHDL/tools/oneclick/prestudy/YAML') + peri_lib = PeripheralLibrary(root_dir, "peripheral.yaml") + + data= {"system": "demo", "peripheral": "peri1", "description": "een iets lagere help tekst"} + make_documentation(data) + return "Normal ending" + + +def make_documentation(data): + """ + \vspace{1cm} + """ + header = \ +r''' +\documentclass{article} +\title{VHDL documentation} +\date{-now-} +\begin{document} +\textbf{\huge Documentation of %(system)s \\} +\\ +''' + footer= \ +r''' +\end{document} +''' + + content = \ +r''' +\textbullet \hspace{0.5cm} \textbf{%(peripheral)s \\} +%(description)s \\ +''' + with open('doc.tex','w') as f: + f.write(header%data) + f.write(content%data) + f.write(footer%data) + + proc = subprocess.Popen(['pdflatex', 'doc.tex']) + proc.communicate() + + os.unlink('doc.tex') + os.unlink('doc.aux') + os.unlink('doc.log') + + return + +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') + + parser = argparse.ArgumentParser() + parser.add_argument('-s', '--system', action='store_true', default=False, help='add system documentation') + parser.add_argument('-p', '--peripheral', action='store_true', default=False, help='add peripheral documentation') + parser.add_argument('-f', '--file', required=True, help='yaml file to generate documentation for.') + args = parser.parse_args() + + response = None + try: + response = 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(response) 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 1953cdda17..ebfc568fd7 100644 --- a/tools/oneclick/prestudy/YAML/mms_diag_block_gen/peripheral.yaml +++ b/tools/oneclick/prestudy/YAML/mms_diag_block_gen/peripheral.yaml @@ -1,28 +1,84 @@ --- -peripheral_name: mms_diag_block_gen - -nof_inst: 1 - -parameters: - g_nof_streams: 1 - g_buf_dat_w: 32 - g_buf_addr_w: 7 - -reg_diag_bg: - - Enable: { width: 2, mode: "RW", offset: 0x0, default: 0, descr: "Bit 0: enable the block generator Bit 1: enable the blok generator on PPS"} - - Samples_per_packet: { width: 16, mode: "RW", offset: 0x1, default: 256, descr: "This register specifies the number samples in a packet"} - - Blocks_per_sync: { width: 16, mode: "RW", offset: 0x2, default: 781250, descr: "This register specifies the number of packets in a sync period"} - - Gapsize: { width: 16, mode: "RW", offset: 0x3, default: 80, descr: "This register specifies the gap in number of clock cycles between two consecutive packets"} - - Mem_low_address: { width: 8, mode: "RW", offset: 0x4, default: 0, descr: "This register specifies the starting address for reading from the waveform memory"} - - Mem_high_address: { width: 8, mode: "RW", offset: 0x5, default: 0, descr: "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"} - - BSN_init_high: { width: 32, mode: "RW", offset: 0x7, default: 0, descr: "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" - -peripheral_description: " Block generator " - \ No newline at end of file +mms_diag_block_gen: + type : peripheral + nof_inst: 1 + + parameters: + g_nof_streams: 1 + g_buf_dat_w : 32 + g_buf_addr_w : 7 + + reg_diag_bg: + Enable: + width : 2 + mode : RW + offset : 0x0 + default : 0 + descr : > + Bit 0: enable the block generator Bit 1: enable the blok generator on PPS + + Samples_per_packet: + width : 16 + mode : RW + offset : 0x1 + default: 256 + descr : > + This register specifies the number samples in a packet + + Blocks_per_sync: + width : 16 + mode : RW + offset : 0x2 + default: 781250 + descr : > + This register specifies the number of packets in a sync period + + Gapsize: + width : 16 + mode : RW + offset : 0x3 + default: 80 + descr : > + This register specifies the gap in number of clock cycles between two consecutive packets + + Mem_low_address: + width : 8 + mode : RW + offset : 0x4 + default: 0 + descr : > + This register specifies the starting address for reading from the waveform memory + + Mem_high_address: + width : 8 + mode : RW + offset : 0x5 + default: 0 + descr : > + 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 + + BSN_init_high: + width : 32 + mode : RW + offset : 0x7 + default: 0 + descr : > + 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 + + peripheral_description: | + 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 2fbd03e181..cbf4c95e1b 100644 --- a/tools/oneclick/prestudy/YAML/mms_diag_data_buffer/peripheral.yaml +++ b/tools/oneclick/prestudy/YAML/mms_diag_data_buffer/peripheral.yaml @@ -1,139 +1,177 @@ --- -peripheral_name: mms_diag_data_buffer +mms_diag_data_buffer: + type : peripheral + nof_inst: 1 -nof_inst: 1 + parameters: + g_nof_streams : 1 + g_data_w : 32 + g_buf_nof_data: 1024 -parameters: - g_nof_streams: 1 - g_data_w: 32 - g_buf_nof_data: 1024 + reg_diag_data_buffer: + Sync_cnt: + width : 32 + mode : RO + 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) -reg_diag_data_buffer: - - Sync_cnt: { width: 32, mode: "RO", 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)"} - - Word_cnt: { width: 32, mode: "RO", 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."} - - Valid_cnt_arm_ena: { width: 32, mode: "RW", offset: 0x2, default: 0, descr: "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."} - - Reg_sync_delay: { width: 32, mode: "RW", 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."} - - Version: { width: 32, mode: "RO", offset: 0x7, default: 0, descr: "Version contains the version number of the databuffer peripheral."} + Word_cnt: + width : 32 + mode : RO + 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. -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." + Valid_cnt_arm_ena: + width : 32 + mode : RW + offset : 0x2 + default: 0 + descr : > + 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. -peripheral_description: "Peripheral diag_data_buffer - - Memory map RAM_DIAG_DATA_BUFFER - - If there is only one instance then the RAM name is RAM_DIAG_DATA_BUFFER, else it - gets an instanceName as post fix so RAM_DIAG_DATA_BUFFER_<instanceName>. - - 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: - - 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. - . The data buffer fills again after an external sync pulse or after the - last data word was read via the MM bus, dependend on whether the generic - g_use_in_sync is TRUE or FALSE in diag_data_buffer.vhd. - . 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) - |-----------------------------------------------------------------------| - - There are 3 modes of operation of the data_buffer. - Version 0 supports Mode 1 and Mode 2 - Version 1 supports Mode 1, Mode 2 and Mode 3 - - (1) NON-SYNC MODE: g_use_in_sync = FALSE - In this mode the first g_nof_data valid data input words are stored in the - data buffer. A new set of data will be stored when the last word is read - from the buffer via the MM interface. - - (2) SYNC-MODE: g_use_in_sync = TRUE and reg_sync_delay = 0 - On every received sync pulse a number of g_nof_data valid words are written - to the databuffer. Data will be overwritten on every new sync pulse. It is - up to the user to read out the data in time in between two sync pulses - - (3) ARM-MODE: g_use_in_sync = TRUE and reg_sync_delay > 0 - First the reg_sync_delay should be written with a desired delay value. Then - the arm register must be written. After being armed the databuffer will wait - for the first sync pulse to arrive. When it has arrived it will wait for - reg_sync_delay valid cycles before g_nof_data valid words are written to the - databuffer. The data can then be read out through the MM interface. New data - will only be written if the databuffer is being armed again. - - - 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 indicates the number of word currently (ST) written in the buffer. - Cleared on (ST) re-write of buffer. - - 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 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. - -" \ No newline at end of file + Reg_sync_delay: + width : 32 + mode : RW + 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. + + Version: + width : 32 + mode : RO + offset : 0x7 + default: 0 + descr : > + 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. + + peripheral_description: | + Peripheral diag_data_buffer + + Memory map RAM_DIAG_DATA_BUFFER + + If there is only one instance then the RAM name is RAM_DIAG_DATA_BUFFER, else it + gets an instanceName as post fix so RAM_DIAG_DATA_BUFFER_<instanceName>. + + 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: + + 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. + - The data buffer fills again after an external sync pulse or after the + last data word was read via the MM bus, dependend on whether the generic + g_use_in_sync is TRUE or FALSE in diag_data_buffer.vhd. + - 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) + |-----------------------------------------------------------------------| + + There are 3 modes of operation of the data_buffer. + Version 0 supports Mode 1 and Mode 2 + Version 1 supports Mode 1, Mode 2 and Mode 3 + + (1) NON-SYNC MODE: g_use_in_sync = FALSE + In this mode the first g_nof_data valid data input words are stored in the + data buffer. A new set of data will be stored when the last word is read + from the buffer via the MM interface. + + (2) SYNC-MODE: g_use_in_sync = TRUE and reg_sync_delay = 0 + On every received sync pulse a number of g_nof_data valid words are written + to the databuffer. Data will be overwritten on every new sync pulse. It is + up to the user to read out the data in time in between two sync pulses + + (3) ARM-MODE: g_use_in_sync = TRUE and reg_sync_delay > 0 + First the reg_sync_delay should be written with a desired delay value. Then + the arm register must be written. After being armed the databuffer will wait + for the first sync pulse to arrive. When it has arrived it will wait for + reg_sync_delay valid cycles before g_nof_data valid words are written to the + databuffer. The data can then be read out through the MM interface. New data + will only be written if the databuffer is being armed again. + + - 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 indicates the number of word currently (ST) written in the buffer. + Cleared on (ST) re-write of buffer. + - 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 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. 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 5880fd0730..9d652c1363 100644 --- a/tools/oneclick/prestudy/YAML/mms_dp_bsn_align/peripheral.yaml +++ b/tools/oneclick/prestudy/YAML/mms_dp_bsn_align/peripheral.yaml @@ -1,12 +1,21 @@ --- - peripheral_name: mms_dp_bsn_align - +mms_dp_bsn_align: + type : peripheral nof_inst: 1 parameters: g_nof_input: 4 reg_dp_bsn_align: - - Enable: { width: 1, mode: "RW", offset: 0x0, 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. "} - - peripheral_description: "This is the BSN aligner" \ No newline at end of file + Enable: + width : 1 + mode : RW + offset : 0x0 + 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. + + peripheral_description: | + 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 bed785c93e..d8d82a127c 100644 --- a/tools/oneclick/prestudy/YAML/mms_dp_fifo_fill/peripheral.yaml +++ b/tools/oneclick/prestudy/YAML/mms_dp_fifo_fill/peripheral.yaml @@ -1,14 +1,39 @@ --- -peripheral_name: mms_dp_fifo_fill +mms_dp_fifo_fill: + type : peripheral + nof_inst: 1 -nof_inst: 1 + parameters: + g_nof_streams: 4 -parameters: - g_nof_streams: 4 + reg_dp_fifo_fill: + fifo_used_words: + width : 32 + mode : RO + offset : 0x0 + default: 0 + repeat : g_nof_streams + descr : > + Register reflects the currently used nof words on the fifo. -reg_dp_fifo_fill: - - fifo_used_words: { width: 32, mode: "RO", offset: 0x0, default: 0, repeat: g_nof_streams, descr: "Register reflects the currently used nof words on the fifo."} - - fifo_status: { width: 2, mode: "RO", offset: 0x0, default: 0, repeat: g_nof_streams, descr: "Bit 0: fifo_read_empty Bit 1: fifo_wr_full"} - - max_fifo_used_words: { width: 32, mode: "RO", offset: 0x0, 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."} + fifo_status: + width: 2 + mode : RO + offset : 0x0 + default: 0 + repeat : g_nof_streams + descr : > + Bit 0: fifo_read_empty Bit 1: fifo_wr_full. -peripheral_description: "This is the MM slave version of the dp_fifo_fill component." + max_fifo_used_words: + width : 32 + mode : RO + offset : 0x0 + 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. + + peripheral_description: | + This is the MM slave version of the dp_fifo_fill component. diff --git a/tools/oneclick/prestudy/YAML/peripheral.py b/tools/oneclick/prestudy/YAML/peripheral.py deleted file mode 100644 index f6506e9db2..0000000000 --- a/tools/oneclick/prestudy/YAML/peripheral.py +++ /dev/null @@ -1,416 +0,0 @@ -############################################################################### -# -# 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 -# -############################################################################### - - -############################################################################### - -import os -import copy -import yaml -import argparse -import common as cm - -field_modes = ["RO", "WO", "RW", "WP", "RR"] - -class Field: - """ A field defines data at certain address or an array of addresses - """ - def __init__(self, name, width, mode, offset, default, descr, repeat=None): - self.name = name - self.width = width - if mode in field_modes: - self.mode = mode - else: - self.mode = "" - - self.offset = offset - self.default = default - self.descr = descr - self.repeat = repeat - - -class Register: - """ A register consists of Fields - """ - def __init__(self, name, fields = [], nof_inst = 1): - self.name = name - self.fields = fields - self.nof_inst = nof_inst - self.depth = self.nof_inst * cm.ceil_pow2(len(fields)) - - def addField(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 setDepth(self): - self.depth = self.nof_inst * cm.ceil_pow2(len(self.fields)) - - def setNof_inst(self, nof_inst): - self.nof_inst = nof_inst - - -class RAM(Field): - """ A RAM is a Field that is repeated depth times - """ - def __init__(self, name, width, mode, depth, nof_inst, descr): - Field.__init__(self, name, width, mode, 0x0, 0, descr) - self.depth = depth - self.nof_inst = nof_inst - - -class FIFO(Field): - """ A FIFO is a specific set of Fields - """ - 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 - - -class Parameter: - """ A Parameter defines a name and value - """ - def __init__(self, name, value): - self.name = name - self.value = value - - -class Peripheral: - """ 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 - instance. - 2) At peripheral level internally in the peripheral if the peripheral - support an array of instances. The size of the array is then specified - 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 - 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.parameters = {} - self.registers = [] - self.rams = [] - self.fifos = [] - - def setName(self, name): - self.name = name - - def setNof_inst(self, nof_inst): - self.nof_inst = nof_inst - - def setLabel(self, label): - self.label = label - - def addParameter(self, name, value): - self.parameters.append(Parameter(name, value)) - - def addRegister(self, name, fields): - self.registers.append(Register(name, fields, self.nof_inst)) - - def addRAM(self, name, width, mode, depth, descr): - self.rams.append(RAM(name, width, mode, depth, self.nof_inst, descr)) - - def evalRAM(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 - print 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) - print ram.depth - print ram.width - ram.width = eval(str(ram.width)) # Here the variables are used to evaluate the true value for the width parameter. - print ram.width - print " " + ram.name + " " + "depth: " + str(ram.depth) - print " " + ram.name + " " + "width: " + str(ram.width) - - def evalRegister(self): - """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: - 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. - 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)) - offset = offset + 1 - register.fields = fields_eval # Update the fields with evaluated fields - register.name = register.name + self.postfix # Create the name - register.setNof_inst(self.nof_inst) - register.setDepth() # Estimate the new depth after evaluation of the fields and nof_inst - print " " + register.name + " " + "depth: " + str(register.depth) - - def evalPeripheral(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 """ - if self.label: - self.postfix = "_" + self.label - self.setName(self.name + self.postfix) - print " Evaluating peripheral: " + self.name - self.evalRAM() - self.evalRegister() - - -class PeripheralLibrary: - """ List of all information for peripheral config files in the root dir - """ - def __init__(self, rootDir, fileName='peripheral.yaml'): - """Store the dictionaries from all fileName files in rootDir.""" - self.rootDir = rootDir - self.fileName = fileName # all peripheral files have the same fileName - self.filePaths = cm.find_all_file_paths(rootDir, fileName) # list of all directory paths of peripheral files that are available in the rootDir tree - if len(self.filePaths)==0: - sys.exit('Error : No %s file found in %s directory tree.' % (fileName, rootDir)) - self.filePathNames = [] # list of all directory paths + fileName of the available peripheral files - for path in self.filePaths: - self.filePathNames.append(os.path.join(path, self.fileName)) - self.peripheralConfigs = self.read_all_peripheral_files() # list of peripheral configurations that are read from the available peripheral files - self.nof_peripheralConfigs = len(self.peripheralConfigs) # number of peripheral configurations - self.peripherals = self.create_all_peripherals() - self.nof_peripherals = len(self.peripherals) # number of peripherals - - def read_all_peripheral_files(self, filePathNames=None): - """Read the peripheral information from all peripheral files that were found in the rootDir tree.""" - if filePathNames==None: filePathNames=self.filePathNames - read_peripherals = [] - for fp in self.filePathNames: - read_peripherals.append(self.read_peripheral_file(fp)) - return read_peripherals - - def read_peripheral_file(self, filePathName=None): - """Read the peripheral information from the filePathName file.""" - if filePathName==None: filePathName=self.filePathNames[0] - - with open (filePathName, "r") as myfile: - peripheral_yaml_config=myfile.read() - peripheral_config = yaml.load(peripheral_yaml_config) - return peripheral_config - - def create_all_peripherals(self, peripheralConfigs=None): - """Create peripheral objects from all peripheral configurations.""" - if peripheralConfigs==None: peripheralConfigs=self.peripheralConfigs - peripherals = [] - for peripheralConfig in peripheralConfigs: - peripherals.append(self.create_peripheral(peripheralConfig)) - return peripherals - - def create_peripheral(self, peripheralConfig=None): - """Create a peripheral object based on the information in the peripheralConfig""" - if peripheralConfig==None: peripheralConfig=self.peripheralConfigs[0] - peripheral = Peripheral(peripheralConfig["peripheral_name"], peripheralConfig["nof_inst"], peripheralConfig["peripheral_description"]) - - for key in peripheralConfig.keys(): - if "ram_" in key: - peripheral.addRAM(key, peripheralConfig[key]["width"], peripheralConfig[key]["mode"], peripheralConfig[key]["depth"], peripheralConfig[key]["descr"]) - if "reg_" in key: - fields = [] - for reg_key in peripheralConfig[key]: -# print reg_key -# print reg_key.keys() -# print reg_key.values() -# print reg_key.values()[0] - repeat = None - if "repeat" in reg_key.values()[0].keys(): - repeat = reg_key.values()[0]["repeat"] # print "YES!" - fields.append(Field(reg_key.keys()[0], reg_key.values()[0]["width"], reg_key.values()[0]["mode"], reg_key.values()[0]["offset"], reg_key.values()[0]["default"], reg_key.values()[0]["descr"], repeat)) - peripheral.addRegister(key, fields) - if "parameters" in key: - for param_key in peripheralConfig[key]: - peripheral.parameters[param_key] = peripheralConfig[key][param_key] - - return peripheral - - def find_peripheral(self, name, peripheral_library=None): - if peripheral_library == None: - peripheral_library = self.peripherals - return_peripheral = None - for peripheral in peripheral_library: - if peripheral.name == name: - return_peripheral = peripheral - - return return_peripheral - - -class System: - """ A System consist of a set of one or more Peripherals. - """ - def __init__(self, filePathName=None): - self.filePathName = filePathName - self.rootDir = os.environ['RADIOHDL'] + "/tools/oneclick/prestudy/YAML" - self.peri_lib = PeripheralLibrary(self.rootDir, "peripheral.yaml") - self.peripherals = [] - - if filePathName==None: - print "No system configuration file specified" - self.systemConfig = None - self.system = None - else: - self.systemConfig = self.read_system_file(filePathName) # list of peripheral configurations that are read from the available peripheral files - self.system = self.create_system(self.systemConfig) - - def read_system_file(self, filePathName=None): - """Read the system information from the filePathName file.""" - if filePathName==None: filePathName=self.filePathNames[0] - - with open (filePathName, "r") as myfile: - system_yaml_config=myfile.read() - system_config = yaml.load(system_yaml_config) - return system_config - - def create_system(self, systemConfig=None): - """Create a system object based on the information in the systemConfig""" - print "Creating system" - print "Instantiating the peripherals from the peripheral Library" - for key in systemConfig.keys(): - if key == "system_name": - self.name = systemConfig[key] - if key == "system_descr": - self.descr = systemConfig[key] - if key == "peripherals": - for peripheral in systemConfig[key]: - peripheral_from_lib = copy.deepcopy(self.peri_lib.find_peripheral(peripheral.keys()[0])) # (Deep)Copy the peripheral from the library in order to avoid creating a reference - print " Finding " + peripheral_from_lib.name - for parameter in peripheral.values()[0]: - if parameter == "nof_inst": - peripheral_from_lib.setNof_inst(peripheral.values()[0][parameter]) - elif parameter == "label": - peripheral_from_lib.setLabel(peripheral.values()[0][parameter]) - elif parameter in peripheral_from_lib.parameters: - print " Parameter " + parameter + " default value:" + str(peripheral_from_lib.parameters[parameter]) + " is overwritten with new value: " + str(peripheral.values()[0][parameter]) - peripheral_from_lib.parameters[parameter] = peripheral.values()[0][parameter] - else: - print " !!! Parameter " + parameter + " does not exist on peripheral: " + peripheral_from_lib.name + " !!!" - - peripheral_check = self.peri_lib.find_peripheral(peripheral_from_lib.name, self.peripherals) - if peripheral_check == None: # Check if peripheral already exists in the systemLibrary - self.peripherals.append(peripheral_from_lib) - elif peripheral_check.label == peripheral_from_lib.label: - print " Duplicate found: use unique labels per instance to distinguish between multiple instances of the same peripheral." - print " Cannot add a second instance of peripheral: " + peripheral_from_lib.name - else: - self.peripherals.append(peripheral_from_lib) - - print "Evaluating the peripherals" - for peripheral in self.peripherals: - peripheral.evalPeripheral() - - def display_system(self): - print "" - print "----------------" - print "SYSTEM OVERVIEW:" - print "----------------" - print " System name: " + self.name - for peripheral in self.peripherals: - print " " + peripheral.name + "(" + str(peripheral.nof_inst) + ")" - print " RAMs and registers:" - for ram in peripheral.rams: - print " " + ram.name + " " + str(ram.width) + " " + str(ram.depth) - for reg in peripheral.registers: - print " " + reg.name + " " + str(reg.depth) - for field in reg.fields: - print " " + field.name + " " + str(field.width) + " " + str(field.mode) + " " + str(field.offset) - print " parameters:" - for param in peripheral.parameters: - - print " " + param + " " + str(peripheral.parameters[param]) - print "" - - -class SystemParseArgs: - """ Parse command line arguments - """ - def __init__(self): - # Parse command line arguments - argparser = argparse.ArgumentParser(description='System and peripheral config command line parser arguments') - argparser.add_argument('-p','--peripheral', default=None, required=False, help='peripheral names separated by commas') - argparser.add_argument('-s','--system', default=None, required=False, help='system names separated by commas') - argparser.add_argument('-r','--run', required=False, action='store_true', default=False, help='run command') - argparser.add_argument('-v','--verbosity', required=False, type=int, default=0, help='verbosity >= 0 for more info') - args = vars(argparser.parse_args()) - - # Keep the argparser for external access of e.g. print_help - self.argparser = argparser - - # Keep arguments in class record - self.peripheral_names = [] - if args['peripheral']!=None: - self.peripheral_names = args['peripheral'].split(',') - - self.system_names = [] - if args['system']!=None: - self.system_names = args['system'].split(',') - - self.run = args['run'] - - self.verbosity = args['verbosity'] - - -if __name__ == '__main__': - # 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 - system_args = SystemParseArgs() - - # Read the peripheral configuration files from the root in the current directory and the sub directories - #hdl = HdlConfig(toolRootDir=os.path.expandvars('$RADIOHDL/tools/oneclick/prestudy/YAML'), libFileName='hdllib.cfg', toolFileName=cli_args.toolFileName) - - if mode==0: - rootDir = os.path.expandvars('$RADIOHDL/tools/oneclick/prestudy/YAML') - - peri_lib = PeripheralLibrary(rootDir, "peripheral.yaml") - - system = System(rootDir + "/system.yaml") - - system.display_system() diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py b/tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py new file mode 100644 index 0000000000..466784ccfb --- /dev/null +++ b/tools/oneclick/prestudy/YAML/py_mm_lib/__init__.py @@ -0,0 +1,9 @@ +""" init file for py_mm_lib +""" + +import os +from my_logger import MyLogger +mylogger = MyLogger(os.path.join(os.getcwd(), 'log')) +logger = mylogger.logger + +from peripheral import PeripheralLibrary diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/my_logger.py b/tools/oneclick/prestudy/YAML/py_mm_lib/my_logger.py new file mode 100644 index 0000000000..715d8ca5fa --- /dev/null +++ b/tools/oneclick/prestudy/YAML/py_mm_lib/my_logger.py @@ -0,0 +1,77 @@ + +import os +import logging +import time + +# first start main logging before including checkhardware_lib +# backup log files +class MyLogger(object): + def __init__(self, log_path, file_name=None): + self.log_levels = {'DEBUG' : logging.DEBUG, + 'INFO' : logging.INFO, + 'WARNING': logging.WARNING, + 'ERROR' : logging.ERROR} + + self.log_path = log_path + self.filename = None + self.stdout_log_level = 'WARNING' + self.file_log_level = 'INFO' + self.backup_depth = 4 + self.file_logger_handler = None + self.stdout_logger_handler = None + + self.logger = logging.getLogger('main') + self.logger.setLevel(logging.DEBUG) + self._setup_stdout_logging() + if file_name is not None: + self.set_logfile_name(file_name) + + def set_logfile_name(self, name): + self.filename = name + self._backup_logfiles() + self._setup_file_logging() + + def set_stdout_log_level(self, level): + if level in self.log_levels: + self.stdout_log_level = level + if self.stdout_logger_handler: + self.stdout_logger_handler.setLevel(self.log_levels[level]) + else: + self.logger.error("'{}' is not a valid level".format(level)) + + def set_file_log_level(self, level): + if level in self.log_levels: + self.file_log_level = level + if self.file_logger_handler: + self.file_logger_handler.setLevel(self.log_levels[level]) + else: + self.logger.error("'{}' is not a valid level".format(level)) + + def _backup_logfiles(self): + for nr in range(self.backup_depth-1, -1, -1): + if nr == 0: + full_filename = os.path.join(self.log_path, '{}.log'.format(self.filename)) + else: + full_filename = os.path.join(self.log_path, '{}.log.{}'.format(self.filename, nr)) + full_filename_new = os.path.join(self.log_path, '{}.log.{}'.format(self.filename, nr+1)) + if os.path.exists(full_filename): + os.rename(full_filename, full_filename_new) + + def _setup_stdout_logging(self): + # create console handler + stream_handler = logging.StreamHandler() + formatter = logging.Formatter('%(asctime)s %(name)-15s %(levelname)-7s %(message)s') + stream_handler.setFormatter(formatter) + stream_handler.setLevel(self.log_levels[self.stdout_log_level]) + self.logger.addHandler(stream_handler) + self.stdout_logger_handler = self.logger.handlers[0] + + def _setup_file_logging(self): + # create file handler + full_filename = os.path.join(self.log_path, '{}.log'.format(self.filename)) + file_handler = logging.FileHandler(full_filename, mode='w') + formatter = logging.Formatter('%(asctime)s %(name)-15s %(levelname)-8s %(message)s') + file_handler.setFormatter(formatter) + file_handler.setLevel(self.log_levels[self.file_log_level]) + self.logger.addHandler(file_handler) + self.file_logger_handler = self.logger.handlers[1] diff --git a/tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py b/tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py new file mode 100755 index 0000000000..fb686cbc68 --- /dev/null +++ b/tools/oneclick/prestudy/YAML/py_mm_lib/peripheral.py @@ -0,0 +1,286 @@ +############################################################################### +# +# 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 logging +import common as cm + +logger = logging.getLogger('main.peripheral') + +class Field(object): + """ A field defines data at certain address or an array of addresses + """ + def __init__(self, name, width, mode, offset, default, descr, repeat=None): + self.name = name + self.width = width + 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)) + self.mode = "" + + self.offset = offset + self.default = default + 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 + 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 set_depth(self): + self.depth = self.nof_inst * cm.ceil_pow2(len(self.fields)) + + def set_nof_inst(self, nof_inst): + self.nof_inst = nof_inst + + +class RAM(Field): + """ A RAM is a Field that is repeated depth times + """ + def __init__(self, name, width, mode, depth, nof_inst, descr): + Field.__init__(self, name, width, mode, 0x0, 0, descr) + self.depth = depth + self.nof_inst = nof_inst + + +class FIFO(Field): + """ A FIFO is a specific set of Fields + """ + 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 + + +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 + instance. + 2) At peripheral level internally in the peripheral if the peripheral + support an array of instances. The size of the array is then specified + 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 + 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.parameters = {} + self.registers = [] + self.rams = [] + self.fifos = [] + + def set_name(self, name): + self.name = name + + def set_nof_inst(self, nof_inst): + 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 add_register(self, name, fields): + self.registers.append(Register(name, fields, self.nof_inst)) + + def add_RAM(self, name, width, mode, depth, descr): + self.rams.append(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)) + + def eval_register(self): + """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: + 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. + 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)) + 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)) + + 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 """ + 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.eval_register() + + +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 + 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 + 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 + #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.""" + 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) + 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): + if peripheral_library is None: + return self.peripherals.get(name, None) + return peripheral_library.get(name, None) + diff --git a/tools/oneclick/prestudy/YAML/system.py b/tools/oneclick/prestudy/YAML/system.py new file mode 100755 index 0000000000..0b687afaae --- /dev/null +++ b/tools/oneclick/prestudy/YAML/system.py @@ -0,0 +1,182 @@ +#!/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 98f8cde46f..5aa6647f53 100644 --- a/tools/oneclick/prestudy/YAML/system.yaml +++ b/tools/oneclick/prestudy/YAML/system.yaml @@ -1,24 +1,80 @@ --- -system_name: demo - -board_select: unb1 -bus_select : qsys - - -peripherals: - #- reg_system_info {locked_address : 0} - #- rom_system_info {locked_address : 0x20} - - fringe_stop: {nof_inst: 1} - - mms_diag_block_gen: {nof_inst: 1, label: "input", g_nof_streams: 12, g_buf_addr_w: 7} - - mms_diag_block_gen: {nof_inst: 1, label: "mesh", g_nof_streams: 8, g_buf_addr_w: 8} - - mms_diag_block_gen: {nof_inst: 1, label: "proc", g_nof_streams: 12, g_buf_addr_w: 7} - - bf_unit: {nof_inst: 3, g_weights_w: 3, g_nof_weights: 128, g_nof_signal_paths: 32, g_nof_subbands: 12, g_nof_signal_paths_per_stream: 2, g_nof_input_streams: 8} - - mms_diag_block_gen: {nof_inst: 1, label: "output", g_nof_streams: 2} - - mms_diag_data_buffer: {nof_inst: 1, label: "input_pre", g_nof_streams: 12, g_data_w: 16, g_buf_nof_data: 8192} - - mms_diag_data_buffer: {nof_inst: 1, label: "input_post", g_nof_streams: 12, g_data_w: 16, g_buf_nof_data: 8192} - - mms_diag_data_buffer: {nof_inst: 1, label: "mesh", g_nof_streams: 8, g_data_w: 16, g_buf_nof_data: 8} - - mms_diag_data_buffer: {nof_inst: 1, label: "proc", g_nof_streams: 12, g_data_w: 16, g_buf_nof_data: 128} - - mms_dp_bsn_align: {nof_inst: 1, label: "input", g_nof_input: 3} - - mms_dp_fifo_fill: {nof_inst: 1, label: "", g_nof_streams: 3} - - \ No newline at end of file +demo: + type: system + + board_select: unb1 + + bus_select : qsys + + reg_system_info: + locked_address: 0 + + rom_system_info: + locked_address: 0x20 + + + peripherals: + + fringe_stop: + nof_inst: 1 + + mms_diag_block_gen.input: + nof_inst : 1 + g_nof_streams: 12 + g_buf_addr_w : 7 + + mms_diag_block_gen.mesh: + 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 + g_nof_weights : 128 + g_nof_signal_paths : 32 + 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 + -- GitLab