diff --git a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd index 795c772f562a4c8e01bd747ff4e3c6bc49016fed..67c5bd1959c35b1a11084c59370e6add731a101a 100644 --- a/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd +++ b/libraries/base/dp/src/vhdl/dp_block_from_mm.vhd @@ -18,11 +18,41 @@ -- -------------------------------------------------------------------------- -- Author: --- . Pieter Donker, R van der Walle +-- . Pieter Donker, R van der Walle, E. Kooistra -- Purpose: -- . Read a block of data from memory mapped (MM) location and stream it as a block of data. -- Description: -- . https://support.astron.nl/confluence/display/L2M/L5+SDPFW+Design+Document%3A+Subband+filterbank +-- +-- . g_*_size, g_word_w: +-- The g_*_size values are in number of g_word_w memory words, so e.g. +-- 32bit words. The 32bit words are read in data blocks of g_data_size +-- words. The data block contains g_data_size / g_user_size number of +-- user words, this occurs e.g. when the data block contains: +-- - a complex value, so with real part and imag part +-- - dual polarization value, so with X polarization and Y polarization +-- The user words contain g_user_size number of g_word_w = 32bit words. +-- The output out_sosi.data width is also g_word_w bits. +-- +-- . g_step_size: +-- The g_step_size = K * g_data_size, where K >= 1 to allow read out of +-- data blocks that are interleaved by a factor K. +-- +-- . g_nof_data and start_pulse, start_address, mm_mosi, mm_miso, mm_done: +-- The g_nof_data is the number of data blocks that are read out via +-- mm_mosi/mm_miso per start_pulse, to form a new aggregate output block +-- with out_sosi.sop and out_sosi.eop. When the read out is done, then +-- mm_done pulses and a new start_pulse can be issued. By incrementing +-- the start_address for every start_pulse it is possible to read out K +-- interleaved sets of data blocks from the memory. +-- +-- . g_reverse_word_order per g_user_size: +-- The g_reverse_word_order has no effect when FALSE, but reverses the +-- read out order of the 32bit words per user word when TRUE. The +-- g_reverse_word_order has to apply per user word and not per data block, +-- to preserve the order of the user parts (e.g. real and imag, X and Y +-- polarization) in a data block. +-- -- -------------------------------------------------------------------------- LIBRARY IEEE,common_lib; @@ -34,10 +64,11 @@ USE work.dp_stream_pkg.ALL; ENTITY dp_block_from_mm IS GENERIC ( + g_user_size : NATURAL; g_data_size : NATURAL; g_step_size : NATURAL; g_nof_data : NATURAL; - g_data_w : NATURAL := c_word_w; + g_word_w : NATURAL := c_word_w; g_mm_rd_latency : NATURAL := 1; -- default 1 from rd_en to rd_val, use 2 to ease timing closure g_reverse_word_order : BOOLEAN := FALSE ); @@ -58,7 +89,7 @@ END dp_block_from_mm; ARCHITECTURE rtl OF dp_block_from_mm IS CONSTANT c_mem_size : NATURAL := g_step_size * g_nof_data; - CONSTANT c_word_index_rst : NATURAL := sel_a_b(g_reverse_word_order, g_data_size - 1, 0); + CONSTANT c_word_index_rst : NATURAL := sel_a_b(g_reverse_word_order, g_user_size - 1, 0); TYPE t_reg IS RECORD busy : STD_LOGIC; @@ -95,7 +126,7 @@ BEGIN u_sosi : PROCESS(r, mm_miso, out_sop, out_eop) BEGIN out_sosi <= c_dp_sosi_rst; -- To avoid Modelsim warnings on conversion to integer from unused fields. - out_sosi.data <= RESIZE_DP_DATA(mm_miso.rddata(g_data_w-1 DOWNTO 0)); + out_sosi.data <= RESIZE_DP_DATA(mm_miso.rddata(g_word_w-1 DOWNTO 0)); out_sosi.valid <= mm_miso.rdval; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so same as the ready latency (RL = 1) out_sosi.sop <= out_sop; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.sop can be used for output sop out_sosi.eop <= out_eop; -- read latency from mm_mosi.rd to mm_miso.rdval is 1, so r.eop can be used for output eop @@ -147,6 +178,15 @@ BEGIN v.sop := '1'; END IF; + -- check end of block + IF mm_address = last_mm_address - (g_data_size - 1) THEN -- with reversed word order the last word to read is actually the first word of the last step index + v.eop := '1'; + -- prepare for next block + v.busy := '0'; + v.step_index := 0; + v.word_index := g_data_size - 1; + END IF; + ELSE IF r.word_index < g_data_size - 1 THEN @@ -161,24 +201,17 @@ BEGIN v.sop := '1'; END IF; - END IF; - -- check end of block - IF g_reverse_word_order THEN - IF mm_address = last_mm_address - (g_data_size - 1) THEN -- with reversed word order the last word to read is actually the first word of the last step index + IF mm_address >= last_mm_address THEN v.eop := '1'; -- prepare for next block v.busy := '0'; v.step_index := 0; - v.word_index := g_data_size - 1; + v.word_index := 0; END IF; - ELSIF mm_address >= last_mm_address THEN -- g_reverse_word_order = False - v.eop := '1'; - -- prepare for next block - v.busy := '0'; - v.step_index := 0; - v.word_index := 0; + END IF; + END IF; END IF; nxt_r <= v;