cmake_minimum_required(VERSION 3.26) project(flow) set (CMAKE_CXX_STANDARD 17) cmake_policy(SET CMP0144 NEW) include(CMakeDependentOption) enable_testing() # -- Build options option(BUILD_USE_BLOOP "Whether to use bloop to spped up elaborate" ON) option(BUILD_SIM_TARGET "Whether to build verilator simulation binary" ON) cmake_dependent_option(BUILD_SIM_NVBOARD_TARGET "Whether to build nvboard target" OFF "BUILD_SIM_TARGET" OFF) option(ENABLE_YSYX_GIT_TRACKER "Ysyx tracker support" OFF) set(TOPMODULE "Flow" CACHE STRING "Topmodule name in chisel") # -- Ysyx tracker, configure if(ENABLE_YSYX_GIT_TRACKER) execute_process( COMMAND ${CMAKE_SOURCE_DIR}/../git_commit.sh "configure(npc)" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/.. ) endif() # -- Check dependencies if(BUILD_SIM_TARGET) find_package(verilator REQUIRED) endif() if(BUILD_SIM_NVBOARD_TARGET) find_package(SDL2 REQUIRED) find_package(SDL2_image REQUIRED) endif() find_package(CLI11 CONFIG REQUIRED) find_library(NVBOARD_LIBRARY NAMES nvboard) find_path(NVBOARD_INCLUDE_DIR NAMES nvboard.h) # FIXME: all scala source file are tracked here, cause all files to rebuild # after a source update. set(SCALA_CORE "${CMAKE_CURRENT_SOURCE_DIR}/core") set(CHISEL_MODULE_CLASS "${CMAKE_PROJECT_NAME}.${TOPMODULE}") # Verilog files are generted in CHISEL_OUTPUT_TMP_DIR and copy to # CHISEL_OUTPUT_DIR if content changes set(CHISEL_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TOPMODULE}/vsrc/) set(CHISEL_OUTPUT_TMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${TOPMODULE}/vsrc_tmp/) set(CHISEL_OUTPUT_VERILATOR_CONF ${CHISEL_OUTPUT_DIR}/conf.vlt) set(CHISEL_OUTPUT_TOPMODULE ${CHISEL_OUTPUT_DIR}/${TOPMODULE}.sv) set(CHISEL_EMIT_ARGS "--target-dir ${CHISEL_OUTPUT_TMP_DIR}") # -- Add an always run target to generate verilog files with sbt/bloop, # as we don't know if the result files will be different from cmake # NOTE: Must reconfigure if we add new files in SCALA_CORE directory file(GLOB_RECURSE SCALA_CORE_SOURCES "${SCALA_CORE}/src/main/scala/*.scala") file(GLOB_RECURSE SCALA_CORE_RESOURCES "${SCALA_CORE}/src/main/resource/*") set(CHISEL_DEPENDENCY ${SCALA_CORE_SOURCES} ${SCALA_CORE_RESOURCES} ${SCALA_CORE}/build.sbt) if(BUILD_USE_BLOOP) set(CHISEL_TARGET bloop_${TOPMODULE}) set(CHISEL_TEST_TARGET bloop_${TOPMODULE}_test) # Export sbt build config to bloop if(NOT EXISTS ${SCALA_CORE}/.bloop) execute_process( COMMAND sbt bloopInstall WORKING_DIRECTORY ${SCALA_CORE} ) endif() string(REPLACE " " ";" CHISEL_EMIT_ARGS_LIST ${CHISEL_EMIT_ARGS}) list(TRANSFORM CHISEL_EMIT_ARGS_LIST PREPEND "--args;") add_custom_command( OUTPUT ${CHISEL_OUTPUT_TOPMODULE} COMMAND bloop run root ${CHISEL_EMIT_ARGS_LIST} COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CHISEL_OUTPUT_TMP_DIR} ${CHISEL_OUTPUT_DIR} WORKING_DIRECTORY ${SCALA_CORE} DEPENDS ${CHISEL_DEPENDENCY} COMMAND_EXPAND_LISTS ) add_test( NAME bloop_${TOPMODULE}_test COMMAND bloop test WORKING_DIRECTORY ${SCALA_CORE} ) else() set(CHISEL_TARGET sbt_${TOPMODULE}) set(CHISEL_TEST_TARGET sbt_${TOPMODULE}_test) add_custom_command( OUTPUT ${CHISEL_OUTPUT_TOPMODULE} COMMAND sbt "run ${CHISEL_EMIT_ARGS}" COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different ${CHISEL_OUTPUT_TMP_DIR} ${CHISEL_OUTPUT_DIR} WORKING_DIRECTORY ${SCALA_CORE} DEPENDS ${CHISEL_DEPENDENCY} VERBATIM ) add_test( NAME sbt_${TOPMODULE}_test COMMAND sbt test WORKING_DIRECTORY ${SCALA_CORE} ) endif() if(NOT EXISTS ${CHISEL_OUTPUT_TOPMODULE}) # Probably cold build, generate verilog at configure time to produce top module file execute_process( COMMAND sbt "run ${CHISEL_EMIT_ARGS}" WORKING_DIRECTORY ${SCALA_CORE} ) execute_process( COMMAND ${CMAKE_COMMAND} -E copy_directory ${CHISEL_OUTPUT_TMP_DIR} ${CHISEL_OUTPUT_DIR} ) endif() # -- Build NVBoard executable if(BUILD_SIM_NVBOARD_TARGET) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TOPMODULE}/auto_bind.cpp COMMAND auto_pin_bind ${CMAKE_SOURCE_DIR}/constr/${TOPMODULE}.nxdc ${CMAKE_CURRENT_BINARY_DIR}/${TOPMODULE}/auto_bind.cpp DEPENDS ${CMAKE_SOURCE_DIR}/constr/${TOPMODULE}.nxdc ) file(GLOB_RECURSE SOURCES csrc_nvboard/${TOPMODULE}/*.cpp) add_executable(V${TOPMODULE}_nvboard ${SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/${TOPMODULE}/auto_bind.cpp) verilate(V${TOPMODULE}_nvboard TRACE THREADS TOP_MODULE ${TOPMODULE} PREFIX V${TOPMODULE} SOURCES ${CHISEL_OUTPUT_TOPMODULE} INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/${TOPMODULE}/vsrc) add_dependencies(V${TOPMODULE}_nvboard ChiselBuild_${TOPMODULE}) target_include_directories(V${TOPMODULE}_nvboard PRIVATE ${NVBOARD_INCLUDE_DIR} ${SDL2_INCLUDE_DIRS}) target_link_libraries(V${TOPMODULE}_nvboard PRIVATE ${NVBOARD_LIBRARY} SDL2::SDL2 SDL2_image::SDL2_image) install(TARGETS V${TOPMODULE}_nvboard) endif() # -- Build Verilator executable and add to test include_directories(include) file(GLOB_RECURSE SOURCES csrc/${TOPMODULE}/*.cpp) add_executable(V${TOPMODULE} ${SOURCES}) verilate(V${TOPMODULE} TRACE COVERAGE THREADS TOP_MODULE ${TOPMODULE} PREFIX V${TOPMODULE} SOURCES ${CHISEL_OUTPUT_TOPMODULE} ${CHISEL_OUTPUT_VERILATOR_CONF} INCLUDE_DIRS ${CMAKE_CURRENT_BINARY_DIR}/${TOPMODULE}/vsrc VERILATOR_ARGS "--vpi" # Enable VPI ) add_test(NAME V${TOPMODULE} COMMAND V${TOPMODULE}) # -- Add build tracking if(ENABLE_YSYX_GIT_TRACKER) add_custom_command( TARGET V${TOPMODULE}_nvboard PRE_BUILD COMMAND ${CMAKE_SOURCE_DIR}/../git_commit.sh "build_${CMAKE_PROJECT_NAME}_V${TOPMODULE}_nvboard" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/.. ) add_custom_command( TARGET V${TOPMODULE} PRE_BUILD COMMAND ${CMAKE_SOURCE_DIR}/../git_commit.sh "build_${CMAKE_PROJECT_NAME}_V${TOPMODULE}" WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/.. ) endif()