Skip to content

Commit

Permalink
Add modelsim DPI support, improve modelsim support and add modelsim e… (
Browse files Browse the repository at this point in the history
  • Loading branch information
Risto97 authored Nov 25, 2024
1 parent c5371a6 commit 25c195b
Show file tree
Hide file tree
Showing 14 changed files with 278 additions and 99 deletions.
205 changes: 128 additions & 77 deletions cmake/sim/modelsim/modelsim.cmake
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
include_guard(GLOBAL)

function(modelsim_compile_lib IP_LIB)
cmake_parse_arguments(ARG "NO_DEPS" "OUTDIR;ARGS" "" ${ARGN})
# Check for any unrecognized arguments
function(modelsim IP_LIB)
cmake_parse_arguments(ARG "TARGET_PER_IP;QUIET" "TOP_MODULE;OUTDIR;ARGS" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}")
endif()

include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../hwip.cmake")

find_modelsim(REQUIRED)

alias_dereference(IP_LIB ${IP_LIB})
get_target_property(BINARY_DIR ${IP_LIB} BINARY_DIR)

Expand All @@ -17,12 +18,130 @@ function(modelsim_compile_lib IP_LIB)
set(LIBRARY work)
endif()

if(NOT ARG_TOP_MODULE)
get_target_property(IP_NAME ${IP_LIB} IP_NAME)
set(ARG_TOP_MODULE ${IP_NAME})
endif()

if(NOT ARG_OUTDIR)
set(OUTDIR ${BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION})
else()
set(OUTDIR ${ARG_OUTDIR})
endif()

if(ARG_QUIET)
set(ARG_QUIET QUIET)
endif()

unset(__lib_args)
unset(__comp_tgts)

get_ip_links(IPS_LIST ${IP_LIB})

# Get all DPI-C compiler libraies and add to list of libraries
foreach(ip ${IPS_LIST})
get_target_property(ip_type ${ip} TYPE)
if(ip_type STREQUAL "SHARED_LIBRARY" OR ip_type STREQUAL "STATIC_LIBRARY")
list(APPEND __lib_args -sv_lib $<TARGET_FILE_DIR:${ip}>/lib$<TARGET_FILE_BASE_NAME:${ip}>)
endif()
endforeach()

unset(__libdirs)
unset(__libnames)
if(ARG_TARGET_PER_IP) # In case TARGET_PER_IP is passed, a compile target is created per IP block
set(list_comp_libs ${IPS_LIST})
set(__no_deps_arg NO_DEPS)
else() # Else only create target for compiling top level IP
set(list_comp_libs ${IP_LIB})
unset(__no_deps_arg)
endif()

list(APPEND __lib_args -Ldir ${OUTDIR})
foreach(ip ${list_comp_libs})
get_target_property(ip_name ${ip} IP_NAME)
if(ip_name) # If IP_NAME IS set, its SoCMake's IP_LIBRARY
__modelsim_compile_lib(${ip} ${__no_deps_arg} OUTDIR ${OUTDIR} ${ARG_QUIET})
if(NOT ${MODELSIM_IP_LIB_NAME} IN_LIST __libnames)
list(APPEND __lib_args -L ${MODELSIM_IP_LIB_NAME})
list(APPEND __libnames ${MODELSIM_IP_LIB_NAME})
endif()
list(APPEND __comp_tgts ${ip}_modelsim_complib)
endif()
endforeach()

get_ip_compile_definitions(COMP_DEFS ${IP_LIB} VHDL SYSTEMVERILOG VERILOG)

foreach(def ${COMP_DEFS})
list(APPEND CMP_DEFS_ARG +${def})
endforeach()

set(__VSIM_CMD ${MODELSIM_HOME}/bin/vsim
${__lib_args}
${CMP_DEFS_ARG}
-c ${LIBRARY}.${ARG_TOP_MODULE}
-do "run -all\; quit"
$<$<BOOL:${ARG_QUIET}>:-quiet>
)
set(DESCRIPTION "Run ${CMAKE_CURRENT_FUNCTION} testbench compiled from ${IP_LIB}")
add_custom_target(
run_${IP_LIB}_${CMAKE_CURRENT_FUNCTION}
COMMAND ${__VSIM_CMD} -noautoldlibpath
DEPENDS ${__comp_tgts}
WORKING_DIRECTORY ${MODELSIM_IP_LIB_DIR}
COMMENT ${DESCRIPTION}
VERBATIM
)
set_property(TARGET run_${IP_LIB}_${CMAKE_CURRENT_FUNCTION} PROPERTY DESCRIPTION ${DESCRIPTION})

endfunction()


function(find_modelsim)
cmake_parse_arguments(ARG "REQUIRED" "" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}")
endif()

find_program(VSIM_EXEC vsim
HINTS ${MODELSIM_HOME}/*/ $ENV{MODELSIM_HOME}/*/
)

if(NOT VSIM_EXEC AND ARG_REQUIRED)
message(FATAL_ERROR "Modelsim was not found, please set MODELSIM_HOME, ENV{MODELSIM_HOME} or system PATH variable")
endif()

if(NOT MODELSIM_HOME)
cmake_path(GET VSIM_EXEC PARENT_PATH __modelsim_bindir)
cmake_path(GET __modelsim_bindir PARENT_PATH MODELSIM_HOME)
set(MODELSIM_HOME ${MODELSIM_HOME} CACHE PATH "Path to Modelsim installation")
mark_as_advanced(MODELSIM_HOME)
endif()

endfunction()

function(__modelsim_compile_lib IP_LIB)
cmake_parse_arguments(ARG "QUIET;NO_DEPS" "OUTDIR;ARGS" "" ${ARGN})
# Check for any unrecognized arguments
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}")
endif()

include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../hwip.cmake")

alias_dereference(IP_LIB ${IP_LIB})
get_target_property(BINARY_DIR ${IP_LIB} BINARY_DIR)

get_target_property(LIBRARY ${IP_LIB} LIBRARY)
if(NOT LIBRARY)
set(LIBRARY work)
endif()

if(NOT ARG_OUTDIR)
set(OUTDIR ${BINARY_DIR}/${IP_LIB}_modelsim)
else()
set(OUTDIR ${ARG_OUTDIR})
endif()

if(ARG_NO_DEPS)
set(ARG_NO_DEPS NO_DEPS)
else()
Expand All @@ -45,10 +164,11 @@ function(modelsim_compile_lib IP_LIB)
endforeach()

set(DESCRIPTION "Compile Verilog and SV files of ${IP_LIB} with modelsim vlog in library ${LIBRARY}")
set(__VLOG_CMD COMMAND vlog
set(__VLOG_CMD COMMAND ${MODELSIM_HOME}/bin/vlog
-nologo
-sv
-sv17compat
$<$<BOOL:${ARG_QUIET}>:-quiet>
${SV_ARG_INCDIRS}
${SV_CMP_DEFS_ARG}
${SV_SOURCES}
Expand All @@ -71,8 +191,9 @@ function(modelsim_compile_lib IP_LIB)
list(APPEND VHDL_CMP_DEFS_ARG +define+${def})
endforeach()

set(__VCOM_CMD COMMAND vcom
set(__VCOM_CMD COMMAND ${MODELSIM_HOME}/bin/vcom
-nologo
$<$<BOOL:${ARG_QUIET}>:-quiet>
${VHDL_ARG_INCDIRS}
${VHDL_CMP_DEFS_ARG}
${VHDL_SOURCES}
Expand All @@ -93,83 +214,13 @@ function(modelsim_compile_lib IP_LIB)
)

add_custom_target(
${IP_LIB}_${CMAKE_CURRENT_FUNCTION}
${IP_LIB}_modelsim_complib
DEPENDS ${STAMP_FILE} ${STAMP_FILE_VHDL} ${IP_LIB}
)
set_property(TARGET ${IP_LIB}_${CMAKE_CURRENT_FUNCTION} PROPERTY
set_property(TARGET ${IP_LIB}_modelsim_complib PROPERTY
DESCRIPTION "Compile VHDL, SV, and Verilog files for ${IP_LIB} with modelsim in library ${LIBRARY}")


set(MODELSIM_IP_LIB_DIR ${OUTDIR} PARENT_SCOPE)
set(MODELSIM_IP_LIB_NAME ${LIBRARY} PARENT_SCOPE)
endfunction()

function(modelsim IP_LIB)
# Parse the function arguments
cmake_parse_arguments(ARG "HIER_TARGETS" "TOP_MODULE;OUTDIR;ARGS" "" ${ARGN})
# Check for any unrecognized arguments
if(ARG_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "${CMAKE_CURRENT_FUNCTION} passed unrecognized argument " "${ARG_UNPARSED_ARGUMENTS}")
endif()

include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../hwip.cmake")

alias_dereference(IP_LIB ${IP_LIB})
get_target_property(BINARY_DIR ${IP_LIB} BINARY_DIR)

get_target_property(LIBRARY ${IP_LIB} LIBRARY)
if(NOT LIBRARY)
set(LIBRARY work)
endif()

if(NOT ARG_TOP_MODULE)
get_target_property(IP_NAME ${IP_LIB} IP_NAME)
set(ARG_TOP_MODULE ${IP_NAME})
endif()

if(NOT ARG_OUTDIR)
set(OUTDIR ${BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION})
else()
set(OUTDIR ${ARG_OUTDIR})
endif()

unset(LIB_ARGS)
unset(MODELSIM_COMP_TARGETS)
if(ARG_HIER_TARGETS)
get_ip_links(IPS_LIST ${IP_LIB})
foreach(ip ${IPS_LIST})
modelsim_compile_lib(${ip} NO_DEPS)
list(APPEND LIB_ARGS -Ldir ${MODELSIM_IP_LIB_DIR} -L ${MODELSIM_IP_LIB_NAME})
list(APPEND MODELSIM_COMP_TARGETS ${ip}_modelsim_compile_lib)
endforeach()
else()
modelsim_compile_lib(${IP_LIB})
list(APPEND LIB_ARGS -Ldir ${MODELSIM_IP_LIB_DIR} -L ${MODELSIM_IP_LIB_NAME})
list(APPEND MODELSIM_COMP_TARGETS ${IP_LIB}_modelsim_compile_lib)
endif()

get_ip_compile_definitions(COMP_DEFS ${IP_LIB} VHDL SYSTEMVERILOG VERILOG)

foreach(def ${COMP_DEFS})
list(APPEND CMP_DEFS_ARG +${def})
endforeach()

set(__VSIM_CMD vsim
${LIB_ARGS}
${CMP_DEFS_ARG}
-c ${LIBRARY}.${ARG_TOP_MODULE}
-do "run -all\; quit"

)
set(DESCRIPTION "Run ${CMAKE_CURRENT_FUNCTION} testbench compiled from ${IP_LIB}")
add_custom_target(
run_${IP_LIB}_${CMAKE_CURRENT_FUNCTION}
COMMAND ${__VSIM_CMD}
DEPENDS ${MODELSIM_COMP_TARGETS}
COMMENT ${DESCRIPTION}
VERBATIM
)
set_property(TARGET run_${IP_LIB}_${CMAKE_CURRENT_FUNCTION} PROPERTY DESCRIPTION ${DESCRIPTION})

endfunction()

21 changes: 0 additions & 21 deletions examples/modelsim/CMakeLists.txt

This file was deleted.

20 changes: 20 additions & 0 deletions examples/modelsim/dpi/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.25)
project(dpi_example NONE)

include("../../../SoCMakeConfig.cmake")

add_ip(tb
DESCRIPTION "Simple verilog testbench"
)

ip_sources(${IP} SYSTEMVERILOG
${PROJECT_SOURCE_DIR}/tb.sv
)

add_subdirectory(hello)

ip_link(${IP} hello_dpi)

modelsim(${IP})

help()
9 changes: 9 additions & 0 deletions examples/modelsim/dpi/hello/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cmake_minimum_required(VERSION 3.25)
project(hello_dpi CXX)

add_library(hello_dpi SHARED
./hello.cpp
)

target_compile_options(hello_dpi PRIVATE -m32)
target_link_options(hello_dpi PRIVATE -m32)
7 changes: 7 additions & 0 deletions examples/modelsim/dpi/hello/hello.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#include <cstdint>

extern "C" uint32_t hello(uint32_t data);
uint32_t hello(uint32_t data)
{
return data + 10;
}
9 changes: 9 additions & 0 deletions examples/modelsim/dpi/tb.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module tb;

import "DPI-C" function int unsigned hello(input int unsigned data);

initial begin
$display("From DPI-C 5 + 10 is: %d", hello(5));
$finish();
end
endmodule
23 changes: 23 additions & 0 deletions examples/modelsim/parallel/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
cmake_minimum_required(VERSION 3.25)
project(parallel_example NONE)

include("../../../SoCMakeConfig.cmake")

add_ip(tb
DESCRIPTION "Simple verilog testbench"
)

ip_sources(${IP} VERILOG
${PROJECT_SOURCE_DIR}/tb.v
)

add_subdirectory(printer)

foreach(cnt RANGE 0 32)
stupid_printer(${cnt})
ip_link(${IP} vendor::lib_${cnt}::printer_${cnt}::0.0.1)
endforeach()

modelsim(${IP} TARGET_PER_IP)

help()
14 changes: 14 additions & 0 deletions examples/modelsim/parallel/printer/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

function(stupid_printer NUM_TO_ADD)
add_ip(vendor::lib_${NUM_TO_ADD}::printer_${NUM_TO_ADD}::0.0.1
DESCRIPTION "A stupid module that prints ${NUM_TO_ADD}")

configure_file(
${CMAKE_CURRENT_FUNCTION_LIST_DIR}/printer.v.in
${CMAKE_BINARY_DIR}/printer_${NUM_TO_ADD}.v
@ONLY
)
ip_sources(${IP} VERILOG
${CMAKE_BINARY_DIR}/printer_${NUM_TO_ADD}.v
)
endfunction()
5 changes: 5 additions & 0 deletions examples/modelsim/parallel/printer/printer.v.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module printer_@NUM_TO_ADD@;
initial begin
$display("NUM IS: %d", @NUM_TO_ADD@);
end
endmodule
Loading

0 comments on commit 25c195b

Please sign in to comment.