cmake_minimum_required(VERSION 3.29.6)
cmake_policy(SET CMP0074 NEW)

project(ISP CXX)

# Add Macro to get all subdir
MACRO(SUBDIRLIST result curdir)
  FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
  SET(dirlist "")
  FOREACH(child ${children})
    IF(IS_DIRECTORY ${curdir}/${child})
      LIST(APPEND dirlist ${curdir}/${child})
    ENDIF()
  ENDFOREACH()
  SET(${result} ${dirlist})
ENDMACRO()

# Set C++ Standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED true)

# Find Verilator
find_package(verilator HINTS $ENV{VERILATOR_ROOT} ${VERILATOR_ROOT})
if(NOT verilator_FOUND)
  message(
        FATAL_ERROR
        "Verilator was not found. Either install it, or set the VERILATOR_ROOT environment variable"
    )
endif()

# SystemC dependencies
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

# Find SystemC using SystemC's CMake integration
find_package(SystemCLanguage QUIET)

# Create software image process library
# file(GLOB_RECURSE IMG_SRC ${PROJECT_SOURCE_DIR}/src/img_process/*.cpp)
# add_library(img_process STATIC ${IMG_SRC})

# ----------------------  EXE  ---------------------------
#                         VISP
# ----------------------  EXE  ---------------------------
add_executable(Visp ${PROJECT_SOURCE_DIR}/src/sc_main.cpp)
target_compile_definitions(Visp
  PRIVATE INPUT_IMG="${PROJECT_SOURCE_DIR}/src/transform/test.bin"
  PRIVATE OUTPUT_DIR="${PROJECT_SOURCE_DIR}/logs/"
)
target_include_directories(Visp PRIVATE ${PROJECT_SOURCE_DIR}/src/img_process)
# target_link_libraries(Visp PRIVATE img_process)

# Get RTL source code dir
SUBDIRLIST(RTL_SUBDIR ${PROJECT_SOURCE_DIR}/rtl)
# Add the Verilated circuit to the target
verilate(Visp SYSTEMC COVERAGE TRACE
  INCLUDE_DIRS ${RTL_SUBDIR}
  VERILATOR_ARGS +librescan +libext+.v+.sv+.vh+.svh -y . -x-assign fast
  SOURCES ${PROJECT_SOURCE_DIR}/rtl/isp.sv
  TOP_MODULE isp
)

# SystemC Link
verilator_link_systemc(Visp)

# ----------------------  EXE  ---------------------------
#                    VISP_Pipeline
# ----------------------  EXE  ---------------------------
add_executable(Visp_Pipeline ${PROJECT_SOURCE_DIR}/src/sc_main_pipeline.cpp)
target_compile_definitions(Visp_Pipeline
  PRIVATE INPUT_IMG="${PROJECT_SOURCE_DIR}/src/transform/test.bin"
  PRIVATE OUTPUT_DIR="${PROJECT_SOURCE_DIR}/logs/"
)
target_include_directories(Visp_Pipeline PRIVATE ${PROJECT_SOURCE_DIR}/src/img_process)
# target_link_libraries(Visp_Pipeline PRIVATE img_process)

# Get RTL source code dir
SUBDIRLIST(RTL_SUBDIR ${PROJECT_SOURCE_DIR}/rtl)
# Add the Verilated circuit to the target
verilate(Visp_Pipeline SYSTEMC COVERAGE TRACE
  INCLUDE_DIRS ${RTL_SUBDIR}
  VERILATOR_ARGS +librescan +libext+.v+.sv+.vh+.svh -y . -x-assign fast -Wno-WIDTHEXPAND
  SOURCES ${PROJECT_SOURCE_DIR}/rtl/isp_Pipeline.sv
  TOP_MODULE isp_Pipeline
)

# SystemC Link
verilator_link_systemc(Visp_Pipeline)