Skip to content
Snippets Groups Projects
Commit 613ff66a authored by Eric Kooistra's avatar Eric Kooistra
Browse files

Merge branch 'L2SDP-186' into 'master'

Resolve L2SDP-186

Closes L2SDP-186

See merge request desp/hdl!71
parents b4d53638 aa3cb9af
No related branches found
No related tags found
2 merge requests!100Removed text for XSub that is now written in Confluence Subband correlator...,!71Resolve L2SDP-186
Showing with 1223 additions and 643 deletions
schema_name : args
schema_version: 1.0
schema_type : fpga
hdl_library_name: lofar2_unb2b_adc
fpga_name : lofar2_unb2b_adc
fpga_description: "FPGA design lofar2_unb2b_adc"
peripherals:
#############################################################################
# Factory
#############################################################################
- peripheral_name: unb2b_board/system_info
slave_port_names:
- ROM_SYSTEM_INFO
- PIO_SYSTEM_INFO
lock_base_address: 0x10000
- peripheral_name: unb2b_board/wdi
slave_port_names:
- PIO_WDI
- peripheral_name: unb2b_board/unb2_fpga_sens
slave_port_names:
- REG_FPGA_TEMP_SENS
- REG_FPGA_VOLTAGE_SENS
- peripheral_name: unb2b_board/ram_scrap
slave_port_names:
- RAM_SCRAP
- peripheral_name: eth/eth
slave_port_names:
- AVS_ETH_0_TSE
- AVS_ETH_0_REG
- AVS_ETH_0_RAM
- peripheral_name: ppsh/ppsh
slave_port_names:
- PIO_PPS
- peripheral_name: epcs/epcs
slave_port_names:
- REG_EPCS
- peripheral_name: dp/dpmm
slave_port_names:
- REG_DPMM_CTRL
- REG_DPMM_DATA
- peripheral_name: dp/mmdp
slave_port_names:
- REG_MMDP_CTRL
- REG_MMDP_DATA
- peripheral_name: remu/remu
slave_port_names:
- REG_REMU
#############################################################################
# Application
#############################################################################
- peripheral_name: tech_jesd204b/jesd_ctrl
slave_port_names:
- PIO_JESD_CTRL
- peripheral_name: tech_jesd204b/jesd204b_arria10
slave_port_names:
- JESD204B
- peripheral_name: dp/dp_shiftram
parameter_overrides:
- { name: g_nof_streams, value: 12 } # = S_pn
- { name: g_nof_words, value: 4096 }
- { name: g_data_w, value: 16 }
slave_port_names:
- REG_DP_SHIFTRAM
- peripheral_name: dp/dp_bsn_source
parameter_overrides:
- { name: g_nof_block_per_sync, value: 195313 } # 390625 = 2 * 195312, to have integer number of blocks in 2 s sync interval
slave_port_names:
- REG_BSN_SOURCE
# TODO: Use REG_BSN_SOURCE_V2 instead of REG_BSN_SOURCE
#peripheral_name: dp/dp_bsn_source_v2
#parameter_overrides:
# - { name: g_nof_clk_per_sync, value: 200000000 } # = f_adc
# - { name: g_block_size, value: 1024 } # = N_fft
# - { name: g_bsn_time_offset_w, value: 10 } # note: g_bsn_time_offset_w = ceil_log2(g_block_size)
#slave_port_names:
# - REG_BSN_SOURCE_V2
- peripheral_name: dp/dp_bsn_scheduler
slave_port_names:
- REG_BSN_SCHEDULER
- peripheral_name: dp/dp_bsn_monitor
peripheral_group: input
slave_port_names:
- REG_BSN_MONITOR_INPUT
- peripheral_name: diag/diag_wg_wideband
parameter_overrides:
- { name: g_nof_streams, value: 12 } # = S_pn
slave_port_names:
- REG_DIAG_WG
- RAM_DIAG_WG
- peripheral_name: aduh/aduh_mon_dc_power
parameter_overrides:
- { name: g_nof_streams, value: 12 } # = S_pn
slave_port_names:
- REG_ADUH_MON
# Commented RAM_ADUH_MON, because use RAM_DIAG_DATA_BUF_BSN instead
#- peripheral_name: aduh/aduh_mon_data_buffer
# parameter_overrides:
# - { name: g_nof_streams, value: 12 } # = S_pn
# - { name: g_symbol_w, value: 16 }
# - { name: g_nof_symbols_per_data, value: 1 }
# - { name: g_buffer_nof_symbols, value: 512 }
# - { name: g_buffer_use_sync, value: true }
# slave_port_names:
# - RAM_ADUH_MON
- peripheral_name: diag/diag_data_buffer
peripheral_group: bsn
parameter_overrides:
- { name: g_nof_streams, value: 12 } # = S_pn
- { name: g_data_w, value: 16 }
- { name: g_nof_data, value: 1024 }
slave_port_names:
- REG_DIAG_DATA_BUF_BSN
- RAM_DIAG_DATA_BUF_BSN
...@@ -4,46 +4,53 @@ schema_type : fpga ...@@ -4,46 +4,53 @@ schema_type : fpga
hdl_library_name: unb2b_minimal hdl_library_name: unb2b_minimal
fpga_name : unb2b_minimal fpga_name : unb2b_minimal
fpga_description: "unb2b_minimal system" fpga_description: "FPGA design unb2b_minimal"
peripherals: peripherals:
- peripheral_name: unb2b_board/unb2b - peripheral_name: unb2b_board/system_info
slave_port_names: slave_port_names:
- rom_system_info - ROM_SYSTEM_INFO
- pio_system_info - PIO_SYSTEM_INFO
- pio_wdi lock_base_address: 0x10000
- reg_wdi
- reg_unb_sens - peripheral_name: unb2b_board/wdi
- reg_unb_pmbus slave_port_names:
- reg_fpga_temp_sens - PIO_WDI
- reg_fpga_voltage_sens
- ram_scrap - peripheral_name: unb2b_board/unb2_fpga_sens
parameter_overrides: slave_port_names:
- { name : g_sim, value: FALSE } - REG_FPGA_TEMP_SENS
- { name : g_clk_freq, value: 125E6 } - REG_FPGA_VOLTAGE_SENS
- { name : g_temp_high, value: 85 }
- peripheral_name: unb2b_board/ram_scrap
lock_base_address: 0x0 slave_port_names:
lock_base_address: 0x4000 - RAM_SCRAP
- peripheral_name: eth/eth1g - peripheral_name: eth/eth
slave_port_names: slave_port_names:
- avs_eth_0_tse - AVS_ETH_0_TSE
- avs_eth_0_reg - AVS_ETH_0_REG
- avs_eth_0_ram - AVS_ETH_0_RAM
- peripheral_name: ppsh/ppsh - peripheral_name: ppsh/ppsh
slave_port_names: slave_port_names:
- pio_pps - PIO_PPS
- peripheral_name: epcs/epcs - peripheral_name: epcs/epcs
slave_port_names: slave_port_names:
- reg_epcs - REG_EPCS
- reg_dpmm_ctrl
- reg_dpmm_data - peripheral_name: dp/dpmm
- reg_mmdp_ctrl slave_port_names:
- reg_mmdp_data - REG_DPMM_CTRL
parameter_overrides: - REG_DPMM_DATA
- { name : g_sim_flash_model, value: FALSE }
- peripheral_name: dp/mmdp
slave_port_names:
- REG_MMDP_CTRL
- REG_MMDP_DATA
- peripheral_name: remu/remu - peripheral_name: remu/remu
slave_port_names: slave_port_names:
- reg_remu - REG_REMU
...@@ -3,122 +3,166 @@ schema_name: args ...@@ -3,122 +3,166 @@ schema_name: args
schema_version: 1.0 schema_version: 1.0
schema_type: peripheral schema_type: peripheral
hdl_library_name : unb2b_board hdl_library_name: unb2b_board # ctrl_unb2b_board.vhd
hdl_library_description: " This is the description for the unb2b_board package " hdl_library_description: "Peripherals in unb2b_board."
# <peripheral_group>_<peripheral_name>_<slave_name>_<slave_type>
peripherals: peripherals:
- peripheral_name: ram_scrap # pi_ram_scrap.py
- peripheral_name: unb2b peripheral_description: ""
parameters:
- { name: g_sim, value: FALSE }
- { name: g_clk_freq, value: c_unb2b_board_mm_clk_freq_125M }
- { name: g_temp_high, value: 85 }
slave_ports: slave_ports:
# rom_system_info # MM port for common_ram_r_w.vhd
- slave_name : rom_system - slave_name: RAM_SCRAP
slave_type : REG slave_type: RAM
slave_description: "One memory mapped block RAM for MM access test purposes."
fields: fields:
- - field_name : info - - field_name: rw_data
access_mode : RO field_description: "Void data"
access_mode: RW
address_offset: 0x0 address_offset: 0x0
number_of_fields: 8192 number_of_fields: 512
field_description: |
"address place for rom_system_info"
slave_description: " rom_info "
# reg_system_info - peripheral_name: system_info # pi_system_info.py
- slave_name : system peripheral_description: ""
slave_type : REG slave_ports:
# MM port for mms_unb2b_board_system_info.vhd / common_rom.vhd
- slave_name: ROM_SYSTEM_INFO # for c_rom_version = 1 in ctrl_unb2b_board.vhd
#- slave_name: ROM_SYSTEM_INFO_V2 # for c_rom_version = 2 in ctrl_unb2b_board.vhd
slave_type: RAM
slave_description: "Memory that stores the MM map system info of the mmap file."
fields: fields:
- - field_name : info - - field_name: ro_data
field_description: "FPGA info memory map data"
access_mode: RO access_mode: RO
address_offset: 0x0 address_offset: 0x0
number_of_fields: 32 number_of_fields: 8192 # c_rom_addr_w in mms_unb2b_board_system_info
field_description: | radix: char
"address place for reg_system_info"
slave_description: " reg_info "
# actual hdl name: unb2b_board_wdi_reg # MM port for mms_unb2b_board_system_info.vhd / unb2b_board_system_info_reg.vhd
- slave_name : ctrl - slave_name: PIO_SYSTEM_INFO
slave_type: REG slave_type: REG
slave_description: "FPGA design name, design note, version and location index info."
fields: fields:
- - field_name : nios_reset # All registers in one array
width : 32 #- - field_name: info
access_mode : WO # field_description: "FPGA info register, see pi_system_info.py for field details."
address_offset : 0x0 # access_mode: RO
number_of_fields: 4 # address_offset: 0x0
field_description: " Reset done by nios " # number_of_fields: 32
slave_description: "Reset register, for nios " # Each field specified
- "info": # field_group
- field_name: gn_index
field_description: "Global node index, unb2 FPGA id = gn_index % 4, unb2 backplane id = gn_index // 4"
width: 8
bit_offset: 0
access_mode: RO
address_offset: 0x0
- field_name: hw_version
field_description: "UniBoard2 hardware (HW) version."
width: 2
bit_offset: 8
access_mode: RO
address_offset: 0x0
- field_name: cs_sim
field_description: "0 when running on HW, 1 when running in simulation."
width: 1
bit_offset: 10
access_mode: RO
address_offset: 0x0
- field_name: fw_version_major
field_description: "FPGA Firmware (FW) version major number, not used use version stamp instead."
width: 4
bit_offset: 16
access_mode: RO
address_offset: 0x0
- field_name: fw_version_minor
field_description: "FPGA Firmware (FW) version minor number, not used use version stamp instead."
width: 4
bit_offset: 20
access_mode: RO
address_offset: 0x0
- field_name: rom_version
field_description: "Version of the mmap schema in ROM_SYSTEM_INFO."
width: 3
bit_offset: 24
access_mode: RO
address_offset: 0x0
- field_name: technology
field_description: "FPGA technology"
width: 5
bit_offset: 27
access_mode: RO
address_offset: 0x0
- - field_name: use_phy
field_description: "PHY interfaces that are active in the FPGA, not used."
width: 8
access_mode: RO
address_offset: 0x4
- - field_name: design_name
field_description: "FPGA FW design name string."
access_mode: RO
address_offset: 0x8
number_of_fields: 13
radix: char
- - field_name: stamp_date
field_description: "FPGA FW compile date string."
access_mode: RO
address_offset: 0x3C
number_of_fields: 1
- - field_name: stamp_time
field_description: "FPGA FW compile time string."
access_mode: RO
address_offset: 0x40
number_of_fields: 1
- - field_name: stamp_commit
field_description: "FPGA FW commit hash string."
access_mode: RO
address_offset: 0x44
number_of_fields: 3
radix: hexadecimal
- - field_name: design_note
field_description: "FPGA FW design note string."
access_mode: RO
address_offset: 0x50
number_of_fields: 13
radix: char
# actual hdl name: unb2b_board_wdi_reg - peripheral_name: wdi # pi_wdi.py
- slave_name : wdi peripheral_description: ""
slave_ports:
# MM port for unb2b_board_wdi_reg.vhd
- slave_name: REG_WDI
slave_type: REG slave_type: REG
slave_description: "Reset register, if the right value is provided the factory image will be reloaded in the FPGA."
fields: fields:
- - field_name : reset_word - - field_name: wdi_override
field_description: "Write value 0xB007FAC7 = 'Boot factory' to disable the watchdog interrupt (WDI), to cause an FPGA image reload."
access_mode: WO access_mode: WO
address_offset: 0x0 address_offset: 0x0
field_description: " Only the value 0xB007FAC7 'Boot factory' will result in a reset "
slave_description: "Reset register, if the right value is provided the factory image will be reloaded " - peripheral_name: unb2_fpga_sens
peripheral_description: ""
# actual hdl name: reg_unb2b_sens slave_ports:
- slave_name : board_sens # MM ports for mms_unb2b_fpga_sens.vhd / unb2b_fpga_sens_reg.vhd
slave_type : REG - slave_name: REG_FPGA_TEMP_SENS # pi_unb_fpga_sens.py
fields:
- - field_name : sens
width : 32
access_mode : RO
address_offset: 0x00
number_of_fields: 41
field_description: ""
slave_description: " "
- slave_name : board_pmbus
slave_type : REG
fields:
- - field_name : pmbus
width : 32
access_mode : RO
address_offset: 0x00
number_of_fields: 43
field_description: ""
slave_description: " "
# actual hdl name: reg_unb2b_sens
- slave_name : fpga_temp
slave_type: REG slave_type: REG
slave_description: |
"FPGA temperature = (AxC)/1024 - B (where A=708; B=273; C=adc value), see page 10 in
https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_alttemp_sense.pdf"
fields: fields:
- - field_name: temp - - field_name: temp
width : 32 field_description: "Raw data"
access_mode: RO access_mode: RO
address_offset: 0x00 address_offset: 0x0
number_of_fields: 1 number_of_fields: 1
field_description: ""
slave_description: " " - slave_name: REG_FPGA_VOLTAGE_SENS # pi_unb_fpga_voltagesens.py
- slave_name : fpga_voltage
slave_type: REG slave_type: REG
slave_description: "Not used, FPGA voltages are monitored via DC-DC converter power supply volages"
fields: fields:
- - field_name : voltage - - field_name: voltages
width : 32 field_description: "Not used"
access_mode: RO access_mode: RO
address_offset: 0x00 address_offset: 0x0
number_of_fields: 6 number_of_fields: 6
field_description: ""
slave_description: " "
- slave_name : scrap_ram
slave_type : RAM
fields:
- - field_name: data
width : 32
access_mode: RW
address_offset: 0x00
number_of_fields: 128
field_description: " "
slave_description: " "
peripheral_description: |
""
\ No newline at end of file
This diff is collapsed.
...@@ -3,57 +3,294 @@ schema_version: 1.0 ...@@ -3,57 +3,294 @@ schema_version: 1.0
schema_type: peripheral schema_type: peripheral
hdl_library_name: dp hdl_library_name: dp
hdl_library_description: " This is the description for the dp package " hdl_library_description: "Data path (DP) peripherals for streaming data."
peripherals: peripherals:
- peripheral_name: bsn - peripheral_name: dpmm # pi_dpmm.py
peripheral_description: "DP to MM FIFO to provide memory mapped MM read access from Data Path (DP) streaming interface."
slave_ports:
# MM port for mms_dp_fifo_to_mm.vhd / dp_fifo_to_mm_reg.vhd
- slave_name: REG_DPMM_CTRL
slave_type: REG
slave_description: "DPMM = Monitor the DP to MM read FIFO."
fields:
- - field_name: rd_usedw
field_description: "Number of words that can be read from the FIFO."
access_mode: RO
address_offset: 0x0
# MM port for mms_dp_fifo_to_mm.vhd / dp_fifo_to_mm.vhd
- slave_name: REG_DPMM_DATA # Use REG_, instead of preferred FIFO_, to match slave_port_name in pi_dpmm.py
slave_type: FIFO
slave_description: "DPMM = read word from the DP to MM read FIFO"
fields:
- - field_name: rd_data
field_description: "Read data from the FIFO."
access_mode: RO
address_offset: 0x0
- peripheral_name: mmdp # pi_mmdp.py
peripheral_description: "MM to DP FIFO to provide memory mapped MM write access to Data Path (DP) streaming interface."
slave_ports:
# MM port for mms_dp_fifo_from_mm.vhd / dp_fifo_from_mm_reg.vhd
- slave_name: REG_MMDP_CTRL
slave_type: REG
slave_description: "MMDP = Monitor the MM to DP write FIFO."
fields:
- - field_name: wr_usedw
field_description: "Number of words that are in the write FIFO."
access_mode: RO
address_offset: 0x0
- - field_name: wr_availw
field_description: "Number of words that can be written to the write FIFO."
access_mode: RO
address_offset: 0x4
# MM port for mms_dp_fifo_from_mm.vhd / dp_fifo_from_mm.vhd
- slave_name: REG_MMDP_DATA # Use REG_, instead of preferred FIFO_, to match slave_port_name in pi_mmdp.py
slave_type: FIFO
slave_description: "MMDP = write word to the MM to DP write FIFO."
fields:
- - field_name: data
field_description: "Write data to the FIFO."
access_mode: WO
address_offset: 0x0
- peripheral_name: dp_shiftram # pi_dp_shiftram.py
peripheral_description: "Sample delay buffer with programmable delay for streaming data."
parameters: parameters:
- { name: g_nof_input, value : 2 } # Parameters of dp_shiftram.vhd
- { name: g_nof_streams, value: 1 }
- { name: g_nof_words, value: 1024 }
- { name: g_data_w, value: 16 }
slave_ports:
# MM port for dp_shiftram.vhd
- slave_name: REG_DP_SHIFTRAM
slave_type: REG
slave_description: ""
number_of_slaves: g_nof_streams
fields:
- - field_name: shift
field_description: "Fill level of the sample delay buffer in number of data samples."
width: ceil_log2(g_nof_words)
access_mode: RW
address_offset: 0x0
- peripheral_name: dp_bsn_source # pi_dp_bsn_source.py
peripheral_description: "Block Sequence Number (BSN) source for timestamping blocks of data samples."
parameters:
# Parameters of dp_bsn_source_reg.vhd
- { name: g_nof_block_per_sync, value: 20 }
slave_ports: slave_ports:
# actual hdl name: reg_dp_bsn_align # MM port for dp_bsn_source_reg.vhd
- slave_name : ALIGN - slave_name: REG_DP_BSN_SOURCE
number_of_slaves: g_nof_input
slave_type: REG slave_type: REG
slave_description: ""
fields: fields:
- - field_name : Enable - - field_name: dp_on
field_description: |
"When 1 then enable BSN source, else when 0 disable BSN source. If dp_on_pps is 0,
then dp_on = 1 enables the BSN source immediately. To enable the BSN source at
the next PPS, then first set dp_on_pps = 1. Clearing dp_on stops the BSN source."
width: 1 width: 1
access_mode: RW
address_offset: 0x0 address_offset: 0x0
- - field_name: dp_on_pps
field_description: "When 1 and dp_on = 1 then enable BSN source at next PPS."
width: 1
bit_offset: 1
access_mode: RW
address_offset: 0x0
- - field_name: nof_block_per_sync
field_description: "Number of blocks per sync interval."
access_mode: RW
address_offset: 0x4
- - field_name: bsn_lo
field_description: "Initial BSN[31:0]"
access_mode: RW
address_offset: 0x8
- - field_name: bsn_hi
field_description: "Initial BSN[63:32]"
access_mode: RW
address_offset: 0xC
- peripheral_name: dp_bsn_source_v2 # pi_dp_bsn_source_v2.py
peripheral_description: "Block Sequence Number (BSN) source with block time offset, for timestamping blocks of data samples."
parameters:
# Parameters of dp_bsn_source_reg_v2.vhd
- { name: g_nof_clk_per_sync, value: 200000000 }
- { name: g_block_size, value: 256 }
- { name: g_bsn_time_offset_w, value: 8 } # note: g_bsn_time_offset_w = ceil_log2(g_block_size)
slave_ports:
# MM port for dp_bsn_source_reg_v2.vhd
- slave_name: REG_DP_BSN_SOURCE_V2
slave_type: REG
slave_description: ""
fields:
- - field_name: dp_on
field_description: | field_description: |
"Input enable register for input 0. If set to 0 the input is discarded from alignment. "When 1 then enable BSN source, else when 0 disable BSN source. If dp_on_pps is 0,
If set to 1 the corresopnding input is taken into account." then dp_on = 1 enables the BSN source immediately. To enable the BSN source at
slave_discription: " " the next PPS, then first set dp_on_pps = 1. Clearing dp_on stops the BSN source."
width: 1
access_mode: RW
address_offset: 0x0
- - field_name: dp_on_pps
field_description: "When 1 and dp_on = 1, then enable BSN source at next PPS."
width: 1
bit_offset: 1
access_mode: RW
address_offset: 0x0
- - field_name: nof_block_per_sync
field_description: "Number of clock cycles per sync interval."
access_mode: RW
address_offset: 0x4
- - field_name: bsn_init_lo
field_description: "Initial BSN[31:0]"
access_mode: RW
address_offset: 0x8
- - field_name: bsn_init_hi
field_description: "Initial BSN[63:32]"
access_mode: RW
address_offset: 0xC
- - field_name: bsn_time_offset
field_description: "The BSN block time offset in number of clock cycles, with respect to the PPS."
width: g_bsn_time_offset_w
access_mode: RW
address_offset: 0x10
peripheral_description: "This is the BSN aligner" - peripheral_name: dp_bsn_scheduler # pi_dp_bsn_scheduler.py
peripheral_description: "Schedule a trigger at a certain Block Sequence Number (BSN) instant."
slave_ports:
# MM port for dp_bsn_scheduler_reg.vhd
- slave_name: REG_DP_BSN_SCHEDULER
slave_type: REG
slave_description: ""
fields:
- - field_name: scheduled_bsn_lo
field_description: "Write scheduled BSN lo, read current BSN lo. First access lo, then hi."
access_mode: RW
address_offset: 0x0
- - field_name: scheduled_bsn_hi
field_description: "Write scheduled BSN hi, read current BSN hi. First access lo, then hi."
access_mode: RW
address_offset: 0x4
- peripheral_name: fifo - peripheral_name: dp_bsn_monitor # pi_dp_bsn_monitor.py
peripheral_description: "Monitor the Block Sequence Number (BSN) status of streaming data."
parameters: parameters:
- { name : g_nof_streams, value: 3 } # Parameters of mms_dp_bsn_monitor.vhd
- { name: g_nof_streams, value: 1 }
slave_ports: slave_ports:
# actual hdl name: reg_dp_fifo_fill # MM port for dp_bsn_monitor_reg.vhd
- slave_name : fill_status - slave_name: REG_DP_BSN_MONITOR
number_of_slaves: g_nof_streams
slave_type: REG slave_type: REG
slave_description: ""
number_of_slaves: g_nof_streams
fields: fields:
- - field_name : fifo_used_words - - field_name: xon_stable
field_description: "Data block flow control xon signal was active and stable during last sync interval."
width: 1
bit_offset: 0
access_mode: RO access_mode: RO
address_offset: 0x0 address_offset: 0x0
field_description: "Register reflects the currently used nof words on the fifo." - - field_name: ready_stable
field_description: "Clock cycle flow control ready signal was active and stable during last sync interval."
- - field_name : fifo_status width: 1
width : 2 bit_offset: 1
access_mode: RO
address_offset: 0x0
- - field_name: sync_timeout
field_description: "Data stream sync did not occur during last sync interval."
width: 1
bit_offset: 2 # EK TODO: using 1 cause gen_doc.py to fail without clear error, because fields then overlap
access_mode: RO
address_offset: 0x0
- - field_name: bsn_at_sync_lo
field_description: "Data stream BSN lo at sync."
access_mode: RO access_mode: RO
address_offset: 0x4 address_offset: 0x4
field_description: "Bit 0: fifo_read_empty Bit 1: fifo_wr_full." - - field_name: bsn_at_sync_hi
field_description: "Data stream BSN hi at sync."
- - field_name : max_fifo_used_words
access_mode: RO access_mode: RO
address_offset: 0x8 address_offset: 0x8
field_description: | - - field_name: nof_sop
"Register contains the maximum number of words that have been in the fifo. field_description: "Number data blocks (sop = start of packet) during last sync interval."
Will be cleared after it has been read." access_mode: RO
slave_discription: "" address_offset: 0xC
- - field_name: nof_valid
field_description: "Number valid samples of the data blocks during last sync interval (= nof_sop * block size)."
access_mode: RO
address_offset: 0x10
- - field_name: nof_err
field_description: "Number data blocks with error indication during last sync interval."
access_mode: RO
address_offset: 0x14
- - field_name: bsn_first_lo
field_description: "First data stream BSN lo ever."
access_mode: RO
address_offset: 0x18
- - field_name: bsn_first_hi
field_description: "First data stream BSN hi ever."
access_mode: RO
address_offset: 0x1C
- - field_name: bsn_first_cycle_cnt
field_description: "Arrival latency of first data stream BSN ever, relative to local sync."
access_mode: RO
address_offset: 0x20
peripheral_description: "This is the MM slave version of the dp_fifo_fill component." - peripheral_name: dp_bsn_monitor_v2 # pi_dp_bsn_monitor_v2.py
peripheral_description: "Monitor the Block Sequence Number (BSN) status and latency of streaming data."
parameters:
# Parameters of mms_dp_bsn_monitor_v2.vhd
- { name: g_nof_streams, value: 1 }
slave_ports:
# MM port for dp_bsn_monitor_reg_v2.vhd
- slave_name: REG_DP_BSN_MONITOR_V2
slave_type: REG
slave_description: ""
number_of_slaves: g_nof_streams
fields:
- - field_name: xon_stable
field_description: "Data block flow control xon signal was active and stable during last sync interval."
width: 1
bit_offset: 0
access_mode: RO
address_offset: 0x0
- - field_name: ready_stable
field_description: "Clock cycle flow control ready signal was active and stable during last sync interval."
width: 1
bit_offset: 1
access_mode: RO
address_offset: 0x0
- - field_name: sync_timeout
field_description: "Data stream sync did not occur during last sync interval."
width: 1
bit_offset: 1
access_mode: RO
address_offset: 0x0
- - field_name: bsn_at_sync_lo
field_description: "Data stream BSN lo at sync."
access_mode: RO
address_offset: 0x4
- - field_name: bsn_at_sync_hi
field_description: "Data stream BSN hi at sync."
access_mode: RO
address_offset: 0x8
- - field_name: nof_sop
field_description: "Number data blocks (sop = start of packet) during last sync interval."
access_mode: RO
address_offset: 0xC
- - field_name: nof_valid
field_description: "Number valid samples of the data blocks during last sync interval (= nof_sop * block size)."
access_mode: RO
address_offset: 0x10
- - field_name: nof_err
field_description: "Number data blocks with error indication during last sync interval."
access_mode: RO
address_offset: 0x14
- - field_name: latency
field_description: "Arrival latency of data stream BSN at sync, relative to local sync."
access_mode: RO
address_offset: 0x20
schema_name: args
schema_version: 1.0
schema_type: peripheral
hdl_library_name: aduh
hdl_library_description: "ADC Unit Handler (ADUH) of APERTIF."
peripherals:
- peripheral_name: aduh_mon_dc_power # pi_aduh_monitor.py
peripheral_description: "Determine mean sum and power sum of samples during a sync interval"
parameters:
# Parameters of mms_aduh_monitor_arr.vhd
- { name: g_nof_streams, value: 1 }
slave_ports:
# MM port for mms_aduh_monitor_arr.vhd / aduh_monitor_reg.vhd
- slave_name: REG_ADUH_MON
slave_type: REG
slave_description: "Sum of samples and sample powers during a sync interval."
number_of_slaves: g_nof_streams
fields:
- - field_name: mean_sum_lo
field_description: "Mean sum[31:0] of samples during a sync interval."
access_mode: RO
address_offset: 0x0
- - field_name: mean_sum_hi
field_description: "Mean sum[63:32] of samples during a sync interval."
access_mode: RO
address_offset: 0x4
- - field_name: power_sum_lo
field_description: "Power sum[31:0] of sample powers during a sync interval."
access_mode: RO
address_offset: 0x8
- - field_name: power_sum_hi
field_description: "Power sum[63:32] of sample powers during a sync interval."
access_mode: RO
address_offset: 0xC
- peripheral_name: aduh_mon_data_buffer # pi_aduh_monitor.py
peripheral_description: "Data buffer to capture samples (= diag_data_buffer)"
parameters:
# Parameters of mms_aduh_monitor_arr.vhd
- { name: g_nof_streams, value: 1 }
- { name: g_symbol_w, value: 16 }
- { name: g_nof_symbols_per_data, value: 1 }
- { name: g_buffer_nof_symbols, value: 512 }
- { name: g_buffer_use_sync, value: true }
slave_ports:
# MM port for mms_aduh_monitor_arr.vhd
- slave_name: RAM_ADUH_MON
slave_type: RAM
slave_description: "Data buffer memory, gets filled after the sync when g_buffer_use_sync = true, else after the last word was read."
number_of_slaves: g_nof_streams
fields:
- - field_name: data
field_description: ""
width: g_symbol_w * g_nof_symbols_per_data
address_offset: 0x0
number_of_fields: g_buffer_nof_symbols / g_nof_symbols_per_data
...@@ -3,123 +3,69 @@ schema_version: 1.0 ...@@ -3,123 +3,69 @@ schema_version: 1.0
schema_type: peripheral schema_type: peripheral
hdl_library_name: epcs hdl_library_name: epcs
hdl_library_description: " This is the description for the epcs package " hdl_library_description: "Serial Configuration (EPCS) Device"
peripherals: peripherals:
- peripheral_name: epcs # pi_epcs.py
peripheral_description: |
"Provide write and read to the flash memory of the FPGA using the EPCS [1]. The write access goes
via a write FIFO (MM to DP) and the read access goes via a read FIFO (DP to MM). The FIFOs
convert between the memory mapped (MM) interface and the data path (DP) streaming interface of
the EPCS [2].
# epcs_reg [1] https://git.astron.nl/desp/hdl/-/blob/master/libraries/io/epcs/src/vhdl/epcs_reg.vhd
- [2] https://git.astron.nl/desp/upe_gear/-/blob/master/peripherals/util_epcs.py"
peripheral_name: epcs
parameters: parameters:
- {name: "g_sim_flash_model", value: TRUE} # parameters of mms_epcs.vhd / epcs_reg.vhd
- {name: "g_epcs_addr_w", value: 24}
slave_ports: slave_ports:
# actual hdl name: epcs_reg # MM port for epcs_reg.vhd
- slave_name : EPCS - slave_name: REG_EPCS # pi_epcs.py
slave_type: REG slave_type: REG
slave_description: "Handle the read, erase and write of the flash memory chip."
fields: fields:
- - field_name: addr - - field_name: addr
field_description: "Address to write to or read from."
width: 24 width: 24
access_mode: WO access_mode: WO
address_offset: 0x0 address_offset: 0x0
field_description: " address to write to or read from "
- - field_name: rden - - field_name: rden
field_description: "Read enable bit."
width: 1 width: 1
access_mode: WO access_mode: WO
address_offset: 0x4 address_offset: 0x4
field_description: " Read enable bit "
- - field_name: read_bit - - field_name: read_bit
field_description: "Read bit."
width: 1 width: 1
access_mode: WO access_mode: WO
side_effect: PW side_effect: PW
address_offset: 0x8 address_offset: 0x8
field_description: " Read bit "
- - field_name: write_bit - - field_name: write_bit
field_description: "Write bit."
width: 1 width: 1
access_mode: WO access_mode: WO
side_effect: PW side_effect: PW
address_offset: 0xc address_offset: 0xc
field_description: " Write bit "
- - field_name: sector_erase - - field_name: sector_erase
field_description: "Sector erase bit."
width: 1 width: 1
access_mode: WO access_mode: WO
address_offset: 0x10 address_offset: 0x10
field_description: " Sector erase bit "
- - field_name: busy - - field_name: busy
field_description: "Busy bit."
width: 1 width: 1
access_mode: RO access_mode: RO
address_offset: 0x14 address_offset: 0x14
field_description: " busy "
- - field_name: unprotect - - field_name: unprotect
field_description: "Use 0xBEDA221E (= Bedazzle) as password to unprotect address range."
width: 32 width: 32
access_mode: WO access_mode: WO
address_offset: 0x18 address_offset: 0x18
field_description: " passphrase to unprotect address range "
slave_description: " Read and write access to flash "
# actual hdl name: mms_dp_fifo_to_mm
- slave_name : DPMM_CTRL
slave_type : REG
fields:
- - field_name : ctrl
width : 32
access_mode : RW
address_offset: 0x0
number_of_fields: 1
field_description: " "
slave_description: " "
- slave_name : DPMM_DATA
slave_type : FIFO
fields:
- - field_name : data
width : 32
access_mode : RO
address_offset: 0x0
number_of_fields: 1
field_description: " "
slave_description: " "
# actual hdl name: mms_dp_fifo_from_mm
- slave_name : MMDP_CTRL
slave_type : REG
fields:
- - field_name : ctrl
width : 32
access_mode : RW
address_offset: 0x0
number_of_fields: 2
field_description: " "
slave_description: " "
- slave_name : MMDP_DATA
slave_type : FIFO
fields:
- - field_name : data
width : 32
access_mode : WO
address_offset: 0x0
number_of_fields: 2
field_description: " "
slave_description: " "
peripheral_description: |
"wi Bits SE R/W Name Default Description |REG_EPCS|
=============================================================================
0 [23..0] WO addr 0x0 Address to write to/read from
1 [0] WO rden 0x0 Read enable
2 [0] PW WE read 0x0 Read
3 [0] PW WE write 0x0 Write
4 [0] WO sector_erase 0x0 Sector erase
5 [0] RO busy 0x0 Busy
============================================================================="
...@@ -3,53 +3,50 @@ schema_version: 1.0 ...@@ -3,53 +3,50 @@ schema_version: 1.0
schema_type: peripheral schema_type: peripheral
hdl_library_name: eth hdl_library_name: eth
hdl_library_description: " This is the description for the eth package " hdl_library_description: "Triple Speed Ethernet (TSE) peripheral for 1GbE."
peripherals: peripherals:
- - peripheral_name: eth # pi_eth.py
peripheral_name: eth1g peripheral_description: |
"The ETH module connects the 1GbE TSE [1] to the microprocessor and to streaming UDP ports [2]. The
parameters: packets for the streaming channels are directed based on the UDP port number and all other packets
- { name: c_eth_ram_nof_words, value: 1024 } are transfered to the default control channel and handled by the microprocessor.
#g_technology: c_tech_select_default
#g_ETH_PHY : "LVDS"
[1] https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_ethernet.pdf
[2] https://git.astron.nl/desp/hdl/-/blob/master/libraries/io/eth/doc/ASTRON_RP_396_eth_1gb_module.pdf"
slave_ports: slave_ports:
# actual hdl name: reg_tse # MM port for registers in the TSE IP [1]
- slave_name : TSE - slave_name: AVS_ETH_0_TSE
slave_type: REG slave_type: REG
slave_description: "Registers in the TSE IP [1], handled by the microprocessor."
fields: fields:
- - field_name: status - - field_name: status
field_description: ""
access_mode: RO access_mode: RO
address_offset: 0x0 address_offset: 0x0
number_of_fields: 1024 number_of_fields: 1024 # = c_tech_tse_byte_addr_w in tech_tse_pkg.vhd
field_description: "reg tse"
slave_description: " "
# actual hdl name: reg # MM port for registers in eth_mm_registers.vhd in the ETH module [2]
- slave_name : ETH - slave_name: AVS_ETH_0_REG
slave_type: REG slave_type: REG
slave_description: "Registers in the ETH module [2], handled by the microprocessor."
fields: fields:
- - field_name: status - - field_name: status
field_description: ""
access_mode: RO access_mode: RO
address_offset: 0x0 address_offset: 0x0
number_of_fields: 12 number_of_fields: 12 # = c_eth_reg_nof_words in eth_pkg.vhd
field_description: "reg registers"
slave_description: " "
# actual hdl name: ram # MM port for ETH packet packet buffers in eth.vhd
- slave_name : ETH - slave_name: AVS_ETH_0_RAM
slave_type: RAM slave_type: RAM
slave_description: |
"Buffer RAM for request packets (Rx) and response packets (Tx) via 1GbE, used by the microprocessor
to receive and transmit packets via the ETH module."
fields: fields:
- - field_name : ram - - field_name: data
number_of_fields: c_eth_ram_nof_words field_description: "Data 32b-word."
field_description: | number_of_fields: 1024 # = c_eth_ram_nof_words in eth_pkg.vhd
"Contains the Waveform data for the data-streams to be send"
slave_description: " "
peripheral_description: |
"
Connect the 1GbE TSE to the microprocessor and to streaming UDP ports. The
packets for the streaming channels are directed based on the UDP port
number and all other packets are transfered to the default control channel."
...@@ -3,45 +3,66 @@ schema_version: 1.0 ...@@ -3,45 +3,66 @@ schema_version: 1.0
schema_type: peripheral schema_type: peripheral
hdl_library_name: ppsh hdl_library_name: ppsh
hdl_library_description: " This is the description for the finppshge_stop library " hdl_library_description: "Pulse Per Second Handler"
peripherals: peripherals:
- - peripheral_name: ppsh # pi_ppsh.py
peripheral_name: ppsh peripheral_description: |
"Capture PPS input signal and monitor its period. See description in [1, 2] and usage in [3].
[1] https://git.astron.nl/desp/hdl/-/blob/master/libraries/io/ppsh/doc/ASTRON_RP_1374_ppsh_module_description.pdf
[2] https://git.astron.nl/desp/hdl/-/blob/master/libraries/io/ppsh/src/vhdl/ppsh_reg.vhd
[3] https://git.astron.nl/desp/upe_gear/-/blob/master/peripherals/util_ppsh.py"
parameters: parameters:
# parameters of ppsh_reg.vhd
- { name: g_cross_clock_domain, value: TRUE } - { name: g_cross_clock_domain, value: TRUE }
- { name: g_st_clk_freq, value: 200 * 10**6 } - { name: g_st_clk_freq, value: 200 * 10**6 }
slave_ports: slave_ports:
# actual hdl name: reg_ppsh # MM port for ppsh_reg.vhd
- slave_name : PPSH - slave_name: PIO_PPS # pi_ppsh.py and in QSYS system.h
slave_type: REG slave_type: REG
slave_description: "Monitor and control PPS input."
dual_clock: g_cross_clock_domain
fields: fields:
- - field_name : status - - field_name: capture_cnt
field_description: "Measured number of clock cycles between captured PPS pulses."
width: 30
bit_offset: 0
access_mode: RO
address_offset: 0x0
- - field_name: stable
field_description: "PPS is stable (1) when capture_cnt = expected_cnt for all PPS periods since last time status was read, else PPS is not stable (0)."
width: 1
bit_offset: 30
access_mode: RO
address_offset: 0x0
- - field_name: toggle
field_description: "Level bit that toggles after every PPS."
width: 1
bit_offset: 31
access_mode: RO access_mode: RO
address_offset: 0x0 address_offset: 0x0
field_description: " ppsh status "
- - field_name : control - - field_name: expected_cnt
field_description: "Expected number of clock cycles between captured PPS pulses."
width: ceil_log2(g_st_clk_freq)
bit_offset: 0
access_mode: RW
address_offset: 0x4 address_offset: 0x4
field_description: " ppsh control "
- - field_name : offset
address_offset: 0x8
field_description: " ppsh offset count "
slave_discription: " "
peripheral_description: | - - field_name: edge
" field_description: "When 0 then clock PPS in on rising edge of clock, else when 1 use falling edge of clock."
. Report PPS toggle, stable and period capture count width: 1
. Set dp_clk capture edge for PPS bit_offset: 31
Set expected period capture count for PPS stable access_mode: RW
+----------------------------------------------------------------------------+ address_offset: 0x4
|31 (byte3) 24|23 (byte2) 16|15 (byte1) 8|7 (byte0) 0| wi |
|-----------------------------------------------------------------------|----| - - field_name: offset_cnt
|toggle[31], stable[30] xxx capture_cnt = [29:0]| 0 | field_description: "Number of clock cycles at read access, that has passed since last PPS."
|-----------------------------------------------------------------------|----| address_offset: 0x8
|edge[31], xxx expected_cnt = [29:0]| 1 | width: ceil_log2(g_st_clk_freq)
|-----------------------------------------------------------------------|----| access_mode: RO
| xxx offset_cnt = [29:0]| 2 |
+----------------------------------------------------------------------------+"
...@@ -3,77 +3,66 @@ schema_version: 1.0 ...@@ -3,77 +3,66 @@ schema_version: 1.0
schema_type: peripheral schema_type: peripheral
hdl_library_name: remu hdl_library_name: remu
hdl_library_description: " This is the description for the remu package " hdl_library_description: "Remote Update (REMU)"
peripherals: peripherals:
- peripheral_name: remu # pi_remu.py
peripheral_description: |
"Remote update to load the factory image or the user from flash into the the FPGA. See description in [1] and usage in [2].
# peripheral, remu_reg [1] https://git.astron.nl/desp/hdl/-/blob/master/libraries/io/remu/src/vhdl/remu_reg.vhd
- peripheral_name: remu [2] https://git.astron.nl/desp/upe_gear/-/blob/master/peripherals/util_remu.py"
parameters: parameters:
# parameters of remu_reg.vhd
- { name: g_data_w, value: 24 } - { name: g_data_w, value: 24 }
slave_ports: slave_ports:
# actual hdl name: reg_remu # MM port for remu_reg.vhd
- slave_name : REMU - slave_name: REG_REMU # pi_remu.py and in QSYS system.h
slave_type: REG slave_type: REG
slave_description: "Remote update."
fields: fields:
- - field_name : reconfigure_key - - field_name: reconfigure
field_description: "Use 0xB007FAC7 (= boot factory) as password to reconfigure."
width: c_word_w width: c_word_w
access_mode: WO access_mode: WO
address_offset: 0x0 address_offset: 0x0
field_description: " reconfigure key for safety "
- - field_name: param - - field_name: param
field_description: "param"
width: 3 width: 3
access_mode: WO access_mode: WO
address_offset: 0x4 address_offset: 0x4
radix : unsigned
field_description: " "
- - field_name: read_param - - field_name: read_param
field_description: "read_param"
width: 1 width: 1
access_mode: WO access_mode: WO
side_effect: PW side_effect: PW
address_offset: 0x8 address_offset: 0x8
field_description: " read_param "
- - field_name: write_param - - field_name: write_param
field_description: "write_param"
width: 1 width: 1
access_mode: WO access_mode: WO
side_effect: PW side_effect: PW
address_offset: 0xc address_offset: 0xc
field_description: " write_param "
- - field_name: data_out - - field_name: data_out
field_description: "data_out"
width: g_data_w width: g_data_w
access_mode: RO access_mode: RO
address_offset: 0x10 address_offset: 0x10
field_description: " data_out "
- - field_name: data_in - - field_name: data_in
field_description: "data_in"
width: g_data_w width: g_data_w
access_mode: WO access_mode: WO
address_offset: 0x14 address_offset: 0x14
field_description: " data_in "
- - field_name: busy - - field_name: busy
field_description: "busy"
width: 1 width: 1
access_mode: RO access_mode: RO
address_offset: 0x18 address_offset: 0x18
field_description: " busy "
slave_description: " Remote Upgrade "
peripheral_description: |
"wi Bits R/W SE Name Default Description |REG_EPCS|
=============================================================================
0 [31..0] WO reconfigure_key 0x0
1 [2..0] WO param
2 [0] WO PW read_param
3 [0] WO PW write_param
4 [23..0] RO data_out
5 [23..0] WO data_in
6 [0] RO busy
=============================================================================
"
schema_name: args
schema_version: 1.0
schema_type: peripheral
hdl_library_name: tech_jesd204b
hdl_library_description: "JESD204b peripherals for ADC interface."
peripherals:
- peripheral_name: jesd_ctrl # pi_jesd_ctrl.py
peripheral_description: "Reset JESD, and enable/disable individual JESD inputs"
slave_ports:
# MM port for node_adc_input_and_timing.vhd
- slave_name: PIO_JESD_CTRL
slave_type: REG
slave_description: ""
fields:
- - field_name: reset
field_description: "Write 1 to reset the full JESD interface for all JESD signal inputs."
width: 1
bit_offset: 31
access_mode: RW
address_offset: 0x0
- - field_name: enable
field_description: "Enable JESD signal input i by setting bit i = 1, disable by clearing bit i = 0."
width: 31
bit_offset: 0
access_mode: RW
address_offset: 0x0
- peripheral_name: jesd204b_arria10 # pi_jesd204b_unb2.py
peripheral_description: |
"M&C of Intel Arria10 JESD204B ADC interface IP, see https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/ug/ug_jesd204b.pdf"
slave_ports:
# MM port for tech_jesd204b.vhd
- slave_name: REG_JESD204B
slave_type: REG
slave_description: ""
fields:
- - {field_name: rx_dll_ctrl, width: 17, bit_offset: 0, access_mode: RW, address_offset: 0x50}
- - {field_name: rx_syncn_sysref_ctrl, width: 25, bit_offset: 0, access_mode: RW, address_offset: 0x54}
- - {field_name: rx_csr_lmfc_offset, width: 8, bit_offset: 12, access_mode: RW, address_offset: 0x54}
- - {field_name: rx_csr_rbd_offset, width: 8, bit_offset: 3, access_mode: RW, address_offset: 0x54}
- - {field_name: rx_csr_sysref_always_on, width: 1, bit_offset: 1, access_mode: RW, address_offset: 0x54}
- - {field_name: rx_err0, width: 9, bit_offset: 0, access_mode: RW, address_offset: 0x60}
- - {field_name: rx_err1, width: 10, bit_offset: 0, access_mode: RW, address_offset: 0x64}
- - {field_name: csr_rbd_count, width: 8, bit_offset: 3, access_mode: RO, address_offset: 0x80}
- - {field_name: csr_dev_syncn, width: 1, bit_offset: 0, access_mode: RO, address_offset: 0x80}
- - {field_name: rx_status1, width: 24, bit_offset: 0, access_mode: RW, address_offset: 0x84}
- - {field_name: rx_status2, width: 24, bit_offset: 0, access_mode: RW, address_offset: 0x88}
- - {field_name: rx_status3, width: 8, bit_offset: 0, access_mode: RW, address_offset: 0x8C}
- - {field_name: rx_ilas_csr_m, width: 8, bit_offset: 24, access_mode: RW, address_offset: 0x94}
- - {field_name: rx_ilas_csr_k, width: 5, bit_offset: 16, access_mode: RW, address_offset: 0x94}
- - {field_name: rx_ilas_csr_f, width: 8, bit_offset: 8, access_mode: RW, address_offset: 0x94}
- - {field_name: rx_ilas_csr_l, width: 5, bit_offset: 0, access_mode: RW, address_offset: 0x94}
- - {field_name: rx_ilas_csr_hd, width: 1, bit_offset: 31, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_ilas_csr_cf, width: 5, bit_offset: 24, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_ilas_csr_jesdv, width: 3, bit_offset: 21, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_ilas_csr_s, width: 5, bit_offset: 16, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_ilas_csr_subclassv, width: 3, bit_offset: 13, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_ilas_csr_np, width: 5, bit_offset: 8, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_ilas_csr_cs, width: 2, bit_offset: 6, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_ilas_csr_n, width: 5, bit_offset: 0, access_mode: RW, address_offset: 0x98}
- - {field_name: rx_status4, width: 16, bit_offset: 0, access_mode: RW, address_offset: 0xF0}
- - {field_name: rx_status5, width: 16, bit_offset: 0, access_mode: RW, address_offset: 0xF4}
- - {field_name: rx_status6, width: 24, bit_offset: 0, access_mode: RW, address_offset: 0xF8}
- - {field_name: rx_status7, width: 32, bit_offset: 0, access_mode: RO, address_offset: 0xFC}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment