diff --git a/.ci/fpga/scripts/run_setup.sh b/.ci/fpga/scripts/run_setup.sh index 144917e1a..67e4918fa 100644 --- a/.ci/fpga/scripts/run_setup.sh +++ b/.ci/fpga/scripts/run_setup.sh @@ -33,7 +33,7 @@ echo "---- Run hwsetup ----" # variables based on the agent's configuration so we can find the EDA # tools. pushd $BUILD_SOURCESDIRECTORY/uhddev/.ci/hwtools -source hwsetup.sh hwtools=0.1.3 +source hwsetup.sh --hwtools=0.1.3 popd echo "---- Fetch the FPGA simulation libraries ----" diff --git a/.ci/fpga/templates/job-regmap.yml b/.ci/fpga/templates/job-regmap.yml new file mode 100644 index 000000000..0c00dafba --- /dev/null +++ b/.ci/fpga/templates/job-regmap.yml @@ -0,0 +1,31 @@ +# +# Copyright 2025 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: LGPL-3.0-or-later +# +# Description: +# +# Updating the register maps for the X400 based FPGA designs. +# +jobs: +- job: + displayName: "Check regmaps" + timeoutInMinutes: 30 + pool: + name: Drivers-NIBuildFarm-RFMIBUILD + demands: + - Agent.OS -equals Linux + steps: + - template: setup_steps.yml + + - bash: | + # Set up the hwtools path and run the build script + source $(Build.SourcesDirectory)/uhddev/.ci/fpga/scripts/run_setup.sh $(Build.SourcesDirectory)/uhddev/fpga/usrp3/top/x400 + python build.py + workingDirectory: uhddev/.ci/hwtools + displayName: "Run xmlparse" + + # Check if regmaps are up to date + - template: check_clean_repo_steps.yml + parameters: + directory: uhddev diff --git a/.ci/hwtools/.gitignore b/.ci/hwtools/.gitignore index 4ed6b372e..15df7720b 100644 --- a/.ci/hwtools/.gitignore +++ b/.ci/hwtools/.gitignore @@ -1,2 +1,4 @@ # Ignore objects/ directory created by hwtools objects/ +# Ignore Python bytecode cache files +__pycache__/ diff --git a/.ci/hwtools/X410/vsmakesettings.py b/.ci/hwtools/X410/vsmakesettings.py new file mode 100644 index 000000000..9b099e931 --- /dev/null +++ b/.ci/hwtools/X410/vsmakesettings.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python3 +# +# Copyright 2025 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: MIT +# + +from hwtools.api import vapi + +def do_options(): + vapi.set_project_name(name="X410_FPGA", pretty_name="USRP X410 FPGA") + +def do_files(): + # x400 related files + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/common") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/x410") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/dboards", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/dboards/zbx") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/rf/common") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/rf/100m") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/rf/200m") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/rf/400m") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/ip/x4xx_ps_rfdc_bd/common/regmap") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/ip/x4xx_ps_rfdc_bd/x410_ps_rfdc_bd/regmap") + + # library + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/lib/rfnoc") + + # regmap files + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/regmap", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/regmap/x410", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/regmap", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/regmap/x410", tree=False) + +def do_preparse(): + pass + +def do_precompile(): + pass + +def do_presynth(): + pass + +def do_finish(): + vapi.run_user_function(function="update_xmlparse_files", base="self", path="../common.py") + +def vhook_warn_filter(msgstr): + return False diff --git a/.ci/hwtools/X440/vsmakesettings.py b/.ci/hwtools/X440/vsmakesettings.py new file mode 100644 index 000000000..537eee10c --- /dev/null +++ b/.ci/hwtools/X440/vsmakesettings.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python3 +# +# Copyright 2025 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: MIT +# + +from hwtools.api import vapi + +def do_options(): + vapi.set_project_name(name="X440_FPGA", pretty_name="USRP X440 FPGA") + +def do_files(): + # x400 related files + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/common") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/x440") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/dboards", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/dboards/fbx") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/rf/common") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/rf/full") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/ip/x4xx_ps_rfdc_bd/common/regmap") + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/ip/x4xx_ps_rfdc_bd/x440_ps_rfdc_bd/regmap") + + # library + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/lib/rfnoc") + + # regmap files + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/regmap", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/regmap/x440", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/regmap", tree=False) + vapi.find_files_and_add_to_fileset(base="repo", path="fpga/usrp3/top/x400/cpld/regmap/x440", tree=False) + +def do_preparse(): + pass + +def do_precompile(): + pass + +def do_presynth(): + pass + +def do_finish(): + vapi.run_user_function(function="update_xmlparse_files", base="self", path="../common.py") + +def vhook_warn_filter(msgstr): + return False diff --git a/.ci/hwtools/build.py b/.ci/hwtools/build.py new file mode 100644 index 000000000..1ba31e61f --- /dev/null +++ b/.ci/hwtools/build.py @@ -0,0 +1,24 @@ +#!/usr/bin/env python3 +# +# Copyright 2025 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: MIT +# +# Generates the register maps for the X400 based FPGA designs. +# + +import os +from hwtools.api import WorkingFolder, cmd + +# enumerate the subdirectories +sub_directories = [d for d in os.listdir() if os.path.isdir(d)] + +# assume the variant is called as the directory +for variant in sub_directories: + with WorkingFolder(variant, delete_and_recreate=False, create_ok=False): + # check if vsmakesettings.py exists + if not os.path.isfile("vsmakesettings.py"): + continue + # generate register map + cmd.runlive("xmlparse", "--clean", raise_on_err=True) + cmd.runlive("xmlparse", raise_on_err=True) diff --git a/.ci/hwtools/common.py b/.ci/hwtools/common.py new file mode 100644 index 000000000..4f84b5e10 --- /dev/null +++ b/.ci/hwtools/common.py @@ -0,0 +1,61 @@ +#!/usr/bin/env python3 +# +# Copyright 2025 Ettus Research, a National Instruments Brand +# +# SPDX-License-Identifier: MIT +# + +import shutil + +from pathlib import Path + +from hwtools.api import vapi, pathapi, cmd + + +def update_xmlparse_files(): + if vapi.is_xmlparse(): + # copy the register map to the correct location + variant = Path.cwd().name + project_name = f"{variant}_FPGA" + src_file = pathapi.get_abs_path( + f"{project_name}/xmlparse/pri1/{project_name}.htm", base="objects" + ) + # search the file recusively in the current directory + dest_file = pathapi.get_abs_path( + f"fpga/usrp3/top/x400/doc/{variant}/{project_name}.htm", base="repo" + ) + shutil.copy(src_file, dest_file) + + # get the directory of generated files and check each file in it + xmlparse_hdl_dir = Path(pathapi.get_abs_path("pri1/hdl", base="xmlparse")) + for gen_file in xmlparse_hdl_dir.iterdir(): + print(f"Checking {gen_file.name}") + + # check for matching files in the repo + existing_files = vapi.get_files_from_fileset("/" + gen_file.name) + if (len(existing_files) != 1): + # if there is no match for vhd files this might be fine for the NI-USRP case + if (len(existing_files) == 0) and (gen_file.name.endswith(".vhd")): + print(f"Skipped") + continue + # print if there are multiple or no matches + raise Exception(f"File {gen_file.name} match set was not unique. Possible targets: {existing_files}") + + # update the file in the repo + # Remove lines containing "not implemented" from the copied file + with open(gen_file, "r") as file: + lines = file.readlines() + with open(existing_files[0], "w") as file: + for line in lines: + if "not implemented" not in line: + file.write(line) + + # revert the file if the year is the only change + cmd.run("git", "diff", "--unified=0", existing_files[0], raise_on_err=False) + lines = cmd.stdout.splitlines() + if lines: + # skip the unified header of 5 lines + lines = lines[5:] + remaining_lines = [line for line in lines if not "Copyright" in line] + if not remaining_lines: + cmd.run("git", "checkout", existing_files[0], raise_on_err=False) diff --git a/.ci/hwtools/root.py b/.ci/hwtools/root.py index 6859a6492..b16153c56 100644 --- a/.ci/hwtools/root.py +++ b/.ci/hwtools/root.py @@ -1,6 +1,6 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -# Copyright 2021 Ettus Research, a National Instruments Brand +# Copyright 2025 Ettus Research, a National Instruments Brand # # SPDX-License-Identifier: LGPL-3.0-or-later # diff --git a/.ci/templates/stages-uhd-pipeline.yml b/.ci/templates/stages-uhd-pipeline.yml index e3efe41ae..712cfa33d 100644 --- a/.ci/templates/stages-uhd-pipeline.yml +++ b/.ci/templates/stages-uhd-pipeline.yml @@ -513,6 +513,20 @@ stages: ### END: CPLD Build Stage +### START: Regmap stage + +- stage: regmap + dependsOn: analyze_changeset + condition: > + and(succeeded(), + contains(dependencies.analyze_changeset.outputs['analyze.gen_testlist.UhdTestList'], 'fpga.usrp3.regmaps') + ) + displayName: 'Check Regmaps' + jobs: + - template: ../fpga/templates/job-regmap.yml + +### END: Regmap stage + - template: ../fpga/templates/job-build-fpga-all.yml parameters: clean_ip_build: ${{ parameters.clean_ip_build }} diff --git a/fpga/.ci/fpga-pipeline.yml b/fpga/.ci/fpga-pipeline.yml index 59e514bb3..64345b6d4 100644 --- a/fpga/.ci/fpga-pipeline.yml +++ b/fpga/.ci/fpga-pipeline.yml @@ -49,6 +49,10 @@ parameters: type: boolean displayName: Build X4xx CPLDs default: false +- name: build_regmaps + type: boolean + displayName: Build Register Maps + default: false - name: package_and_publish_images type: boolean displayName: Package & Publish Images @@ -141,7 +145,7 @@ extends: parameters: add_tests: ${{ format( - '{0};{1};{2};{3};{4};{5};{6};{7};', + '{0};{1};{2};{3};{4};{5};{6};{7};{8};', iif(parameters.run_testbenches,'fpga.usrp3.testbenches',''), iif(parameters.build_x3x0,'fpga.usrp3.x3xx',''), iif(parameters.build_n3xx,'fpga.usrp3.n3xx',''), @@ -149,7 +153,8 @@ extends: iif(parameters.build_e32x,'fpga.usrp3.e32x',''), iif(parameters.build_x410,'fpga.usrp3.x410',''), iif(parameters.build_x440,'fpga.usrp3.x440',''), - iif(parameters.build_x4xx_cplds,'fpga.usrp3.cpld.x4xx','') + iif(parameters.build_x4xx_cplds,'fpga.usrp3.cpld.x4xx',''), + iif(parameters.build_regmaps,'fpga.usrp3.regmaps','') ) }} skip_rule_checking: true diff --git a/tools/changeset_testlist.yaml b/tools/changeset_testlist.yaml index 0a7d83404..d667b763a 100644 --- a/tools/changeset_testlist.yaml +++ b/tools/changeset_testlist.yaml @@ -222,6 +222,7 @@ - re: fpga/usrp3/ add: - fpga.usrp3.testbenches + - fpga.usrp3.regmaps stop: False # library changes @@ -341,16 +342,24 @@ - uhd.rfnoc_modtool.all -- re: fpga/.ci/templates +- re: .ci/fpga/templates add: - fpga.usrp3.all - fpga.usrp3.cpld.x4xx - fpga.usrp3.testbenches -- re: fpga/.ci/scripts + - fpga.usrp3.regmaps +- re: .ci/fpga/scripts add: - fpga.usrp3.all - fpga.usrp3.cpld.x4xx - fpga.usrp3.testbenches + - fpga.usrp3.regmaps +- re: .ci/hwtools + add: + - fpga.usrp3.all + - fpga.usrp3.cpld.x4xx + - fpga.usrp3.testbenches + - fpga.usrp3.regmaps # Device-specific pipeline changes. - re: .ci/fpga/devices/job-build-x400.yml add: