From a99fac391b568c69152c499cda628d274e6a672c Mon Sep 17 00:00:00 2001 From: Laez Barbosa Date: Thu, 26 Sep 2024 12:42:24 -0300 Subject: [PATCH 1/2] pulsar_adc: add split transfer functionality add a parameter, SPLIT_TRANSFER_SIZE, to enable and control split transfers. If SPLIT_TRANSFER_SIZE is set to 0 (default), the project behaves as usual (no split transfers). Otherwise, an asymetric fifo is used to stitch together 2 transfers before sending them to the DMA, SPLIT_TRANSFER_SIZE being used to indicate the size of each transfer in the split. Signed-off-by: Laez Barbosa --- docs/projects/pulsar_adc/index.rst | 9 +++++++ projects/pulsar_adc/common/pulsar_adc_bd.tcl | 27 +++++++++++++++++++- projects/pulsar_adc/zed/Makefile | 1 + projects/pulsar_adc/zed/system_project.tcl | 5 ++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/docs/projects/pulsar_adc/index.rst b/docs/projects/pulsar_adc/index.rst index e7df78a4e8..95cdb49a86 100644 --- a/docs/projects/pulsar_adc/index.rst +++ b/docs/projects/pulsar_adc/index.rst @@ -185,6 +185,15 @@ These modes are selected using the ``SPI_OP_MODE`` parameter: The SPI_OP_MODE parameter must only be used for the FMC variant. +Some ADCs like the AD7944 allow for split transfers, which require samples to be +assembled out of two SPI Engine transfer reads from the ADC. This is enabled by +the ``SPLIT_TRANSFER_SIZE`` parameter. If 0, split transfers are disabled. For +values greater than 0, it determines the size of each of the two transfers that +make up the split transfer. + +* 0 - for no split transfers (default) +* N - for N>0, selects the size of each transfer that make up the sample + CPU/Memory interconnects addresses ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/projects/pulsar_adc/common/pulsar_adc_bd.tcl b/projects/pulsar_adc/common/pulsar_adc_bd.tcl index eec33060ad..81315dab8e 100644 --- a/projects/pulsar_adc/common/pulsar_adc_bd.tcl +++ b/projects/pulsar_adc/common/pulsar_adc_bd.tcl @@ -15,6 +15,8 @@ set num_sdo 1 set sdi_delay 1 set echo_sclk 0 +set SPLIT_TRANSFER_SIZE [get_env_param SPLIT_TRANSFER_SIZE 0] + set hier_spi_engine spi_pulsar_adc spi_engine_create $hier_spi_engine $data_width $async_spi_clk $num_cs $num_sdi $num_sdo $sdi_delay $echo_sclk @@ -40,6 +42,24 @@ ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_2D_TRANSFER 0 ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_DATA_WIDTH_SRC $data_width ad_ip_parameter axi_pulsar_adc_dma CONFIG.DMA_DATA_WIDTH_DEST 64 +if {$SPLIT_TRANSFER_SIZE != 0} { + ad_ip_instance util_axis_fifo_asym rx_asym_fifo + ad_ip_parameter rx_asym_fifo CONFIG.ASYNC_CLK 0 + ad_ip_parameter rx_asym_fifo CONFIG.S_DATA_WIDTH $SPLIT_TRANSFER_SIZE + ad_ip_parameter rx_asym_fifo CONFIG.S_ADDRESS_WIDTH 3 + ad_ip_parameter rx_asym_fifo CONFIG.M_DATA_WIDTH [expr {2*$SPLIT_TRANSFER_SIZE}] + ad_ip_parameter rx_asym_fifo CONFIG.M_AXIS_REGISTERED 1 + ad_ip_parameter rx_asym_fifo CONFIG.ALMOST_EMPTY_THRESHOLD 2 + ad_ip_parameter rx_asym_fifo CONFIG.ALMOST_FULL_THRESHOLD 6 + ad_ip_parameter rx_asym_fifo CONFIG.TLAST_EN 0 + ad_ip_parameter rx_asym_fifo CONFIG.TKEEP_EN 0 + + ad_connect spi_clk rx_asym_fifo/s_axis_aclk + ad_connect $hier_spi_engine/${hier_spi_engine}_axi_regmap/spi_resetn rx_asym_fifo/s_axis_aresetn + ad_connect spi_clk rx_asym_fifo/m_axis_aclk + ad_connect $hier_spi_engine/${hier_spi_engine}_axi_regmap/spi_resetn rx_asym_fifo/m_axis_aresetn +} + ad_connect $sys_cpu_clk spi_clkgen/clk ad_connect spi_clk spi_clkgen/clk_0 @@ -48,7 +68,12 @@ ad_connect $sys_cpu_clk pulsar_adc_trigger_gen/s_axi_aclk ad_connect sys_cpu_resetn pulsar_adc_trigger_gen/s_axi_aresetn ad_connect pulsar_adc_trigger_gen/pwm_0 $hier_spi_engine/trigger -ad_connect axi_pulsar_adc_dma/s_axis $hier_spi_engine/M_AXIS_SAMPLE +if {$SPLIT_TRANSFER_SIZE != 0} { + ad_connect rx_asym_fifo/s_axis $hier_spi_engine/M_AXIS_SAMPLE + ad_connect axi_pulsar_adc_dma/s_axis rx_asym_fifo/m_axis +} else { + ad_connect axi_pulsar_adc_dma/s_axis $hier_spi_engine/M_AXIS_SAMPLE +} ad_connect $hier_spi_engine/m_spi pulsar_adc_spi ad_connect $sys_cpu_clk $hier_spi_engine/clk diff --git a/projects/pulsar_adc/zed/Makefile b/projects/pulsar_adc/zed/Makefile index 12f8344512..3dd4bdb95b 100644 --- a/projects/pulsar_adc/zed/Makefile +++ b/projects/pulsar_adc/zed/Makefile @@ -31,5 +31,6 @@ LIB_DEPS += spi_engine/spi_engine_interconnect LIB_DEPS += spi_engine/spi_engine_offload LIB_DEPS += sysid_rom LIB_DEPS += util_i2c_mixer +LIB_DEPS += util_axis_fifo_asym include ../../scripts/project-xilinx.mk diff --git a/projects/pulsar_adc/zed/system_project.tcl b/projects/pulsar_adc/zed/system_project.tcl index 6cdf733e14..355920f1e1 100644 --- a/projects/pulsar_adc/zed/system_project.tcl +++ b/projects/pulsar_adc/zed/system_project.tcl @@ -25,6 +25,7 @@ source $ad_hdl_dir/projects/scripts/adi_board.tcl ## set FMC_N_PMOD [get_env_param FMC_N_PMOD 1] set SPI_OP_MODE [get_env_param SPI_OP_MODE 0] +set SPLIT_TRANSFER_SIZE [get_env_param SPLIT_TRANSFER_SIZE 0] adi_project pulsar_adc_pmdz_zed 0 [list \ FMC_N_PMOD [get_env_param FMC_N_PMOD 1] \ @@ -56,5 +57,9 @@ if {$FMC_N_PMOD == 0} { return -code error [format "ERROR: Invalid eval board type! ..."] } +if {$SPLIT_TRANSFER_SIZE < 0 || ![string is integer $SPLIT_TRANSFER_SIZE]} { + return -code error [format "ERROR: Illegal value for SPLIT_TRANSFER_SIZE ..."] +} + adi_project_run pulsar_adc_pmdz_zed From 7203b455c94a0c59efc20993fc6195ea7f7d44a1 Mon Sep 17 00:00:00 2001 From: Laez Barbosa Date: Fri, 4 Oct 2024 14:06:48 -0300 Subject: [PATCH 2/2] util_axis_fifo_asym: avoid errors for data width <8b Signed-off-by: Laez Barbosa --- .../util_axis_fifo_asym/util_axis_fifo_asym.v | 27 +++++++++++-------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/library/util_axis_fifo_asym/util_axis_fifo_asym.v b/library/util_axis_fifo_asym/util_axis_fifo_asym.v index c297d64e81..770ab68ee5 100644 --- a/library/util_axis_fifo_asym/util_axis_fifo_asym.v +++ b/library/util_axis_fifo_asym/util_axis_fifo_asym.v @@ -79,6 +79,7 @@ module util_axis_fifo_asym #( localparam A_ADDRESS = (RATIO_TYPE) ? S_ADDRESS_WIDTH : (S_ADDRESS_WIDTH-$clog2(RATIO)); localparam A_ALMOST_FULL_THRESHOLD = (RATIO_TYPE) ? ALMOST_FULL_THRESHOLD : (ALMOST_FULL_THRESHOLD/RATIO); localparam A_ALMOST_EMPTY_THRESHOLD = (RATIO_TYPE) ? (ALMOST_EMPTY_THRESHOLD/RATIO) : ALMOST_EMPTY_THRESHOLD; + localparam A_KEEP_WIDTH = ((A_WIDTH/8)>1) ? (A_WIDTH/8) : 1; // avoids errors for A_WIDTH<8 // slave and master sequencers reg [$clog2(RATIO)-1:0] s_axis_counter; @@ -87,7 +88,7 @@ module util_axis_fifo_asym #( wire [RATIO-1:0] m_axis_ready_int_s; wire [RATIO-1:0] m_axis_valid_int_s; wire [RATIO*A_WIDTH-1:0] m_axis_data_int_s; - wire [RATIO*A_WIDTH/8-1:0] m_axis_tkeep_int_s; + wire [RATIO*A_KEEP_WIDTH-1:0] m_axis_tkeep_int_s; wire [RATIO-1:0] m_axis_tlast_int_s; wire [RATIO-1:0] m_axis_empty_int_s; wire [RATIO-1:0] m_axis_almost_empty_int_s; @@ -96,7 +97,7 @@ module util_axis_fifo_asym #( wire [RATIO-1:0] s_axis_ready_int_s; wire [RATIO-1:0] s_axis_valid_int_s; wire [RATIO*A_WIDTH-1:0] s_axis_data_int_s; - wire [RATIO*A_WIDTH/8-1:0] s_axis_tkeep_int_s; + wire [RATIO*A_KEEP_WIDTH-1:0] s_axis_tkeep_int_s; wire [RATIO-1:0] s_axis_tlast_int_s; wire [RATIO-1:0] s_axis_full_int_s; wire [RATIO-1:0] s_axis_almost_full_int_s; @@ -122,7 +123,7 @@ module util_axis_fifo_asym #( .m_axis_valid (m_axis_valid_int_s[i]), .m_axis_data (m_axis_data_int_s[A_WIDTH*i+:A_WIDTH]), .m_axis_tlast (m_axis_tlast_int_s[i]), - .m_axis_tkeep (m_axis_tkeep_int_s[A_WIDTH/8*i+:A_WIDTH/8]), + .m_axis_tkeep (m_axis_tkeep_int_s[A_KEEP_WIDTH*i+:A_KEEP_WIDTH]), .m_axis_level (m_axis_level_int_s[A_ADDRESS*i+:A_ADDRESS]), .m_axis_empty (m_axis_empty_int_s[i]), .m_axis_almost_empty (m_axis_almost_empty_int_s[i]), @@ -131,7 +132,7 @@ module util_axis_fifo_asym #( .s_axis_ready (s_axis_ready_int_s[i]), .s_axis_valid (s_axis_valid_int_s[i]), .s_axis_data (s_axis_data_int_s[A_WIDTH*i+:A_WIDTH]), - .s_axis_tkeep (s_axis_tkeep_int_s[A_WIDTH/8*i+:A_WIDTH/8]), + .s_axis_tkeep (s_axis_tkeep_int_s[A_KEEP_WIDTH*i+:A_KEEP_WIDTH]), .s_axis_tlast (s_axis_tlast_int_s[i]), .s_axis_room (s_axis_room_int_s[A_ADDRESS*i+:A_ADDRESS]), .s_axis_full (s_axis_full_int_s[i]), @@ -165,7 +166,7 @@ module util_axis_fifo_asym #( for (i=0; i> (m_axis_counter*A_WIDTH) ; - assign m_axis_tkeep = m_axis_tkeep_int_s >> (m_axis_counter*A_WIDTH/8) ; + assign m_axis_tkeep = m_axis_tkeep_int_s >> (m_axis_counter*A_KEEP_WIDTH) ; // VALID/EMPTY/ALMOST_EMPTY is driven by the current atomic instance assign m_axis_valid = m_axis_valid_int_s >> m_axis_counter; @@ -222,11 +223,15 @@ module util_axis_fifo_asym #( assign m_axis_ready_int_s[i] = m_axis_ready; end - for (i=0; i