Skip to content

Commit

Permalink
copy_rtl function update (#96)
Browse files Browse the repository at this point in the history
Co-authored-by: Benoit Denkinger <[email protected]>
  • Loading branch information
benoitdenkinger and Benoit Denkinger authored Oct 28, 2024
1 parent 4a41390 commit f966713
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 109 deletions.
2 changes: 2 additions & 0 deletions SoCMakeConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/graphviz.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/multi_option.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/find_python.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/copy_rtl_files/copy_rtl_files.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/copy_rtl_files/read_rtl_sources.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/print_list.cmake")
include("${CMAKE_CURRENT_LIST_DIR}/cmake/utils/uniquify_files_by_basename.cmake")

# ====================================
# ======== Simulation ================
Expand Down
11 changes: 2 additions & 9 deletions cmake/fpga/vivado/vivado.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,6 @@ function(vivado IP_LIB)
set(TOP ${ARG_TOP})
endif()

foreach(vdef ${ARG_VERILOG_DEFINES})
string(REPLACE "=" ";" vdef_l ${vdef})
endforeach()

# get_ip_sources(XDC_FILES ${IP_LIB} XDC)
get_target_property(XDC_FILES ${IP_LIB} XDC)
get_target_property(FPGA_PART ${IP_LIB} FPGA_PART)
Expand All @@ -44,10 +40,7 @@ function(vivado IP_LIB)

get_ip_compile_definitions(COMP_DEFS_SV ${IP_LIB} SYSTEMVERILOG)
get_ip_compile_definitions(COMP_DEFS_V ${IP_LIB} VERILOG) # TODO Add VHDL??
set(COMP_DEFS ${COMP_DEFS_SV} ${COMP_DEFS_V})
foreach(def ${COMP_DEFS})
list(APPEND CMP_DEFS_ARG -D${def})
endforeach()
set(CMP_DEFS_ARG ${COMP_DEFS_SV} ${COMP_DEFS_V} ${ARG_VERILOG_DEFINES})

set(BITSTREAM ${OUTDIR}/${IP_LIB}.bit)
set_source_files_properties(${BITSTREAM} PROPERTIES GENERATED TRUE)
Expand All @@ -63,7 +56,7 @@ function(vivado IP_LIB)
--name ${IP_LIB}
--top ${TOP}
--outdir ${OUTDIR}
--verilog-defs ${ARG_VERILOG_DEFINES} ${CMP_DEFS_ARG}
--verilog-defs ${CMP_DEFS_ARG}

COMMAND /bin/sh -c date > ${STAMP_FILE}
DEPENDS ${SOURCES} ${XDC_FILES} ${IP_LIB}
Expand Down
114 changes: 34 additions & 80 deletions cmake/sim/cadence/xcelium.cmake
Original file line number Diff line number Diff line change
@@ -1,93 +1,34 @@
#[[[ @module xcelium
#]]

#[[[
# Create a target for invoking Xcelium simulation on IP_LIB.
#
# It will create a target **run_<IP_LIB>_xcelium** that will compile, elaborate and run the xcelium simulation
#
# :param IP_LIB: RTL interface library, it needs to have SOURCES property set with a list of System Verilog files.
# :type IP_LIB: INTERFACE_LIBRARY
#
# **Keyword Arguments**
#
# :keyword GUI: launch SimVision gui together with the simulation
# :type GUI: boolean
#]]

include_guard(GLOBAL)

function(xcelium_run IP_LIB)
cmake_parse_arguments(ARG "GUI" "" "" ${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")

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

if(ARG_GUI)
set(ARG_GUI -gui -access +rwc)
else()
unset(ARG_GUI)
endif()

# Get RTL and TB sources
get_ip_rtl_sources(SOURCES ${IP_LIB})
get_ip_tb_only_rtl_sources(TB_SOURCES ${IP_LIB})
list(APPEND SOURCES ${TB_SOURCES})

get_ip_include_directories(SYSTEMVERILOG_INCLUDE_DIRS ${IP_LIB} SYSTEMVERILOG)
get_ip_include_directories(VERILOG_INCLUDE_DIRS ${IP_LIB} VERILOG)
set(INC_DIRS ${SYSTEMVERILOG_INCLUDE_DIRS} ${VERILOG_INCLUDE_DIRS})

foreach(dir ${INC_DIRS})
list(APPEND ARG_INCDIRS -incdir ${dir})
endforeach()

get_ip_compile_definitions(COMP_DEFS_SV ${IP_LIB} SYSTEMVERILOG)
get_ip_compile_definitions(COMP_DEFS_V ${IP_LIB} VERILOG) # TODO Add VHDL??
set(COMP_DEFS ${COMP_DEFS_SV} ${COMP_DEFS_V})
foreach(def ${COMP_DEFS})
list(APPEND CMP_DEFS_ARG -D${def})
endforeach()

add_custom_target(${IP_LIB}_${CMAKE_CURRENT_FUNCTION}
COMMAND xrun
# Enable parameters without default value
-setenv CADENCE_ENABLE_AVSREQ_44905_PHASE_1=1 -setenv CADENCE_ENABLE_AVSREQ_63188_PHASE_1=1
-define COMMON_CELLS_ASSERTS_OFF
${SOURCES}
${ARG_INCDIRS}
${CMP_DEFS_ARG}
${ARG_GUI}
COMMENT "Running ${CMAKE_CURRENT_FUNCTION} on ${IP_LIB}"
DEPENDS ${SOURCES} ${IP_LIB}
)
endfunction()

#[[[
# Create a target for invoking Xcelium compilation and elaboration on IP_LIB.
# Create a target for invoking Xcelium (compilation, elaboration, and simulation) on IP_LIB.
#
# It will create a target **<IP_LIB>_xcelium_elab** that will compile, elaborate the design
# It will create a target **<IP_LIB>_xcelium_elab** that will compile, elaborate, and simulate the IP_LIB design.
#
# :param IP_LIB: RTL interface library, it needs to have SOURCES property set with a list of System Verilog files.
# :type IP_LIB: INTERFACE_LIBRARY
#
# **Keyword Arguments**
#
# :keyword GUI: launch SimVision gui together with the simulation
# :type GUI: boolean
# :keyword ELABORATE: sets xrun to compile and elaborate only the design (no simulation).
# :type ELABORATE: string
# :keyword UNIQUIFY: Uniquifies the list of ip sources based on the basename of the files.
# :type UNIQUIFY: string
# :keyword ACCESS: Access rights (i.e., visibility) used to compile and elaborate the design. For debugging pass 'rwc'.
# :type ACCESS: string
# :keyword SETENV: List of env variables passed to xrun.
# :type SETENV: string
# :keyword DEFINES: List of defines passed to xrun.
# :type DEFINES: string
# :keyword ARGS: Additional arguments passed to xrun.
# :type ARGS: string
#]]
function(xcelium_elab IP_LIB)
cmake_parse_arguments(ARG "" "ACCESS" "SETENV;DEFINES;ARGS" ${ARGN})
function(xcelium IP_LIB)
cmake_parse_arguments(ARG "ELABORATE;UNIQUIFY" "ACCESS" "SETENV;DEFINES;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")
include("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../utils/uniquify_files_by_basename.cmake")

ip_assume_last(IP_LIB ${IP_LIB})
get_target_property(BINARY_DIR ${IP_LIB} BINARY_DIR)
Expand All @@ -97,22 +38,35 @@ function(xcelium_elab IP_LIB)
get_ip_tb_only_rtl_sources(TB_SOURCES_LIST ${IP_LIB})
list(APPEND SOURCES_LIST ${TB_SOURCES_LIST})

if(${ARG_UNIQUIFY})
# uniquify the list of files to avoid redefinition (comparing file basenames)
# This function also check files with same basename have the same content
uniquify_files_by_basename(SOURCES_LIST_UNIQUIFY "${SOURCES_LIST}")
else()
set(SOURCES_LIST_UNIQUIFY ${SOURCES_LIST})
endif()

get_ip_include_directories(SYSTEMVERILOG_INCLUDE_DIRS ${IP_LIB} SYSTEMVERILOG)
get_ip_include_directories(VERILOG_INCLUDE_DIRS ${IP_LIB} VERILOG)
set(INC_DIRS ${SYSTEMVERILOG_INCLUDE_DIRS} ${VERILOG_INCLUDE_DIRS})

# Sets the flag to compile and elaborate only
if(${ARG_ELABORATE})
set(ELABORATE_ARG -elaborate)
endif()

# Add the xrun parameter for the passed include directories, env variables and verilog defines
foreach(dir ${INC_DIRS})
list(APPEND INCDIR_LIST -incdir ${dir})
endforeach()
# message("ARG_SETENV: ${ARG_SETENV}")
foreach(var ${ARG_SETENV})
list(APPEND SETENV_LIST -setenv ${var})
endforeach()
# message("ARG_DEFINES: ${ARG_DEFINES}")
foreach(def ${ARG_DEFINES})
list(APPEND DEFINES_LIST -define ${def})
endforeach()

# Change the default timescale 1ps/1ps if TIMESCALE argument is passed
if(${TIMESCALE_ARG})
set(TIMESCALE_ARG -timescale ${TIMESCALE_ARG})
else()
Expand All @@ -131,7 +85,7 @@ function(xcelium_elab IP_LIB)
endif()

add_custom_target(${IP_LIB}_${CMAKE_CURRENT_FUNCTION}
COMMAND xrun
COMMAND xrun ${ELABORATE_ARG}
# xrun compiler options
${SETENV_LIST}
${DEFINES_LIST}
Expand All @@ -144,7 +98,7 @@ function(xcelium_elab IP_LIB)
# Miscellaneous arguments
${ARG_ARGS}
# Source files and include directories
${SOURCES_LIST}
${SOURCES_LIST_UNIQUIFY}
${INCDIR_LIST}
BYPRODUCTS xcelium.d xrun.history xrun.key xrun.log
COMMENT "Running ${CMAKE_CURRENT_FUNCTION} on ${IP_LIB}"
Expand Down
19 changes: 11 additions & 8 deletions cmake/tmrg/tmrg/tmrg.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,20 @@ function(tmrg IP_LIB)
# error by tmrg because tmrg tracks the non-triplicated module names.
set(LIB_STRIP_DIR ${OUTDIR}/lib_strip)
set(LIB_STRIP_CMD
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/lib_module_strip.py --files ${SRC_DEPS} --outdir ${LIB_STRIP_DIR}
${Python3_EXECUTABLE} ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/lib_module_strip.py --files ${SRC_DEPS} --outdir ${LIB_STRIP_DIR}
)

set(SCR_DEPS_STRIPPED)
set(SRC_DEPS_STRIPPED)
foreach(file ${SRC_DEPS})
get_filename_component(BASE_NAME ${file} NAME)
set(NEW_FILE_PATH "${LIB_STRIP_DIR}/${BASE_NAME}")
list(APPEND SCR_DEPS_STRIPPED ${NEW_FILE_PATH})
list(APPEND SRC_DEPS_STRIPPED ${NEW_FILE_PATH})
endforeach()


set(STAMP_FILE "${BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION}_lib_strip.stamp")
add_custom_command(
OUTPUT ${STAMP_FILE} ${SCR_DEPS_STRIPPED}
OUTPUT ${STAMP_FILE} ${SRC_DEPS_STRIPPED}
COMMAND ${LIB_STRIP_CMD}
COMMAND touch ${STAMP_FILE}
DEPENDS ${SRC_DEPS}
Expand All @@ -107,7 +107,7 @@ function(tmrg IP_LIB)

add_custom_target(
${IP_LIB}_${CMAKE_CURRENT_FUNCTION}_lib_strip
DEPENDS ${STAMP_FILE} ${SCR_DEPS_STRIPPED}
DEPENDS ${STAMP_FILE} ${SRC_DEPS_STRIPPED}
)

foreach(vfile ${IP_TMRG_SRC})
Expand All @@ -128,10 +128,10 @@ function(tmrg IP_LIB)
# SRC_DEPS contains non-triplicated and triplicated sources as
# long as the deps use tmrg with the REPLACE argument.
# Each dep source is passed as libraries
if(SCR_DEPS_STRIPPED)
if(SRC_DEPS_STRIPPED)
set(SRC_LIBS)
# Each file needs to be passed with the '-l' option
foreach(file ${SCR_DEPS_STRIPPED})
foreach(file ${SRC_DEPS_STRIPPED})
list(APPEND SRC_LIBS -l ${file})
endforeach()
set(TMRG_COMMAND ${TMRG_COMMAND} ${SRC_LIBS})
Expand Down Expand Up @@ -168,7 +168,7 @@ function(tmrg IP_LIB)
OUTPUT ${TRMG_GEN} ${STAMP_FILE}
COMMAND ${TMRG_COMMAND}
COMMAND /bin/sh -c date > ${STAMP_FILE}
DEPENDS ${IP_TMRG_SRC} ${SCR_DEPS_STRIPPED}
DEPENDS ${IP_TMRG_SRC} ${SRC_DEPS_STRIPPED}
COMMENT "Running ${CMAKE_CURRENT_FUNCTION} on ${IP_LIB}"
)

Expand Down Expand Up @@ -211,11 +211,14 @@ function(tmrg IP_LIB)
# Get the existing linked libraries
safe_get_target_property(LINKED_IP ${IP_LIB} INTERFACE_LINK_LIBRARIES "")
# Trigger the dependencies tmrg targets if they exist
message(DEBUG "TMRG: checking linked libraries for IP ${IP_LIB}")
foreach(linked_lib ${LINKED_IP})
alias_dereference(linked_lib ${linked_lib})
# Check if a tmrg target exists
message(DEBUG " Found linked library ${linked_lib}")
if(TARGET ${linked_lib}_${CMAKE_CURRENT_FUNCTION})
add_dependencies(${IP_LIB}_${CMAKE_CURRENT_FUNCTION} ${linked_lib}_${CMAKE_CURRENT_FUNCTION})
message(DEBUG " └─> Found tmrg target ${linked_lib}_${CMAKE_CURRENT_FUNCTION}")
endif()
endforeach()

Expand Down
49 changes: 40 additions & 9 deletions cmake/utils/copy_rtl_files/copy_rtl_files.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,28 @@
#[[[
# This function copies the RTL sources of an IP to a given location.
#
# This function gets an IP_LIB target and get its RTL source files (exluding SIM/TB/FPGA files) and include directories and copy
# them to a default or given location. The output location contains a file listing all the sources, an include directory containing
# all the include files and the source files with a preserved hierarchy folder. It uses the vhier tool to parse and build the library
# hierachy and copy only the files instantiated in the hierarchy.
# vhier is part of a set of tools:
# https://github.com/gitpan/Verilog-Perl
# https://metacpan.org/pod/vhier
#
# :param IP_LIB: IP library to get RTL sources from.
# :type IP_LIB: string
#
# **Keyword Arguments**
#
# :keyword SYNTHESIS: Define SYNTHESIS, and ignore text between "ambit", "pragma", "synopsys" or "synthesis" translate_off and translate_on meta comments.
# :type SYNTHESIS: string
# :keyword OUTDIR: Change the default copy location ${CMAKE_BINARY_DIR}/ip_sources to OUTDIR.
# :type OUTDIR: string
# :keyword TOP_MODULE: Start the report at the specified module name, ignoring all modules that are not the one specified with --top-module or below, and report an error if the --top-module specified does not exist.
# :type TOP_MODULE: string
# :keyword SKIPLIST_FILE: Given file contains a list of regular expressions, one per line. If a module name in the design hierarchy matches one of these expressions, skip showing that module and any sub-hierarchy.
# :type SKIPLIST_FILE: string
#]]
function(copy_rtl_files IP_LIB)
cmake_parse_arguments(ARG "SYNTHESIS" "OUTDIR;TOP_MODULE;SKIPLIST_FILE" "" ${ARGN})
if(ARG_UNPARSED_ARGUMENTS)
Expand Down Expand Up @@ -42,18 +67,24 @@ function(copy_rtl_files IP_LIB)
${RTL_SOURCES}
)

# Call the Python script with the output directory and the RTL files
set(STAMP_FILE "${CMAKE_BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION}.stamp")
add_custom_command(
OUTPUT ${STAMP_FILE}
COMMAND ${__CMD}
COMMENT "Copying RTL files to ${OUTDIR}"
VERBATIM
)
# # Call the Python script with the output directory and the RTL files
# set(STAMP_FILE "${CMAKE_BINARY_DIR}/${IP_LIB}_${CMAKE_CURRENT_FUNCTION}.stamp")
# add_custom_command(
# OUTPUT ${STAMP_FILE}
# COMMAND ${__CMD}
# COMMAND /bin/sh -c date > ${STAMP_FILE}
# COMMENT "Copying RTL files to ${OUTDIR}"
# VERBATIM
# )

# Create a target to run the custom command
add_custom_target(
${IP_LIB}_copy_rtl
ALL DEPENDS ${IP_LIB} ${STAMP_FILE}
ALL # This forces the target to be run every time as outputs are not known in advance
COMMAND ${__CMD}
COMMENT "Copying RTL files to ${OUTDIR}"
DEPENDS ${IP_LIB} ${STAMP_FILE}
VERBATIM
)

endfunction()
23 changes: 20 additions & 3 deletions cmake/utils/copy_rtl_files/copy_rtl_files.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import shutil
import subprocess
import os
import sys

def make_parser():
parser = argparse.ArgumentParser(description="Filter RTL files based on module hierarchy.")
Expand All @@ -25,7 +26,7 @@ def main():
if vhier is None:
raise FileNotFoundError
except FileNotFoundError:
print('Error: "vhier" executable not found')
print("Error: 'vhier' executable not found", file=sys.stderr)

# Initialize the output list with all the packages,
# because they're not retained by vhier
Expand All @@ -49,11 +50,27 @@ def main():
try:
cells_output = subprocess.run([*vhier_base_args, '--cells'], capture_output=True, check=True)
except subprocess.CalledProcessError as e:
print("Fatal: ", e.returncode, e.stderr)
print(f"Fatal: error({e.returncode}): {e.stderr.decode('ascii')}", file=sys.stderr)
raise

output_src.extend(sorted(set([f.decode() for f in cells_output.stdout.split()])))

# Check if the output directory exists
if os.path.isdir(args.outdir):
# Clean everything inside if it exists
for filename in os.listdir(args.outdir):
file_path = os.path.join(args.outdir, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print('Failed to delete %s. Reason: %s' % (file_path, e))
else:
# Create the directory
os.makedirs(args.outdir, exist_ok=False)

# Copy files to output directory
copied_src = []
for i in output_src:
Expand All @@ -74,7 +91,7 @@ def main():
try:
includes_output = subprocess.run([*vhier_base_args, '--includes'], capture_output=True, check=True)
except subprocess.CalledProcessError as e:
print("Fatal: ", e.returncode, e.stderr)
print(f"Fatal: error({e.returncode}): {e.stderr.decode('ascii')}", file=sys.stderr)
raise

output_inc = sorted(set([f.decode() for f in includes_output.stdout.split()]))
Expand Down
Loading

0 comments on commit f966713

Please sign in to comment.