From 2d28e37b93794a951904a5dc1b15d557b2c4a2f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Sun, 23 Nov 2025 09:31:43 +0100 Subject: [PATCH 01/10] Add testbench and lint functions --- ...ulate-with-verilator.yml => ci-config.yml} | 148 +++++++++--------- CMakeLists.txt | 2 + cmake/lint.cmake | 51 ++++++ cmake/testbench.cmake | 84 ++++++++++ ...-lint.rules => default-verible-lint.rules} | 0 ...int.waives => default-verible-lint.waives} | 0 tests/CMakeLists.txt | 82 +++------- 7 files changed, 233 insertions(+), 134 deletions(-) rename .github/workflows/{simulate-with-verilator.yml => ci-config.yml} (59%) create mode 100644 cmake/lint.cmake create mode 100644 cmake/testbench.cmake rename config/{verible-lint.rules => default-verible-lint.rules} (100%) rename config/{verible-lint.waives => default-verible-lint.waives} (100%) diff --git a/.github/workflows/simulate-with-verilator.yml b/.github/workflows/ci-config.yml similarity index 59% rename from .github/workflows/simulate-with-verilator.yml rename to .github/workflows/ci-config.yml index beae7ad..cb2f09e 100644 --- a/.github/workflows/simulate-with-verilator.yml +++ b/.github/workflows/ci-config.yml @@ -1,10 +1,10 @@ -name: Simulated testing using verilator +name: ECAP5-DTESTLIB continuous integration on: push: - branches: [ "main" ] + branches: [ "main", "release/**" ] pull_request: - branches: [ "main" ] + branches: [ "main", "release/**" ] permissions: actions: write @@ -12,9 +12,9 @@ permissions: env: # Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.) BUILD_TYPE: Release - REPORT_ARTIFACT_NAME: ecap5-dtlib-report-${{github.run_number}}-${{github.run_attempt}} - ARCH_ARTIFACT_NAME: ecap5-dtlib-arch-${{github.run_number}}-${{github.run_attempt}} - BUILD_CACHE_KEY: build-directory-${{ github.run_id }}-${{ github.run_attempt }} + REPORT_ARTIFACT_NAME: ecap5-dtestlib-report-${{github.run_number}}-${{github.run_attempt}} + DOCUMENTATION_ARTIFACT_NAME: ecap5-dtestlib-docs-${{github.run_number}}-${{github.run_attempt}} + BUILD_CACHE_KEY: simulation-build-directory-${{ github.run_id }}-${{ github.run_attempt }} jobs: prepare: @@ -24,41 +24,17 @@ jobs: - uses: actions/checkout@v4.1.1 - name: Configure CMake - run: cmake -B ${{github.workspace}}/build + run: cmake -B ${{github.workspace}}/build -GNinja - name: Cache build directory if: always() - uses: actions/cache/save@v4.0.1 + uses: actions/cache/save@v4.3.0 env: cache-folder-path: ${{github.workspace}}/build with: path: ${{ env.cache-folder-path }} key: ${{ runner.os }}-${{env.BUILD_CACHE_KEY}} - documentation: - runs-on: self-hosted - needs: prepare - - steps: - - uses: actions/checkout@v4.1.1 - - - name: Import build directory - uses: actions/cache/restore@v4.0.1 - env: - cache-folder-path: ${{github.workspace}}/build - with: - path: ${{ env.cache-folder-path }} - key: ${{ runner.os }}-${{env.BUILD_CACHE_KEY}} - - - name: Generate documentation - run: make -C ${{github.workspace}}/build docs - - - name: Upload documentation - uses: actions/upload-artifact@v4 - with: - name: ${{env.ARCH_ARTIFACT_NAME}} - path: ${{github.workspace}}/build/docs/documentation/build/html - lint: runs-on: self-hosted needs: prepare @@ -68,7 +44,7 @@ jobs: - name: Import build directory id: import-build - uses: actions/cache/restore@v4.0.1 + uses: actions/cache/restore@v4.3.0 env: cache-folder-path: ${{github.workspace}}/build with: @@ -76,17 +52,17 @@ jobs: key: ${{ runner.os }}-${{env.BUILD_CACHE_KEY}} - name: Lint - run: make -C ${{github.workspace}}/build lint + run: ninja -C ${{github.workspace}}/build lint - name: Delete Previous Cache - if: steps.import-build.outputs.cache-hit == 'true' + if: ${{ always() && steps.import-build.outputs.cache-hit == 'true'}} run: gh cache delete "${{ runner.os }}-${{env.BUILD_CACHE_KEY}}" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Cache build directory if: always() - uses: actions/cache/save@v4.0.1 + uses: actions/cache/save@v4.3.0 env: cache-folder-path: ${{github.workspace}}/build with: @@ -102,7 +78,7 @@ jobs: - name: Import build directory id: import-build - uses: actions/cache/restore@v4.0.1 + uses: actions/cache/restore@v4.3.0 env: cache-folder-path: ${{github.workspace}}/build with: @@ -110,7 +86,7 @@ jobs: key: ${{ runner.os }}-${{env.BUILD_CACHE_KEY}} - name: Build simulation - run: make -C ${{github.workspace}}/build build + run: ninja -C ${{github.workspace}}/build build - name: Simulate id: simulate @@ -118,19 +94,19 @@ jobs: # Checks if there is any testdata # Check if there is any fail in that testdata run: >- - make -C ${{github.workspace}}/build -k tests && + ninja -C ${{github.workspace}}/build -k 0 tests && ls -A1q ${{github.workspace}}/build/tests/testdata/ | grep -q . && (! grep -qe "[^;]*;0" ${{github.workspace}}/build/tests/testdata/*) - name: Delete Previous Cache - if: steps.import-build.outputs.cache-hit == 'true' + if: ${{ always() && steps.import-build.outputs.cache-hit == 'true'}} run: gh cache delete "${{ runner.os }}-${{env.BUILD_CACHE_KEY}}" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Cache build directory if: always() - uses: actions/cache/save@v4.0.1 + uses: actions/cache/save@v4.3.0 env: cache-folder-path: ${{github.workspace}}/build with: @@ -139,14 +115,15 @@ jobs: report: runs-on: self-hosted - needs: simulate + needs: bitstream if: always() steps: - uses: actions/checkout@v4.1.1 - name: Import build directory - uses: actions/cache/restore@v4.0.1 + id: import-build + uses: actions/cache/restore@v4.3.0 env: cache-folder-path: ${{github.workspace}}/build with: @@ -155,8 +132,8 @@ jobs: - name: Generate report run: >- - make -C ${{github.workspace}}/build report_markdown && - make -C ${{github.workspace}}/build report + ninja -C ${{github.workspace}}/build report_markdown && + ninja -C ${{github.workspace}}/build report - name: Write summary run: cat ${{github.workspace}}/build/report.md >> $GITHUB_STEP_SUMMARY @@ -170,32 +147,61 @@ jobs: - name: Check for report errors run: (! grep -qe "\[\!CAUTION\]" ${{github.workspace}}/build/report.md) - - name: Generate badges - if: ${{ github.ref == 'refs/heads/main' }} - run: make -C ${{github.workspace}}/build badges; + - name: Delete Previous Cache + if: ${{ always() && steps.import-build.outputs.cache-hit == 'true'}} + run: gh cache delete "${{ runner.os }}-${{env.BUILD_CACHE_KEY}}" + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Check generated badges - if: ${{ always() && github.ref == 'refs/heads/main' }} - run: >- - if [ ! -f "build/test-result-badge.json" ]; then - mkdir -p build && - echo "{\"schemaVersion\": 1, \"label\": \"Test result\", \"message\": \"Failed\", \"color\": \"red\"}" > build/test-result-badge.json; - fi - - - name: Upload test result badge - if: ${{ always() && github.ref == 'refs/heads/main' }} - uses: exuanbo/actions-deploy-gist@v1.1.4 + - name: Cache build directory + if: always() + uses: actions/cache/save@v4.3.0 + env: + cache-folder-path: ${{github.workspace}}/build + with: + path: ${{ env.cache-folder-path }} + key: ${{ runner.os }}-${{env.BUILD_CACHE_KEY}} + + documentation: + runs-on: self-hosted + needs: report + + steps: + - uses: actions/checkout@v4.1.1 + + - name: Import build directory + uses: actions/cache/restore@v4.3.0 + env: + cache-folder-path: ${{github.workspace}}/build with: - token: ${{ secrets.GIST_SECRET }} - gist_id: 32195ea7fa70c0218ef3f9952504c59e - file_path: build/test-result-badge.json - file_type: text - - - name: Upload traceability result badge - if: ${{ always() && github.ref == 'refs/heads/main' }} - uses: exuanbo/actions-deploy-gist@v1.1.4 + path: ${{ env.cache-folder-path }} + key: ${{ runner.os }}-${{env.BUILD_CACHE_KEY}} + + - name: Generate documentation + run: ninja -C ${{github.workspace}}/build docs + + - uses: actions/upload-pages-artifact@v3.0.1 + with: + name: ${{env.DOCUMENTATION_ARTIFACT_NAME}} + path: ${{github.workspace}}/build/docs/documentation/build/html + + deploy: + if: ${{ github.ref == 'refs/heads/main' }} + runs-on: self-hosted + + needs: documentation + + permissions: + pages: write + id-token: write + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + steps: + - uses: actions/deploy-pages@v4.0.4 + id: deployment with: - token: ${{ secrets.GIST_SECRET }} - gist_id: 32195ea7fa70c0218ef3f9952504c59e - file_path: build/traceability-result-badge.json - file_type: text + artifact_name: ${{env.DOCUMENTATION_ARTIFACT_NAME}} + preview: true diff --git a/CMakeLists.txt b/CMakeLists.txt index 7df7f20..53d0913 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -62,6 +62,8 @@ add_dependency(verilator-cmake include(${verilator_cmake_SOURCE_DIR}/cmake/verilator-config.cmake) include(${ecap5_treq_SOURCE_DIR}/config.cmake) list(APPEND CMAKE_MODULE_PATH "${sphinx_cmake_SOURCE_DIR}/cmake") +include(${CMAKE_CURRENT_LIST_DIR}/cmake/lint.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/cmake/testbench.cmake) # Include subdirectories diff --git a/cmake/lint.cmake b/cmake/lint.cmake new file mode 100644 index 0000000..d7436d5 --- /dev/null +++ b/cmake/lint.cmake @@ -0,0 +1,51 @@ +# __ _ +# ________/ / ___ _(_)__ ___ +# / __/ __/ _ \/ _ `/ / _ \/ -_) +# \__/\__/_//_/\_,_/_/_//_/\__/ +# +# Copyright (C) Clément Chain +# This file is part of ECAP5-DTESTLIB +# +# ECAP5-DTESTLIB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ECAP5-DTESTLIB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ECAP5-DTESTLIB. If not, see . + +set(DEFAULT_RULE_FILE ${CMAKE_CURRENT_LIST_DIR}/../config/default-verible-lint.rules) +set(DEFAULT_WAIVE_FILE ${CMAKE_CURRENT_LIST_DIR}/../config/default-verible-lint.waives) + +function(add_lint_target) + cmake_parse_arguments(ARG "" + "TARGET;CUSTOM_RULE_FILE;CUSTOM_WAIVE_FILE" + "SRC_DIRS" + ${ARGN}) + if (NOT ARG_TARGET) + message(FATAL_ERROR "Need a target name") + endif() + + if (NOT ARG_SRC_DIRS) + message(FATAL_ERROR "Need a source directory") + endif() + + if (NOT CUSTOM_RULE_FILE) + set(CUSTOM_RULE_FILE ${DEFAULT_RULE_FILE}) + endif() + + if (NOT CUSTOM_WAIVE_FILE) + set(CUSTOM_WAIVE_FILE ${DEFAULT_WAIVE_FILE}) + endif() + + file(GLOB SRC_FILES ${ARG_SRC_DIRS}/*.sv) + add_custom_target(${ARG_TARGET} + COMMAND verible-verilog-lint ${SRC_FILES} --rules_config="${CUSTOM_RULE_FILE}" --waiver_files="${CUSTOM_WAIVE_FILE}" + DEPENDS ${SRC_FILES} ${CUSTOM_RULE_FILE} ${CUSTOM_WAIVE_FILE}) +endfunction() + diff --git a/cmake/testbench.cmake b/cmake/testbench.cmake new file mode 100644 index 0000000..db9ae5f --- /dev/null +++ b/cmake/testbench.cmake @@ -0,0 +1,84 @@ +# __ _ +# ________/ / ___ _(_)__ ___ +# / __/ __/ _ \/ _ `/ / _ \/ -_) +# \__/\__/_//_/\_,_/_/_//_/\__/ +# +# Copyright (C) Clément Chain +# This file is part of ECAP5-DTESTLIB +# +# ECAP5-DTESTLIB is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# ECAP5-DTESTLIB is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ECAP5-DTESTLIB. If not, see . + +macro(add_testbench) + cmake_parse_arguments(ARG "" + "MODULE;BENCH_DIR;LIBS_DIR;BENCH;TESTDATA_DIR" + "SRC_DIRS;LIBS;CUSTOM_DEPENDS" + ${ARGN}) + if(NOT ARG_BENCH_DIR) + message(FATAL_ERROR "Need a bench directory") + endif() + + if(NOT ARG_MODULE) + message(FATAL_ERROR "Need a module name") + endif() + + if(NOT ARG_TESTDATA_DIR) + message(FATAL_ERROR "Need a testdata directory") + endif() + + if(NOT ARG_SRC_DIRS) + message(FATAL_ERROR "Need at least one source directory") + endif() + + # Create folders for the waves and testdata + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/waves) + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/testdata) + + if("${ARG_BENCH}" STREQUAL "") + set(ARG_BENCH ${ARG_MODULE}) + endif() + set(TARGET tb_${ARG_BENCH}) + + # Make a file list for testing libraries + list(TRANSFORM ARG_LIBS APPEND ".sv") + list(TRANSFORM ARG_LIBS PREPEND ${ARG_LIBS_DIR}) + + # Create the test executable + add_executable(${TARGET} ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.cpp) + target_include_directories(${TARGET} PUBLIC ${TEST_INCLUDE_DIR}) + verilate(${TARGET} + PREFIX V${TARGET} + SOURCES ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.sv + ${ARG_LIBS} + INCLUDE_DIRS ${ARG_SRC_DIRS} + TRACE) + + set(TEST_TARGET simulate_${ARG_BENCH}) + set(TEST_OUTPUT ${ARG_TESTDATA_DIR}/${ARG_BENCH}.csv) + # Create the ${TEST_TARGET} command to run the test + get_target_property(BINARY_DIR "${TARGET}" BINARY_DIR) + if(${DEBUGLOG}) + set(RUN_TARGET_ARGUMENT "-v") + endif() + add_custom_command( + COMMAND ${TARGET} ${RUN_TARGET_ARGUMENT} + OUTPUT ${TEST_OUTPUT} + DEPENDS ${TARGET} + WORKING_DIRECTORY ${CMAKE_PROJECT_DIR}) + add_custom_target(${TEST_TARGET} DEPENDS ${TEST_OUTPUT}) + # Add the ${TEST_TARGET} target to the test targets + list(APPEND TEST_BINARIES ${TARGET}) + list(APPEND TEST_TARGETS ${TEST_TARGET}) + list(APPEND TEST_OUTPUTS ${TEST_OUTPUT}) +endmacro() + diff --git a/config/verible-lint.rules b/config/default-verible-lint.rules similarity index 100% rename from config/verible-lint.rules rename to config/default-verible-lint.rules diff --git a/config/verible-lint.waives b/config/default-verible-lint.waives similarity index 100% rename from config/verible-lint.waives rename to config/default-verible-lint.waives diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9fb26ad..45895dd 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -19,75 +19,31 @@ # You should have received a copy of the GNU General Public License # along with ECAP5-DTESTLIB. If not, see . +# Bench parent directory set(BENCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}/benches/) +# C++ bench include directory set(TEST_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include/) -set(SRC_DIR ${CMAKE_SOURCE_DIR}/src/) -set(INCLUDE_DIR ${SRC_DIR}/include/) +# HDL source directories +set(SRC_DIRS ${CMAKE_SOURCE_DIR}/src/) +# HDL library directories set(LIBS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/) +# Bench CSV output directory set(TESTDATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/testdata/) -set(CONFIG_DIR ${CMAKE_SOURCE_DIR}/config/) - -# Create folders for the waves and testdata -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/waves) -file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/testdata) # Lint -file(GLOB SRC_FILES ${SRC_DIR}/*.sv) -file(GLOB INCLUDE_FILES ${INCLUDE_DIR}/*.svh) -add_custom_target(lint - COMMAND verible-verilog-lint ${SRC_FILES} ${INCLUDE_FILES} --rules_config="${CONFIG_DIR}/verible-lint.rules" --waiver_files="${CONFIG_DIR}/verible-lint.waives" - DEPENDS ${SRC_FILES} ${INCLUDE_FILES}) - -# Testbench -set(TEST_BINARIES) -set(TEST_TARGETS) -set(TEST_OUTPUTS) -macro(add_testbench module) - cmake_parse_arguments(ARG "" - "BENCH" - "LIBS" - ${ARGN}) - - if("${ARG_BENCH}" STREQUAL "") - set(ARG_BENCH ${module}) - endif() - set(TARGET tb_${ARG_BENCH}) - - # Make a file list for testing libraries - list(TRANSFORM ARG_LIBS APPEND ".sv") - list(TRANSFORM ARG_LIBS PREPEND ${LIBS_DIR}) - - # Create the test executable - add_executable(${TARGET} ${BENCH_DIR}/${module}/${TARGET}.cpp) - target_include_directories(${TARGET} PUBLIC ${TEST_INCLUDE_DIR}) - verilate(${TARGET} - PREFIX V${TARGET} - SOURCES ${SV_HEADERS} - ${BENCH_DIR}/${module}/${TARGET}.sv - ${ARG_LIBS} - INCLUDE_DIRS ${SRC_DIR} - TRACE) - - set(TEST_TARGET simulate_${ARG_BENCH}) - set(TEST_OUTPUT ${TESTDATA_DIR}/${ARG_BENCH}.csv) - # Create the ${TEST_TARGET} command to run the test - get_target_property(BINARY_DIR "${TARGET}" BINARY_DIR) - if(${DEBUGLOG}) - set(RUN_TARGET_ARGUMENT "-v") - endif() - add_custom_command( - COMMAND ${TARGET} ${RUN_TARGET_ARGUMENT} - OUTPUT ${TEST_OUTPUT} - DEPENDS ${TARGET} - WORKING_DIRECTORY ${CMAKE_PROJECT_DIR}) - add_custom_target(${TEST_TARGET} DEPENDS ${TEST_OUTPUT}) - # Add the ${TEST_TARGET} target to the test targets - list(APPEND TEST_BINARIES ${TARGET}) - list(APPEND TEST_TARGETS ${TEST_TARGET}) - list(APPEND TEST_OUTPUTS ${TEST_OUTPUT}) -endmacro() - -add_testbench(instr_wb_slave) +add_lint_target( + TARGET lint + SRC_DIRS ${SRC_DIRS} +) + +# Add testbenches +add_testbench( + MODULE instr_wb_slave + BENCH_DIR ${BENCH_DIR} + LIBS_DIR ${LIBS_DIR} + TESTDATA_DIR ${TESTDATA_DIR} + SRC_DIRS ${SRC_DIRS} +) # Main targets add_custom_target(build DEPENDS ${TEST_BINARIES}) From 81b52448570f0f1f52b2a88857650e25c399d02f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Sun, 23 Nov 2025 10:08:27 +0100 Subject: [PATCH 02/10] Fix issue in CI build --- .github/workflows/ci-config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-config.yml b/.github/workflows/ci-config.yml index cb2f09e..37bd732 100644 --- a/.github/workflows/ci-config.yml +++ b/.github/workflows/ci-config.yml @@ -115,7 +115,7 @@ jobs: report: runs-on: self-hosted - needs: bitstream + needs: simulate if: always() steps: From 66dc6e597ad26250780a15203073755771773d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Sun, 23 Nov 2025 10:12:37 +0100 Subject: [PATCH 03/10] Add support for test bench clock frequency configuration --- include/testbench.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/testbench.h b/include/testbench.h index a8096ed..8483f9d 100644 --- a/include/testbench.h +++ b/include/testbench.h @@ -50,12 +50,15 @@ template class Testbench { int * err_cycles; int cycle; + int clk_period_in_ps; + Testbench() { this->tickcount = 0; this->core = new Module; this->success = true; this->testdata_path = NULL; this->debug_log = false; + this->clk_period_in_ps = 10; this->conditions = NULL; this->err_cycles = NULL; @@ -106,13 +109,13 @@ template class Testbench { core->clk_i = 1; core->eval(); if(this->trace) { - this->trace->dump(10 * this->tickcount + 1); + this->trace->dump(this->clk_period_in_ps * this->tickcount + 1); } core->clk_i = 0; core->eval(); if(this->trace) { - this->trace->dump(10 * this->tickcount + 5); + this->trace->dump(this->clk_period_in_ps * this->tickcount + 5); this->trace->flush(); } @@ -122,7 +125,7 @@ template class Testbench { core->clk_i = 1; core->eval(); if(this->trace) { - this->trace->dump(10 * this->tickcount); + this->trace->dump(this->clk_period_in_ps * this->tickcount); } } From 313cb90715e0b1933389779e504f4b5b523bc72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Sun, 23 Nov 2025 10:37:34 +0100 Subject: [PATCH 04/10] Fix wrong clock handling --- include/testbench.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/testbench.h b/include/testbench.h index 8483f9d..aaf06ec 100644 --- a/include/testbench.h +++ b/include/testbench.h @@ -50,7 +50,7 @@ template class Testbench { int * err_cycles; int cycle; - int clk_period_in_ps; + uint64_t clk_period_in_ps; Testbench() { this->tickcount = 0; @@ -109,13 +109,13 @@ template class Testbench { core->clk_i = 1; core->eval(); if(this->trace) { - this->trace->dump(this->clk_period_in_ps * this->tickcount + 1); + this->trace->dump(this->clk_period_in_ps * this->tickcount + (this->clk_period_in_ps / 10)); } core->clk_i = 0; core->eval(); if(this->trace) { - this->trace->dump(this->clk_period_in_ps * this->tickcount + 5); + this->trace->dump(this->clk_period_in_ps * this->tickcount + (this->clk_period_in_ps / 2)); this->trace->flush(); } From ca80a950bca8f0d4bf1b451472988f46690b94d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Sun, 23 Nov 2025 23:51:31 +0100 Subject: [PATCH 05/10] Add support for include directories --- cmake/testbench.cmake | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cmake/testbench.cmake b/cmake/testbench.cmake index db9ae5f..22e628e 100644 --- a/cmake/testbench.cmake +++ b/cmake/testbench.cmake @@ -22,7 +22,7 @@ macro(add_testbench) cmake_parse_arguments(ARG "" "MODULE;BENCH_DIR;LIBS_DIR;BENCH;TESTDATA_DIR" - "SRC_DIRS;LIBS;CUSTOM_DEPENDS" + "SRC_DIRS;INCLUDE_DIRS;LIBS;CUSTOM_DEPENDS" ${ARGN}) if(NOT ARG_BENCH_DIR) message(FATAL_ERROR "Need a bench directory") @@ -41,8 +41,8 @@ macro(add_testbench) endif() # Create folders for the waves and testdata - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/waves) - file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/testdata) + file(MAKE_DIRECTORY ${TESTDATA_DIR}/waves) + file(MAKE_DIRECTORY ${TESTDATA_DIR}/testdata) if("${ARG_BENCH}" STREQUAL "") set(ARG_BENCH ${ARG_MODULE}) @@ -53,12 +53,16 @@ macro(add_testbench) list(TRANSFORM ARG_LIBS APPEND ".sv") list(TRANSFORM ARG_LIBS PREPEND ${ARG_LIBS_DIR}) + # List include files + file(GLOB INCLUDE_FILES ${ARG_INCLUDE_DIRS}/*.svh) + # Create the test executable add_executable(${TARGET} ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.cpp) target_include_directories(${TARGET} PUBLIC ${TEST_INCLUDE_DIR}) verilate(${TARGET} PREFIX V${TARGET} - SOURCES ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.sv + SOURCES ${INCLUDE_FILES} + ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.sv ${ARG_LIBS} INCLUDE_DIRS ${ARG_SRC_DIRS} TRACE) @@ -74,7 +78,7 @@ macro(add_testbench) COMMAND ${TARGET} ${RUN_TARGET_ARGUMENT} OUTPUT ${TEST_OUTPUT} DEPENDS ${TARGET} - WORKING_DIRECTORY ${CMAKE_PROJECT_DIR}) + WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/tests/) add_custom_target(${TEST_TARGET} DEPENDS ${TEST_OUTPUT}) # Add the ${TEST_TARGET} target to the test targets list(APPEND TEST_BINARIES ${TARGET}) From 6f58a9772d2bc1fdb803e62c44db48615ba5a800 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Wed, 26 Nov 2025 17:47:13 +0100 Subject: [PATCH 06/10] Use cmake interface libraries --- CMakeLists.txt | 43 ++++++++++++++++++++------------- cmake/dependency.cmake | 54 +++++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 53d0913..1669b03 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,7 +19,7 @@ # You should have received a copy of the GNU General Public License # along with ECAP5-DTESTLIB. If not, see . -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.21) include(FetchContent) project(ECAP5_DTESTLIB VERSION 1.0.0) @@ -44,29 +44,38 @@ find_package(Python3 COMPONENTS Interpreter Development) message(STATUS "Collecting dependencies") include(${CMAKE_CURRENT_LIST_DIR}/cmake/dependency.cmake) -add_dependency(ECAP5_TREQ - GIT ecap5/ecap5-treq - TAG tags/v2.2.0 - BINARY ecap5-treq) - -add_dependency(sphinx-cmake +add_dependency( GIT ecap5/sphinx-cmake TAG tags/v1.0.1) -add_dependency(verilator-cmake +add_dependency( GIT ecap5/verilator-cmake TAG tags/v1.0.1) -# Configure dependencies +add_dependency( + GIT ecap5/ecap5-treq + TAG 109-use-cmake-interface-libraries + BINARY ecap5-treq) + +# Define an interface library -include(${verilator_cmake_SOURCE_DIR}/cmake/verilator-config.cmake) -include(${ecap5_treq_SOURCE_DIR}/config.cmake) -list(APPEND CMAKE_MODULE_PATH "${sphinx_cmake_SOURCE_DIR}/cmake") -include(${CMAKE_CURRENT_LIST_DIR}/cmake/lint.cmake) -include(${CMAKE_CURRENT_LIST_DIR}/cmake/testbench.cmake) +add_library(ecap5_dtestlib INTERFACE) +target_sources(ecap5_dtestlib INTERFACE + ${CMAKE_CURRENT_LIST_DIR}/src/instr_wb_slave.sv +) -# Include subdirectories +# Only perform if the project will be tested +if(PROJECT_IS_TOP_LEVEL) + # Configure dependencies + list(APPEND CMAKE_MODULE_PATH "${ecap5_sphinx_cmake_SOURCE_DIR}/cmake") + include(${ecap5_verilator_cmake_SOURCE_DIR}/cmake/verilator-config.cmake) + include(${ecap5_ecap5_treq_SOURCE_DIR}/config.cmake) -add_subdirectory(docs) -add_subdirectory(tests) + # Include local cmake configuration files + include(${CMAKE_CURRENT_LIST_DIR}/cmake/lint.cmake) + include(${CMAKE_CURRENT_LIST_DIR}/cmake/testbench.cmake) + # Include subdirectories + add_subdirectory(docs) + add_subdirectory(tests) +endif() diff --git a/cmake/dependency.cmake b/cmake/dependency.cmake index c82ee15..7553f2b 100644 --- a/cmake/dependency.cmake +++ b/cmake/dependency.cmake @@ -1,26 +1,48 @@ -macro(add_dependency id) +macro(add_dependency) cmake_parse_arguments(ARG "" "GIT;TAG;BINARY" "" ${ARGN}) - string(MAKE_C_IDENTIFIER "${id}" name) - string(TOLOWER "${name}" name) + set(REPOSITORY_URL https://github.com/${ARG_GIT}) - FetchContent_Declare(${name} - GIT_REPOSITORY https://github.com/${ARG_GIT} - GIT_TAG ${ARG_TAG} - SOURCE_SUBDIR __none__ - ) - FetchContent_MakeAvailable(${name}) + # Create a unique identifier for the dependency + string(MAKE_C_IDENTIFIER "${ARG_GIT}" DEPENDENCY_ID) + string(TOLOWER "${DEPENDENCY_ID}" DEPENDENCY_ID) - if(NOT DEFINED ${name}_EXECUTABLE) - if(EXISTS "${${name}_SOURCE_DIR}/pyproject.toml") - message(STATUS "Configuring ${name}") - execute_process(COMMAND ${Python3_EXECUTABLE} -m pip install -e ${${name}_SOURCE_DIR} OUTPUT_QUIET RESULT_VARIABLE rv) - if("${rv}" STREQUAL "0") - set(${name}_EXECUTABLE ${VENV_DIR}/bin/${ARG_BINARY} CACHE STRING "path to the ${name} executable") + message("${DEPENDENCY_ID} ${${DEPENDENCY_ID}_VERSION}") + + # Check if the dependency is already present + if(DEFINED ${DEPENDENCY_ID}_VERSION) + # Check that the version is the same + if(NOT ${DEPENDENCY_ID}_VERSION STREQUAL ARG_TAG) + message(FATAL_ERROR "Dependency ${DEPENDENCY_ID} version mismatched : ${${DEPENDENCY_ID}_VERSION} != ${ARG_TAG}") + endif() + else() + # Define the version + set(${DEPENDENCY_ID}_VERSION ${ARG_TAG}) + + # Fetch the repository + FetchContent_Declare(${DEPENDENCY_ID} + GIT_REPOSITORY ${REPOSITORY_URL} + GIT_TAG ${ARG_TAG} + SOURCE_SUBDIR __none__ + ) + FetchContent_MakeAvailable(${DEPENDENCY_ID}) + + # Add cmake build if it exists + if(EXISTS "${${DEPENDENCY_ID}_SOURCE_DIR}/CMakeLists.txt") + add_subdirectory(${${DEPENDENCY_ID}_SOURCE_DIR} ${${DEPENDENCY_ID}_SOURCE_DIR}../${DEPENDENCY_ID}-build) + endif() + + # Handle python executable if it exists + if(NOT DEFINED ${DEPENDENCY_ID}_EXECUTABLE) + if(EXISTS "${${DEPENDENCY_ID}_SOURCE_DIR}/pyproject.toml") + message(STATUS "Configuring ${DEPENDENCY_ID}") + execute_process(COMMAND ${Python3_EXECUTABLE} -m pip install -e ${${DEPENDENCY_ID}_SOURCE_DIR} OUTPUT_QUIET RESULT_VARIABLE rv) + if("${rv}" STREQUAL "0") + set(${DEPENDENCY_ID}_EXECUTABLE ${VENV_DIR}/bin/${ARG_BINARY} CACHE STRING "path to the ${DEPENDENCY_ID} executable") + endif() endif() endif() endif() - endmacro() From 448a105a28f85bb23ad90435c0c1389230668ed0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Wed, 26 Nov 2025 18:24:40 +0100 Subject: [PATCH 07/10] Update lint script --- cmake/lint.cmake | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/cmake/lint.cmake b/cmake/lint.cmake index d7436d5..91e0e24 100644 --- a/cmake/lint.cmake +++ b/cmake/lint.cmake @@ -24,15 +24,19 @@ set(DEFAULT_WAIVE_FILE ${CMAKE_CURRENT_LIST_DIR}/../config/default-verible-lint. function(add_lint_target) cmake_parse_arguments(ARG "" - "TARGET;CUSTOM_RULE_FILE;CUSTOM_WAIVE_FILE" - "SRC_DIRS" + "LIB;TARGET;CUSTOM_RULE_FILE;CUSTOM_WAIVE_FILE" + "" ${ARGN}) if (NOT ARG_TARGET) message(FATAL_ERROR "Need a target name") endif() - if (NOT ARG_SRC_DIRS) - message(FATAL_ERROR "Need a source directory") + if (NOT ARG_LIB) + message(FATAL_ERROR "Need an interface library") + endif() + + if (NOT TARGET ${ARG_LIB}) + message(FATAL_ERROR "Library ${ARG_LIB} not defined") endif() if (NOT CUSTOM_RULE_FILE) @@ -43,9 +47,9 @@ function(add_lint_target) set(CUSTOM_WAIVE_FILE ${DEFAULT_WAIVE_FILE}) endif() - file(GLOB SRC_FILES ${ARG_SRC_DIRS}/*.sv) add_custom_target(${ARG_TARGET} - COMMAND verible-verilog-lint ${SRC_FILES} --rules_config="${CUSTOM_RULE_FILE}" --waiver_files="${CUSTOM_WAIVE_FILE}" - DEPENDS ${SRC_FILES} ${CUSTOM_RULE_FILE} ${CUSTOM_WAIVE_FILE}) + COMMAND verible-verilog-lint $ --rules_config="${CUSTOM_RULE_FILE}" --waiver_files="${CUSTOM_WAIVE_FILE}" + DEPENDS ${SRC_FILES} ${CUSTOM_RULE_FILE} ${CUSTOM_WAIVE_FILE} + COMMAND_EXPAND_LISTS) endfunction() From b4cbeb4cd7ccfffc59db90efe91ab540c1ad9114 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Wed, 26 Nov 2025 18:31:40 +0100 Subject: [PATCH 08/10] Update the testbench script --- CMakeLists.txt | 6 +++-- cmake/dependency.cmake | 7 +++--- cmake/testbench.cmake | 56 +++++++++++++++++++++++++++++++----------- 3 files changed, 49 insertions(+), 20 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1669b03..6bfa310 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,6 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") # Create python virtual env -message(STATUS "Creating python venv") set(VENV_DIR ${CMAKE_BINARY_DIR}/venv) if(NOT EXISTS "${VENV_DIR}") find_package(Python3 COMPONENTS Interpreter) @@ -41,7 +40,6 @@ find_package(Python3 COMPONENTS Interpreter Development) # Dependencies -message(STATUS "Collecting dependencies") include(${CMAKE_CURRENT_LIST_DIR}/cmake/dependency.cmake) add_dependency( @@ -65,17 +63,21 @@ target_sources(ecap5_dtestlib INTERFACE ) # Only perform if the project will be tested + if(PROJECT_IS_TOP_LEVEL) # Configure dependencies + list(APPEND CMAKE_MODULE_PATH "${ecap5_sphinx_cmake_SOURCE_DIR}/cmake") include(${ecap5_verilator_cmake_SOURCE_DIR}/cmake/verilator-config.cmake) include(${ecap5_ecap5_treq_SOURCE_DIR}/config.cmake) # Include local cmake configuration files + include(${CMAKE_CURRENT_LIST_DIR}/cmake/lint.cmake) include(${CMAKE_CURRENT_LIST_DIR}/cmake/testbench.cmake) # Include subdirectories + add_subdirectory(docs) add_subdirectory(tests) endif() diff --git a/cmake/dependency.cmake b/cmake/dependency.cmake index 7553f2b..1d421b9 100644 --- a/cmake/dependency.cmake +++ b/cmake/dependency.cmake @@ -9,15 +9,15 @@ macro(add_dependency) string(MAKE_C_IDENTIFIER "${ARG_GIT}" DEPENDENCY_ID) string(TOLOWER "${DEPENDENCY_ID}" DEPENDENCY_ID) - message("${DEPENDENCY_ID} ${${DEPENDENCY_ID}_VERSION}") - # Check if the dependency is already present if(DEFINED ${DEPENDENCY_ID}_VERSION) # Check that the version is the same if(NOT ${DEPENDENCY_ID}_VERSION STREQUAL ARG_TAG) - message(FATAL_ERROR "Dependency ${DEPENDENCY_ID} version mismatched : ${${DEPENDENCY_ID}_VERSION} != ${ARG_TAG}") + message(FATAL_ERROR "Dependency ${DEPENDENCY_ID} version mismatched\n\t${${DEPENDENCY_ID}_VERSION} != ${ARG_TAG}") endif() else() + message(STATUS "Configuring ${DEPENDENCY_ID}") + # Define the version set(${DEPENDENCY_ID}_VERSION ${ARG_TAG}) @@ -37,7 +37,6 @@ macro(add_dependency) # Handle python executable if it exists if(NOT DEFINED ${DEPENDENCY_ID}_EXECUTABLE) if(EXISTS "${${DEPENDENCY_ID}_SOURCE_DIR}/pyproject.toml") - message(STATUS "Configuring ${DEPENDENCY_ID}") execute_process(COMMAND ${Python3_EXECUTABLE} -m pip install -e ${${DEPENDENCY_ID}_SOURCE_DIR} OUTPUT_QUIET RESULT_VARIABLE rv) if("${rv}" STREQUAL "0") set(${DEPENDENCY_ID}_EXECUTABLE ${VENV_DIR}/bin/${ARG_BINARY} CACHE STRING "path to the ${DEPENDENCY_ID} executable") diff --git a/cmake/testbench.cmake b/cmake/testbench.cmake index 22e628e..59757d0 100644 --- a/cmake/testbench.cmake +++ b/cmake/testbench.cmake @@ -19,10 +19,34 @@ # You should have received a copy of the GNU General Public License # along with ECAP5-DTESTLIB. If not, see . +function(get_all_sources_recursive TARGET_NAME OUTPUT_LIST) + set(CURRENT_FILES "") + + get_target_property(RAW_SOURCES ${TARGET_NAME} INTERFACE_SOURCES) + + if(RAW_SOURCES AND NOT "${RAW_SOURCES}" MATCHES "NOTFOUND") + list(APPEND CURRENT_FILES ${RAW_SOURCES}) + endif() + + get_target_property(RAW_LIBS ${TARGET_NAME} INTERFACE_LINK_LIBRARIES) + if(RAW_LIBS AND NOT "${RAW_LIBS}" MATCHES "NOTFOUND") + foreach(DEP ${RAW_LIBS}) + if(TARGET ${DEP}) + get_all_sources_recursive(${DEP} SUB_FILES_LIST) + list(APPEND CURRENT_FILES ${SUB_FILES_LIST}) + else() + message(FATAL_ERROR "Recursive dependency ${DEP} not found") + endif() + endforeach() + endif() + + set(${OUTPUT_LIST} ${CURRENT_FILES} PARENT_SCOPE) +endfunction() + macro(add_testbench) cmake_parse_arguments(ARG "" - "MODULE;BENCH_DIR;LIBS_DIR;BENCH;TESTDATA_DIR" - "SRC_DIRS;INCLUDE_DIRS;LIBS;CUSTOM_DEPENDS" + "MODULE;BENCH_DIR;BENCH;TESTDATA_DIR" + "LIBS;CUSTOM_DEPENDS" ${ARGN}) if(NOT ARG_BENCH_DIR) message(FATAL_ERROR "Need a bench directory") @@ -36,10 +60,16 @@ macro(add_testbench) message(FATAL_ERROR "Need a testdata directory") endif() - if(NOT ARG_SRC_DIRS) - message(FATAL_ERROR "Need at least one source directory") + if(NOT ARG_LIBS) + message(FATAL_ERROR "Need at least one source library") endif() + foreach(LIB ${ARG_LIBS}) + if(NOT TARGET ${LIB}) + message(FATAL_ERROR "Library ${LIB} not defined") + endif() + endforeach() + # Create folders for the waves and testdata file(MAKE_DIRECTORY ${TESTDATA_DIR}/waves) file(MAKE_DIRECTORY ${TESTDATA_DIR}/testdata) @@ -49,22 +79,20 @@ macro(add_testbench) endif() set(TARGET tb_${ARG_BENCH}) - # Make a file list for testing libraries - list(TRANSFORM ARG_LIBS APPEND ".sv") - list(TRANSFORM ARG_LIBS PREPEND ${ARG_LIBS_DIR}) + # Define a source collecting library + add_library(lib${TARGET} INTERFACE) + target_link_libraries(lib${TARGET} INTERFACE ${ARG_LIBS}) - # List include files - file(GLOB INCLUDE_FILES ${ARG_INCLUDE_DIRS}/*.svh) + get_all_sources_recursive(lib${TARGET} ${TARGET}_SOURCES) # Create the test executable add_executable(${TARGET} ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.cpp) target_include_directories(${TARGET} PUBLIC ${TEST_INCLUDE_DIR}) verilate(${TARGET} - PREFIX V${TARGET} - SOURCES ${INCLUDE_FILES} - ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.sv - ${ARG_LIBS} - INCLUDE_DIRS ${ARG_SRC_DIRS} + PREFIX V${TARGET} + TOP_MODULE ${TARGET} + SOURCES ${${TARGET}_SOURCES} + ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.sv TRACE) set(TEST_TARGET simulate_${ARG_BENCH}) From ac2564da937879758518f87d04ac476f869a6574 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Wed, 26 Nov 2025 22:28:01 +0100 Subject: [PATCH 09/10] Fix wrong scope for add_testbench input --- CMakeLists.txt | 2 +- cmake/dependency.cmake | 9 ++++++--- cmake/testbench.cmake | 8 ++++++-- tests/CMakeLists.txt | 20 ++++++++------------ 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bfa310..37d88d7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ cmake_minimum_required(VERSION 3.21) include(FetchContent) -project(ECAP5_DTESTLIB VERSION 1.0.0) +project(ECAP5_DTESTLIB) set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") set(CMAKE_PREFIX_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") diff --git a/cmake/dependency.cmake b/cmake/dependency.cmake index 1d421b9..5cd2456 100644 --- a/cmake/dependency.cmake +++ b/cmake/dependency.cmake @@ -9,8 +9,11 @@ macro(add_dependency) string(MAKE_C_IDENTIFIER "${ARG_GIT}" DEPENDENCY_ID) string(TOLOWER "${DEPENDENCY_ID}" DEPENDENCY_ID) + get_property(IS_DEPENDENCY_PRESENT GLOBAL PROPERTY ${DEPENDENCY_ID}_VERSION SET) + # Check if the dependency is already present - if(DEFINED ${DEPENDENCY_ID}_VERSION) + if(${IS_DEPENDENCY_PRESENT}) + get_property(${DEPENDENCY_ID}_VERSION GLOBAL PROPERTY ${DEPENDENCY_ID}_VERSION) # Check that the version is the same if(NOT ${DEPENDENCY_ID}_VERSION STREQUAL ARG_TAG) message(FATAL_ERROR "Dependency ${DEPENDENCY_ID} version mismatched\n\t${${DEPENDENCY_ID}_VERSION} != ${ARG_TAG}") @@ -19,7 +22,7 @@ macro(add_dependency) message(STATUS "Configuring ${DEPENDENCY_ID}") # Define the version - set(${DEPENDENCY_ID}_VERSION ${ARG_TAG}) + set_property(GLOBAL PROPERTY ${DEPENDENCY_ID}_VERSION ${ARG_TAG}) # Fetch the repository FetchContent_Declare(${DEPENDENCY_ID} @@ -31,7 +34,7 @@ macro(add_dependency) # Add cmake build if it exists if(EXISTS "${${DEPENDENCY_ID}_SOURCE_DIR}/CMakeLists.txt") - add_subdirectory(${${DEPENDENCY_ID}_SOURCE_DIR} ${${DEPENDENCY_ID}_SOURCE_DIR}../${DEPENDENCY_ID}-build) + add_subdirectory(${${DEPENDENCY_ID}_SOURCE_DIR} ${${DEPENDENCY_ID}_SOURCE_DIR}/../${DEPENDENCY_ID}-build) endif() # Handle python executable if it exists diff --git a/cmake/testbench.cmake b/cmake/testbench.cmake index 59757d0..715df29 100644 --- a/cmake/testbench.cmake +++ b/cmake/testbench.cmake @@ -40,13 +40,17 @@ function(get_all_sources_recursive TARGET_NAME OUTPUT_LIST) endforeach() endif() + if(CURRENT_FILES) + list(REMOVE_DUPLICATES CURRENT_FILES) + endif() + set(${OUTPUT_LIST} ${CURRENT_FILES} PARENT_SCOPE) endfunction() macro(add_testbench) cmake_parse_arguments(ARG "" "MODULE;BENCH_DIR;BENCH;TESTDATA_DIR" - "LIBS;CUSTOM_DEPENDS" + "LIBS;CUSTOM_DEPENDS;TEST_INCLUDE_DIRS" ${ARGN}) if(NOT ARG_BENCH_DIR) message(FATAL_ERROR "Need a bench directory") @@ -87,7 +91,7 @@ macro(add_testbench) # Create the test executable add_executable(${TARGET} ${ARG_BENCH_DIR}/${ARG_MODULE}/${TARGET}.cpp) - target_include_directories(${TARGET} PUBLIC ${TEST_INCLUDE_DIR}) + target_include_directories(${TARGET} PUBLIC ${ARG_TEST_INCLUDE_DIRS}) verilate(${TARGET} PREFIX V${TARGET} TOP_MODULE ${TARGET} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 45895dd..ab451a1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,27 +22,23 @@ # Bench parent directory set(BENCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}/benches/) # C++ bench include directory -set(TEST_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/include/) -# HDL source directories -set(SRC_DIRS ${CMAKE_SOURCE_DIR}/src/) -# HDL library directories -set(LIBS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libs/) +set(TEST_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/include/) # Bench CSV output directory -set(TESTDATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/testdata/) +set(TESTDATA_DIR ${CMAKE_CURRENT_BINARY_DIR}/) # Lint add_lint_target( TARGET lint - SRC_DIRS ${SRC_DIRS} + LIB ecap5_dtestlib ) # Add testbenches add_testbench( - MODULE instr_wb_slave - BENCH_DIR ${BENCH_DIR} - LIBS_DIR ${LIBS_DIR} - TESTDATA_DIR ${TESTDATA_DIR} - SRC_DIRS ${SRC_DIRS} + MODULE instr_wb_slave + LIBS ecap5_dtestlib + BENCH_DIR ${BENCH_DIR} + TESTDATA_DIR ${TESTDATA_DIR} + TEST_INCLUDE_DIRS ${TEST_INCLUDE_DIRS} ) # Main targets From 4637d4df09d3b75d31cc03f88de6b7758dc0e0bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Chaine?= Date: Thu, 27 Nov 2025 00:11:31 +0100 Subject: [PATCH 10/10] Update ci build --- .github/workflows/ci-config.yml | 6 +++++- cmake/dependency.cmake | 11 +++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci-config.yml b/.github/workflows/ci-config.yml index 37bd732..2a1dbe9 100644 --- a/.github/workflows/ci-config.yml +++ b/.github/workflows/ci-config.yml @@ -24,7 +24,11 @@ jobs: - uses: actions/checkout@v4.1.1 - name: Configure CMake - run: cmake -B ${{github.workspace}}/build -GNinja + run: cmake -B ${{github.workspace}}/build -GNinja -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} 2>&1 | tee ${{github.workspace}}/cmake.log + + - name: Check versions + if: github.event.pull_request.base.ref == 'main' + run: (! grep -e "Using .* with unreleased version" ${{github.workspace}}/cmake.log) - name: Cache build directory if: always() diff --git a/cmake/dependency.cmake b/cmake/dependency.cmake index 5cd2456..60e913a 100644 --- a/cmake/dependency.cmake +++ b/cmake/dependency.cmake @@ -16,14 +16,21 @@ macro(add_dependency) get_property(${DEPENDENCY_ID}_VERSION GLOBAL PROPERTY ${DEPENDENCY_ID}_VERSION) # Check that the version is the same if(NOT ${DEPENDENCY_ID}_VERSION STREQUAL ARG_TAG) - message(FATAL_ERROR "Dependency ${DEPENDENCY_ID} version mismatched\n\t${${DEPENDENCY_ID}_VERSION} != ${ARG_TAG}") + message(FATAL_ERROR "Dependency ${ARG_GIT} version mismatched\n\t${${DEPENDENCY_ID}_VERSION} != ${ARG_TAG}") endif() else() - message(STATUS "Configuring ${DEPENDENCY_ID}") + message(STATUS "Configuring ${ARG_GIT}") # Define the version set_property(GLOBAL PROPERTY ${DEPENDENCY_ID}_VERSION ${ARG_TAG}) + # Check if released version + if(CMAKE_BUILD_TYPE STREQUAL "Release") + if(NOT ${ARG_TAG} MATCHES "^tags/.*") + message(WARNING "Using ${ARG_GIT} with unreleased version ${ARG_TAG}") + endif() + endif() + # Fetch the repository FetchContent_Declare(${DEPENDENCY_ID} GIT_REPOSITORY ${REPOSITORY_URL}