Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/ci-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
51 changes: 31 additions & 20 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,15 @@
# You should have received a copy of the GNU General Public License
# along with ECAP5-DTESTLIB. If not, see <http://www.gnu.org/licenses/>.

cmake_minimum_required(VERSION 3.12)
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")

# 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)
Expand All @@ -41,32 +40,44 @@ find_package(Python3 COMPONENTS Interpreter Development)

# Dependencies

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

add_subdirectory(docs)
add_subdirectory(tests)
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()
67 changes: 49 additions & 18 deletions cmake/dependency.cmake
Original file line number Diff line number Diff line change
@@ -1,26 +1,57 @@
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)

FetchContent_Declare(${name}
GIT_REPOSITORY https://github.com/${ARG_GIT}
GIT_TAG ${ARG_TAG}
SOURCE_SUBDIR __none__
)
FetchContent_MakeAvailable(${name})

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")
set(REPOSITORY_URL https://github.com/${ARG_GIT})

# Create a unique identifier for the 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(${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 ${ARG_GIT} version mismatched\n\t${${DEPENDENCY_ID}_VERSION} != ${ARG_TAG}")
endif()
else()
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()
endif()

# 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")
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()
18 changes: 11 additions & 7 deletions cmake/lint.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 $<TARGET_PROPERTY:${ARG_LIB},INTERFACE_SOURCES> --rules_config="${CUSTOM_RULE_FILE}" --waiver_files="${CUSTOM_WAIVE_FILE}"
DEPENDS ${SRC_FILES} ${CUSTOM_RULE_FILE} ${CUSTOM_WAIVE_FILE}
COMMAND_EXPAND_LISTS)
endfunction()

62 changes: 47 additions & 15 deletions cmake/testbench.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,38 @@
# You should have received a copy of the GNU General Public License
# along with ECAP5-DTESTLIB. If not, see <http://www.gnu.org/licenses/>.

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()

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;LIBS_DIR;BENCH;TESTDATA_DIR"
"SRC_DIRS;INCLUDE_DIRS;LIBS;CUSTOM_DEPENDS"
"MODULE;BENCH_DIR;BENCH;TESTDATA_DIR"
"LIBS;CUSTOM_DEPENDS;TEST_INCLUDE_DIRS"
${ARGN})
if(NOT ARG_BENCH_DIR)
message(FATAL_ERROR "Need a bench directory")
Expand All @@ -36,10 +64,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)
Expand All @@ -49,22 +83,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})
target_include_directories(${TARGET} PUBLIC ${ARG_TEST_INCLUDE_DIRS})
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})
Expand Down
20 changes: 8 additions & 12 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading