diff --git a/libraries/base/reorder/src/vhdl/reorder_transpose.vhd b/libraries/base/reorder/src/vhdl/reorder_transpose.vhd index 5a6e2dd17dd871910f9c07bfe9e6bdc39c80edcf..6dd5f8d94265deb533818f66d3467cb197ae534f 100644 --- a/libraries/base/reorder/src/vhdl/reorder_transpose.vhd +++ b/libraries/base/reorder/src/vhdl/reorder_transpose.vhd @@ -23,44 +23,56 @@ -- Purpose: Performing a transpose (reordering data) on one or more streaming -- inputs using external memory. -- --- Description: The input of multiple streams (g_nof_streams) is concatenated into a --- single stream. Either the data field or the complex fields can be --- used, based on the g_use_complex generic. +-- Description: +-- The input of multiple streams (g_nof_streams) is concatenated into a +-- single stream. Either the data field or the complex fields can be +-- used, based on the g_use_complex generic. -- --- Data on this single stream is than transposed according to the settings --- of g_frame_size_in and g_reorder_seq. --- The actual transpose is divided in two stages. The first stage (pre_transpose) --- is done using a subband select module (reorder_col in RadioHDL). --- The second stage is done in external memory (DDR3, DDR4,...). --- --- Stage 1: Pre Transpose --- This stage is used to reorder data with a resolution as high as a single --- sample, because the second stage (if using DDR3 for instance) has a resolution --- of 16 or more samples. The ss_ss_transp mm interface can be used to specify --- the desired reordering for the pre transpose. +-- Data on this single stream is than transposed according to the settings +-- of g_frame_size_in and g_reorder_seq. +-- The actual transpose is divided in two stages. The first stage (pre_transpose) +-- is done using a subband select module (reorder_col in RadioHDL). +-- The second stage is done in external memory (DDR3, DDR4,...). +-- +-- Stage 1: Pre Transpose +-- This stage is used to reorder data with a resolution as high as a single +-- sample, because the second stage (if using DDR3 for instance) has a resolution +-- of 16 or more samples. The ss_ss_transp mm interface can be used to specify +-- the desired reordering for the pre transpose. -- --- Stage 2: Reorder Sequencer --- After the pre transpose the data is send to the external memory --- interface (to_mem_src_out). The reorder sequencer module provides the address --- and control signals for the external memory. Writing and reading is done in a --- alternating way. Data from the external memory is received via the --- from_mem_snk_in interface. The sequencers rhythm is based on the settings of --- the g_reorder_seq generic. +-- Stage 2: Reorder Sequencer +-- After the pre transpose the data is send to the external memory +-- interface (to_mem_src_out). The reorder sequencer module provides the address +-- and control signals for the external memory. Writing and reading is done in a +-- alternating way. Data from the external memory is received via the +-- from_mem_snk_in interface. The sequencers rhythm is based on the settings of +-- the g_reorder_seq generic. -- --- At the output the data from the single stream is split up in the original --- g_nof_streams again. A block_gen module is used to generate the SYNC, SOP and EOP --- signals. +-- At the output the data from the single stream is split up in the original +-- g_nof_streams again. A block_gen module is used to generate the SYNC, SOP and EOP +-- signals. -- --- SYNC and BSN --- At the input the BSN number at every SYNC is written to a fifo. This BSN number --- is inserted in the output data again when a SYNC is applied at the output. +-- SYNC and BSN +-- At the input the BSN number at every SYNC is written to a fifo. This BSN number +-- is inserted in the output data again when a SYNC is applied at the output. -- --- SYNC Period --- The SYNC period (the number of blocks per sync interval) is monitored with a counter. --- In case the number of blocks within a syncperiod is not equal to the specified --- g_reorder_seq.nof_blocks the sequencer will reset and start again when the number of --- received blocksdoes match the g_reorder_seq.nof_blocks. +-- SYNC Period +-- The SYNC period (the number of blocks per sync interval) is monitored with a counter. +-- In case the number of blocks within a syncperiod is not equal to the specified +-- g_reorder_seq.nof_blocks the sequencer will reset and start again when the number of +-- received blocksdoes match the g_reorder_seq.nof_blocks. -- +-- Complex or real data: +-- The the width of snk_in.data, re, im is g_in_dat_w. When g_use_complex = FALSE then +-- snk_in.data is passed on internally, so then the internal sosi.data width is also +-- g_in_dat_w. When g_use_complex = TRUE then snk_in.im and snk_in.re are concatenated +-- into an internal sosi.data that has then width 2*g_in_dat_w. The g_nof_streams are +-- also concatenated into the sosi.data. +-- . g_use_complex = FALSE : sosi.data = data[g_nof_streams-1] & ... & data[1] & data[0] +-- . g_use_complex = TRUE : sosi.data = im&re[g_nof_streams-1] & ... & im&re[1] & im&re[0] +-- Hence: +-- . g_use_complex = FALSE : c_data_w = g_nof_streams*g_in_dat_w +-- . g_use_complex = TRUE : c_data_w = g_nof_streams*g_in_dat_w*c_nof_complex -- Remarks: LIBRARY IEEE, common_lib, technology_lib, dp_lib; @@ -129,7 +141,8 @@ ARCHITECTURE str OF reorder_transpose IS CONSTANT c_complex_data_w : NATURAL := c_total_data_w*c_nof_complex; CONSTANT c_data_w : NATURAL := sel_a_b(g_use_complex, c_complex_data_w, c_total_data_w); CONSTANT c_data_w_pre : NATURAL := sel_a_b(g_use_complex, c_total_data_w, c_total_data_w/2); -- Datawidth for pre-transpose defines Re or Im part. - + CONSTANT c_sdata_w : NATURAL := c_data_w / g_nof_streams; + CONSTANT c_nof_ch_in : NATURAL := g_frame_size_in*g_reorder_seq.rd_chunksize; CONSTANT c_nof_ch_sel : NATURAL := g_reorder_seq.wr_chunksize*g_reorder_seq.rd_chunksize; @@ -152,7 +165,7 @@ ARCHITECTURE str OF reorder_transpose IS SIGNAL dvr_nof_data : STD_LOGIC_VECTOR(c_mem_size_w-1 DOWNTO 0); SIGNAL dvr_wr_flush_en : STD_LOGIC; - SIGNAL to_mem_src_out_i : t_dp_sosi; + SIGNAL i_to_mem_src_out : t_dp_sosi; SIGNAL block_gen_out_sosi : t_dp_sosi; SIGNAL pipeline_out_sosi : t_dp_sosi; @@ -163,7 +176,55 @@ ARCHITECTURE str OF reorder_transpose IS SIGNAL rd_dat_i : STD_LOGIC_VECTOR(c_dp_stream_bsn_w-1 DOWNTO 0); SIGNAL rd_val_i : STD_LOGIC; -BEGIN + SIGNAL i_src_out_arr : t_dp_sosi_arr(g_nof_streams-1 DOWNTO 0); + + -- debug signals + -- . g_use_complex = FALSE : view sosi.data + SIGNAL dbg_snk_in_data_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_to_mem_src_out_data_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_from_mem_snk_in_data_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_src_out_data_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + -- . g_use_complex = TRUE : view sosi.re and sosi.im + SIGNAL dbg_snk_in : t_dp_sosi; + SIGNAL dbg_snk_in_re_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_snk_in_im_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_to_mem_src_out : t_dp_sosi; + SIGNAL dbg_to_mem_src_out_re_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_to_mem_src_out_im_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_from_mem_snk_in : t_dp_sosi; + SIGNAL dbg_from_mem_snk_in_re_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_from_mem_snk_in_im_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_src_out : t_dp_sosi; + SIGNAL dbg_src_out_re_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + SIGNAL dbg_src_out_im_concat : STD_LOGIC_VECTOR(c_total_data_w-1 DOWNTO 0); + +BEGIN + + to_mem_src_out <= i_to_mem_src_out; + src_out_arr <= i_src_out_arr; + + -- Internal transport is done via sosi.data, for debug view sosi.data or view sosi.re and sosi.im dependent on g_use_complex + dbg_snk_in <= snk_in_arr(0); + dbg_to_mem_src_out <= i_to_mem_src_out; + dbg_from_mem_snk_in <= from_mem_snk_in; + dbg_src_out <= i_src_out_arr(0); + gen_debug : FOR I IN 0 TO g_nof_streams-1 GENERATE + -- g_use_complex = FALSE : view sosi.data + dbg_snk_in_data_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= snk_in_arr(I).data( g_in_dat_w-1 DOWNTO 0); + dbg_to_mem_src_out_data_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= i_to_mem_src_out.data((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w); + dbg_from_mem_snk_in_data_concat((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= from_mem_snk_in.data((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w); + dbg_src_out_data_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= i_src_out_arr(I).data( g_in_dat_w-1 DOWNTO 0); + + -- g_use_complex = TRUE : view sosi.re and sosi.im (transported via sosi.data, factor 2 = c_nof_complex) + dbg_snk_in_re_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= snk_in_arr(I).re( g_in_dat_w-1 DOWNTO 0); + dbg_snk_in_im_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= snk_in_arr(I).im( g_in_dat_w-1 DOWNTO 0); + dbg_to_mem_src_out_re_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= i_to_mem_src_out.data((2*I+1)*g_in_dat_w-1 DOWNTO (2*I+0)*g_in_dat_w); + dbg_to_mem_src_out_im_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= i_to_mem_src_out.data((2*I+2)*g_in_dat_w-1 DOWNTO (2*I+1)*g_in_dat_w); + dbg_from_mem_snk_in_re_concat((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= from_mem_snk_in.data((2*I+1)*g_in_dat_w-1 DOWNTO (2*I+0)*g_in_dat_w); + dbg_from_mem_snk_in_im_concat((I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= from_mem_snk_in.data((2*I+2)*g_in_dat_w-1 DOWNTO (2*I+1)*g_in_dat_w); + dbg_src_out_re_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= i_src_out_arr(I).re( g_in_dat_w-1 DOWNTO 0); + dbg_src_out_im_concat( (I+1)*g_in_dat_w-1 DOWNTO I*g_in_dat_w) <= i_src_out_arr(I).im( g_in_dat_w-1 DOWNTO 0); + END GENERATE; g_merge_in_complex : IF g_use_complex = TRUE GENERATE PROCESS(snk_in_arr) @@ -261,16 +322,14 @@ BEGIN input_sosi => ss_in_sosi, input_siso => OPEN, -- Don't allow backpressure. - output_sosi => to_mem_src_out_i, + output_sosi => i_to_mem_src_out, output_siso => to_mem_src_in ); END GENERATE; - to_mem_src_out <= to_mem_src_out_i; - gen_not_pre_transpose : IF g_ena_pre_transp = FALSE GENERATE - to_mem_src_out_i <= packet_merge_in_sosi; + i_to_mem_src_out <= packet_merge_in_sosi; packet_merge_in_siso <= to_mem_src_in; END GENERATE; @@ -298,7 +357,7 @@ BEGIN address => dvr_start_address, burstsize => dvr_nof_data, - done => dvr_done + done => dvr_done ); --------------------------------------------------------------- @@ -395,12 +454,12 @@ BEGIN gen_merge_out : PROCESS(block_gen_out_sosi, pipeline_out_sosi, sync_bsn) BEGIN FOR i IN 0 TO g_nof_streams-1 LOOP - src_out_arr(i) <= block_gen_out_sosi; - src_out_arr(i).valid <= pipeline_out_sosi.valid; - src_out_arr(i).re <= RESIZE_DP_DSP_DATA(pipeline_out_sosi.data((2*i+1)*g_in_dat_w-1 DOWNTO 2*i*g_in_dat_w)); - src_out_arr(i).im <= RESIZE_DP_DSP_DATA(pipeline_out_sosi.data((2*i+2)*g_in_dat_w-1 DOWNTO (2*i+1)*g_in_dat_w)); + i_src_out_arr(i) <= block_gen_out_sosi; + i_src_out_arr(i).valid <= pipeline_out_sosi.valid; + i_src_out_arr(i).re <= RESIZE_DP_DSP_DATA(pipeline_out_sosi.data((2*i+1)*g_in_dat_w-1 DOWNTO 2*i*g_in_dat_w)); + i_src_out_arr(i).im <= RESIZE_DP_DSP_DATA(pipeline_out_sosi.data((2*i+2)*g_in_dat_w-1 DOWNTO (2*i+1)*g_in_dat_w)); IF (block_gen_out_sosi.sync = '1') THEN - src_out_arr(i).bsn <= sync_bsn; + i_src_out_arr(i).bsn <= sync_bsn; END IF; END LOOP; END PROCESS; @@ -410,11 +469,11 @@ BEGIN gen_merge_out : PROCESS(block_gen_out_sosi, pipeline_out_sosi) BEGIN FOR i IN 0 TO g_nof_streams-1 LOOP - src_out_arr(i) <= block_gen_out_sosi; - src_out_arr(i).valid <= pipeline_out_sosi.valid; - src_out_arr(i).data <= RESIZE_DP_DATA(pipeline_out_sosi.data((i+1)*g_in_dat_w-1 DOWNTO i*g_in_dat_w)); + i_src_out_arr(i) <= block_gen_out_sosi; + i_src_out_arr(i).valid <= pipeline_out_sosi.valid; + i_src_out_arr(i).data <= RESIZE_DP_DATA(pipeline_out_sosi.data((i+1)*g_in_dat_w-1 DOWNTO i*g_in_dat_w)); IF (block_gen_out_sosi.sync = '1') THEN - src_out_arr(i).bsn <= sync_bsn; + i_src_out_arr(i).bsn <= sync_bsn; END IF; END LOOP; END PROCESS;