From a9add0a6a5baefe7dcc8fbb5a39f01dc935c7a3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Max=20K=C3=B6hler?= Date: Fri, 8 Nov 2024 00:32:10 +0100 Subject: [PATCH 01/24] fpga: x400: add rf core ctrlport --- .../regmap/radio_ctrlport_regmap_utils.vh | 7 +++- fpga/usrp3/top/x400/x4xx.sv | 33 +++++++++++++++++++ fpga/usrp3/top/x400/x4xx_core.v | 15 +++++++++ fpga/usrp3/top/x400/x4xx_core_common.v | 26 +++++++++++++-- 4 files changed, 78 insertions(+), 3 deletions(-) diff --git a/fpga/usrp3/top/x400/regmap/radio_ctrlport_regmap_utils.vh b/fpga/usrp3/top/x400/regmap/radio_ctrlport_regmap_utils.vh index 861752b4a3..4633d97fec 100644 --- a/fpga/usrp3/top/x400/regmap/radio_ctrlport_regmap_utils.vh +++ b/fpga/usrp3/top/x400/regmap/radio_ctrlport_regmap_utils.vh @@ -13,6 +13,7 @@ // DB_WINDOW : 0x0 (x4xx_core_common.v) // RFDC_TIMING_WINDOW : 0x8000 (x4xx_core_common.v) + // RF_CORE_WINDOW : 0xA000 (x4xx_core_common.v) // DIO_WINDOW : 0xC000 (x4xx_core_common.v) //=============================================================================== @@ -29,7 +30,11 @@ // RFDC_TIMING_WINDOW Window (from x4xx_core_common.v) localparam RFDC_TIMING_WINDOW = 'h8000; // Window Offset - localparam RFDC_TIMING_WINDOW_SIZE = 'h4000; // size in bytes + localparam RFDC_TIMING_WINDOW_SIZE = 'h2000; // size in bytes + + // RF_CORE_WINDOW Window (from x4xx_core_common.v) + localparam RF_CORE_WINDOW = 'hA000; // Window Offset + localparam RF_CORE_WINDOW_SIZE = 'h2000; // size in bytes // DIO_WINDOW Window (from x4xx_core_common.v) localparam DIO_WINDOW = 'hC000; // Window Offset diff --git a/fpga/usrp3/top/x400/x4xx.sv b/fpga/usrp3/top/x400/x4xx.sv index c73b9e9342..80b6e427f1 100644 --- a/fpga/usrp3/top/x400/x4xx.sv +++ b/fpga/usrp3/top/x400/x4xx.sv @@ -272,6 +272,7 @@ module x4xx ( `include "regmap/global_regs_regmap_utils.vh" `include "regmap/versioning_utils.vh" + `include "../../lib/rfnoc/core/ctrlport.vh" //--------------------------------------------------------------------------- @@ -1922,6 +1923,15 @@ module x4xx ( wire [31:0] db_ctrlport_resp_data [0:NUM_DBOARDS-1]; wire [ 1:0] db_ctrlport_resp_status [0:NUM_DBOARDS-1]; + // RF core ctrlport interface + wire rf_core_ctrlport_req_rd [0:NUM_DBOARDS-1]; + wire rf_core_ctrlport_req_wr [0:NUM_DBOARDS-1]; + wire [19:0] rf_core_ctrlport_req_addr [0:NUM_DBOARDS-1]; + wire [31:0] rf_core_ctrlport_req_data [0:NUM_DBOARDS-1]; + wire rf_core_ctrlport_resp_ack [0:NUM_DBOARDS-1]; + wire [31:0] rf_core_ctrlport_resp_data [0:NUM_DBOARDS-1]; + wire [ 1:0] rf_core_ctrlport_resp_status [0:NUM_DBOARDS-1]; + // GPIO to CPLD ctrlport interface wire db_to_cpld_ctrlport_req_rd [0:NUM_DBOARDS-1]; wire db_to_cpld_ctrlport_req_wr [0:NUM_DBOARDS-1]; @@ -2162,6 +2172,22 @@ module x4xx ( .version_info (rf_core_version[db_i]) ); end // gen_rf_core_full + + // terminate unused rf core ctrlport interfaces + ctrlport_terminator #( + .START_ADDRESS (0), + .LAST_ADDRESS (2**CTRLPORT_ADDR_W-1) + ) pl_terminator ( + .ctrlport_clk (rfdc_clk[db_i]), + .ctrlport_rst (radio_rst[db_i]), + .s_ctrlport_req_wr (rf_core_ctrlport_req_wr[db_i]), + .s_ctrlport_req_rd (rf_core_ctrlport_req_rd[db_i]), + .s_ctrlport_req_addr (rf_core_ctrlport_req_addr[db_i]), + .s_ctrlport_req_data (rf_core_ctrlport_req_data[db_i]), + .s_ctrlport_resp_ack (rf_core_ctrlport_resp_ack[db_i]), + .s_ctrlport_resp_status (rf_core_ctrlport_resp_status[db_i]), + .s_ctrlport_resp_data (rf_core_ctrlport_resp_data[db_i]) + ); end // gen_rf_cores `ifdef X440 @@ -2975,6 +3001,13 @@ module x4xx ( .m_ctrlport_radio_resp_ack ({ db_ctrlport_resp_ack [1], db_ctrlport_resp_ack [0] }), .m_ctrlport_radio_resp_status ({ db_ctrlport_resp_status [1], db_ctrlport_resp_status [0] }), .m_ctrlport_radio_resp_data ({ db_ctrlport_resp_data [1], db_ctrlport_resp_data [0] }), + .m_ctrlport_rf_core_req_wr ({ rf_core_ctrlport_req_wr [1], rf_core_ctrlport_req_wr [0] }), + .m_ctrlport_rf_core_req_rd ({ rf_core_ctrlport_req_rd [1], rf_core_ctrlport_req_rd [0] }), + .m_ctrlport_rf_core_req_addr ({ rf_core_ctrlport_req_addr [1], rf_core_ctrlport_req_addr [0] }), + .m_ctrlport_rf_core_req_data ({ rf_core_ctrlport_req_data [1], rf_core_ctrlport_req_data [0] }), + .m_ctrlport_rf_core_resp_ack ({ rf_core_ctrlport_resp_ack [1], rf_core_ctrlport_resp_ack [0] }), + .m_ctrlport_rf_core_resp_status({ rf_core_ctrlport_resp_status [1], rf_core_ctrlport_resp_status [0] }), + .m_ctrlport_rf_core_resp_data ({ rf_core_ctrlport_resp_data [1], rf_core_ctrlport_resp_data [0] }), .start_nco_reset (start_nco_reset), .nco_reset_done (nco_reset_done), .adc_reset_pulse (adc_reset_pulse), diff --git a/fpga/usrp3/top/x400/x4xx_core.v b/fpga/usrp3/top/x400/x4xx_core.v index 638dca1af2..4294c63d31 100644 --- a/fpga/usrp3/top/x400/x4xx_core.v +++ b/fpga/usrp3/top/x400/x4xx_core.v @@ -326,6 +326,14 @@ module x4xx_core #( input wire [ 2*NUM_DBOARDS-1:0] m_ctrlport_radio_resp_status, input wire [ 32*NUM_DBOARDS-1:0] m_ctrlport_radio_resp_data, + output wire [ 1*NUM_DBOARDS-1:0] m_ctrlport_rf_core_req_wr, + output wire [ 1*NUM_DBOARDS-1:0] m_ctrlport_rf_core_req_rd, + output wire [ 20*NUM_DBOARDS-1:0] m_ctrlport_rf_core_req_addr, + output wire [ 32*NUM_DBOARDS-1:0] m_ctrlport_rf_core_req_data, + input wire [ 1*NUM_DBOARDS-1:0] m_ctrlport_rf_core_resp_ack, + input wire [ 2*NUM_DBOARDS-1:0] m_ctrlport_rf_core_resp_status, + input wire [ 32*NUM_DBOARDS-1:0] m_ctrlport_rf_core_resp_data, + // RF Reset Control output wire start_nco_reset, input wire nco_reset_done, @@ -501,6 +509,13 @@ module x4xx_core #( .m_radio_ctrlport_resp_ack (m_ctrlport_radio_resp_ack), .m_radio_ctrlport_resp_status (m_ctrlport_radio_resp_status), .m_radio_ctrlport_resp_data (m_ctrlport_radio_resp_data), + .m_rf_core_ctrlport_req_wr (m_ctrlport_rf_core_req_wr), + .m_rf_core_ctrlport_req_rd (m_ctrlport_rf_core_req_rd), + .m_rf_core_ctrlport_req_addr (m_ctrlport_rf_core_req_addr), + .m_rf_core_ctrlport_req_data (m_ctrlport_rf_core_req_data), + .m_rf_core_ctrlport_resp_ack (m_ctrlport_rf_core_resp_ack), + .m_rf_core_ctrlport_resp_status (m_ctrlport_rf_core_resp_status), + .m_rf_core_ctrlport_resp_data (m_ctrlport_rf_core_resp_data), .start_nco_reset (start_nco_reset), .nco_reset_done (nco_reset_done), .adc_reset_pulse (adc_reset_pulse), diff --git a/fpga/usrp3/top/x400/x4xx_core_common.v b/fpga/usrp3/top/x400/x4xx_core_common.v index ca82abd07a..c816941f37 100644 --- a/fpga/usrp3/top/x400/x4xx_core_common.v +++ b/fpga/usrp3/top/x400/x4xx_core_common.v @@ -133,6 +133,15 @@ module x4xx_core_common #( input wire [ 2*NUM_DBOARDS-1:0] m_radio_ctrlport_resp_status, input wire [ 32*NUM_DBOARDS-1:0] m_radio_ctrlport_resp_data, + // CtrlPort Master (to RF cores, Domain: radio_clk) + output wire [ 1*NUM_DBOARDS-1:0] m_rf_core_ctrlport_req_wr, + output wire [ 1*NUM_DBOARDS-1:0] m_rf_core_ctrlport_req_rd, + output wire [ 20*NUM_DBOARDS-1:0] m_rf_core_ctrlport_req_addr, + output wire [ 32*NUM_DBOARDS-1:0] m_rf_core_ctrlport_req_data, + input wire [ 1*NUM_DBOARDS-1:0] m_rf_core_ctrlport_resp_ack, + input wire [ 2*NUM_DBOARDS-1:0] m_rf_core_ctrlport_resp_status, + input wire [ 32*NUM_DBOARDS-1:0] m_rf_core_ctrlport_resp_data, + // RF Reset Control output wire start_nco_reset, input wire nco_reset_done, @@ -477,6 +486,7 @@ module x4xx_core_common #( localparam [19:0] DIGITAL_IFC_OFFSET = DIO_WINDOW + DIGITAL_IFC_REGS; // Register space size calculation + localparam [31:0] RF_CORE_WINDOW_SIZE_W = $clog2(RF_CORE_WINDOW_SIZE); localparam [31:0] RFDC_TIMING_WINDOW_SIZE_W = $clog2(RFDC_TIMING_WINDOW_SIZE); localparam [31:0] DB_WINDOW_SIZE_W = $clog2(DB_WINDOW_SIZE); localparam [31:0] DIO_SOURCE_CONTROL_SIZE_W = $clog2(DIO_SOURCE_CONTROL_SIZE); @@ -484,16 +494,18 @@ module x4xx_core_common #( localparam [31:0] DIGITAL_IFC_REGS_SIZE_W = $clog2(DIGITAL_IFC_REGS_SIZE); ctrlport_decoder_param #( - .NUM_SLAVES (5), + .NUM_SLAVES (6), .PORT_BASE ({ DIGITAL_IFC_OFFSET, DIO_SOURCE_CONTROL_OFFSET, RADIO_GPIO_ATR_OFFSET, + RF_CORE_WINDOW[19:0], RFDC_TIMING_WINDOW[19:0], DB_WINDOW[19:0] }), .PORT_ADDR_W ({ DIGITAL_IFC_REGS_SIZE_W, DIO_SOURCE_CONTROL_SIZE_W, RADIO_GPIO_ATR_SIZE_W, + RF_CORE_WINDOW_SIZE_W, RFDC_TIMING_WINDOW_SIZE_W, DB_WINDOW_SIZE_W }) @@ -513,21 +525,25 @@ module x4xx_core_common #( .m_ctrlport_req_wr ({ gpio_spi_ctrlport_req_wr [ 1*db_i+: 1], radio_dio_req_wr [ 1*db_i+: 1], gpio_atr_ctrlport_req_wr [ 1*db_i+: 1], + m_rf_core_ctrlport_req_wr [ 1*db_i+: 1], rf_ctrlport_req_wr [ 1*db_i+: 1], m_radio_ctrlport_req_wr [ 1*db_i+: 1] }), .m_ctrlport_req_rd ({ gpio_spi_ctrlport_req_rd [ 1*db_i+: 1], radio_dio_req_rd [ 1*db_i+: 1], gpio_atr_ctrlport_req_rd [ 1*db_i+: 1], + m_rf_core_ctrlport_req_rd [ 1*db_i+: 1], rf_ctrlport_req_rd [ 1*db_i+: 1], m_radio_ctrlport_req_rd [ 1*db_i+: 1] }), .m_ctrlport_req_addr ({ gpio_spi_ctrlport_req_addr [20*db_i+:20], radio_dio_req_addr [20*db_i+:20], gpio_atr_ctrlport_req_addr [20*db_i+:20], + m_rf_core_ctrlport_req_addr [20*db_i+:20], rf_ctrlport_req_addr [20*db_i+:20], m_radio_ctrlport_req_addr [20*db_i+:20] }), .m_ctrlport_req_data ({ gpio_spi_ctrlport_req_data [32*db_i+:32], radio_dio_req_data [32*db_i+:32], gpio_atr_ctrlport_req_data [32*db_i+:32], + m_rf_core_ctrlport_req_data [32*db_i+:32], rf_ctrlport_req_data [32*db_i+:32], m_radio_ctrlport_req_data [32*db_i+:32] }), .m_ctrlport_req_byte_en (), @@ -536,16 +552,19 @@ module x4xx_core_common #( .m_ctrlport_resp_ack ({ gpio_spi_ctrlport_resp_ack [ 1*db_i+: 1], radio_dio_resp_ack [ 1*db_i+: 1], gpio_atr_ctrlport_resp_ack [ 1*db_i+: 1], + m_rf_core_ctrlport_resp_ack [ 1*db_i+: 1], rf_ctrlport_resp_ack [ 1*db_i+: 1], m_radio_ctrlport_resp_ack [ 1*db_i+: 1] }), .m_ctrlport_resp_status ({ gpio_spi_ctrlport_resp_status [ 2*db_i+: 2], radio_dio_resp_status [ 2*db_i+: 2], gpio_atr_ctrlport_resp_status [ 2*db_i+: 2], + m_rf_core_ctrlport_resp_status [ 2*db_i+: 2], rf_ctrlport_resp_status [ 2*db_i+: 2], m_radio_ctrlport_resp_status [ 2*db_i+: 2] }), .m_ctrlport_resp_data ({ gpio_spi_ctrlport_resp_data [32*db_i+:32], radio_dio_resp_data [32*db_i+:32], gpio_atr_ctrlport_resp_data [32*db_i+:32], + m_rf_core_ctrlport_resp_data [32*db_i+:32], rf_ctrlport_resp_data [32*db_i+:32], m_radio_ctrlport_resp_data [32*db_i+:32] }) ); @@ -891,9 +910,12 @@ endmodule // Daughterboard GPIO interface. Register access within this space // is directed to the associated daughterboard CPLD. // -// +// // RFDC timing control interface. // +// +// Interface for the RF core. +// // // DIO control interface. Interacts with the DIO source selection // block, ATR-based DIO control and the DIO digital interface From af6b2ddbaeb3f7bc820a60edf3ff3f00618248a1 Mon Sep 17 00:00:00 2001 From: Frank Dietze Date: Mon, 11 Nov 2024 10:21:37 +0100 Subject: [PATCH 02/24] ci: added pipeline for weekly test runs based on hardware dev pipeline --- .ci/uhd-hardware-test-weekly-pipeline.yml | 150 ++++++++++++++++++++++ 1 file changed, 150 insertions(+) create mode 100644 .ci/uhd-hardware-test-weekly-pipeline.yml diff --git a/.ci/uhd-hardware-test-weekly-pipeline.yml b/.ci/uhd-hardware-test-weekly-pipeline.yml new file mode 100644 index 0000000000..a785b8766b --- /dev/null +++ b/.ci/uhd-hardware-test-weekly-pipeline.yml @@ -0,0 +1,150 @@ +trigger: none +schedules: +- cron: '0 13 * * 6' + displayName: Weekly Test + branches: + include: + - master + always: true + +pr: none + +parameters: +- name: fpga_imgs_source + type: string + values: + - 'Filesytem/Images Downloader' + - 'FPGA Pipeline' + - 'FPGA Pipeline PR' + displayName: FPGA Images Source + default: 'FPGA Pipeline' +- name: testLength + type: string + values: + - 'smoke' + - 'full' + - 'stress' + default: 'smoke' + +variables: + - name: uhd_fpga_artifact_source + ${{ if eq(parameters.fpga_imgs_source, 'FPGA Pipeline PR') }}: + value: uhd_fpga_pr_pipeline + ${{ else }}: + value: uhd_fpga_pipeline + +resources: + pipelines: + - pipeline: uhd_mono_pipeline + source: 'uhddev mono pipeline' + branch: master + - pipeline: usrp-kas-pipeline + source: 'usrp-kas' + branch: kirkstone + - pipeline: uhd_fpga_pipeline + source: 'uhddev fpga pipeline' + branch: master + - pipeline: uhd_fpga_pr_pipeline + source: 'uhddev fpga pipeline PR' + branch: master + repositories: + - repository: meta-ettus + type: github + name: EttusResearch/meta-ettus-dev + endpoint: EttusResearch + ref: kirkstone + - repository: gr-ettus + type: github + name: EttusResearch/gr-ettusdev + endpoint: EttusResearch + ref: maint-3.8-uhd4.0 + - repository: ettus-rts + type: github + endpoint: EttusResearch + name: EttusResearch/ettus-rts + ref: master + +stages: +- stage: test_uhd_devtest_stage + displayName: Test UHD Devtest + dependsOn: [] + jobs: + - template: templates/tests/job-uhd-x410-hardware-tests-sdr-test0.yml + parameters: + testOS: 'ubuntu1804' + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + - template: templates/tests/job-uhd-x440-hardware-tests-sdr-test0.yml + parameters: + testOS: 'ubuntu1804' + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + - template: templates/job-uhd-devtest-rhombus.yml + parameters: + testOS: 'ubuntu2004' + uhdSrcDir: $(Build.SourcesDirectory) + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + +- stage: test_streaming_stage + displayName: Test UHD Streaming + dependsOn: [] + jobs: + - template: templates/job-uhd-streaming-tests-beauty.yml + parameters: + testOS: 'ubuntu2004' + uhdSrcDir: $(Build.SourcesDirectory)/uhddev + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + testLength: ${{ parameters.testLength }} + - template: templates/job-uhd-streaming-tests-x440.yml + parameters: + testOS: 'ubuntu2204' + uhdSrcDir: $(Build.SourcesDirectory)/uhddev + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + testLength: ${{ parameters.testLength }} + +- stage: test_rf_tests_stage + displayName: Test UHD RF Tests + dependsOn: [] + jobs: + - template: templates/job-uhd-rf-tests-pebbles.yml + parameters: + testOS: 'ubuntu1804' + uhdSrcDir: $(Build.SourcesDirectory)/uhddev + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + - template: templates/tests/job-uhd-x410-hardware-tests-pebbles.yml + parameters: + testOS: 'ubuntu1804' + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + testLength: ${{ parameters.testLength }} + - template: templates/tests/job-uhd-x440-hardware-tests-pebbles.yml + parameters: + testOS: 'ubuntu1804' + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + testLength: ${{ parameters.testLength }} + +- stage: test_uhd_phase_tests + displayName: Test UHD Phase Tests + dependsOn: [] + jobs: + - template: templates/tests/job-uhd-x440-hardware-tests-saison.yml + parameters: + testOS: 'ubuntu2204' + uhdArtifactSource: uhd_mono_pipeline + uhdFpgaArtifactSource: ${{ variables.uhd_fpga_artifact_source }} + fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + testLength: ${{ parameters.testLength }} + extra_rf_test_args: --test_selector test_rx_phase_coherence.py test_tx_phase_coherence.py From 310177923a027c175d54b9d6c52210b6a7c437ae Mon Sep 17 00:00:00 2001 From: Joerg Hofrichter Date: Sun, 17 Nov 2024 19:56:52 +0100 Subject: [PATCH 03/24] ci: hardware tests: remove hard-coded uartSerial use environment variable to set the variables instead --- .ci/templates/tests/job-uhd-x410-hardware-tests-pebbles.yml | 2 +- .ci/templates/tests/job-uhd-x410-hardware-tests-sdr-test0.yml | 2 +- .ci/templates/tests/job-uhd-x440-hardware-tests-pebbles.yml | 2 +- .ci/templates/tests/job-uhd-x440-hardware-tests-saison.yml | 2 +- .ci/templates/tests/job-uhd-x440-hardware-tests-sdr-test0.yml | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.ci/templates/tests/job-uhd-x410-hardware-tests-pebbles.yml b/.ci/templates/tests/job-uhd-x410-hardware-tests-pebbles.yml index d9a1d3f55d..c66b18f225 100644 --- a/.ci/templates/tests/job-uhd-x410-hardware-tests-pebbles.yml +++ b/.ci/templates/tests/job-uhd-x410-hardware-tests-pebbles.yml @@ -38,7 +38,7 @@ jobs: devtestPattern: 'x4x0' dutFPGA: 'X4_200' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '2516351DDCC0' + uartSerial: $(x410_uartSerial) pipelineAgent: pebbles-agent-1 pytestAtsConfig: uhd_oss_ats pytestDUT: 'x410' diff --git a/.ci/templates/tests/job-uhd-x410-hardware-tests-sdr-test0.yml b/.ci/templates/tests/job-uhd-x410-hardware-tests-sdr-test0.yml index af91d82572..757b826aec 100644 --- a/.ci/templates/tests/job-uhd-x410-hardware-tests-sdr-test0.yml +++ b/.ci/templates/tests/job-uhd-x410-hardware-tests-sdr-test0.yml @@ -31,6 +31,6 @@ jobs: devtestPattern: 'x410' dutFPGA: 'X4_200' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '2516351FE64E' + uartSerial: $(x410_uartSerial) pytestDUT: 'x410' pipelineAgent: sdr-test0 diff --git a/.ci/templates/tests/job-uhd-x440-hardware-tests-pebbles.yml b/.ci/templates/tests/job-uhd-x440-hardware-tests-pebbles.yml index 18c87ef194..2bbd9b5848 100644 --- a/.ci/templates/tests/job-uhd-x440-hardware-tests-pebbles.yml +++ b/.ci/templates/tests/job-uhd-x440-hardware-tests-pebbles.yml @@ -38,7 +38,7 @@ jobs: devtestPattern: 'x4x0' dutFPGA: 'X4_400' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '251635284FC9' + uartSerial: $(x440_uartSerial) pipelineAgent: pebbles-agent-1 pytestAtsConfig: uhd_oss_ats pytestDUT: 'x440' diff --git a/.ci/templates/tests/job-uhd-x440-hardware-tests-saison.yml b/.ci/templates/tests/job-uhd-x440-hardware-tests-saison.yml index 543b26a71d..824b2c45e2 100644 --- a/.ci/templates/tests/job-uhd-x440-hardware-tests-saison.yml +++ b/.ci/templates/tests/job-uhd-x440-hardware-tests-saison.yml @@ -45,7 +45,7 @@ jobs: devtestPattern: 'x4x0' dutFPGA: 'X4_400' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '251635284FCA' + uartSerial: $(x440_uartSerial) pipelineAgent: saison-agent-1 pytestAtsConfig: saison_multichan_ats pytestDUT: 'x440' diff --git a/.ci/templates/tests/job-uhd-x440-hardware-tests-sdr-test0.yml b/.ci/templates/tests/job-uhd-x440-hardware-tests-sdr-test0.yml index 8e83c90009..61a22ed569 100644 --- a/.ci/templates/tests/job-uhd-x440-hardware-tests-sdr-test0.yml +++ b/.ci/templates/tests/job-uhd-x440-hardware-tests-sdr-test0.yml @@ -32,6 +32,6 @@ jobs: master_clock_rate: '125e6' dutFPGA: 'X4_400' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '25163525D2B3' + uartSerial: $(x440_uartSerial) pytestDUT: 'x440' pipelineAgent: sdr-test0 From 7f1ddbe3c5db80b5d8744d85591f896031bd6c36 Mon Sep 17 00:00:00 2001 From: Joerg Hofrichter Date: Mon, 18 Nov 2024 10:08:15 +0100 Subject: [PATCH 04/24] ci: streaming tests: remove hard-coded parameters use environment variable to set the variable instead. --- .../job-uhd-streaming-tests-beauty.yml | 39 ++++++++++--------- .../job-uhd-streaming-tests-x440.yml | 20 +++++----- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/.ci/templates/job-uhd-streaming-tests-beauty.yml b/.ci/templates/job-uhd-streaming-tests-beauty.yml index 0aaac1a03e..8c7fd8546d 100644 --- a/.ci/templates/job-uhd-streaming-tests-beauty.yml +++ b/.ci/templates/job-uhd-streaming-tests-beauty.yml @@ -46,55 +46,58 @@ jobs: beauty-X310-0: dutName: 'beauty-X310-0' dutType: 'X310' - dutAddr: '192.168.10.3' - dutSecondAddr: '192.168.20.3' + dutAddr: '$(x310_dutAddr)' + dutSecondAddr: '$(x310_dutSecondAddr)' dutFPGA: 'XG' dutNameId: '' dutNumRecvFrames: '' dutNumSendFrames: '' jtagSerial: '251635138E94' - sfpInt0: 'ens4f0' - sfpInt1: 'ens4f1' + sfpInt0: '$(x310_sfpInt0)' + sfpInt1: '$(x310_sfpInt1)' # beauty-X410-0 X4_200: # dutName: 'beauty-X410-0' # dutFamily: 'x4xx' # dutType: 'x410' - # dutAddr: '192.168.10.2' - # dutSecondAddr: '192.168.20.2' + # dutAddr: '$(x410_dutAddr)' + # dutSecondAddr: '$(x410_dutSecondAddr)' # dutFPGA:'X4_200' # dutNameId: '' + # dutEmbeddedImagesArtifact: 'x4xx-images' + # uartSerial: '$(x410_uartSerial)' # dutNumRecvFrames: '' # dutNumSendFrames: '' - # sfpInt0: 'ens6f0' - # sfpInt1: 'ens6f1' + # sfpInt0: '$(x410_sfpInt0)' + # sfpInt1: '$(x410_sfpInt1)' beauty-X410-0 CG_400: dutName: 'beauty-X410-0' dutFamily: 'x4xx' dutType: 'x410' - dutAddr: '192.168.110.2' - dutSecondAddr: '192.168.120.2' + dutAddr: '$(x410_dutAddr)' + dutSecondAddr: '$(x410_dutSecondAddr)' dutFPGA: 'CG_400' dutNameId: '' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '2516351E2C9A' + uartSerial: '$(x410_uartSerial)' dutNumRecvFrames: '' dutNumSendFrames: '' - sfpInt0: 'ens6f0' - sfpInt1: 'ens6f1' + sfpInt0: '$(x410_sfpInt0)' + sfpInt1: '$(x410_sfpInt1)' beauty-X410-0 UC_200: dutName: 'beauty-X410-0' dutFamily: 'x4xx' dutType: 'x410' - dutAddr: '192.168.120.2' - dutSecondAddr: '192.168.120.2' + # UC image: device is reachable only via dutSecondAddr + dutAddr: '$(x410_dutSecondAddr)' + dutSecondAddr: '$(x410_dutSecondAddr)' dutFPGA: 'UC_200' dutNameId: '' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '2516351E2C9A' + uartSerial: '$(x410_uartSerial)' dutNumRecvFrames: '' dutNumSendFrames: '' - sfpInt0: 'ens6f0' - sfpInt1: 'ens6f1' + sfpInt0: '$(x410_sfpInt0)' + sfpInt1: '$(x410_sfpInt1)' # beauty-E320-0: # dutName: 'beauty-E320-0' # dutType: 'E320' diff --git a/.ci/templates/job-uhd-streaming-tests-x440.yml b/.ci/templates/job-uhd-streaming-tests-x440.yml index c76500a9de..a57779ae42 100644 --- a/.ci/templates/job-uhd-streaming-tests-x440.yml +++ b/.ci/templates/job-uhd-streaming-tests-x440.yml @@ -39,27 +39,27 @@ jobs: dutName: 'streaming-X440-0' dutFamily: 'x4xx' dutType: 'x440' - dutAddr: '192.168.110.2' - dutSecondAddr: '192.168.120.2' + dutAddr: '$(x440_dutAddr)' + dutSecondAddr: '$(x440_dutSecondAddr)' dutFPGA: 'CG_400' dutNameId: '' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '251635271947' + uartSerial: '$(x440_uartSerial)' dutNumRecvFrames: '' dutNumSendFrames: '' - sfpInt0: 'enp1s0f0np0' - sfpInt1: 'enp1s0f1np1' + sfpInt0: '$(x440_sfpInt0)' + sfpInt1: '$(x440_sfpInt1)' X440-0 CG_1600: dutName: 'streaming-X440-0' dutFamily: 'x4xx' dutType: 'x440' - dutAddr: '192.168.110.2' - dutSecondAddr: '192.168.120.2' + dutAddr: '$(x440_dutAddr)' + dutSecondAddr: '$(x440_dutSecondAddr)' dutFPGA: 'CG_1600' dutNameId: '' dutEmbeddedImagesArtifact: 'x4xx-images' - uartSerial: '251635271947' + uartSerial: '$(x440_uartSerial)' dutNumRecvFrames: '' dutNumSendFrames: '' - sfpInt0: 'enp1s0f0np0' - sfpInt1: 'enp1s0f1np1' + sfpInt0: '$(x440_sfpInt0)' + sfpInt1: '$(x440_sfpInt1)' From 68fe30c4e8e0b26e95086f8bd9a8134b9c1c08bd Mon Sep 17 00:00:00 2001 From: Joerg Hofrichter Date: Tue, 19 Nov 2024 21:33:18 +0100 Subject: [PATCH 05/24] ci: filesystem build: set machine parameter as list This partly reverts commit c37b3189abf2c5a24bad461d94744ec814cbc870. --- .ci/templates/stages-uhd-pipeline.yml | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-) diff --git a/.ci/templates/stages-uhd-pipeline.yml b/.ci/templates/stages-uhd-pipeline.yml index fa444e8236..462e0cfe9d 100644 --- a/.ci/templates/stages-uhd-pipeline.yml +++ b/.ci/templates/stages-uhd-pipeline.yml @@ -253,21 +253,16 @@ stages: cache_sstate: ${{ parameters.cache_sstate }} cache_downloads: False machines: - ${{ if parameters.build_e310_sg1 }}: - e310_sg1: - machineName: e310_sg1 - ${{ if parameters.build_e310_sg3 }}: - e310_sg3: - machineName: e310_sg3 - ${{ if parameters.build_e320 }}: - e320: - machineName: e320 - ${{ if parameters.build_n3xx }}: - n3xx: - machineName: n3xx - ${{ if parameters.build_x4xx }}: - x4xx: - machineName: x4xx + - ${{ if parameters.build_e310_sg1 }}: + - e310_sg1 + - ${{ if parameters.build_e310_sg3 }}: + - e310_sg3 + - ${{ if parameters.build_e320 }}: + - e320 + - ${{ if parameters.build_n3xx }}: + - n3xx + - ${{ if parameters.build_x4xx }}: + - x4xx auto_conf: $AUTO_CONF run_from_external_repo: true prebuild_steps: From 0a635d0d11b52b300474cb2871f54a1a5458647c Mon Sep 17 00:00:00 2001 From: Joerg Hofrichter Date: Thu, 21 Nov 2024 15:51:49 +0100 Subject: [PATCH 06/24] fpga: x4xx: assemble x410/x440-version-info.dtsi in BUILD_DIR --- fpga/usrp3/top/x400/.gitignore | 1 - fpga/usrp3/top/x400/Makefile | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/fpga/usrp3/top/x400/.gitignore b/fpga/usrp3/top/x400/.gitignore index d96446d270..21b2f49993 100644 --- a/fpga/usrp3/top/x400/.gitignore +++ b/fpga/usrp3/top/x400/.gitignore @@ -4,4 +4,3 @@ build-* *.jou vivado*.str ip/*/sim/ -dts/x4*0-version-info.dtsi diff --git a/fpga/usrp3/top/x400/Makefile b/fpga/usrp3/top/x400/Makefile index 72be08fa51..6e9f6b1a64 100644 --- a/fpga/usrp3/top/x400/Makefile +++ b/fpga/usrp3/top/x400/Makefile @@ -134,24 +134,24 @@ X410_IP: ##Build X410 IP only. Use the -j option to build multiple IP block X440_IP: ##Build X440 IP only. Use the -j option to build multiple IP blocks simultaneously. +$(call vivado_ip,X440,$(DEFS) X440=1) -dts/x410-version-info.dtsi: regmap/x410/versioning_regs_regmap_utils.vh +$(BUILD_DIR)/x410-version-info.dtsi: regmap/x410/versioning_regs_regmap_utils.vh tools/parse_versions_for_dts.py \ --input $< --output $@ \ --components fpga,cpld_ifc,db_gpio_ifc,rf_core_100m,rf_core_400m -dts/x440-version-info.dtsi: regmap/x440/versioning_regs_regmap_utils.vh +$(BUILD_DIR)/x440-version-info.dtsi: regmap/x440/versioning_regs_regmap_utils.vh tools/parse_versions_for_dts.py \ --input $< --output $@ \ --components fpga,cpld_ifc,db_gpio_ifc,rf_core_full # The device tree source file $(BUILD_DIR)/device_tree.dts is generated by the # RFNoC image builder. -$(BUILD_DIR)/X410.dts: $(BUILD_DIR)/device_tree.dts dts/x410-version-info.dtsi dts/*.dtsi +$(BUILD_DIR)/X410.dts: $(BUILD_DIR)/device_tree.dts $(BUILD_DIR)/x410-version-info.dtsi dts/*.dtsi ${CC} -o $@ -C -E -I dts -nostdinc -undef -x assembler-with-cpp -D__DTS__ $< # The device tree source file $(BUILD_DIR)/device_tree.dts is generated by the # RFNoC image builder. -$(BUILD_DIR)/X440.dts: $(BUILD_DIR)/device_tree.dts dts/x440-version-info.dtsi dts/*.dtsi +$(BUILD_DIR)/X440.dts: $(BUILD_DIR)/device_tree.dts $(BUILD_DIR)/x440-version-info.dtsi dts/*.dtsi ${CC} -o $@ -C -E -I dts -nostdinc -undef -x assembler-with-cpp -D__DTS__ $< clean: ##Clean up all target build outputs. From f263311509c4c7a2825ad78619db8416a549cc2a Mon Sep 17 00:00:00 2001 From: Aki Tomita Date: Thu, 21 Nov 2024 12:57:37 -0600 Subject: [PATCH 07/24] ci: remove hardcoded serial for the n310 in pebbles --- .ci/templates/job-uhd-rf-tests-pebbles.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/templates/job-uhd-rf-tests-pebbles.yml b/.ci/templates/job-uhd-rf-tests-pebbles.yml index f1e6d12ba5..b52e1aa93c 100644 --- a/.ci/templates/job-uhd-rf-tests-pebbles.yml +++ b/.ci/templates/job-uhd-rf-tests-pebbles.yml @@ -37,8 +37,8 @@ jobs: devType: 'n3xx' devModel: 'n310' devName: pebbles-n310-0 - devSerial: '3176DDF' - devHostname: 'ni-n3xx-3176DDF' + devSerial: '$(n310_devSerial)' + devHostname: 'ni-n3xx-$(n310_devSerial)' devBus: 'ip' devAddr: '192.168.40.17' sfpAddrs: '192.168.10.17,192.168.40.17' From a56d67135bc124dee2568ef01fa147ad786ed9b6 Mon Sep 17 00:00:00 2001 From: Aki Tomita Date: Thu, 21 Nov 2024 13:36:00 -0600 Subject: [PATCH 08/24] ci: update usb serial for the n310 in pebbles --- .../tests/pebbles-labgrid/exporter-conf/exporter.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.ci/templates/tests/pebbles-labgrid/exporter-conf/exporter.yaml b/.ci/templates/tests/pebbles-labgrid/exporter-conf/exporter.yaml index 57aae25c51..693f6413bc 100755 --- a/.ci/templates/tests/pebbles-labgrid/exporter-conf/exporter.yaml +++ b/.ci/templates/tests/pebbles-labgrid/exporter-conf/exporter.yaml @@ -2,13 +2,13 @@ pebbles-n310-0-group: console-scu: cls: USBSerialPort match: - ID_SERIAL: 'Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_0097D46F' + ID_SERIAL: 'Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_00B56895' ID_USB_INTERFACE_NUM: '01' speed: 115200 console-linux: cls: USBSerialPort match: - ID_SERIAL: 'Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_0097D46F' + ID_SERIAL: 'Silicon_Labs_CP2105_Dual_USB_to_UART_Bridge_Controller_00B56895' ID_USB_INTERFACE_NUM: '00' speed: 115200 USBSDMuxDevice: From 7b41d5c6ddd7cf3eae64bc137fabb7a5f8b2c440 Mon Sep 17 00:00:00 2001 From: Aki Tomita Date: Tue, 26 Nov 2024 14:06:09 -0600 Subject: [PATCH 09/24] ci: update cmake version to the min. version required by UHD --- .ci/docker/uhd-builder-ubuntu1804.Dockerfile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.ci/docker/uhd-builder-ubuntu1804.Dockerfile b/.ci/docker/uhd-builder-ubuntu1804.Dockerfile index 9b86e06f74..5ac62457a0 100644 --- a/.ci/docker/uhd-builder-ubuntu1804.Dockerfile +++ b/.ci/docker/uhd-builder-ubuntu1804.Dockerfile @@ -27,7 +27,6 @@ RUN apt-get update && \ sudo \ # Install UHD dependencies abi-dumper \ - cmake \ doxygen \ dpdk \ libboost-all-dev \ @@ -85,3 +84,10 @@ RUN python3 -m pip install \ click-plugins \ zmq \ scipy + +RUN wget https://cmake.org/files/v3.12/cmake-3.12.4-Linux-x86_64.tar.gz -O /tmp/cmake.tar.gz && \ + (echo "486edd6710b5250946b4b199406ccbf8f567ef0e23cfe38f7938b8c78a2ffa5f /tmp/cmake.tar.gz" | sha256sum --check --status ) && \ + tar -zxvf /tmp/cmake.tar.gz -C /opt && \ + cp -r /opt/cmake-3.12.4-Linux-x86_64/bin/* /usr/local/bin/ && \ + cp -r /opt/cmake-3.12.4-Linux-x86_64/share/* /usr/local/share/ && \ + rm /tmp/cmake.tar.gz From 9fc242122e85a7aaec1395dce330577fc8780c43 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Thu, 21 Nov 2024 15:55:12 +0100 Subject: [PATCH 10/24] Update CHANGELOG MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lars Amsel Co-authored-by: Martin Anderseck Co-authored-by: Wade Fife Co-authored-by: Jörg Hofrichter Co-authored-by: Grant Meyerhoff --- CHANGELOG | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/CHANGELOG b/CHANGELOG index 58fb24c131..9e7d785bf2 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,69 @@ Change Log for Releases ============================== +## Next Release +* New Features: + - Image Builder: + - Add GRC support. This allows designing RFNoC bitfiles from GNU Radio + Companion (GRC). + - Improve clock connection checks and checks for duplicate connections. + - Improve IO port compat check (e.g., check if wire widths match). + - Allow default clocks in domain checks. + - Simplify image core YAMLs by better usage of RADIO_NIPC parameter. + - Improve parameter resolution. + - Add --SYNTH and --CHECK options. + - Add support for building an FPGA image using multiple parallel jobs and + unique seeds with repeat_fpga_build.py and the --fpga-jobs option. + - rfnoc-gain (OOT RFNoC example): + - Overhaul directory structure, and rename to rfnoc-gain from + rfnoc-example. + - Simplify dynamic loading of OOT DLLs by using the new modules.d feature. + - Add CE clock support to gain block. This enables the example on X4x0. + - Add a GNU Radio subdirectory with examples of how to run the gain block + in GNU Radio. + - Add rfnoc_modtool. This is a command line utility to help design OOT RFNoC + blocks. + - RFNoC: + - Add tune requests. This allows tuning a complete graph as known from + multi_usrp instead of single blocks individually. + - multi_usrp: + - Add Python bindings for get_user_settings_iface() + - General UHD: + - Add modules.d support +* Bug Fixes + - E320: Ensure consistent sequencing when powering on/off GPSDO + - RFNoC: + - RFNoC DDC/DUC block (used in all Gen-3 USRPs and X410): Fix fractional + frequency offset. + - Fix AIS/spp calculation (e.g., for connecting FFT blocks). + - Image Builder: + - Fix colors + - Fix error message for missing control SEP + - Improve error reporting for invalid connections + - Accept ~ and ~user on command line + - Fix deprecated usage of yaml.load() + - Ensure correct device tree files generation when chosing a custom build + directory + - rfnoc_modtool: + - Fix generation of noc_shells + - General UHD: + - Fix compatibility with DPDK >= 22.11 + - Fix compiler warnings for better compatibility with C++ 17 and 20. + - Add logic for loading uhd.dll from the correct path for Windows with Python3.8+. + - Remove duplicate results from find + - Release GIL when calling find from Python which improves response time for large setups. + - MPM: + - Allow images without RF frontend (will only be initialized if FPGA reports availability) +* Validated OS Environments + (Versions for build and runtime dependencies can be determined from the + docker container definitions in the UHD repository at .ci/docker/...) + - Linux: + - Ubuntu: bionic (18.04), focal (20.04), jammy (22.04), noble (24.04) + - Fedora: 39, 40, 41 + - Windows: 10 21H2, 11 21H2 + - MacOS: Monterey (12.6) + + ## 004.007.000.000 * Highlights / Main Changes - Major updates to rfnoc_image_builder (a98ce26). This change adds support for From 3f2a0616148b9e0dd2e70efa59c1c04e4eed75e5 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Tue, 26 Nov 2024 16:34:15 +0100 Subject: [PATCH 11/24] mg: Fix LO query API for lowband LO The code for querying the RX lowband LO for N310 (Magnesium Daughterboard) was broken: It used the wrong string for identifying the LO. That meant there was not valid code path for querying the RX LO frequency. --- host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp index ca4fd17079..636c9551ac 100644 --- a/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp +++ b/host/lib/usrp/dboard/magnesium/magnesium_radio_control.cpp @@ -897,7 +897,7 @@ double magnesium_radio_control_impl::get_rx_lo_freq( std::string source = this->get_rx_lo_source(name, chan); if (name == MAGNESIUM_LO1) { return _ad9371_freq.at(RX_DIRECTION); - } else if (name == "adf4531") { + } else if (name == MAGNESIUM_LO2) { return _adf4351_freq.at(RX_DIRECTION); } else { RFNOC_LOG_ERROR("get_rx_lo_freq(): No such LO: " << name); From e2c36d49ca9a754d9853c450743d93a1a38c3b02 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Tue, 26 Nov 2024 16:47:29 +0100 Subject: [PATCH 12/24] doc: rfnoc: Clarify radio_control tuning capabilities --- .../uhd/rfnoc/rf_control/core_iface.hpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/host/include/uhd/rfnoc/rf_control/core_iface.hpp b/host/include/uhd/rfnoc/rf_control/core_iface.hpp index a557bf9df4..c297e154b2 100644 --- a/host/include/uhd/rfnoc/rf_control/core_iface.hpp +++ b/host/include/uhd/rfnoc/rf_control/core_iface.hpp @@ -79,6 +79,15 @@ class core_iface * If there is a single LO in this radio, and we're doing direct conversion, * then this is the LO frequency. * + * Note that unlike the uhd::usrp::multi_usrp::set_tx_freq() API, this does + * not attempt to tune any attached digital frequency shifter, unless it is + * part of the radio. That is why this API only returns a double value (the + * actual frequency) instead of a uhd::tune_result_t. If a combined tuning + * of digital frequency correction and LO tuning is desired (the same way + * that uhd::usrp::multi_usrp does by default), then the caller has to + * either also call uhd::rfnoc::dc_block_control::set_freq() with the + * residual frequency, or tune through the graph. + * * \param freq Frequency in Hz * \param chan Channel to tune * @@ -110,6 +119,15 @@ class core_iface * If there is a single LO in this radio, and we're doing direct conversion, * then this is the LO frequency. * + * Note that unlike the uhd::usrp::multi_usrp::set_rx_freq() API, this does + * not attempt to tune any attached digital frequency shifter, unless it is + * part of the radio. That is why this API only returns a double value (the + * actual frequency) instead of a uhd::tune_result_t. If a combined tuning + * of digital frequency correction and LO tuning is desired (the same way + * that uhd::usrp::multi_usrp does by default), then the caller has to + * either also call uhd::rfnoc::ddc_block_control::set_freq() with the + * residual frequency, or tune through the graph. + * * \param freq Requested frequency * \param chan Channel number. * \return The actual frequency. From 381ecf857852a5184402b20d82d8b19f2188f434 Mon Sep 17 00:00:00 2001 From: Wade Fife Date: Fri, 22 Nov 2024 14:13:39 -0600 Subject: [PATCH 13/24] fpga: tools: Add --ignore-warnings to repeat_fpga_build --- fpga/usrp3/tools/utils/repeat_fpga_build.py | 29 +++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/fpga/usrp3/tools/utils/repeat_fpga_build.py b/fpga/usrp3/tools/utils/repeat_fpga_build.py index b38ef35b0a..0003debce5 100755 --- a/fpga/usrp3/tools/utils/repeat_fpga_build.py +++ b/fpga/usrp3/tools/utils/repeat_fpga_build.py @@ -202,6 +202,12 @@ def parse_args(): "location (e.g., /tools/Xilinx/Vivado).", default=None, ) + parser.add_argument( + "--ignore-warnings", + "-W", + help="Run build even when there are warnings from the RFNoC image builder", + action="store_true", + ) parser.add_argument( "--num", "-n", @@ -282,6 +288,7 @@ def rfnoc_image_builder_cmd( image_core_name, fpga_dir, vivado_path, + ignore_warnings, build_num=None, ): """ @@ -300,6 +307,8 @@ def rfnoc_image_builder_cmd( cmd += f"--fpga-dir {fpga_dir} " if vivado_path: cmd += f"--vivado-path {vivado_path} " + if ignore_warnings: + cmd += "--ignore-warnings " return cmd @@ -313,6 +322,7 @@ def run_fpga_build( image_core_name, fpga_dir, vivado_path, + ignore_warnings, parallel_builds, ): """Performs one iteration of an FPGA build. @@ -327,6 +337,8 @@ def run_fpga_build( image_core_name: --image-core-name argument to be passed fpga_dir: --fpga-dir argument to be passed vivado_path: --vivado-path argument to be passed + ignore_warnings: --ignore-warnings argument to be passed + parallel_builds: Indicates if we are doing builds in parallel Returns: Status.SUCCESS: The build succeeded @@ -343,6 +355,7 @@ def run_fpga_build( image_core_name, fpga_dir, vivado_path, + ignore_warnings, cmd_build_num, ) logging.info(f"Running FPGA build command: {cmd}") @@ -388,7 +401,9 @@ def run_fpga_build( return status -def run_ip_build(ip_jobs, target, image_core, image_core_name, fpga_dir, vivado_path): +def run_ip_build( + ip_jobs, target, image_core, image_core_name, fpga_dir, vivado_path, ignore_warnings +): """Performs the IP build. This is done separately so that when we do parallel FPGA builds, they don't @@ -401,13 +416,21 @@ def run_ip_build(ip_jobs, target, image_core, image_core_name, fpga_dir, vivado_ image_core_name: --image-core-name argument to be passed fpga_dir: --fpga-dir argument to be passed vivado_path: --vivado-path argument to be passed + ignore_warnings: --ignore-warnings argument to be passed Returns: 0: The IP build succeeded non-zero: The IP build failed """ cmd = rfnoc_image_builder_cmd( - None, target, image_core, image_core_name, fpga_dir, vivado_path, None + None, + target, + image_core, + image_core_name, + fpga_dir, + vivado_path, + ignore_warnings, + None, ) cmd += f" --ip-only --jobs {ip_jobs}" logging.info(f"Running IP build with command: {cmd}") @@ -475,6 +498,7 @@ def main(): args.image_core_name, args.fpga_dir, args.vivado_path, + args.ignore_warnings, ) if status != Status.SUCCESS: return status.value @@ -502,6 +526,7 @@ def main(): args.image_core_name, args.fpga_dir, args.vivado_path, + args.ignore_warnings, args.fpga_jobs > 1, ), ) From c0cebd879fda98e5d0ec61b1aabe342a225b065b Mon Sep 17 00:00:00 2001 From: mkoop Date: Wed, 27 Nov 2024 16:41:28 +0100 Subject: [PATCH 14/24] docs: Lock python version to 3.12 used by readthedocs build Locking python version to 3.12 to ensure our specified version of sphinx (locked to 5.3) can find all it's depended on python modules. This addresses an issued observed with python 3.13 that eliminated the imghdr module (depreciated since python 3.11, see also https://github.com/sphinx-doc/sphinx/issues/10440). --- host/docs/sphinx/environment.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/host/docs/sphinx/environment.yml b/host/docs/sphinx/environment.yml index e4eb11154f..9e78686275 100644 --- a/host/docs/sphinx/environment.yml +++ b/host/docs/sphinx/environment.yml @@ -3,6 +3,7 @@ channels: - conda-forge - defaults dependencies: + - python=3.12 - pip - cmake - compilers From 97cab721ce75401173b8823cdd5bfc0f3da938a6 Mon Sep 17 00:00:00 2001 From: Martin Anderseck Date: Thu, 21 Nov 2024 16:25:09 +0100 Subject: [PATCH 15/24] host: x4xx: Fix ATR helpers This doesn't change anything functionally, but since the helper for looping is based on the number of ATR states, it is wrong to use the max number of channels in FBX. And since in ZBX there's this magic number of 4, this change makes it clearer where the number comes from. --- .../include/uhdlib/usrp/dboard/fbx/fbx_constants.hpp | 11 ++++++----- .../include/uhdlib/usrp/dboard/zbx/zbx_constants.hpp | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/host/lib/include/uhdlib/usrp/dboard/fbx/fbx_constants.hpp b/host/lib/include/uhdlib/usrp/dboard/fbx/fbx_constants.hpp index eefb173360..fd23fb8efd 100644 --- a/host/lib/include/uhdlib/usrp/dboard/fbx/fbx_constants.hpp +++ b/host/lib/include/uhdlib/usrp/dboard/fbx/fbx_constants.hpp @@ -72,11 +72,12 @@ static const std::vector FBX_LOS = {RFDC_NCO}; static constexpr size_t FBX_MAX_NUM_CHANS = 4; // These are addresses for the various table-based registers -static constexpr uint32_t ATR_ADDR_0X = 0; -static constexpr uint32_t ATR_ADDR_RX = 1; -static constexpr uint32_t ATR_ADDR_TX = 2; -static constexpr uint32_t ATR_ADDR_XX = 3; // Full-duplex +static constexpr uint32_t ATR_ADDR_0X = 0; +static constexpr uint32_t ATR_ADDR_RX = 1; +static constexpr uint32_t ATR_ADDR_TX = 2; +static constexpr uint32_t ATR_ADDR_XX = 3; // Full-duplex +static constexpr uint32_t NUM_ATR_STATES = 4; // Helper for looping -static constexpr std::array ATR_ADDRS{0, 1, 2, 3}; +static constexpr std::array ATR_ADDRS{0, 1, 2, 3}; }}} // namespace uhd::usrp::fbx diff --git a/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_constants.hpp b/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_constants.hpp index 63762be4ee..501abb28b4 100644 --- a/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_constants.hpp +++ b/host/lib/include/uhdlib/usrp/dboard/zbx/zbx_constants.hpp @@ -184,12 +184,13 @@ static constexpr std::array ZBX_CHANNELS{0, 1}; static constexpr double ZBX_MIX1_MN_THRESHOLD = 4e9; // These are addresses for the various table-based registers -static constexpr uint32_t ATR_ADDR_0X = 0; -static constexpr uint32_t ATR_ADDR_RX = 1; -static constexpr uint32_t ATR_ADDR_TX = 2; -static constexpr uint32_t ATR_ADDR_XX = 3; // Full-duplex +static constexpr uint32_t ATR_ADDR_0X = 0; +static constexpr uint32_t ATR_ADDR_RX = 1; +static constexpr uint32_t ATR_ADDR_TX = 2; +static constexpr uint32_t ATR_ADDR_XX = 3; // Full-duplex +static constexpr uint32_t NUM_ATR_STATES = 4; // Helper for looping -static constexpr std::array ATR_ADDRS{0, 1, 2, 3}; +static constexpr std::array ATR_ADDRS{0, 1, 2, 3}; // Turn clang-formatting off so it doesn't compress these tables into a mess. // clang-format off From 76fd34f6ff09ec88d6752584ead85bd242c31baa Mon Sep 17 00:00:00 2001 From: Frank Dietze Date: Mon, 25 Nov 2024 17:07:37 +0100 Subject: [PATCH 16/24] ci: Split test stages by test systems --- .ci/templates/stages-uhd-pipeline.yml | 78 +++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/.ci/templates/stages-uhd-pipeline.yml b/.ci/templates/stages-uhd-pipeline.yml index 462e0cfe9d..27ec964ec8 100644 --- a/.ci/templates/stages-uhd-pipeline.yml +++ b/.ci/templates/stages-uhd-pipeline.yml @@ -423,8 +423,8 @@ stages: fpga_imgs_source: ${{ parameters.fpga_imgs_source }} testDevices: 'n3xx,e320' -- stage: test_uhd_x4xx_stage - displayName: Test UHD x4xx +- stage: test_uhd_x4xx_sdrtest0_stage + displayName: Test UHD x4xx sdr-test-0 dependsOn: - build_uhd_stage_linux - build_uhd_embedded_system_images @@ -458,6 +458,32 @@ stages: testOS: ubuntu1804 uhdFpgaArtifactSource: uhd_fpga_pipeline fpga_imgs_source: ${{ parameters.fpga_imgs_source }} + +- stage: test_uhd_x4xx_pebbles_stage + displayName: Test UHD x4xx pebbles + dependsOn: + - build_uhd_stage_linux + - build_uhd_embedded_system_images + - build_gnuradio_stage_linux + - analyze_changeset + # This will make $(UhdTestList) available to jobs/steps/tasks, but not for the + # condition. + variables: + UhdTestList: $[stageDependencies.analyze_changeset.analyze.outputs['gen_testlist.UhdTestList']] + condition: > + and( + succeeded(), + or( + ${{ parameters.skip_analyze_changeset }}, + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.all'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.x4xx'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.x410'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.x440'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'devtest.all'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'devtest.x410'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'devtest.x440') + )) + jobs: - template: tests/job-uhd-x410-hardware-tests-pebbles.yml parameters: testOS: ubuntu1804 @@ -470,6 +496,32 @@ stages: uhdFpgaArtifactSource: uhd_fpga_pipeline fpga_imgs_source: ${{ parameters.fpga_imgs_source }} testLength: ${{ parameters.testLength }} + +- stage: test_uhd_x4xx_saison_stage + displayName: Test UHD x4xx saison + dependsOn: + - build_uhd_stage_linux + - build_uhd_embedded_system_images + - build_gnuradio_stage_linux + - analyze_changeset + # This will make $(UhdTestList) available to jobs/steps/tasks, but not for the + # condition. + variables: + UhdTestList: $[stageDependencies.analyze_changeset.analyze.outputs['gen_testlist.UhdTestList']] + condition: > + and( + succeeded(), + or( + ${{ parameters.skip_analyze_changeset }}, + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.all'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.x4xx'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.x410'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.rf.x440'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'devtest.all'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'devtest.x410'), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'devtest.x440') + )) + jobs: - template: tests/job-uhd-x440-hardware-tests-saison.yml parameters: testOS: ubuntu2204 @@ -504,8 +556,8 @@ stages: testOS: ubuntu1804 testDevices: 'n3xx' -- stage: test_streaming_stage - displayName: Test UHD Streaming +- stage: test_streaming_beauty_stage + displayName: Test UHD Streaming beauty dependsOn: - analyze_changeset - build_uhd_stage_linux @@ -528,6 +580,24 @@ stages: uhdFpgaArtifactSource: uhd_fpga_pipeline fpga_imgs_source: ${{ parameters.fpga_imgs_source }} testLength: ${{ parameters.testLength }} + +- stage: test_streaming_x440_stage + displayName: Test UHD Streaming x440 + dependsOn: + - analyze_changeset + - build_uhd_stage_linux + - build_uhd_embedded_system_images + condition: > + and( + succeeded('build_uhd_stage_linux'), + succeeded('build_uhd_embedded_system_images'), + ${{ parameters.run_streaming_tests }}, + or( + ${{ parameters.skip_analyze_changeset }}, + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'hw.streaming') + ) + ) + jobs: - template: job-uhd-streaming-tests-x440.yml parameters: testOS: ubuntu2204 From f64ea12c1f9fe37a0707bb0ab8388a443578c3b3 Mon Sep 17 00:00:00 2001 From: Frank Dietze Date: Wed, 27 Nov 2024 14:12:18 +0100 Subject: [PATCH 17/24] ci: Refactor display names of test stages --- .ci/templates/stages-uhd-pipeline.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.ci/templates/stages-uhd-pipeline.yml b/.ci/templates/stages-uhd-pipeline.yml index 27ec964ec8..e5425840b1 100644 --- a/.ci/templates/stages-uhd-pipeline.yml +++ b/.ci/templates/stages-uhd-pipeline.yml @@ -375,7 +375,7 @@ stages: installer: nsis - stage: devtest_uhd_x3xx_b2xx_stage - displayName: devtest UHD x3xx b2xx + displayName: Dev Test UHD x3xx b2xx dependsOn: - build_uhd_stage_linux - analyze_changeset @@ -399,7 +399,7 @@ stages: testDevices: 'x3xx,b2xx' - stage: devtest_uhd_n3xx_e320_stage - displayName: devtest UHD n3xx e320 + displayName: Dev Test UHD n3xx e320 dependsOn: - build_uhd_stage_linux - build_uhd_embedded_system_images @@ -424,7 +424,7 @@ stages: testDevices: 'n3xx,e320' - stage: test_uhd_x4xx_sdrtest0_stage - displayName: Test UHD x4xx sdr-test-0 + displayName: RF Test UHD x4xx sdr-test0 dependsOn: - build_uhd_stage_linux - build_uhd_embedded_system_images @@ -460,7 +460,7 @@ stages: fpga_imgs_source: ${{ parameters.fpga_imgs_source }} - stage: test_uhd_x4xx_pebbles_stage - displayName: Test UHD x4xx pebbles + displayName: RF Test UHD x4xx pebbles dependsOn: - build_uhd_stage_linux - build_uhd_embedded_system_images @@ -498,7 +498,7 @@ stages: testLength: ${{ parameters.testLength }} - stage: test_uhd_x4xx_saison_stage - displayName: Test UHD x4xx saison + displayName: RF Test UHD x4xx saison dependsOn: - build_uhd_stage_linux - build_uhd_embedded_system_images @@ -531,7 +531,7 @@ stages: testLength: ${{ parameters.testLength }} - stage: test_uhd_rf_test_stage - displayName: Run rf tests n3xx + displayName: RF Test UHD n3xx pebbles dependsOn: - analyze_changeset - build_uhd_stage_linux From adf88ee412a87b8e844c3c5986ea809fca20bd89 Mon Sep 17 00:00:00 2001 From: Joerg Hofrichter Date: Wed, 27 Nov 2024 15:03:14 +0100 Subject: [PATCH 18/24] ci/tools: Update changeset analyzer tool Trigger builds/tests if pipeline definition files (.yml) change --- tools/changeset_testlist.yaml | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/tools/changeset_testlist.yaml b/tools/changeset_testlist.yaml index 71dcc280b1..3aa094e0db 100644 --- a/tools/changeset_testlist.yaml +++ b/tools/changeset_testlist.yaml @@ -196,7 +196,36 @@ ############################################################################### # CI CHANGES ############################################################################### -- re: .ci/templates/tests/templates/job-uhd-x4xx-hardware-tests.yml +# Changes to pipeline infrastructure or build jobs -> build and test all +- re: .ci/templates/stages-.*.yml + add: + - uhd.build.all + - hw.streaming.all + - hw.rf.all + - devtest.all +- re: .ci/templates/.*-build.*.yml + add: + - uhd.build.all + - hw.streaming.all + - hw.rf.all + - devtest.all +# Devtest +- re: .ci/templates/.*-devtest.*.yml + add: + - uhd.build.linux + - devtest.all +# RF Test +- re: .ci/templates/.*-rf-tests.*.yml + add: + - uhd.build.linux + - hw.rf.all +# Streaming Test +- re: .ci/templates/.*-streaming.*.yml + add: + - uhd.build.linux + - hw.streaming.all +# RF Test x4xx +- re: .ci/templates/tests/.*.yml add: - uhd.build.linux - hw.rf.x4xx From 1e7bf2c1b3b6f249460a73d57f8dcb379a44b129 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Wed, 27 Nov 2024 12:40:22 +0100 Subject: [PATCH 19/24] ci: Add --verbose to changeset analyzer --- .ci/templates/job-analyze-changeset.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.ci/templates/job-analyze-changeset.yml b/.ci/templates/job-analyze-changeset.yml index 20cee51f71..c8877796c2 100644 --- a/.ci/templates/job-analyze-changeset.yml +++ b/.ci/templates/job-analyze-changeset.yml @@ -40,7 +40,7 @@ jobs: $AGENT_TEMPDIRECTORY/ac_venv/$VENV_BIN_DIR/python3 tools/changeset_testlist.py \ --target-branch $TARGET_BRANCH \ --set-azdo-var UhdTestList \ - --list-tests $EXTRA_ARGS + --list-tests --verbose $EXTRA_ARGS name: gen_testlist displayName: Generate Test-List env: From 48e41a86784d92081fb75f245b8cc034b872612c Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Wed, 27 Nov 2024 10:31:28 +0100 Subject: [PATCH 20/24] tools: changeset_testlist.py skips comments If a changeset includes only comments in a C++ or Python file, then the corresponding tests are not triggered. This is achieved by a new rule `include_content`, which checks the changeset for code and/or content changes. The values of the include_content argument have the following meaning: - 'code': at least one line with code changed - 'code-only': all changed lines must be code changes - 'comments': at least one line with comments changed - 'comments-only': all changed lines must be comment changes - 'code-and-comments': either code or comments changes (always True) Co-authored-by: Joerg Hofrichter --- tools/changeset_testlist.py | 117 ++++++++++++++++++++++++++++++++-- tools/changeset_testlist.yaml | 7 ++ 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/tools/changeset_testlist.py b/tools/changeset_testlist.py index cd668edcb2..2b9a96bda6 100644 --- a/tools/changeset_testlist.py +++ b/tools/changeset_testlist.py @@ -55,10 +55,96 @@ def parse_args(): return parser.parse_args() -def get_changed_files(repo_path, target_branch, source_branch, include_target): +def check_changeset_content(file, **kwargs): + """Check changeset content for code and/or comments changes + + For example, if a .cpp file only has a comment change, we can use this to + remove it from the "changed files" list. This is useful when we only want to + only include tests if the underlying code was actually changed, and not just + a comment (which cannot change the outcome of a hardware test). + + The values of the include_content argument have the following meaning: + - 'code': at least one line with code changed + - 'code-only': all changed lines must be code changes + - 'comments': at least one line with comments changed + - 'comments-only': all changed lines must be comment changes + - 'code-and-comments': either code or comments changes (always True) + + Arguments: + file: List of files that have been changed. + repo_path: Path to the UHD repository. + git_cmd: Path to the git command. + include_content: allowed values are: code, code-only, comments, + comments-only, code-and-comments + + Returns: True if the file should be included, False otherwise. """ - Returns a list of paths in the UHD repository that have are different between - two branches. + + def identify_comment_line_cpp(line): + """Identify if a line is a comment in a C++ file.""" + line = line.strip() + return line.startswith("//") or line.startswith("/*") or line.startswith("*") + + def identify_comment_line_py(line): + """Identify if a line is a comment in a Python file.""" + line = line.strip() + return line.startswith("#") + + comment_identifer = { + ".cpp": identify_comment_line_cpp, + ".hpp": identify_comment_line_cpp, + ".c": identify_comment_line_cpp, + ".h": identify_comment_line_cpp, + ".py": identify_comment_line_py, + } + + include_content = kwargs.get("include_content", None) + if include_content == "code-and-comments": + # No need to check, result will always be true + return True + elif include_content in ["code", "code-only"]: + invert = True + elif include_content in ["comments", "comments-only"]: + invert = False + else: + raise ValueError(f"Unsupported argument: include_content={include_content}") + + target_branch = kwargs["target_branch"] + if kwargs.get("include_target"): + target_branch += "..." + get_diff_args = [ + shutil.which("git"), + "-C", + kwargs["repo_path"], + "diff", + "--no-color", + "--unified=0", + target_branch, + "--", + ] + + ext = os.path.splitext(file)[1] + if ext not in comment_identifer: + # If we have no rule to check, then always include the file. + return True + diff_lines = ( + subprocess.check_output(get_diff_args + [file], encoding="utf-8").strip().split("\n")[4:] + ) + line_matches = [comment_identifer[ext](line[1:])^invert for line in diff_lines if line[0] in ("-", "+")] + if include_content.endswith("-only"): + return all(line_matches) + else: + return any(line_matches) + + +def get_changed_files(repo_path, target_branch, source_branch, include_target): + """Return a list of paths in the UHD repository that have are different between two branches. + + Arguments: + repo_path: Path to the UHD repository. + target_branch: Branch to compare against (e.g., master). + source_branch: Branch to compare from. Defaults to the current branch. + include_target: Include changes that originate from the target branch. """ assert target_branch # If include_target is false, then current (unstaged/uncommited) changes are @@ -84,14 +170,16 @@ def load_rules(rule_file): class RuleApplier: """Helper class to update an internal test list based on a set of rules.""" - def __init__(self, rules, labels): + def __init__(self, rules, labels, **kwargs): """Initialize. Arguments: rules: List of rules to apply. + labels: List of labels relevant to the current changeset. """ self.rules = rules self.labels = labels + self.args = kwargs self.test_list = set() def apply(self, filename, verbose=False): @@ -130,9 +218,20 @@ def _apply_rule(self, rule, filename, verbose=False): if verbose: sys.stderr.write(f"Filename {filename} matches rule: {rule}\n") if "label" in rule and not rule["label"] in self.labels: + if verbose: + sys.stderr.write(f"Skipping file based on missing label: {rule['label']}\n") return False if "label" in rule and verbose: sys.stderr.write(f"Label {rule['label']} found\n") + include_content = rule.get("include_content", "code") + if not check_changeset_content( + filename, **self.args, include_content=include_content + ): + if verbose: + sys.stderr.write( + f"Skipping {filename} based on content rule: include_content='{include_content}'\n" + ) + return False if "add" in rule: self.test_list.update(rule["add"]) if "remove" in rule: @@ -170,7 +269,15 @@ def main(): args.include_target, ) labels = get_labels(args.github_label_api_endpoint, args.github_token) - rule_applier = RuleApplier(load_rules(rule_file), labels) + rule_applier = RuleApplier( + load_rules(rule_file), + labels, + repo_path=args.repo_path, + target_branch=args.target_branch, + source_branch=args.source_branch, + include_target=args.include_target, + verbose=args.verbose, + ) for filename in file_list: rule_applier.apply(filename, args.verbose) rule_applier.apply_labels() diff --git a/tools/changeset_testlist.yaml b/tools/changeset_testlist.yaml index 3aa094e0db..ebbac6157c 100644 --- a/tools/changeset_testlist.yaml +++ b/tools/changeset_testlist.yaml @@ -25,6 +25,13 @@ - re: ^host/docs/ add: - uhd.docs +# If a comment in a public header changed, then most likely the documentation +# changed, but we still want to run other tests, too +- re: ^host/include/uhd/.+\.hpp$ + add: + - uhd.docs + include_content: comments + stop: False # Device-specific changes. These should trigger HW tests only on those devices # they affect. We start with daughterboard rules, then motherboard rules. - re: host/lib/usrp/dboard/zbx/ From da78380e027162b27c5861db3acef6b9590be159 Mon Sep 17 00:00:00 2001 From: Lars Amsel Date: Fri, 22 Nov 2024 09:28:45 +0100 Subject: [PATCH 21/24] host: Fix Windows RC version numbers Current implementations squeezes the UHD major/API number into the major version number while leaving the minor version number empty. So for 4.7 the version number would read 4007.0.x.y. This changes modifies that to 4.7.x.y. --- host/lib/CMakeLists.txt | 1 - host/lib/uhd.rc.in | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/host/lib/CMakeLists.txt b/host/lib/CMakeLists.txt index 06a5a2784c..bec8ea1d76 100644 --- a/host/lib/CMakeLists.txt +++ b/host/lib/CMakeLists.txt @@ -143,7 +143,6 @@ LIBUHD_APPEND_LIBS(uhd_rc) # Add DLL resource file to Windows build ######################################################################## if(MSVC) - math(EXPR RC_VERSION_MAJOR_API "${UHD_VERSION_MAJOR} * 1000 + ${UHD_VERSION_API}") set(RC_VERSION_PATCH ${UHD_VERSION_PATCH}) if(UHD_VERSION_DEVEL) set(RC_VERSION_PATCH "999") diff --git a/host/lib/uhd.rc.in b/host/lib/uhd.rc.in index dee6bb8a3d..89045400ed 100644 --- a/host/lib/uhd.rc.in +++ b/host/lib/uhd.rc.in @@ -1,8 +1,8 @@ #include VS_VERSION_INFO VERSIONINFO - FILEVERSION @RC_VERSION_MAJOR_API@,@UHD_VERSION_ABI@,@RC_VERSION_PATCH@,@UHD_GIT_COUNT@ - PRODUCTVERSION @RC_VERSION_MAJOR_API@,@UHD_VERSION_ABI@,@RC_VERSION_PATCH@,@UHD_GIT_COUNT@ + FILEVERSION @UHD_VERSION_MAJOR@,@UHD_VERSION_API@,@UHD_VERSION_ABI@,@RC_VERSION_PATCH@ + PRODUCTVERSION @UHD_VERSION_MAJOR@,@UHD_VERSION_API@,@UHD_VERSION_ABI@,@RC_VERSION_PATCH@ FILEFLAGSMASK 0x3fL #ifndef NDEBUG FILEFLAGS 0x0L From 46f14f8791f13fbf0831e34d45e6eaa8a2d0c0dd Mon Sep 17 00:00:00 2001 From: Joerg Hofrichter Date: Thu, 28 Nov 2024 15:59:28 +0100 Subject: [PATCH 22/24] docs: fixed warnings This fixes the following warnings: (...)/host/docs/install.dox:43: warning: Found unknown command '\VS20XX' (...)/host/docs/install.dox:43: warning: Found unknown command '\MSYY' (...)/host/docs/install.dox:43: warning: Found unknown command '\dll' WARNING: Invalid configuration value found: 'language = None'. Update your configuration to a valid language code. Falling back to 'en' (English). WARNING: html_static_path entry '_static' does not exist --- host/docs/install.dox | 2 +- host/docs/sphinx/source/conf.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/host/docs/install.dox b/host/docs/install.dox index 6ec796daae..16be561865 100644 --- a/host/docs/install.dox +++ b/host/docs/install.dox @@ -40,7 +40,7 @@ and compiler version used for the UHD binaries. This detail is indicated in the name of the installer executable; for example, uhd_4.7.0.0-release_Win64_VS2017.exe indicates it was built for the 64-bit Windows platform using the Visual Studio 2017 compiler suite. -Copy all files from the path \VS20XX\MSYY\dll within the archive to the bin folder +Copy all files from the path \\VS20XX\\MSYY\\dll within the archive to the bin folder of the UHD installation location (by default "C:\Program Files\UHD\bin"). VS20XX is the Visual Studio version that you find in the name of the UHD installer. YY is the bitness of your Windows version (32 or 64). diff --git a/host/docs/sphinx/source/conf.py b/host/docs/sphinx/source/conf.py index e8a7c413c1..c662521e12 100644 --- a/host/docs/sphinx/source/conf.py +++ b/host/docs/sphinx/source/conf.py @@ -60,7 +60,7 @@ # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. -language = None +language = 'en' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. @@ -87,7 +87,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +# html_static_path = ['_static'] # Custom sidebar templates, must be a dictionary that maps document names # to template names. From 84f270a3dd1428c6d56ea674400c15503b89ecd4 Mon Sep 17 00:00:00 2001 From: Joerg Hofrichter Date: Wed, 27 Nov 2024 12:42:45 +0100 Subject: [PATCH 23/24] deps: rpclib: support detection of arm64 architecture for Windows Fixes #785 Cannot build for Windows on ARM64 --- .../rpclib/include/rpc/msgpack/predef/architecture/arm.h | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/host/lib/deps/rpclib/include/rpc/msgpack/predef/architecture/arm.h b/host/lib/deps/rpclib/include/rpc/msgpack/predef/architecture/arm.h index bfc4a3404a..737a066e1e 100644 --- a/host/lib/deps/rpclib/include/rpc/msgpack/predef/architecture/arm.h +++ b/host/lib/deps/rpclib/include/rpc/msgpack/predef/architecture/arm.h @@ -27,11 +27,13 @@ Distributed under the Boost Software License, Version 1.0. [[`__TARGET_ARCH_ARM`] [__predef_detection__]] [[`__TARGET_ARCH_THUMB`] [__predef_detection__]] [[`_M_ARM`] [__predef_detection__]] + [[`_M_ARM64`] [__predef_detection__]] [[`__arm64`] [8.0.0]] [[`__TARGET_ARCH_ARM`] [V.0.0]] [[`__TARGET_ARCH_THUMB`] [V.0.0]] [[`_M_ARM`] [V.0.0]] + [[`_M_ARM64`] [V.0.0]] ] */ @@ -39,7 +41,7 @@ Distributed under the Boost Software License, Version 1.0. #if defined(__arm__) || defined(__arm64) || defined(__thumb__) || \ defined(__TARGET_ARCH_ARM) || defined(__TARGET_ARCH_THUMB) || \ - defined(_M_ARM) + defined(_M_ARM) || defined(_M_ARM64) # undef MSGPACK_ARCH_ARM # if !defined(MSGPACK_ARCH_ARM) && defined(__arm64) # define MSGPACK_ARCH_ARM MSGPACK_VERSION_NUMBER(8,0,0) @@ -53,6 +55,9 @@ Distributed under the Boost Software License, Version 1.0. # if !defined(MSGPACK_ARCH_ARM) && defined(_M_ARM) # define MSGPACK_ARCH_ARM MSGPACK_VERSION_NUMBER(_M_ARM,0,0) # endif +# if !defined(MSGPACK_ARCH_ARM) && defined(_M_ARM64) +# define MSGPACK_ARCH_ARM MSGPACK_VERSION_NUMBER(_M_ARM64,0,0) +# endif # if !defined(MSGPACK_ARCH_ARM) # define MSGPACK_ARCH_ARM MSGPACK_VERSION_NUMBER_AVAILABLE # endif From 87c4ff673a9e0d095d568f12e85f02d688aba727 Mon Sep 17 00:00:00 2001 From: Martin Braun Date: Mon, 11 Nov 2024 15:06:43 +0100 Subject: [PATCH 24/24] lib: dsp: Refactor dsp_core_utils This refactors get_freq_and_freq_word(). It had the following issues: - It used a static const for the scaling factor, which depends on the word width. Previously, we (incorrectly) used different word widths for B200 and RFNoC devices, but because of the static const nature of the calculated scaling factor, this could cause incorrect frequency words being calculated when running both a B2xx and RFNoC device in the same session. (Note that this bug can no longer be triggered with the bug fix to the word widths, but this cleans up this potential pitfall regardless) - In general, the word width shouldn't be a runtime parameter (it depends on hardware), and thus was made a template parameter. This removes a runtime call to `std::pow()`, and uses a `constexpr` instead. This function is rarely cause for performance issues, so this change is mostly cosmetic in practice, but it's good practice nevertheless. - Due to templatization, the code was moved from the .cpp file to its header (the .cpp file is no longer required and was removed). - While we're modifying this file, we remove all unnecessary multiplications/divisions and use normalized values where possible. --- .../uhdlib/usrp/cores/dsp_core_utils.hpp | 51 +++++++++++++++- host/lib/usrp/cores/CMakeLists.txt | 1 - host/lib/usrp/cores/dsp_core_utils.cpp | 61 ------------------- 3 files changed, 48 insertions(+), 65 deletions(-) delete mode 100644 host/lib/usrp/cores/dsp_core_utils.cpp diff --git a/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp b/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp index 6371eb2e52..d83a8239a1 100644 --- a/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp +++ b/host/lib/include/uhdlib/usrp/cores/dsp_core_utils.hpp @@ -7,21 +7,66 @@ #pragma once +#include +#include +#include +#include +#include #include /*! For a requested frequency, sampling rate, and frequency word width (in * number of bits), return the correct frequency word (to set the CORDIC or * DDS) and the actual frequency. */ +template void get_freq_and_freq_word(const double requested_freq, const double tick_rate, double& actual_freq, - int32_t& freq_word, - int word_width = 32); + int32_t& freq_word) +{ + constexpr int32_t MAX_FREQ_WORD = std::numeric_limits::max(); + constexpr int32_t MIN_FREQ_WORD = std::numeric_limits::min(); + constexpr double scale_factor = static_cast(uint64_t(1) << word_width); + // Frequency normalized by sampling rate, and wrapped to [-0.5, 0.5). + const double freq_norm_scaled = + uhd::math::wrap_frequency(requested_freq / tick_rate, 1.0) * scale_factor; + + // confirm that the target frequency is within range of the CORDIC + UHD_ASSERT_THROW(std::abs(freq_norm_scaled) - 1 <= MAX_FREQ_WORD); + + /* Now calculate the frequency word. It is possible for this calculation + * to cause an overflow. As the requested DSP frequency approaches the + * master clock rate, that ratio multiplied by the scaling factor (2^32) + * will generally overflow within the last few kHz of tunable range. + * Thus, we check to see if the operation will overflow before doing it, + * and if it will, we set it to the integer min or max of this system. + */ + if (freq_norm_scaled >= MAX_FREQ_WORD) { + /* Operation would have caused a positive overflow of int32. */ + freq_word = MAX_FREQ_WORD; + + } else if (freq_norm_scaled <= MIN_FREQ_WORD) { + /* Operation would have caused a negative overflow of int32. */ + freq_word = MIN_FREQ_WORD; + + } else { + /* The operation is safe. Perform normally. */ + freq_word = int32_t(std::lround(freq_norm_scaled)); + } + + actual_freq = (double(freq_word) / scale_factor) * tick_rate; +} /*! For a requested frequency, sampling rate, and frequency word width (in * number of bits), return the correct frequency word (to set the CORDIC or * DDS) and the actual frequency. */ +template std::tuple get_freq_and_freq_word( - const double requested_freq, const double tick_rate, int word_width = 32); + const double requested_freq, const double tick_rate) +{ + double actual_freq; + int32_t freq_word; + get_freq_and_freq_word(requested_freq, tick_rate, actual_freq, freq_word); + return {actual_freq, freq_word}; +} diff --git a/host/lib/usrp/cores/CMakeLists.txt b/host/lib/usrp/cores/CMakeLists.txt index 2e2132ad3b..f43161a571 100644 --- a/host/lib/usrp/cores/CMakeLists.txt +++ b/host/lib/usrp/cores/CMakeLists.txt @@ -28,7 +28,6 @@ endif() LIBUHD_APPEND_SOURCES( ${CMAKE_CURRENT_SOURCE_DIR}/dma_fifo_core_3000.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/dsp_core_utils.cpp ${CMAKE_CURRENT_SOURCE_DIR}/gpio_atr_3000.cpp ${CMAKE_CURRENT_SOURCE_DIR}/i2c_core_100_wb32.cpp ${CMAKE_CURRENT_SOURCE_DIR}/rx_dsp_core_3000.cpp diff --git a/host/lib/usrp/cores/dsp_core_utils.cpp b/host/lib/usrp/cores/dsp_core_utils.cpp deleted file mode 100644 index 5575d97759..0000000000 --- a/host/lib/usrp/cores/dsp_core_utils.cpp +++ /dev/null @@ -1,61 +0,0 @@ -// -// Copyright 2016 Ettus Research LLC -// Copyright 2018 Ettus Research, a National Instruments Company -// -// SPDX-License-Identifier: GPL-3.0-or-later -// - -#include -#include -#include -#include -#include - -static const int32_t MAX_FREQ_WORD = std::numeric_limits::max(); -static const int32_t MIN_FREQ_WORD = std::numeric_limits::min(); - -void get_freq_and_freq_word(const double requested_freq, - const double tick_rate, - double& actual_freq, - int32_t& freq_word, - int word_width) -{ - const double freq = uhd::math::wrap_frequency(requested_freq, tick_rate); - - // confirm that the target frequency is within range of the CORDIC - UHD_ASSERT_THROW(std::abs(freq) <= tick_rate / 2.0); - - /* Now calculate the frequency word. It is possible for this calculation - * to cause an overflow. As the requested DSP frequency approaches the - * master clock rate, that ratio multiplied by the scaling factor (2^32) - * will generally overflow within the last few kHz of tunable range. - * Thus, we check to see if the operation will overflow before doing it, - * and if it will, we set it to the integer min or max of this system. - */ - freq_word = 0; - - static const double scale_factor = std::pow(2.0, word_width); - if ((freq / tick_rate) >= (MAX_FREQ_WORD / scale_factor)) { - /* Operation would have caused a positive overflow of int32. */ - freq_word = MAX_FREQ_WORD; - - } else if ((freq / tick_rate) <= (MIN_FREQ_WORD / scale_factor)) { - /* Operation would have caused a negative overflow of int32. */ - freq_word = MIN_FREQ_WORD; - - } else { - /* The operation is safe. Perform normally. */ - freq_word = int32_t(std::lround((freq / tick_rate) * scale_factor)); - } - - actual_freq = (double(freq_word) / scale_factor) * tick_rate; -} - -std::tuple get_freq_and_freq_word( - const double requested_freq, const double tick_rate, int word_width) -{ - double actual_freq; - int32_t freq_word; - get_freq_and_freq_word(requested_freq, tick_rate, actual_freq, freq_word, word_width); - return std::make_tuple(actual_freq, freq_word); -}