Skip to content

Commit

Permalink
Modelsim support (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
Risto97 authored Oct 23, 2024
1 parent 6fe25e0 commit 0489dcd
Show file tree
Hide file tree
Showing 6 changed files with 236 additions and 0 deletions.
3 changes: 3 additions & 0 deletions SoCMakeConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ include("${CMAKE_CURRENT_LIST_DIR}/cmake/sim/iverilog/iverilog.cmake")
# ----- xcelium ------
include("${CMAKE_CURRENT_LIST_DIR}/cmake/sim/cadence/xcelium.cmake")

# ----- modelsim ------
include("${CMAKE_CURRENT_LIST_DIR}/cmake/sim/modelsim/modelsim.cmake")

# ----- vcs ------
include("${CMAKE_CURRENT_LIST_DIR}/cmake/sim/synopsys/vcs.cmake")

Expand Down
175 changes: 175 additions & 0 deletions cmake/sim/modelsim/modelsim.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
include_guard(GLOBAL)

function(modelsim_compile_lib IP_LIB)
cmake_parse_arguments(ARG "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}_${CMAKE_CURRENT_FUNCTION})
else()
set(OUTDIR ${ARG_OUTDIR})
endif()

if(ARG_NO_DEPS)
set(ARG_NO_DEPS NO_DEPS)
else()
unset(ARG_NO_DEPS)
endif()

# SystemVerilog and Verilog files and arguments
unset(__VLOG_CMD)
get_ip_sources(SV_SOURCES ${IP_LIB} SYSTEMVERILOG VERILOG ${ARG_NO_DEPS} )
if(SV_SOURCES)
get_ip_include_directories(SV_INC_DIRS ${IP_LIB} SYSTEMVERILOG VERILOG)
get_ip_compile_definitions(SV_COMP_DEFS ${IP_LIB} SYSTEMVERILOG VERILOG)

foreach(dir ${SV_INC_DIRS})
list(APPEND SV_ARG_INCDIRS +incdir+${dir})
endforeach()

foreach(def ${SV_COMP_DEFS})
list(APPEND SV_CMP_DEFS_ARG +define+${def})
endforeach()

set(DESCRIPTION "Compile Verilog and SV files of ${IP_LIB} with modelsim vlog in library ${LIBRARY}")
set(__VLOG_CMD COMMAND vlog
-nologo
-sv
-sv17compat
${SV_ARG_INCDIRS}
${SV_CMP_DEFS_ARG}
${SV_SOURCES}
-work ${OUTDIR}/${LIBRARY}
)
endif()

# VHDL files and arguments
unset(__VCOM_CMD)
get_ip_sources(VHDL_SOURCES ${IP_LIB} VHDL ${ARG_NO_DEPS})
if(VHDL_SOURCES)
get_ip_include_directories(VHDL_INC_DIRS ${IP_LIB} VHDL)
get_ip_compile_definitions(VHDL_COMP_DEFS ${IP_LIB} VHDL)

foreach(dir ${VHDL_INC_DIRS})
list(APPEND VHDL_ARG_INCDIRS +incdir+${dir})
endforeach()

foreach(def ${VHDL_COMP_DEFS})
list(APPEND VHDL_CMP_DEFS_ARG +define+${def})
endforeach()

set(__VCOM_CMD COMMAND vcom
-nologo
${VHDL_ARG_INCDIRS}
${VHDL_CMP_DEFS_ARG}
${VHDL_SOURCES}
-work ${OUTDIR}/${LIBRARY}
)
endif()

set(DESCRIPTION "Compile VHDL, SV, and Verilog files for ${IP_LIB} with modelsim in library ${LIBRARY}")
set(STAMP_FILE "${BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION}.stamp")
add_custom_command(
OUTPUT ${STAMP_FILE} ${OUTDIR}/${LIBRARY}
COMMAND ${CMAKE_COMMAND} -E make_directory ${OUTDIR}
${__VLOG_CMD}
${__VCOM_CMD}
COMMAND touch ${STAMP_FILE}
DEPENDS ${SV_SOURCES} ${VHDL_SOURCES}
COMMENT ${DESCRIPTION}
)

add_custom_target(
${IP_LIB}_${CMAKE_CURRENT_FUNCTION}
DEPENDS ${STAMP_FILE} ${STAMP_FILE_VHDL} ${IP_LIB}
)
set_property(TARGET ${IP_LIB}_${CMAKE_CURRENT_FUNCTION} 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: 21 additions & 0 deletions examples/modelsim/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
cmake_minimum_required(VERSION 3.25)
project(example NONE)

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

add_ip(cern::ip::tb::0.0.1
DESCRIPTION "Simple verilog testbench"
)

ip_sources(${IP} VERILOG # Add source files to the VERILOG file set
${PROJECT_SOURCE_DIR}/tb.v
)

add_subdirectory(adder)

ip_link(${IP} vendor::lib::adder::0.0.1)

modelsim(${IP} HIER_TARGETS)

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

add_ip(vendor::lib::adder::0.0.1)

ip_sources(${IP} VHDL
${CMAKE_CURRENT_LIST_DIR}/adder.vhdl
)
16 changes: 16 additions & 0 deletions examples/modelsim/adder/adder.vhdl
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity adder is
Port ( NUM1 : in STD_LOGIC_VECTOR (4 downto 0) := "00000";
NUM2 : in STD_LOGIC_VECTOR (4 downto 0) := "00000";
SUM : out STD_LOGIC_VECTOR (4 downto 0));
end adder;

architecture Behavioral of adder is
begin

SUM <= NUM1 + NUM2;

end Behavioral;
15 changes: 15 additions & 0 deletions examples/modelsim/tb.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module tb;
initial begin
$display("Hello world, from SoCMake build system\n");
$finish();
end

wire [4:0] a, b, o;

adder adder_i (
.NUM1(a),
.NUM2(b),
.SUM(o)
);

endmodule

0 comments on commit 0489dcd

Please sign in to comment.