2424#include "stats.h"
2525#include "vspa_dmem_proxy.h"
2626
27+ #if defined(IQMOD_2DEC2INT ) || defined(IQMOD_4DEC4INT )
28+ // Use IPPU DMEM for input buffer and decimation
29+ vspa_complex_fixed16 input_buffer [RX_NUM_BUF * RX_DMA_TXR_size ] __attribute__((section (".ippu_dmem" )))
30+ __attribute__((aligned (64 ))) = { 0x00000000 , 0x00010001 , 0x00020002 , 0x00030003 };
31+ // Decimated output in VCPU DMEM
32+ vspa_complex_fixed16 input_dec_buffer [RX_NUM_DEC_BUF * (RX_DMA_TXR_size / RX_DECIM )] __attribute__((section (".vcpu_dmem" )))
33+ __attribute__((aligned (64 )));
34+
35+ // Decimation filter state
36+ cfixed16_t filtState [32 ] __attribute__((section (".ippu_dmem" ))) __attribute__((aligned (64 )));
37+
38+ // Filter coefficients
39+ int filter_taps_downsampling [8 ] __attribute__((aligned (64 ))) = {
40+ #include "para_files\2xdown_coeff.txt"
41+ };
42+ #else
43+ // Original buffer allocation for non-decimating configs
2744vspa_complex_fixed16 input_buffer [RX_NUM_BUF * RX_DMA_TXR_size ] __attribute__((section (".vcpu_dmem" )))
2845__attribute__((aligned (64 ))) = { 0x00000000 , 0x00010001 , 0x00020002 , 0x00030003 };
2946vspa_complex_fixed16 input_qec_buffer [RX_NUM_QEC_BUF * RX_DMA_TXR_size ] __attribute__((section (".ippu_dmem" )))
3047__attribute__((aligned (64 ))) = { 0x00000000 , 0x00010001 , 0x00020002 , 0x00030003 };
48+ #endif
3149
32- // uint32_t DDR_wr_QEC_enable= 0, DDR_wr_CMP_enable=0;
3350#define DDR_wr_QEC_enable 1
34- #define DDR_wr_CMP_enable 0
3551uint32_t DDR_wr_start_bit_update = 0 , DDR_wr_load_start_bit_update = 0 , DDR_wr_continuous = 0 ;
3652uint32_t ddr_wr_dma_xfr_size = RX_DDR_STEP ;
3753uint32_t DDR_wr_buff_wrap_equeued = 0 ;
@@ -42,21 +58,35 @@ volatile uint32_t RX_ext_dma_enabled = 0;
4258uint32_t ddr_wr_dma_ch_nb = 0 ;
4359uint32_t ddr_wr_dma_ch_mask = 0 ;
4460
45- static uint32_t RX_total_axiq_enqueued_size = 0 ; /* 0: Axiq rx in fifo cmd */
46- static uint32_t RX_total_axiq_received_size = 0 ; /* 1: Axiq rx dma completed */
47- volatile uint32_t RX_total_dmem_QECed_size = 0 ; /* 2: Rx data QECed */
48- #define RX_total_dmem_CMPed_size (rx_vspa_proxy[0].la9310_fifo_produced_size) /* 4: compressed */
61+ static uint32_t RX_total_axiq_enqueued_size = 0 ; /* 0: Axiq rx in fifo cmd */
62+ static uint32_t RX_total_axiq_received_size = 0 ; /* 1: Axiq rx dma completed */
63+ volatile uint32_t RX_total_dmem_QECed_size = 0 ; /* 2: Rx data QECed */
64+
65+ #if defined(IQMOD_2DEC2INT ) || defined(IQMOD_4DEC4INT )
66+ static uint32_t RX_total_dmem_input_Decimated_size = 0 ; /* 3: Input to decimation */
67+ #define RX_total_dmem_output_Decimated_size (rx_vspa_proxy[0].la9310_fifo_produced_size) /* 4: Output from decimation */
68+ #endif
69+
4970static uint32_t RX_total_ddr_enqueued_size = 0 ; /* 5: DDR wr cmd fifo */
5071#define RX_total_dmem_consumed_size (rx_vspa_proxy[0].la9310_fifo_consumed_size) /* 6: xfer to DDR complete */
5172#define RX_total_ddr_consumed_size (tx_vspa_proxy.host_consumed_size[0]) /* 7: DDR data ready */
5273
5374static vspa_complex_fixed16 * p_rx_axiq_enqueued = & input_buffer [0 ];
54- static vspa_complex_fixed16 * p_rx_axiq_received = & input_buffer [0 ];
75+
76+ #if defined(IQMOD_2DEC2INT ) || defined(IQMOD_4DEC4INT )
77+ // For decimating configs: in-place QEC, separate decimation buffers
78+ static vspa_complex_fixed16 * p_rx_dmem_QECed = & input_buffer [0 ];
79+ static vspa_complex_fixed16 * p_rx_dmem_input_decimated = & input_buffer [0 ];
80+ static vspa_complex_fixed16 * p_rx_dmem_output_decimated = & input_dec_buffer [0 ];
81+ static vspa_complex_fixed16 * p_rx_ddr_enqueued = & input_dec_buffer [0 ];
82+ static vspa_complex_fixed16 * p_rx_consumed = & input_dec_buffer [0 ];
83+ #else
84+ // For non-decimating configs: separate QEC buffer
5585static vspa_complex_fixed16 * p_rx_dmem_QECed_in = & input_buffer [0 ];
5686static vspa_complex_fixed16 * p_rx_dmem_QECed_out = & input_qec_buffer [0 ];
57- static vspa_complex_fixed16 * p_rx_dmem_CMPed = & input_qec_buffer [0 ];
5887static vspa_complex_fixed16 * p_rx_ddr_enqueued = & input_qec_buffer [0 ];
5988static vspa_complex_fixed16 * p_rx_consumed = & input_qec_buffer [0 ];
89+ #endif
6090
6191// uint32_t DDR_wr_base_address = 0xdeadbeef;
6292uint32_t DDR_wr_offset = 0 ;
@@ -91,15 +121,6 @@ void DDR_write_multi_dma(uint32_t DDR_wr_dma_channel, uint32_t nb_dma, uint32_t
91121 }
92122}
93123
94- volatile cmp_cycle = 0 ;
95- #define CMP_CYCLES (24 + 2 * 512 / 32)
96- void rx_compress (vspa_complex_fixed16 * data ) {
97- if (!DDR_wr_CMP_enable )
98- return ;
99- // compression place holder
100- for (cmp_cycle = 0 ; cmp_cycle < CMP_CYCLES ; cmp_cycle ++ ) {
101- };
102- }
103124void rx_qec_correction (vspa_complex_fixed16 * dataIn , vspa_complex_fixed16 * dataOut ) {
104125 if (!DDR_wr_QEC_enable )
105126 return ;
@@ -123,7 +144,6 @@ void RX_IQ_DATA_TO_DDR(void) {
123144 DDR_wr_load_start_bit_update = (HIWORD (msg64 )) & 0x00200000 ;
124145 DDR_wr_continuous = (HIWORD (msg64 )) & 0x00800000 ;
125146 // DDR_wr_QEC_enable= (HIWORD(msg64)) & 0x00400000;
126- // DDR_wr_CMP_enable= (HIWORD(msg64)) & 0x00080000;
127147 ddr_wr_dma_ch_nb = ((HIWORD (msg64 )) & 0x00070000 ) >> 16 ;
128148 host_flow_control_disable = (HIWORD (msg64 )) & 0x00400000 ;
129149
@@ -137,22 +157,32 @@ void RX_IQ_DATA_TO_DDR(void) {
137157 ddr_wr_dma_ch_nb = 1 ;
138158 }
139159 ddr_wr_dma_ch_mask = dma_chan_mask (DDR_WR_DMA_CHANNEL_1 , ddr_wr_dma_ch_nb );
140- ddr_wr_dma_xfr_size = ( DDR_wr_CMP_enable ? RX_DDR_STEP * RX_COMPRESS_RATIO_PCT / 100 : RX_DDR_STEP ) ;
160+ ddr_wr_dma_xfr_size = RX_DDR_STEP ;
141161
142162 dmac_reset (0x1 << dma_channel_rd );
143163
144164 p_rx_axiq_enqueued = & input_buffer [0 ];
145- p_rx_axiq_received = & input_buffer [0 ];
165+
166+ #if defined(IQMOD_2DEC2INT ) || defined(IQMOD_4DEC4INT )
167+ p_rx_dmem_QECed = & input_buffer [0 ];
168+ p_rx_dmem_input_decimated = & input_buffer [0 ];
169+ p_rx_dmem_output_decimated = & input_dec_buffer [0 ];
170+ p_rx_ddr_enqueued = & input_dec_buffer [0 ];
171+ p_rx_consumed = & input_dec_buffer [0 ];
172+ RX_total_dmem_input_Decimated_size = 0 ;
173+ RX_total_dmem_output_Decimated_size = 0 ;
174+ // Clear decimation filter state
175+ memclr ((void * )filtState , sizeof (filtState ));
176+ #else
146177 p_rx_dmem_QECed_in = & input_buffer [0 ];
147178 p_rx_dmem_QECed_out = & input_qec_buffer [0 ];
148- p_rx_dmem_CMPed = & input_qec_buffer [0 ];
149179 p_rx_ddr_enqueued = & input_qec_buffer [0 ];
150180 p_rx_consumed = & input_qec_buffer [0 ];
181+ #endif
151182
152183 RX_total_axiq_enqueued_size = 0 ;
153184 RX_total_axiq_received_size = 0 ;
154185 RX_total_dmem_QECed_size = 0 ;
155- RX_total_dmem_CMPed_size = 0 ;
156186 RX_total_ddr_enqueued_size = 0 ;
157187 RX_total_dmem_consumed_size = 0 ;
158188
@@ -220,8 +250,10 @@ void RX_IQ_DATA_TO_DDR(void) {
220250 }
221251
222252 DDR_wr_base_address = 0xdeadbeef ;
223- RX_total_dmem_CMPed_size = 0 ;
224253 RX_total_dmem_consumed_size = 0 ;
254+ #if defined(IQMOD_2DEC2INT ) || defined(IQMOD_4DEC4INT )
255+ RX_total_dmem_output_Decimated_size = 0 ;
256+ #endif
225257
226258 DDR_wr_start_bit_update = 0 ;
227259 DDR_wr_load_start_bit_update = 0 ;
@@ -278,7 +310,11 @@ void PUSH_RX_DATA(void) {
278310 l1_trace (L1_TRACE_MSG_DMA_DDR_WR_COMP , (uint32_t )g_stats .rx_stats [0 ][STAT_DMA_DDR_WR ]);
279311 }
280312 // restart DDR dma if possible
313+ #if defined(IQMOD_2DEC2INT ) || defined(IQMOD_4DEC4INT )
314+ p_rx_ddr_enqueued = input_dec_buffer ;
315+ #else
281316 p_rx_ddr_enqueued = input_qec_buffer ;
317+ #endif
282318 if (dmac_is_available (ddr_wr_dma_ch_mask ) == ddr_wr_dma_ch_mask ) {
283319 DDR_write_multi_dma (DDR_WR_DMA_CHANNEL_1 , ddr_wr_dma_ch_nb , DDR_wr_base_address + DDR_wr_offset ,
284320 2 * (uint32_t )p_rx_ddr_enqueued , ddr_wr_dma_xfr_size );
@@ -316,7 +352,7 @@ void PUSH_RX_DATA(void) {
316352 if (dmac_is_complete (0x1 << dma_channel_rd )) {
317353 dmac_clear_complete (0x1 << dma_channel_rd );
318354 dmac_clear_event (0x1 << dma_channel_rd );
319- RX_total_axiq_received_size += RX_DDR_STEP ;
355+ RX_total_axiq_received_size += RX_DMA_TXR_STEP ;
320356 g_stats .rx_stats [0 ][STAT_DMA_AXIQ_READ ]++ ;
321357 l1_trace (L1_TRACE_MSG_DMA_AXIQ_RX_COMP , (uint32_t )g_stats .rx_stats [0 ][STAT_DMA_AXIQ_READ ]);
322358 // check axiq dma error
@@ -326,7 +362,83 @@ void PUSH_RX_DATA(void) {
326362 l1_trace (L1_TRACE_MSG_DMA_AXIQ_RX_XFER_ERROR , (uint32_t )g_stats .gbl_stats [ERROR_DMA_XFER_ERROR ]);
327363 }
328364 }
329- // restart axiq dma if possible
365+
366+ #if defined(IQMOD_2DEC2INT ) || defined(IQMOD_4DEC4INT )
367+ // QEC buffer just received (in-place)
368+ if ((RX_total_axiq_received_size - RX_total_dmem_QECed_size ) >= RX_DMA_TXR_STEP ) {
369+ l1_trace (L1_TRACE_L1APP_RX_QEC_START , (uint32_t )p_rx_dmem_QECed );
370+ rx_qec_correction ((vspa_complex_fixed16 * )p_rx_dmem_QECed , (vspa_complex_fixed16 * )p_rx_dmem_QECed );
371+ INCR_RX_BUFF (p_rx_dmem_QECed );
372+ RX_total_dmem_QECed_size += RX_DMA_TXR_STEP ;
373+ l1_trace (L1_TRACE_L1APP_RX_QEC_COMP , (uint32_t )RX_total_dmem_QECed_size );
374+ }
375+
376+ // Decimation
377+ if ((RX_total_dmem_QECed_size - RX_total_dmem_input_Decimated_size ) >= RX_DMA_TXR_STEP ) {
378+ rx_busy_size = RX_total_dmem_output_Decimated_size - RX_total_dmem_consumed_size ;
379+ rx_empty_size = (RX_NUM_DEC_BUF * RX_DDR_STEP ) - rx_busy_size ;
380+ if (rx_empty_size >= RX_DDR_STEP ) {
381+ l1_trace (L1_TRACE_L1APP_RX_DEC_START , (uint32_t )p_rx_dmem_input_decimated );
382+ #ifdef IQMOD_2DEC2INT
383+ decimator_2x_8_Taps_asm ((cfixed16_t * )p_rx_dmem_output_decimated , (cfixed16_t * )p_rx_dmem_input_decimated ,
384+ (float32_t * )filter_taps_downsampling , (cfixed16_t * )filtState , RX_DMA_TXR_size );
385+ #endif
386+ #ifdef IQMOD_4DEC4INT
387+ decimator_4x_8_Taps_asm ((cfixed16_t * )p_rx_dmem_output_decimated , (cfixed16_t * )p_rx_dmem_input_decimated ,
388+ (float32_t * )filter_taps_downsampling , (cfixed16_t * )filtState , RX_DMA_TXR_size );
389+ #endif
390+ INCR_RX_BUFF (p_rx_dmem_input_decimated );
391+ INCR_RX_DEC_BUFF (p_rx_dmem_output_decimated );
392+ RX_total_dmem_input_Decimated_size += RX_DMA_TXR_STEP ;
393+ RX_total_dmem_output_Decimated_size += RX_DDR_STEP ;
394+ rx_proxy_updated = 1 ;
395+ l1_trace (L1_TRACE_L1APP_RX_DEC_COMP , (uint32_t )RX_total_dmem_input_Decimated_size );
396+ }
397+ }
398+ // restart axiq dma if possible
399+ if (dmac_is_available (0x1 << dma_channel_rd )) {
400+ rx_busy_size = RX_total_axiq_enqueued_size - RX_total_dmem_input_Decimated_size ;
401+ rx_empty_size = (RX_NUM_BUF * RX_DMA_TXR_STEP ) - rx_busy_size ;
402+ if (rx_empty_size >= RX_DMA_TXR_STEP ) {
403+ stream_read (dma_channel_rd , axi_rd , 2 * (uint32_t )(p_rx_axiq_enqueued ));
404+ INCR_RX_BUFF (p_rx_axiq_enqueued );
405+ RX_total_axiq_enqueued_size += RX_DMA_TXR_STEP ;
406+ l1_trace (L1_TRACE_MSG_DMA_AXIQ_RX_START , (uint32_t )p_rx_axiq_enqueued );
407+ } else {
408+ g_stats .rx_stats [0 ][ERROR_DMA_DDR_WR_OVERRUN ]++ ;
409+ l1_trace (L1_TRACE_MSG_DMA_DDR_WR_OVERRUN , (uint32_t )g_stats .rx_stats [0 ][ERROR_DMA_DDR_WR_OVERRUN ]);
410+ }
411+ }
412+
413+ // Push data to DDR if standalone mode
414+ if (!RX_ext_dma_enabled ) {
415+ if (dmac_is_complete (ddr_wr_dma_ch_mask ) == ddr_wr_dma_ch_mask ) {
416+ dmac_clear_complete (ddr_wr_dma_ch_mask );
417+ RX_total_dmem_consumed_size += RX_DDR_STEP ;
418+ g_stats .rx_stats [0 ][STAT_DMA_DDR_WR ]++ ;
419+ l1_trace (L1_TRACE_MSG_DMA_DDR_WR_COMP , (uint32_t )g_stats .rx_stats [0 ][STAT_DMA_DDR_WR ]);
420+ }
421+
422+ // host flow control
423+ if ((RX_total_ddr_enqueued_size - tx_vspa_proxy .host_consumed_size [0 ] < DDR_wr_size ) || host_flow_control_disable ) {
424+ if ((RX_total_dmem_output_Decimated_size - RX_total_ddr_enqueued_size ) >= RX_DDR_STEP ) {
425+ if (dmac_is_available (ddr_wr_dma_ch_mask ) == ddr_wr_dma_ch_mask ) {
426+ DDR_write_multi_dma (DDR_WR_DMA_CHANNEL_1 , ddr_wr_dma_ch_nb , DDR_wr_base_address + DDR_wr_offset ,
427+ 2 * (uint32_t )p_rx_ddr_enqueued , ddr_wr_dma_xfr_size );
428+ INCR_RX_DEC_BUFF (p_rx_ddr_enqueued );
429+ RX_total_ddr_enqueued_size += RX_DDR_STEP ;
430+ DDR_wr_offset += ddr_wr_dma_xfr_size ;
431+ if (DDR_wr_offset >= DDR_wr_size ) {
432+ DDR_wr_buff_wrap_equeued = 1 ;
433+ DDR_wr_offset = 0 ;
434+ }
435+ l1_trace (L1_TRACE_MSG_DMA_DDR_WR_START , (uint32_t )p_rx_ddr_enqueued );
436+ }
437+ }
438+ }
439+ }
440+ #else
441+ // restart axiq dma if possible
330442 if (dmac_is_available (0x1 << dma_channel_rd )) {
331443 rx_busy_size = RX_total_axiq_enqueued_size - RX_total_dmem_QECed_size ;
332444 rx_empty_size = (RX_NUM_BUF * RX_DDR_STEP ) - rx_busy_size ;
@@ -355,17 +467,7 @@ void PUSH_RX_DATA(void) {
355467 l1_trace (L1_TRACE_L1APP_RX_QEC_COMP , (uint32_t )RX_total_dmem_QECed_size );
356468 }
357469 }
358- if ((RX_total_dmem_QECed_size - RX_total_dmem_CMPed_size ) >= RX_DDR_STEP ) {
359- // Compress buffer
360- l1_trace (L1_TRACE_L1APP_RX_CMP_START , (uint32_t )p_rx_dmem_CMPed );
361- // rx_compress((vspa_complex_fixed16 *)p_rx_dmem_CMPed);
362- INCR_RX_QEC_BUFF (p_rx_dmem_CMPed );
363- RX_total_dmem_CMPed_size += RX_DDR_STEP ;
364- l1_trace (L1_TRACE_L1APP_RX_CMP_COMP , (uint32_t )RX_total_dmem_QECed_size );
365470
366- // update host vspa_dmem_proxy
367- rx_proxy_updated = 1 ;
368- }
369471 // Push data to DDR if standalone mode
370472 if (!RX_ext_dma_enabled ) {
371473 // check DDR dma completion
@@ -382,7 +484,7 @@ void PUSH_RX_DATA(void) {
382484
383485 // host flow control
384486 if ((RX_total_ddr_enqueued_size - tx_vspa_proxy .host_consumed_size [0 ] < DDR_wr_size ) || host_flow_control_disable ) {
385- if ((RX_total_dmem_CMPed_size - RX_total_ddr_enqueued_size ) >= RX_DDR_STEP ) {
487+ if ((RX_total_dmem_QECed_size - RX_total_ddr_enqueued_size ) >= RX_DDR_STEP ) {
386488 if (dmac_is_available (ddr_wr_dma_ch_mask ) == ddr_wr_dma_ch_mask ) {
387489 DDR_write_multi_dma (DDR_WR_DMA_CHANNEL_1 , ddr_wr_dma_ch_nb , DDR_wr_base_address + DDR_wr_offset ,
388490 2 * (uint32_t )p_rx_ddr_enqueued , ddr_wr_dma_xfr_size );
@@ -398,6 +500,8 @@ void PUSH_RX_DATA(void) {
398500 }
399501 }
400502 }
503+ #endif
504+
401505 if ((DDR_wr_buff_loop_count ) && (!DDR_wr_continuous )) {
402506
403507 dmac_abort (0x1 << dma_channel_rd );
0 commit comments