diff --git a/applications/lofar2/doc/prestudy/station2_sdp_transient_buffer.txt b/applications/lofar2/doc/prestudy/station2_sdp_transient_buffer.txt index 4f7028dc031bdaa52e648e09a075ebd907349205..c90a88688f9bf3c446042e7567287b4b5c63c4d8 100644 --- a/applications/lofar2/doc/prestudy/station2_sdp_transient_buffer.txt +++ b/applications/lofar2/doc/prestudy/station2_sdp_transient_buffer.txt @@ -144,11 +144,11 @@ The CP FPGA_beamlet_output_nof_beamlets_RW is not supported in SDPTR and SDPFW y - timing . Use sample sequence number (RSN) or mem_bsn: - - RSN increments by nof_samples_per_page = 8176 - - mem_bsn increments by 1 per page, so per block of nof_samples_per_page = 8176. + - RSN increments by c_tbuf_nof_samples_per_page = 8176 + - mem_bsn increments by 1 per page, so per block of c_tbuf_nof_samples_per_page = 8176. . RSN counts sample periods (5 ns) since t_epoch = 1970, can fit 2**64 / (365.25 * 24 * 3600 / 5e-9) > 2922 years - . TBuf uses sop and eop to mark nof_samples_per_page = 8176 + . TBuf uses sop and eop to mark c_tbuf_nof_samples_per_page = 8176 . TBuf does not need sync ? . Start RSN or mem BSN at same time as SDP BSN by FPGA_processing_enable_RW. @@ -206,10 +206,10 @@ The CP FPGA_beamlet_output_nof_beamlets_RW is not supported in SDPTR and SDPFW y that DDR4-I can wrap without a gap or extend to DDR-II without a gap. - RSN = 64b = 8B - 14b packed data - . nof_samples_per_page = 8K - 8 - 8 = 8192 - 16 = 8176 B / 14b = 4672 + . c_tbuf_nof_samples_per_page = 8K - 8 - 8 = 8192 - 16 = 8176 B / 14b = 4672 . 4672 * 5 ns = 23.36 us per page, so ~42.8 pages / ms - CRC = 64b = 8B, use 64b CRC to match 64b words, no need to reduce stored - CRC to less bits, because nof_samples_per_page fits preferrably a multiple + CRC to less bits, because c_tbuf_nof_samples_per_page fits preferrably a multiple of 64b words. - Memory storage overhead is 16 / 8192 = 0.2% @@ -250,120 +250,206 @@ The CP FPGA_beamlet_output_nof_beamlets_RW is not supported in SDPTR and SDPFW y 5) TBuf ICD SC-SDP, SDPTR-SDPFW -- Control Points (CP): - . FPGA_tbuf_alloc_start_page_RW [pn][si] # in range 0:2M-1 - FPGA_tbuf_alloc_nof_pages_RW [pn][si] # 0 = free, > 0 = in use - - of als allocatie fixed is, dan alleen MP: - - FPGA_tbuf_alloc_start_page_R [pn][si] # in range 0:2M-1 - FPGA_tbuf_alloc_nof_pages_R [pn][si] - - * In LOFAR1 bepaald LCU welke si uitgelezen moet worden richting CEP. De - TBB uP zorgt dan dat de nof pages verstuurd worden. - - . FPGA_tbuf_record_enable_RW[pn] # True = start/continue, False = stop/freeze recording immediately - - . FPGA_tbuf_record_all_antenna_RW[pn] # True = record all antenna inputs, False = record only half of the antenna inputs, the once that have even index. +* In LOFAR1 bepaald LCU welke si uitgelezen moet worden richting CEP. De + TBB uP zorgt dan dat de nof pages verstuurd worden. +* Only FPGA_TBuf CP and MP. No need for TR_tbuf CP or MP +- Control Points (CP) en Monitor Points (MP): + * Raw data: + . W_adc = 14b, always use all ADC bits, so no need for W_raw. + . W_ant = N_pol * W_adc = 28b + . c_tbuf_raw_sample_period + = 5 ns at FPGA_sdp_info_f_adc_R = 200 MHz + = 6.25 ns at FPGA_sdp_info_f_adc_R = 160 MHz + + * RSN source (dp_rsn_source with nof_clk_per_sync register) + FPGA_processing_enable_RW + . SDPTR: set tbuf_nof_clk_per_sync dependent on FPGA_sdp_info_f_adc_R + . SDPFW: start RSN source at BSN sync, RSN derived from BSN + . c_tbuf_nof_samples_per_block = + c_tbuf_nof_samples_per_page = + c_tbuf_nof_samples_per_packet = 2000 + . tbuf_nof_block_per_sync = tbuf_nof_clk_per_sync / c_tbuf_nof_samples_per_packet + = 100k for sync interval 1 s at FPGA_sdp_info_f_adc_R = 200 MHz + = 80k for sync interval 1 s at FPGA_sdp_info_f_adc_R = 160 MHz + * RSN monitor (dp_bsn_monitor) + . FPGA_tbuf_signal_input_timestamp_R = FPGA_tbuf_signal_input_rsn_R * raw_sample_period + . FPGA_tbuf_signal_input_rsn_R = RSN at sync + FPGA_tbuf_signal_input_nof_blocks_R : expected value tbuf_nof_block_per_sync + FPGA_tbuf_signal_input_nof_samples_R : expected value tbuf_nof_clk_per_sync + + * Record: + . FPGA_tbuf_record_all_RW[pn] + True = record all antenna inputs, + False = record only half of the antenna inputs, the once that have even index. + . FPGA_tbuf_record_enable_RW[pn] + True = start/continue, + False = stop/freeze recording immediately - . FPGA_tbuf_dump_inter_packet_gap_RW --> wait time between packets send to CEP in FPGA_tbuf_sample_period_R units - FPGA_tbuf_dump_timestamp_range_RW[pn][rsn] --> [0] = from rsn, [1] to rsn, SDPTR translates between float timestamp and int RSN - FPGA_tbuf_dump_enable_RW[pn][ai] --> boolean, SC takes care that only one global ai is TRUE - --> SC / dump tool loops global ai via FPGA_tbuf_dump_enable_RW and - FPGA_tbuf_dumping_R - --> SC / dump tool needs to take care that only one global ai is selected at - a time to avoid 10GbE link overload - --> use FPGA_tbuf_dumping_R to see when dump is busy or done, hoe als het heel snel klaar is ??? + * Recording: + . FPGA_tbuf_recording_R[pn] + True = pn is recording, all ai or half of ai (dependent on FPGA_tbuf_record_all_RW) + False = pn is frozen - FPGA_tbuf_clear_total_counts_RW[pn] --> clear all TBuf total counts in pn + . FPGA_tbuf_recorded_last_timestamp_R[pn] = recorded_last_rsn * raw_sample_period + . FPGA_tbuf_recorded_first_timestamp_R[pn] = recorded_first_rsn * raw_sample_period + . FPGA_tbuf_recorded_time_interval_R[pn] = FPGA_tbuf_recorded_last_timestamp_R - FPGA_tbuf_recorded_first_timestamp_R + While FPGA_tbuf_recording_R = True then the last and first timestamps will increment in time + After the circular buffer has filled, then the time_interval will remain fixed at maximum. + * Dumping: + . FPGA_tbuf_dump_inter_packet_gap_RW --> wait time between packets send to CEP in raw_sample_period units + . FPGA_tbuf_dump_timestamp_range_RW[pn][start, end] + [0] = start timestamp, + [1] = end timestamp + SDPTR translates between float timestamp = integer RSN * raw_sample_period + . FPGA_tbuf_dump_enable_RW[pn][ai] + True = start / keep dumping packets for the requested ai, + False = stop dumping + SDPFW: + - loops over one or multiple ai + SC / dump tool: + - takes care that only one global pn is selected at a time to avoid 10GbE link overload + - loops global pn, ai via FPGA_tbuf_dump_enable_RW and FPGA_tbuf_dumping_R + - use FPGA_tbuf_dumping_R to see whether PN is busy dumping, + - use FPGA_tbuf_dump_remaining_nof_packets_R = 0 to see whether PN dumping has finished + if FPGA_tbuf_dump_enable_RW is made False before PN dumping has finished, then + FPGA_tbuf_dump_remaining_nof_packets_R can be > 0. + + . FPGA_tbuf_dumping_R[pn] + True when dump is busy, + False when dump has finished. + - when busy then FPGA_tbuf_read_nof_packets_R increments until it reaches initial value of + FPGA_tbuf_dump_remaining_nof_packets_R + - when finished then FPGA_tbuf_dump_remaining_nof_packets_R = 0 + + . FPGA_tbuf_dump_nof_packets_R[pn][ai] + amount of packets that will be dumped for FPGA_tbuf_dump_timestamp_range_RW, + forced to 0 if FPGA_tbuf_dump_timestamp_range_RW is not in buffer + + . FPGA_tbuf_dump_remaining_nof_packets_R[pn][ai] + amount of packets that still need to be dumped, + = 0, when FPGA_tbuf_dump_enable_RW is False, + = dump_last_page_index_RW - dump_first_page_index_RW + 1, when FPGA_tbuf_dump_enable_RW is True. + + FPGA_tbuf_read_nof_packets_R[pn][ai] + amount of packets that have been read so far + FPGA_tbuf_read_nof_memory_errors_R[pn][ai] + amount of packets that have been read and had a CRC error, count per ai, because each ai has own CRC + + FPGA_tbuf_dumped_nof_packets_R[pn][ai] + amount of packets that have been dumped, packets with a read error are not passed on for dump + = FPGA_tbuf_read_nof_packets_R - FPGA_tbuf_read_nof_memory_errors_R, + + Not: FPGA_tbuf_clear_total_counts_RW[pn] --> clear all TBuf total counts in pn, + total count not needed if MP is read after every dump Not: FPGA_tbuf_dump_enable_RW[pn] -- antenna index - Not: TR_tbuf_dump_enable_RW -- antenna index - - . FPGA_tbuf_output_hdr_eth_destination_mac_RW - . FPGA_tbuf_output_hdr_ip_destination_address_RW - . FPGA_tbuf_output_hdr_udp_destination_port_RW - . FPGA_tbuf_output_enable_RW[pn] - -- Monitor Points (MP): - * Raw data: - . FPGA_tbuf_nof_bits_per_sample_R --> 14 b = W_adc - . FPGA_tbuf_sample_period_R --> 5 ns - - * RSN monitor (dp_bsn_monitor) - . sync interval 1 s - . block size = 2000 + Not: Fixed buffer sizes, so no need to allocate pages per ai. - * Memory (DDR4): + * 10GbE output: + . FPGA_tbuf_output_hdr_eth_destination_mac_RW + . FPGA_tbuf_output_hdr_ip_destination_address_RW + . FPGA_tbuf_output_hdr_udp_destination_port_RW + . FPGA_tbuf_output_enable_RW[pn] + True : pass on dumped packets to 10GbE output + False : stop 10GbE output + * Memory DDR4: With streaming use of io_ddr then the dvr_wr_flush_en = '0' (so ctlr_wr_flush_en = 0 in MP), because the sequencer takes of writing and reading blocks like in reorder_transpose.vhd. Use MP to check FIFOs. - Support onl MP for DDR4 module in slot I. + Support only MP for DDR4 module in slot I. REG_IO_DDR_MB_I in io_ddr: [3] RESIZE_UVEC(rd_fifo_full_reg & wr_fifo_full_reg, c_mem_reg_dat_w) # gets cleared upon read [2] RESIZE_UVEC(ctlr_wr_fifo_usedw, c_mem_reg_dat_w) & [1] RESIZE_UVEC(ctlr_rd_fifo_usedw, c_mem_reg_dat_w) & - [0] RESIZE_UVEC(ctlr_tech_mosi.wr & ctlr_tech_miso.rdval & ctlr_tech_miso.cal_fail & ctlr_tech_miso.cal_ok & + [0] RESIZE_UVEC(ddr_gigabytes[7:0] & + ctrl_nof_bytes_per_ddr_word[7:0] & + ctlr_tech_mosi.wr & ctlr_tech_miso.rdval & ctlr_tech_miso.cal_fail & ctlr_tech_miso.cal_ok & ctlr_rst_out_i & ctlr_wr_flush_en & ctlr_tech_miso.waitrequest_n & ctlr_tech_miso.done, c_mem_reg_dat_w); - Use ddr_ for DDR4 in slot I, in case in future DDR4 slot II is also used, then use e.g. ddr_ii for that module. - . FPGA_ddr_calibrated_R = cal_ok && !cal_fail --> True is ddr4 memory is available, False is ddr4 calibration failed or ddr4 not present + Use ddr_ prefix for DDR4 in slot I, in case in future DDR4 slot II is also used, then use e.g. ddr_ii for that module. + . FPGA_ddr_calibrated_R = ctlr_tech_miso.done = cal_ok && !cal_fail --> + True is ddr4 memory is available, + False is ddr4 calibration failed or ddr4 not present. + . FPGA_ddr_wr_fifo_full_R = wr_fifo_full_reg, True if write FIFO to ddr4 memory got full since last MP read, else False. Should remain False. . FPGA_ddr_rd_fifo_full_R = rd_fifo_full_reg, True if read FIFO from ddr4 memory got full since last MP read, else False. Should remain False. . FPGA_ddr_wr_fifo_usedw_R = ctlr_wr_fifo_usedw, current fill level of write FIFO to ddr4 memory in number of 512b words, should be 0 when not recording . FPGA_ddr_rd_fifo_usedw_R = ctlr_rd_fifo_usedw, current fill level of read FIFO from ddr4 memory in number of 512b words, should be 0 when not dumping + There is no MP for drv_miso.done, could show hanging io_ddr_driver. All other fields in drv_miso are unused ('X'). + No need for CP of: - dvr_wr_flush_en, because io_ddr and DDR4 should work without need to flush when they operate OK. No need to MP for: - ctlr_tech_mosi.wr, because controlled by streaming sequencer - ctlr_rst_out_i, because also used as reset for io_ddr itself - - ctlr_tech_miso.waitrequest_n ? could show hanging io_ddr_driver - - ctlr_tech_miso.done ? could show hanging io_ddr_driver + - ctlr_tech_miso.waitrequest_n ? could show hanging io_ddr_driver or refresh cycles + * Memory buffer: REG_TBUF_RAW new in node_sdp_transient_buffer_raw.vhd - . nof_bytes_in_ddr_R = 16 * 1024**3 (16GiB) - . nof_bytes_per_ddr_word_R = 64 Bytes (= 512b) - . nof_ddr_words_per_page_R = 657 or 329, depends on FPGA_tbuf_record_all_antenna_RW - ==> SDPTR: ddr_total_nof_pages = floor(nof_bytes_in_ddr_R / (nof_ddr_words_per_page_R * nof_bytes_per_ddr_word_R) - - . last_recorded_page_index_R --> last page that was recorded in ddr, restarts at 0 when recording starts, increments during recording - . last_recorded_rsn_R --> RSN of block at last_recorded_page_index - . first_recorded_page_index_R --> restarts at 0 when recording starts, equals last_recorded_page_index + 1 when recording has - filled the circular buffer once and continues recording - . first_recorded_rsn_R --> RSN of block at first_recorded_page_index + . record_all_RW + True = record all antenna inputs, + False = record only half of the antenna inputs, the once that have even index. + . record_enable_RW + True = pn is recording, all ai or half of ai (dependent on record_all_RW) + False = pn is frozen + + . c_tbuf_nof_samples_per_page = c_tbuf_nof_samples_per_packet = 2000 + . nof_ddr_words_per_page_R = 657 or 329, depends on FPGA_tbuf_record_all_RW + SDPTR: ddr_nof_pages = floor(ddr_gigabytes * 1024**3 / (nof_ddr_words_per_page_R * ctrl_nof_bytes_per_ddr_word) + + . recorded_first_page_index_R + freezes when recording stops by record_enable_RW = False, + restarts at 0 when recording starts by record_enable_RW = True, + first page that was recorded in ddr, + remains 0 until recording has filled the circular buffer once, + equals recorded_last_page_index + 1 when recording continues + recorded_last_page_index_R + freezes when recording stops by record_enable_RW = False, + restarts at 0 when recording starts by record_enable_RW = True, + last page that was recorded in ddr, increments during recording + + . recorded_first_rsn_R + RSN of block at recorded_first_page_index + recorded_last_rsn_R + RSN of block at recorded_last_page_index + + . dump_first_page_index_RW --> index of first page to dump, same for all ai in pn + dump_last_page_index_RW --> index of last page to dump, same for all ai in pn + SDPTR: + # Get RSN range from timestamp range + FPGA_tbuf_dump_timestamp_range_RW / raw_sample_period --> dump_start_rsn, dump_end_rsn + + # Determine start page that includes start RSN + offset_page = floor((dump_start_rsn - recorded_first_rsn_R) / c_tbuf_nof_samples_per_page) + if offset_page < 0: + offset_page = 0 + dump_start_page = recorded_first_page_index + offset_page + + # Determine end page that includes end RSN + offset_page = ceil((dump_end_rsn - recorded_last_rsn_R) / c_tbuf_nof_samples_per_page) + if offset_page > 0: + offset_page = 0 + dump_end_page = recorded_last_page_index + offset_page + dump_nof_pages = dump_end_page - dump_start_page + 1 + + # Report nof packts that will be dumped + FPGA_tbuf_dump_nof_packets_R = 0 + if dump_nof_pages > 0: + FPGA_tbuf_dump_nof_packets_R = dump_nof_pages SDPTR based on: - . FPGA_tbuf_dump_timestamp_range_RW[pn][rsn] (from_rsn, to_rsn) + . FPGA_tbuf_dump_timestamp_range_RW[pn][rsn] (start_rsn, end_rsn) . FPGA_tbuf_dump_enable_RW[pn][ai] sets: - . dump_first_page_W = page index of from_rsn - . dump_nof_pages_W = nof pages in range from_rsn, to_rsn - . dump_antenna_input_W = active ai in FPGA_tbuf_dump_enable_RW - . dump_enable <-- enable to dump ai, - - * Recording: - . FPGA_tbuf_recording_R[pn] --> pn is recording, all ai or half of ai (dependent on FPGA_tbuf_record_all_antenna_RW) - - . FPGA_tbuf_last_timestamp_R[pn] = last_recorded_rsn * FPGA_tbuf_sample_period_R - . FPGA_tbuf_first_timestamp_R[pn] = first_recorded_rsn * FPGA_tbuf_sample_period_R - . FPGA_tbuf_recorded_time_R[pn] = FPGA_tbuf_last_timestamp_R - FPGA_tbuf_first_timestamp_R - - - * Dumping: - . FPGA_tbuf_dumping_R[pn] --> boolean or report remaining nof packets to predict when it will be done - - . FPGA_tbuf_total_nof_memory_errors_R[pn][ai] --> count per ai, because each ai has own CRC - FPGA_tbuf_total_nof_dumped_packets_R[pn][ai] --> count per ai - - Maybe: - . Not: FPGA_tbuf_last_page [pn][si] --> index of last recorded page - . Not: FPGA_tbuf_nof_recorded_pages[pn][si] --> number of fresh recorded pages <= alloc nof_pages - + . dump_first_page_RW = page index of from_rsn + . dump_nof_pages_RW = nof pages in range from_rsn, to_rsn + . dump_antenna_input_RW = active ai in FPGA_tbuf_dump_enable_RW + . dump_enable_RW <-- enable to dump ai, Not (no peek and poke): . FPGA_tbuf_memory_address_RW[pn] @@ -371,7 +457,7 @@ The CP FPGA_beamlet_output_nof_beamlets_RW is not supported in SDPTR and SDPFW y FPGA_tbuf_memory_read_data_R[pn] --> read data results from FPGA_tbuf_memory_read_nof_words_RW . FPGA_tbuf_memory_write_data_words_RW[pn] --> write data words (512b) to FPGA_tbuf_memory_address_RW - Not: FPGA_tbuf_page_period_R # = FPGA_tbuf_sample_period_R * 23.36 us + Not: FPGA_tbuf_page_period_R # = raw_sample_period * 23.36 us 6) TBuf ICD STAT/SDP-CEP