Add cmake support, bug1363.

Signed-off-by: Wilson Snyder <wsnyder@wsnyder.org>
This commit is contained in:
Patrick Stewart 2019-10-17 19:44:10 -04:00 committed by Wilson Snyder
parent 1232746395
commit 1e4f471049
41 changed files with 1987 additions and 65 deletions

2
.gitignore vendored
View File

@ -30,4 +30,6 @@ verilator.txt
verilator_bin*
verilator_coverage_bin*
verilator.pc
verilator-config.cmake
verilator-config-version.cmake
**/obj_dir/*

View File

@ -6,6 +6,8 @@ The contributors that suggested a given feature are shown in []. Thanks!
** Add --protect-lib, bug1490. [Todd Strader]
** Add cmake support, bug1363. [Patrick Stewart]
*** Examples have been renamed.
*** Add --protect-ids to obscure information in objects, bug1521. [Todd Strader]

View File

@ -15,6 +15,7 @@
.*\.vcd
.*\.1
\.travis\.yml
/build/
/obj_dir/
/obj_dbg/
/obj_nc/
@ -39,6 +40,8 @@ config.cache$
config.status$
verilator\.log
verilator\.tex
verilator-config.cmake$
verilator-config-version.cmake$
verilator.pc$
verilator_bin.*
verilator_coverage_bin.*

View File

@ -104,6 +104,11 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
SHELL = /bin/sh
SUBDIRS = src test_regress \
examples/cmake_hello_c \
examples/cmake_hello_sc \
examples/cmake_tracing_c \
examples/cmake_tracing_sc \
examples/cmake_protect_lib \
examples/make_hello_c \
examples/make_hello_sc \
examples/make_tracing_c \
@ -122,6 +127,8 @@ DISTFILES_INC = $(INFOS) .gitignore \
Changes \
LICENSE \
MANIFEST.SKIP \
verilator-config.cmake.in \
verilator-config-version.cmake.in \
bin/verilator \
bin/verilator_coverage \
bin/verilator_difftree \
@ -151,8 +158,14 @@ DISTFILES_INC = $(INFOS) .gitignore \
src/*.pl src/*.pod \
examples/*/.*ignore examples/*/Makefile* \
examples/*/*.[chv]* examples/*/*.pl \
examples/*/CMakeLists.txt \
test_*/.*ignore test_*/Makefile* test_*/*.cpp \
test_*/*.pl test_*/*.v test_*/*.vc test_*/*.vh \
test_regress/*.pl \
test_regress/Makefile \
test_regress/Makefile_obj \
test_regress/input.vc \
test_regress/CMakeLists.txt \
test_regress/t/t*/*.sv* \
test_regress/t/t*/*.v* \
test_regress/t/t*/*/*.sv* \
@ -302,6 +315,7 @@ VL_INST_INC_SRCDIR_FILES = \
VL_INST_DATA_SRCDIR_FILES = \
examples/*/*.[chv]* examples/*/Makefile* \
examples/*/CMakeLists.txt
installbin:
$(MKINSTALLDIRS) $(DESTDIR)$(bindir)
@ -338,12 +352,19 @@ installdata:
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_tracing_c
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_tracing_sc
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/make_protect_lib
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_c
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_sc
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
$(MKINSTALLDIRS) $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
cd $(srcdir) \
; for p in $(VL_INST_DATA_SRCDIR_FILES) ; do \
$(INSTALL_DATA) $$p $(DESTDIR)$(pkgdatadir)/$$p; \
done
$(MKINSTALLDIRS) $(DESTDIR)$(pkgconfigdir)
$(INSTALL_DATA) verilator.pc $(DESTDIR)$(pkgconfigdir)
$(INSTALL_DATA) verilator-config.cmake $(DESTDIR)$(pkgdatadir)
$(INSTALL_DATA) verilator-config-version.cmake $(DESTDIR)$(pkgdatadir)
# We don't trust rm -rf, so rmdir instead as it will fail if user put in other files
uninstall:
@ -354,6 +375,8 @@ uninstall:
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_INC_SRCDIR_FILES)
-cd $(DESTDIR)$(pkgdatadir) && rm -f $(VL_INST_DATA_SRCDIR_FILES)
-rm $(DESTDIR)$(pkgconfigdir)/verilator.pc
-rm $(DESTDIR)$(pkgdatadir)/verilator-config.cmake
-rm $(DESTDIR)$(pkgdatadir)/verilator-config-version.cmake
-rmdir $(DESTDIR)$(pkgdatadir)/bin
-rmdir $(DESTDIR)$(pkgdatadir)/include/gtkwave
-rmdir $(DESTDIR)$(pkgdatadir)/include/vltstd
@ -363,7 +386,13 @@ uninstall:
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_tracing_c
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_tracing_sc
-rmdir $(DESTDIR)$(pkgdatadir)/examples/make_protect_lib
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_c
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_hello_sc
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_c
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_tracing_sc
-rmdir $(DESTDIR)$(pkgdatadir)/examples/cmake_protect_lib
-rmdir $(DESTDIR)$(pkgdatadir)/examples
-rmdir $(DESTDIR)$(pkgdatadir)/cmake
-rmdir $(DESTDIR)$(pkgdatadir)
-rmdir $(DESTDIR)$(pkgconfigdir)

View File

@ -257,6 +257,11 @@ The directories in the package directory are as follows:
examples/make_tracing_c => Example GNU-make Verilog->C++ with tracing
examples/make_tracing_sc => Example GNU-make Verilog->SystemC with tracing
examples/make_protect_lib => Example using --protect-lib
examples/cmake_hello_c => Example building make_hello_c with CMake
examples/cmake_hello_sc => Example building make_hello_sc with CMake
examples/cmake_tracing_c => Example building make_tracing_c with CMake
examples/cmake_tracing_sc => Example building make_tracing_sc with CMake
examples/cmake_protect_lib => Example building make_protect_lib with CMake
include/ => Files that should be in your -I compiler path
include/verilated*.cpp => Global routines to link into your simulator
include/verilated*.h => Global headers

View File

@ -283,6 +283,7 @@ detailed descriptions in L</"VERILATION ARGUMENTS"> for more information.
--cc Create C++ output
--cdc Clock domain crossing analysis
--clk <signal-name> Mark specified signal as clock
--make <make-system> Generate scripts for specified make system
--compiler <compiler-name> Tune for specified C++ compiler
--converge-limit <loops> Tune convergence settle time
--coverage Enable all coverage
@ -574,6 +575,13 @@ If clock signals are assigned to vectors and then later used individually,
Verilator will attempt to decompose the vector and connect the single-bit
clock signals directly. This should be transparent to the user.
=item --make I<make-system>
Generates a script for the specified make system.
Supported make systems are gmake and cmake. Both can be specified.
If no make system is specified, gmake is assumed.
=item --compiler I<compiler-name>
Enables tunings and workarounds for the specified C++ compiler.
@ -1944,9 +1952,15 @@ All output files are placed in the output directory name specified with the
Verilator creates the following files in the output directory:
For --make gmake, it creates:
{prefix}.mk // Make include file for compiling
{prefix}_classes.mk // Make include file with class names
For --make cmake, it creates:
{prefix}.cmake // CMake include script for compiling
For -cc and -sc mode, it also creates:
{prefix}.cpp // Top level C++ file
@ -2406,6 +2420,152 @@ The target system may also require edits to the Makefiles, the simple
Makefiles produced by Verilator presume the target system is the same type
as the build system.
=head2 CMake
Verilator can be run using CMake, which takes care of both running
Verilator and compiling the output. There is a CMake example in the
examples/ directory. The following is a minimal CMakeLists.txt that
would build the code listed in "EXAMPLE C++ EXECUTION":
project(cmake_example)
find_package(verilator HINTS $ENV{VERILATOR_ROOT})
add_executable(Vour sim_main.cpp)
verilate(Vour SOURCES our.v)
find_package will automatically find an installed copy of Verilator, or use
a local build if VERILATOR_ROOT is set.
It is recommended to use CMake >= 3.12 and the Ninja generator, though
other combinations should work. To build with CMake, change to the folder
containing CMakeLists.txt and run:
mkdir build
cd build
cmake -GNinja ..
ninja
Or to build with your system default generator:
mkdir build
cd build
cmake ..
cmake --build .
If you're building the example you should have an executable to run:
./Vour
The package sets the CMake variables verilator_FOUND, VERILATOR_ROOT and
VERILATOR_BIN to the appropriate values, and also creates a verilate()
function. verilate() will automatically create custom commands to run
Verilator and add the generated C++ sources to the target specified.
verilate(target SOURCES source ... [TOP_MODULE top] [PREFIX name]
[TRACE] [TRACE_FST] [SYSTEMC] [COVERAGE]
[INCLUDE_DIRS dir ...] [OPT_SLOW ...] [OPT_FAST ...]
[DIRECTORY dir] [VERILATOR_ARGS ...])
Lowercase and ... should be replaced with arguments, the uppercase parts
delimit the arguments and can be passed in any order, or left out entirely
if optional.
verilate(target ...) can be called multiple times to add other verilog
modules to an executable or library target.
When generating Verilated SystemC sources, you should also include the
SystemC include directories and link to the SystemC libraries.
Verilator's CMake support provides a convenience function to automatically
find and link to the SystemC library. It can be used as:
verilator_link_systemc(target)
where target is the name of your target.
The search paths can be configured by setting some variables:
- The variables SYSTEMC_INCLUDE and SYSTEMC_LIBDIR to give a direct path to
the SystemC include an library path.
- SYSTEMC_ROOT to set the installation prefix of an installed SystemC
library.
- SYSTEMC to set the installation prefix of an installed SystemC library
(same as above).
- When using Accellera's SystemC with CMake support, a CMake target is
available that will easen above steps. This will only work if the SystemC
installation can be found by CMake. This can be configured by setting the
CMAKE_PREFIX_PATH variable during CMake configuration.
Don't forget to set the same C++ standard for the Verilated sources as the
SystemC library. This can be specified using the SYSTEMC_CXX_FLAGS environment
variable.
=over 4
=item target
Name of a target created by add_executable or add_library.
=item SOURCES
List of verilog files to Verilate. Must have at least one file.
=item PREFIX
Optional. Sets the Verilator output prefix. Defaults to the name of the
first hdl source with a "V" prepended. Must be unique in each call to
verilate(), so this is necessary if you build a module multiple times with
different parameters. Must be a valid C++ identifer, i.e. contains no
whitespace and only characters A-Z, a-z, 0-9 or _.
=item TOP_MODULE
Optional. Sets the name of the top module. Defaults to the name of the
first file in the SOURCES array.
=item TRACE
Optional. Enables VCD tracing if present, equivalent to "VERILATOR_ARGS --trace".
=item TRACE_FST
Optional. Enables FST tracing if present, equivalent to "VERILATOR_ARGS --trace-fst".
=item SYSTEMC
Optional. Enables SystemC mode, defaults to C++ if not specified.
=item COVERAGE
Optional. Enables coverage if present, equivalent to "VERILATOR_ARGS --coverage"
=item INCLUDE_DIRS
Optional. Sets directories that Verilator searches (same as -y).
=item OPT_SLOW
Optional. Set compiler flags for the slow path. You may want to reduce the
optimisation level to improve compile times with large designs.
=item OPT_FAST
Optional. Set compiler flags for the fast path.
=item DIRECTORY
Optional. Set the verilator output directory. It is preferable to use the
default, which will avoid collisions with other files.
=item VERILATOR_ARGS
Optional. Extra arguments to Verilator. Do not specify --Mdir or --prefix
here, use DIRECTORY or PREFIX.
=back
=head2 Cadence NC-SystemC Models
Similar to compiling Verilated designs with gcc, Verilated designs may be

View File

@ -13,7 +13,7 @@ AC_INIT([Verilator],[4.020 devel],
# and commit using "devel release" or "Version bump" message
AC_CONFIG_HEADER(src/config_build.h)
AC_CONFIG_FILES(Makefile docs/Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc)
AC_CONFIG_FILES(Makefile docs/Makefile src/Makefile src/Makefile_obj include/verilated.mk include/verilated_config.h verilator.pc verilator-config.cmake verilator-config-version.cmake)
AC_MSG_RESULT([configuring for $PACKAGE_STRING])
@ -276,24 +276,37 @@ AC_SUBST(CFG_CXXFLAGS_PARSER)
# For some reason -faligned-new does not work under Travis w/ clang but the
# configure test doesn't catch this either
AS_IF([test "x$TRAVIS_COMPILER" != xclang], [_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-faligned-new)])
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-fbracket-depth=4096)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Qunused-arguments)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-bool-operation)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-parentheses-equality)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-sign-compare)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-uninitialized)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-but-set-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-parameter)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-unused-variable)
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,-Wno-shadow)
CFG_CXX_FLAGS_CMAKE="-faligned-new"
m4_foreach([cflag],[
[-fbracket-depth=4096],
[-Qunused-arguments],
[-Wno-bool-operation],
[-Wno-parentheses-equality],
[-Wno-sign-compare],
[-Wno-uninitialized],
[-Wno-unused-but-set-variable],
[-Wno-unused-parameter],
[-Wno-unused-variable],
[-Wno-shadow]],[
_MY_CXX_CHECK_OPT(CFG_CXXFLAGS_NO_UNUSED,cflag)
# CMake will test what flags work itself, so pass all flags through to it
CFG_CXX_FLAGS_CMAKE="$CFG_CXX_FLAGS_CMAKE cflag"
])
AC_SUBST(CFG_CXXFLAGS_NO_UNUSED)
AC_SUBST(CFG_CXX_FLAGS_CMAKE)
# Find multithread linker flags
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-mt)
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-pthread)
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-lpthread)
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,-latomic)
m4_foreach([ldflag], [
[-mt],
[-pthread],
[-lpthread],
[-latomic]],[
_MY_LDLIBS_CHECK_OPT(CFG_LDLIBS_THREADS,ldflag)
# CMake will test what flags work itself, so pass all flags through to it
CFG_LDFLAGS_THREADS_CMAKE="$CFG_LDFLAGS_THREADS_CMAKE ldflag"
])
AC_SUBST(CFG_LDLIBS_THREADS)
AC_SUBST(CFG_LDFLAGS_THREADS_CMAKE)
# Set CFG_WITH_THREADED if can support threading
AC_MSG_CHECKING(whether $CXX supports Verilated threads)

1
examples/cmake_hello_c/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build*

View File

@ -0,0 +1,37 @@
######################################################################
#
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt
#
# This is an example cmake script to build a verilog to systemc project
# using cmake and verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
# This example builds the tracing_c example using CMake
# To use it, run the following:
# cd /path/to/verilator/examples/cmake_c
# rm -rf build && mkdir build && cd build
# cmake ..
# cmake --build .
cmake_minimum_required(VERSION 3.8)
project(cmake_hello_c)
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()
# Create a new executable target that will contain all your sources
add_executable(example ../make_hello_c/sim_main.cpp)
# Add the Verilated circuit to the target
verilate(example
INCLUDE_DIRS "../make_hello_c"
SOURCES ../make_hello_c/top.v)

View File

@ -0,0 +1,79 @@
######################################################################
#
# DESCRIPTION: Verilator CMake example usage
#
# This file shows usage of the CMake script.
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
######################################################################
# Set up variables
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package install, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
VERILATOR_COVERAGE = verilator_coverage
else
export VERILATOR_ROOT
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
endif
######################################################################
# Check if CMake is installed and of correct version
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
ifeq ($(CMAKE_GT_3_8),true)
TARGET := run
else
TARGET := oldcmake
endif
endif
default: $(TARGET)
run:
@echo
@echo "-- Verilator CMake hello world example"
@echo
@echo "-- CMake ----------------"
mkdir -p build && cd build && cmake ..
@echo
@echo "-- COMPILE -----------------"
cmake --build build
@echo
@echo "-- RUN ---------------------"
build/example
@echo
@echo "-- DONE --------------------"
@echo
clean mostlyclean distclean maintainer-clean:
@rm -rf build logs
nocmake:
@echo
@echo "%Skip: CMake has not been found"
@echo
oldcmake:
@echo
@echo "%Skip: CMake version is too old (need at least 3.8)"
@echo

1
examples/cmake_hello_sc/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build*

View File

@ -0,0 +1,46 @@
######################################################################
#
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt with SystemC
#
# This is an example cmake script to build a verilog to SystemC project
# using CMake and Verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
# This example builds the tracing_sc example using CMake
# To use it, run the following:
# cd /path/to/verilator/examples/cmake_sc
# rm -rf build && mkdir build && cd build
# cmake ..
# cmake --build .
cmake_minimum_required(VERSION 3.8)
project(cmake_hello_sc)
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 a new executable target that will contain all your sources
add_executable(example ../make_hello_sc/sc_main.cpp)
# Add the Verilated circuit to the target
verilate(example SYSTEMC
INCLUDE_DIRS "../make_hello_sc"
SOURCES ../make_hello_sc/top.v)
verilator_link_systemc(example)

View File

@ -0,0 +1,129 @@
######################################################################
#
# DESCRIPTION: Verilator CMake example usage
#
# This file shows usage of the CMake script.
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
######################################################################
# Set up variables
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package install, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
VERILATOR_COVERAGE = verilator_coverage
else
export VERILATOR_ROOT
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
endif
######################################################################
# Check if CMake is installed and of correct version
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
ifneq ($(CMAKE_GT_3_8),true)
TARGET := oldcmake
else
# Test existence of SYSTEMC_INCLUDE and SYSTEMC_LIBDIR environment variabless
ifneq (,$(SYSTEMC_INCLUDE))
ifneq (,${SYSTEMC_LIBDIR})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC_ROOT environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC_ROOT})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC})
SYSTEMC_SET := true
endif
endif
# Test whether SystemC is installed with CMake support
# This will print a CMake error about processing arguments that can (currently) be ignored.
ifneq (SYSTEMC_SET, true)
FINDSC := $(shell mkdir -p build && cd build && cmake --find-package -DNAME=SystemCLanguage -DCMAKE_USE_PTHREADS_INIT=ON -DCOMPILER_ID=GNU -DLANGUAGE=CXX -DMODE=EXIST -DThreads_FOUND=ON)
ifneq (,$(findstring SystemCLanguage found,$(FINDSC)))
SYSTEMC_SET := true
endif
endif
ifeq ($(SYSTEMC_SET), true)
TARGET := run
else
TARGET := nosc
endif
endif
endif
default: $(TARGET)
run:
@echo
@echo "-- Verilator CMake SystemC hello-world simple example"
@echo
@echo "-- CMake ----------------"
mkdir -p build && cd build && cmake ..
@echo
@echo "-- COMPILE -----------------"
cmake --build build
@echo
@echo "-- RUN ---------------------"
@mkdir -p logs
build/example
@echo "-- DONE --------------------"
@echo "Note: Once this example is understood, see examples/cmake_tracing_sc."
@echo "Note: Also see the EXAMPLE section in the verilator manpage/document."
clean mostlyclean distclean maintainer-clean:
@rm -rf build logs
nocmake:
@echo
@echo "%Skip: CMake has not been found"
@echo
oldcmake:
@echo
@echo "%Skip: CMake version is too old (need at least 3.8)"
@echo
nosc:
@echo
@echo "%Skip: CMake could not find SystemC."
@echo "% Make sure that either:"
@echo "% - The environment variables SYSTEMC_INCLUDE and SYSTEMC_LIBDIR are exported."
@echo "% - Or, the environment variable SYSTEMC_ROOT is exported."
@echo "% - Or, The environment variable SYSTEMC is exported."
@echo "% - Or, if the SystemC installation provides CMake support,"
@echo "% that its installation prefix is in CMAKE_PREFIX_PATH."
@echo "% Also that the C++ standard of the SystemC library is the same as this example."
@echo "% Please see the Verilator documentation's CMake section for more information."
@echo

1
examples/cmake_protect_lib/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
build*

View File

@ -0,0 +1,60 @@
######################################################################
#
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt
#
# This is an example cmake script to build a verilog to systemc project
# using cmake and verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
# This example builds the tracing_c example using CMake
# To use it, run the following:
# cd /path/to/verilator/examples/cmake_c
# rm -rf build && mkdir build && cd build
# cmake ..
# cmake --build .
cmake_minimum_required(VERSION 3.8)
project(cmake_protect_lib)
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()
# Create the main executable target
add_executable(example ../make_protect_lib/sim_main.cpp)
# Create a secret library
add_library(verilated_secret STATIC) # or SHARED for a shared library
target_link_libraries(example PRIVATE verilated_secret)
# To create both libraries on CMake >= 3.12 replace the above 2 lines with the following:
# add_library(verilated_secret OBJECT)
# set_property(TARGET verilated_secret PROPERTY POSITION_INDEPENDENT_CODE 1)
# add_library(verilated_secret_static STATIC $<TARGET_OBJECTS:verilated_secret>)
# set_target_properties(verilated_secret_static PROPERTIES OUTPUT_NAME verilated_secret)
# add_library(verilated_secret_shared SHARED $<TARGET_OBJECTS:verilated_secret>)
# set_target_properties(verilated_secret_shared PROPERTIES OUTPUT_NAME verilated_secret)
# target_link_libraries(example PRIVATE verilated_secret_static)
# Setup random seed
verilator_generate_key(KEY_INIT)
set(PROTECT_KEY ${KEY_INIT} CACHE STRING "Random seed for protection")
# Add the Verilated modules to the targets
verilate(verilated_secret
VERILATOR_ARGS --protect-lib verilated_secret
--protect-key ${PROTECT_KEY}
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/verilated_secret
SOURCES ../make_protect_lib/secret_impl.v)
# Include location of verilated_secret.sv wrapper
verilate(example
VERILATOR_ARGS "-I${CMAKE_CURRENT_BINARY_DIR}/verilated_secret"
SOURCES ../make_protect_lib/top.v)

View File

@ -0,0 +1,79 @@
######################################################################
#
# DESCRIPTION: Verilator CMake example usage
#
# This file shows usage of the CMake script.
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
######################################################################
# Set up variables
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package install, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
VERILATOR_COVERAGE = verilator_coverage
else
export VERILATOR_ROOT
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
endif
######################################################################
# Check if CMake is installed and of correct version
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
ifeq ($(CMAKE_GT_3_8),true)
TARGET := run
else
TARGET := oldcmake
endif
endif
default: $(TARGET)
run:
@echo
@echo "-- Verilator CMake protect_lib example"
@echo
@echo "-- CMake ----------------"
mkdir -p build && cd build && cmake ..
@echo
@echo "-- COMPILE -----------------"
cmake --build build
@echo
@echo "-- RUN ---------------------"
build/example
@echo
@echo "-- DONE --------------------"
@echo
clean mostlyclean distclean maintainer-clean:
@rm -rf build logs
nocmake:
@echo
@echo "%Skip: CMake has not been found"
@echo
oldcmake:
@echo
@echo "%Skip: CMake version is too old (need at least 3.8)"
@echo

2
examples/cmake_tracing_c/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
build*
logs

View File

@ -0,0 +1,38 @@
######################################################################
#
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt with tracing
#
# This is an example cmake script to build a verilog to systemc project
# using cmake and verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
# This example builds the make_tracing_c example using CMake
# To use it, run the following:
# cd /path/to/verilator/examples/cmake_tracing_c
# rm -rf build && mkdir build && cd build
# cmake ..
# cmake --build .
cmake_minimum_required(VERSION 3.8)
project(cmake_tracing_c)
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()
# Create a new executable target that will contain all your sources
add_executable(example ../make_tracing_c/sim_main.cpp)
# Add the Verilated circuit to the target
verilate(example COVERAGE TRACE
INCLUDE_DIRS "../make_tracing_c"
VERILATOR_ARGS -f ../make_tracing_c/input.vc -O2 -x-assign 0
SOURCES ../make_tracing_c/top.v)

View File

@ -0,0 +1,85 @@
######################################################################
#
# DESCRIPTION: Verilator CMake example usage
#
# This file shows usage of the CMake script.
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
######################################################################
# Set up variables
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package install, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
VERILATOR_COVERAGE = verilator_coverage
else
export VERILATOR_ROOT
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
endif
######################################################################
# Check if CMake is installed and of correct version
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
ifeq ($(CMAKE_GT_3_8),true)
TARGET := run
else
TARGET := oldcmake
endif
endif
default: $(TARGET)
run:
@echo
@echo "-- Verilator CMake tracing example"
@echo
@echo "-- CMake ----------------"
mkdir -p build && cd build && cmake ..
@echo
@echo "-- COMPILE -----------------"
cmake --build build
@echo
@echo "-- RUN ---------------------"
@mkdir -p logs
build/example +trace
@echo
@echo "-- COVERAGE ----------------"
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
@echo
@echo "-- DONE --------------------"
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
@echo
clean mostlyclean distclean maintainer-clean:
@rm -rf build logs
nocmake:
@echo
@echo "%Skip: CMake has not been found"
@echo
oldcmake:
@echo
@echo "%Skip: CMake version is too old (need at least 3.8)"
@echo

7
examples/cmake_tracing_sc/.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
*.dmp
*.log
*.csrc
*.vcd
obj_*
logs
build*

View File

@ -0,0 +1,47 @@
######################################################################
#
# DESCRIPTION: Verilator CMake Example: Small CMakeLists.txt with SystemC tracing
#
# This is an example cmake script to build a verilog to SystemC project
# using CMake and Verilator.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
# This example builds the tracing_sc example using CMake
# To use it, run the following:
# cd /path/to/verilator/examples/cmake_tracing_sc
# rm -rf build && mkdir build && cd build
# cmake ..
# cmake --build .
cmake_minimum_required(VERSION 3.8)
project(cmake_tracing_sc_example)
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 a new executable target that will contain all your sources
add_executable(example ../make_tracing_sc/sc_main.cpp)
# Add the Verilated circuit to the target
verilate(example SYSTEMC COVERAGE TRACE
INCLUDE_DIRS "../make_tracing_sc"
VERILATOR_ARGS -f ../make_tracing_sc/input.vc -O2 -x-assign 0
SOURCES ../make_tracing_sc/top.v)
verilator_link_systemc(example)

View File

@ -0,0 +1,134 @@
######################################################################
#
# DESCRIPTION: Verilator CMake example usage
#
# This file shows usage of the CMake script.
# This makefile is here for testing the examples and should
# generally not be added to a CMake project.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
######################################################################
# Set up variables
# If $VERILATOR_ROOT isn't in the environment, we assume it is part of a
# package install, and verilator is in your path. Otherwise find the
# binary relative to $VERILATOR_ROOT (such as when inside the git sources).
ifeq ($(VERILATOR_ROOT),)
VERILATOR_COVERAGE = verilator_coverage
else
export VERILATOR_ROOT
VERILATOR_COVERAGE = $(VERILATOR_ROOT)/bin/verilator_coverage
endif
######################################################################
# Check if CMake is installed and of correct version
ifeq ($(shell which cmake),)
TARGET := nocmake
else
CMAKE_VERSION := $(shell cmake --version | grep -Po '(\d[\.\d]+)')
CMAKE_MAJOR := $(shell echo $(CMAKE_VERSION) | cut -f1 -d.)
CMAKE_MINOR := $(shell echo $(CMAKE_VERSION) | cut -f2 -d.)
CMAKE_GT_3_8 := $(shell [ $(CMAKE_MAJOR) -gt 3 -o \( $(CMAKE_MAJOR) -eq 3 -a $(CMAKE_MINOR) -ge 8 \) ] && echo true)
ifneq ($(CMAKE_GT_3_8),true)
TARGET := oldcmake
else
# Test existence of SYSTEMC_INCLUDE and SYSTEMC_LIBDIR environment variabless
ifneq (,$(SYSTEMC_INCLUDE))
ifneq (,${SYSTEMC_LIBDIR})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC_ROOT environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC_ROOT})
SYSTEMC_SET := true
endif
endif
# Test existence of SYSTEMC environment variable
ifneq (SYSTEMC_SET, true)
ifneq (,${SYSTEMC})
SYSTEMC_SET := true
endif
endif
# Test whether SystemC is installed with CMake support
# This will print a CMake error about processing arguments that can (currently) be ignored.
ifneq (SYSTEMC_SET, true)
FINDSC := $(shell mkdir -p build && cd build && cmake --find-package -DNAME=SystemCLanguage -DCMAKE_USE_PTHREADS_INIT=ON -DCOMPILER_ID=GNU -DLANGUAGE=CXX -DMODE=EXIST -DThreads_FOUND=ON)
ifneq (,$(findstring SystemCLanguage found,$(FINDSC)))
SYSTEMC_SET := true
endif
endif
ifeq ($(SYSTEMC_SET), true)
TARGET := run
else
TARGET := nosc
endif
endif
endif
default: $(TARGET)
run:
@echo
@echo "-- Verilator CMake SystemC tracing example"
@echo
@echo "-- CMake ----------------"
mkdir -p build && cd build && cmake ..
@echo
@echo "-- COMPILE -----------------"
cmake --build build
@echo
@echo "-- RUN ---------------------"
@mkdir -p logs
build/example +trace
@echo
@echo "-- COVERAGE ----------------"
$(VERILATOR_COVERAGE) --annotate logs/annotated logs/coverage.dat
@echo
@echo "-- DONE --------------------"
@echo "To see waveforms, open vlt_dump.vcd in a waveform viewer"
@echo
clean mostlyclean distclean maintainer-clean:
@rm -rf build logs
nocmake:
@echo
@echo "%Skip: CMake has not been found"
@echo
oldcmake:
@echo
@echo "%Skip: CMake version is too old (need at least 3.8)"
@echo
nosc:
@echo
@echo "%Skip: CMake could not find SystemC."
@echo "% Make sure that either:"
@echo "% - The environment variables SYSTEMC_INCLUDE and SYSTEMC_LIBDIR are exported."
@echo "% - Or, the environment variable SYSTEMC_ROOT is exported."
@echo "% - Or, The environment variable SYSTEMC is exported."
@echo "% - Or, if the SystemC installation provides CMake support,"
@echo "% that its installation prefix is in CMAKE_PREFIX_PATH."
@echo "% Also that the C++ standard of the SystemC library is the same as this example."
@echo "% Please see the Verilator documentation's CMake section for more information."
@echo

View File

@ -183,6 +183,7 @@ RAW_OBJS = \
V3EmitC.o \
V3EmitCInlines.o \
V3EmitCSyms.o \
V3EmitCMake.o \
V3EmitMk.o \
V3EmitV.o \
V3EmitXml.o \

206
src/V3EmitCMake.cpp Normal file
View File

@ -0,0 +1,206 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit CMake file list
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2004-2019 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#include "config_build.h"
#include "verilatedos.h"
#include "V3Global.h"
#include "V3Os.h"
#include "V3EmitCMake.h"
#include "V3EmitCBase.h"
#include <memory>
//######################################################################
// Emit statements
class CMakeEmitter {
// METHODS
VL_DEBUG_FUNC; // Declare debug()
// STATIC FUNCTIONS
// Concatenate all strings in 'strs' with ' ' between them.
template<typename List>
static string cmake_list(const List& strs) {
string s;
if (strs.begin() != strs.end()) {
s.append("\"");
s.append(*strs.begin());
s.append("\"");
for (typename List::const_iterator it = ++strs.begin(); it != strs.end(); ++it) {
s.append(" \"");
s.append(*it);
s.append("\"");
}
}
return s;
}
// Print CMake variable set command: output raw_value unmodified
// cache_type should be empty for a normal variable
// "BOOL", "FILEPATH", "PATH", "STRING" or "INTERNAL" for a CACHE variable
// See https://cmake.org/cmake/help/latest/command/set.html
static void cmake_set_raw(std::ofstream& of, const string& name, const string& raw_value,
const string& cache_type = "", const string& docstring = "") {
of << "set(" << name << " " << raw_value;
if (!cache_type.empty()) {
of << " CACHE " << cache_type << " \"" << docstring << "\"";
}
of << ")\n";
}
static void cmake_set(std::ofstream& of, const string& name, const string& value,
const string& cache_type = "", const string& docstring = "") {
string raw_value = "\"" + value + "\"";
cmake_set_raw(of, name, raw_value, cache_type, docstring);
}
//Swap all backslashes for forward slashes, because of Windows
static string deslash(const string& s) {
std::string res = s;
for (string::iterator it = res.begin(); it != res.end(); ++it) {
if (*it == '\\')
*it = '/';
}
return res;
}
static void emitOverallCMake() {
const vl_unique_ptr<std::ofstream>
of (V3File::new_ofstream(v3Global.opt.makeDir()+"/"+v3Global.opt.prefix()+".cmake"));
string name = v3Global.opt.prefix();
*of << "# Verilated -*- CMake -*-\n";
*of << "# DESCR" "IPTION: Verilator output: CMake include script with class lists\n";
*of << "#\n";
*of << "# This CMake script lists generated Verilated files, for including in higher level CMake scripts.\n";
*of << "# This file is meant to be consumed by the verilate() function,\n";
*of << "# which becomes available after executing `find_package(verilator).\n";
*of << "\n### Constants...\n";
cmake_set(*of, "PERL", deslash(V3Options::getenvPERL()),
"FILEPATH", "Perl executable (from $PERL)");
cmake_set(*of, "VERILATOR_ROOT", deslash(V3Options::getenvVERILATOR_ROOT()),
"PATH", "Path to Verilator kit (from $VERILATOR_ROOT)");
*of << "\n### Compiler flags...\n";
*of << "# User CFLAGS (from -CFLAGS on Verilator command line)\n";
cmake_set_raw(*of, name + "_USER_CFLAGS", cmake_list(v3Global.opt.cFlags()));
*of << "# User LDLIBS (from -LDFLAGS on Verilator command line)\n";
cmake_set_raw(*of, name + "_USER_LDLIBS", cmake_list(v3Global.opt.ldLibs()));
*of << "\n### Switches...\n";
*of << "# SystemC output mode? 0/1 (from --sc)\n";
cmake_set_raw(*of, name + "_SC", v3Global.opt.systemC() ? "1" : "0");
*of << "# Coverage output mode? 0/1 (from --coverage)\n";
cmake_set_raw(*of, name + "_COVERAGE", v3Global.opt.coverage()?"1":"0");
*of << "# Threaded output mode? 0/1/N threads (from --threads)\n";
cmake_set_raw(*of, name + "_THREADS", cvtToStr(v3Global.opt.threads()));
*of << "# VCD Tracing output mode? 0/1 (from --trace)\n";
cmake_set_raw(*of, name + "_TRACE_VCD", (v3Global.opt.trace() && (v3Global.opt.traceFormat() == TraceFormat::VCD))?"1":"0");
*of << "# FST Tracing output mode? 0/1 (from --fst-trace)\n";
cmake_set_raw(*of, name + "_TRACE_FST", (v3Global.opt.trace() && (v3Global.opt.traceFormat() != TraceFormat::VCD)) ? "1":"0");
*of << "\n### Sources...\n";
std::vector<string> classes_fast, classes_slow, support_fast, support_slow, global;
for (AstFile* nodep = v3Global.rootp()->filesp(); nodep;
nodep = VN_CAST(nodep->nextp(), File)) {
AstCFile* cfilep = VN_CAST(nodep, CFile);
if (cfilep && cfilep->source()) {
if (cfilep->support()) {
if (cfilep->slow()) {
support_slow.push_back(cfilep->name());
} else {
support_fast.push_back(cfilep->name());
}
} else {
if (cfilep->slow()) {
classes_slow.push_back(cfilep->name());
} else {
classes_fast.push_back(cfilep->name());
}
}
}
}
global.push_back("${VERILATOR_ROOT}/include/verilated.cpp");
if (v3Global.dpi()) {
global.push_back("${VERILATOR_ROOT}/include/verilated_dpi.cpp");
}
if (v3Global.opt.vpi()) {
global.push_back("${VERILATOR_ROOT}/include/verilated_vpi.cpp");
}
if (v3Global.opt.savable()) {
global.push_back("${VERILATOR_ROOT}/include/verilated_save.cpp");
}
if (v3Global.opt.coverage()) {
global.push_back("${VERILATOR_ROOT}/include/verilated_cov.cpp");
}
if (v3Global.opt.trace()) {
global.push_back("${VERILATOR_ROOT}/include/"
+ v3Global.opt.traceSourceName()+"_c.cpp");
if (v3Global.opt.systemC()) {
if (v3Global.opt.traceFormat() != TraceFormat::VCD) {
v3error("Unsupported: This trace format is not supported in SystemC, use VCD format.");
}
global.push_back("${VERILATOR_ROOT}/include/"
+ v3Global.opt.traceSourceName()+"_sc.cpp");
}
}
if (v3Global.opt.mtasks()) {
global.push_back("${VERILATOR_ROOT}/include/verilated_threads.cpp");
}
if (!v3Global.opt.protectLib().empty()) {
global.push_back(v3Global.opt.makeDir()+"/"+v3Global.opt.protectLib()+".cpp");
}
*of << "# Global classes, need linked once per executable\n";
cmake_set_raw(*of, name + "_GLOBAL", deslash(cmake_list(global)));
*of << "# Generated module classes, non-fast-path, compile with low/medium optimization\n";
cmake_set_raw(*of, name + "_CLASSES_SLOW", deslash(cmake_list(classes_slow)));
*of << "# Generated module classes, fast-path, compile with highest optimization\n";
cmake_set_raw(*of, name + "_CLASSES_FAST", deslash(cmake_list(classes_fast)));
*of << "# Generated support classes, non-fast-path, compile with low/medium optimization\n";
cmake_set_raw(*of, name + "_SUPPORT_SLOW", deslash(cmake_list(support_slow)));
*of << "# Generated support classes, fast-path, compile with highest optimization\n";
cmake_set_raw(*of, name + "_SUPPORT_FAST", deslash(cmake_list(support_fast)));
*of << "# All dependencies\n";
cmake_set_raw(*of, name + "_DEPS", deslash(cmake_list(V3File::getAllDeps())));
*of << "# User .cpp files (from .cpp's on Verilator command line)\n";
cmake_set_raw(*of, name + "_USER_CLASSES", deslash(cmake_list(v3Global.opt.cppFiles())));
}
public:
explicit CMakeEmitter() {
emitOverallCMake();
}
virtual ~CMakeEmitter() {}
};
void V3EmitCMake::emit() {
UINFO(2,__FUNCTION__<<": "<<endl);
CMakeEmitter emitter;
}

34
src/V3EmitCMake.h Normal file
View File

@ -0,0 +1,34 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
// DESCRIPTION: Verilator: Emit CMake file list
//
// Code available from: http://www.veripool.org/verilator
//
//*************************************************************************
//
// Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
// redistribute it and/or modify it under the terms of either the GNU
// Lesser General Public License Version 3 or the Perl Artistic License
// Version 2.0.
//
// Verilator is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
//*************************************************************************
#ifndef _V3EMITCMAKE_H_
#define _V3EMITCMAKE_H_ 1
#include "config_build.h"
#include "verilatedos.h"
//============================================================================
class V3EmitCMake {
public:
static void emit();
};
#endif // Guard

View File

@ -26,16 +26,10 @@
#include "V3EmitMk.h"
#include "V3EmitCBase.h"
#include <algorithm>
#include <cmath>
#include <cstdarg>
#include <map>
#include <vector>
//######################################################################
// Emit statements and math operators
class EmitMkVisitor : public EmitCBaseVisitor {
class EmitMk {
public:
// METHODS
@ -252,23 +246,18 @@ public:
of.putsHeader();
}
//--------------------
virtual void visit(AstNode* nodep) { // LCOV_EXCL_LINE
nodep->v3fatalSrc("No visitors implemented.");
}
public:
explicit EmitMkVisitor(AstNetlist*) {
explicit EmitMk() {
emitClassMake();
emitOverallMake();
}
virtual ~EmitMkVisitor() {}
virtual ~EmitMk() {}
};
//######################################################################
// Gate class functions
void V3EmitMk::emitmk(AstNetlist* nodep) {
void V3EmitMk::emitmk() {
UINFO(2,__FUNCTION__<<": "<<endl);
EmitMkVisitor visitor (nodep);
EmitMk emitter;
}

View File

@ -24,14 +24,11 @@
#include "config_build.h"
#include "verilatedos.h"
#include "V3Error.h"
#include "V3Ast.h"
//============================================================================
class V3EmitMk {
public:
static void emitmk(AstNetlist* nodep);
static void emitmk();
};
#endif // Guard

View File

@ -65,17 +65,19 @@ class V3FileDependImp {
class DependFile {
// A single file
bool m_target; // True if write, else read
bool m_exists;
string m_filename; // Filename
struct stat m_stat; // Stat information
public:
DependFile(const string& filename, bool target)
: m_target(target), m_filename(filename) {
: m_target(target), m_exists(true), m_filename(filename) {
m_stat.st_ctime = 0;
m_stat.st_mtime = 0;
}
~DependFile() {}
const string& filename() const { return m_filename; }
bool target() const { return m_target; }
bool exists() const { return m_exists; }
off_t size() const { return m_stat.st_size; }
ino_t ino() const { return m_stat.st_ino; }
time_t cstime() const { return m_stat.st_ctime; } // Seconds
@ -89,6 +91,7 @@ class V3FileDependImp {
if (err!=0) {
memset(&m_stat, 0, sizeof(m_stat));
m_stat.st_mtime = 1;
m_exists = false;
// Not an error... This can occur due to `line directives in the .vpp files
UINFO(1,"-Info: File not statable: "<<filename()<<endl);
}
@ -125,6 +128,7 @@ public:
}
}
void writeDepend(const string& filename);
std::vector<string> getAllDeps() const;
void writeTimes(const string& filename, const string& cmdlineIn);
bool checkTimes(const string& filename, const string& cmdlineIn);
};
@ -168,6 +172,17 @@ inline void V3FileDependImp::writeDepend(const string& filename) {
}
}
inline std::vector<string> V3FileDependImp::getAllDeps() const {
std::vector<string> r;
for (std::set<DependFile>::const_iterator iter=m_filenameList.begin();
iter!=m_filenameList.end(); ++iter) {
if (!iter->target() && iter->exists()) {
r.push_back(iter->filename());
}
}
return r;
}
inline void V3FileDependImp::writeTimes(const string& filename, const string& cmdlineIn) {
const vl_unique_ptr<std::ofstream> ofp (V3File::new_ofstream(filename));
if (ofp->fail()) v3fatal("Can't write "<<filename);
@ -283,6 +298,9 @@ void V3File::addTgtDepend(const string& filename) {
void V3File::writeDepend(const string& filename) {
dependImp.writeDepend(filename);
}
std::vector<string> V3File::getAllDeps() {
return dependImp.getAllDeps();
}
void V3File::writeTimes(const string& filename, const string& cmdlineIn) {
dependImp.writeTimes(filename, cmdlineIn);
}

View File

@ -29,6 +29,7 @@
#include <stack>
#include <set>
#include <list>
#include <vector>
#include <fstream>
//============================================================================
@ -65,6 +66,7 @@ public:
static void addSrcDepend(const string& filename);
static void addTgtDepend(const string& filename);
static void writeDepend(const string& filename);
static std::vector<string> getAllDeps();
static void writeTimes(const string& filename, const string& cmdlineIn);
static bool checkTimes(const string& filename, const string& cmdlineIn);

View File

@ -534,6 +534,12 @@ void V3Options::notify() {
&& !cdc()) {
v3fatal("verilator: Need --cc, --sc, --cdc, --lint-only, --xml_only or --E option");
}
// Make sure at least one make system is enabled
if (!m_gmake && !m_cmake) {
m_gmake = true;
}
if (protectIds()) {
FileLine* cmdfl = new FileLine(FileLine::commandLineFilename());
if (allPublic()) {
@ -889,6 +895,16 @@ void V3Options::parseOptsList(FileLine* fl, const string& optdir, int argc, char
else if (!strcmp(sw, "-l2name")) { // Historical and undocumented
m_l2Name = "v";
}
else if (!strcmp(sw, "-make")) {
shift;
if (!strcmp(argv[i], "cmake")) {
m_cmake = true;
} else if (!strcmp(argv[i], "gmake")) {
m_gmake = true;
} else {
fl->v3fatal("Unknown --make system specified: '"<<argv[i]<<"'");
}
}
else if (!strcmp(sw, "-no-l2name")) { // Historical and undocumented
m_l2Name = "";
}
@ -1323,6 +1339,7 @@ V3Options::V3Options() {
m_bboxSys = false;
m_bboxUnsup = false;
m_cdc = false;
m_cmake = false;
m_coverageLine = false;
m_coverageToggle = false;
m_coverageUnderscore = false;
@ -1341,6 +1358,7 @@ V3Options::V3Options() {
m_ignc = false;
m_inhibitSim = false;
m_lintOnly = false;
m_gmake = false;
m_makeDepend = true;
m_makePhony = false;
m_orderClockDly = true;

View File

@ -109,6 +109,7 @@ class V3Options {
bool m_bboxSys; // main switch: --bbox-sys
bool m_bboxUnsup; // main switch: --bbox-unsup
bool m_cdc; // main switch: --cdc
bool m_cmake; // main switch: --make cmake
bool m_coverageLine; // main switch: --coverage-block
bool m_coverageToggle;// main switch: --coverage-toggle
bool m_coverageUnderscore;// main switch: --coverage-underscore
@ -127,6 +128,7 @@ class V3Options {
bool m_ignc; // main switch: --ignc
bool m_inhibitSim; // main switch: --inhibit-sim
bool m_lintOnly; // main switch: --lint-only
bool m_gmake; // main switch: --make gmake
bool m_orderClockDly;// main switch: --order-clock-delay
bool m_outFormatOk; // main switch: --cc, --sc or --sp was specified
bool m_pinsScUint; // main switch: --pins-sc-uint
@ -282,6 +284,7 @@ class V3Options {
bool bboxSys() const { return m_bboxSys; }
bool bboxUnsup() const { return m_bboxUnsup; }
bool cdc() const { return m_cdc; }
bool cmake() const { return m_cmake; }
bool coverage() const { return m_coverageLine || m_coverageToggle || m_coverageUser; }
bool coverageLine() const { return m_coverageLine; }
bool coverageToggle() const { return m_coverageToggle; }
@ -298,6 +301,7 @@ class V3Options {
bool dpiHdrOnly() const { return m_dpiHdrOnly; }
bool dumpDefines() const { return m_dumpDefines; }
bool exe() const { return m_exe; }
bool gmake() const { return m_gmake; }
bool threadsDpiPure() const { return m_threadsDpiPure; }
bool threadsDpiUnpure() const { return m_threadsDpiUnpure; }
bool threadsCoarsen() const { return m_threadsCoarsen; }

View File

@ -43,6 +43,7 @@
#include "V3DepthBlock.h"
#include "V3Descope.h"
#include "V3EmitC.h"
#include "V3EmitCMake.h"
#include "V3EmitMk.h"
#include "V3EmitV.h"
#include "V3EmitXml.h"
@ -565,7 +566,12 @@ void process() {
&& !v3Global.opt.xmlOnly()
&& !v3Global.opt.dpiHdrOnly()) {
// Makefile must be after all other emitters
V3EmitMk::emitmk(v3Global.rootp());
if (v3Global.opt.cmake()) {
V3EmitCMake::emit();
}
if (v3Global.opt.gmake()) {
V3EmitMk::emitmk();
}
}
// Note early return above when opt.cdc()
@ -596,6 +602,7 @@ int main(int argc, char** argv, char** env) {
// Validate settings (aka Boost.Program_options)
v3Global.opt.notify();
V3Error::abortIfErrors();
// Can we skip doing everything if times are ok?

105
test_regress/CMakeLists.txt Normal file
View File

@ -0,0 +1,105 @@
######################################################################
#
# DESCRIPTION: CMake script for regression tests
#
# This CMake file is meant to be consumed by regression tests.
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
cmake_minimum_required(VERSION 3.8)
set(TEST_REQUIRED_VARS NAME CSOURCES OPT_FAST VERILATOR_ROOT VERILATOR_ARGS
VERILATOR_SOURCES SYSTEMC VERBOSE VERILATION)
foreach(var ${TEST_REQUIRED_VARS})
if (NOT DEFINED TEST_${var})
message(FATAL_ERROR "TEST_${var} not defined. This CMakeLists.txt file is meant to be run by driver.pl.")
endif()
endforeach()
project("${TEST_NAME}")
if(TEST_VERBOSE)
add_definitions(-DTEST_VERBOSE=1)
endif()
separate_arguments(TEST_VERILATOR_ARGS UNIX_COMMAND "${TEST_VERILATOR_ARGS}")
# filter out empty arguments
list(FILTER TEST_VERILATOR_ARGS EXCLUDE REGEX "$^")
set(TEST_PREFIX ${TEST_NAME})
# If --ARG <val> is present, set OUT = <val>
function(getarg LST ARG OUT)
list(FIND ${LST} ${ARG} _INDEX)
if(NOT _INDEX EQUAL -1)
list(REMOVE_AT ${LST} ${_INDEX})
list(GET ${LST} ${_INDEX} VAL)
set(${OUT} ${VAL} PARENT_SCOPE)
endif()
endfunction()
# Normalise -- to -
string(REGEX REPLACE "(^|;)--" "\\1-"
TEST_VERILATOR_ARGS_NORM
"${TEST_VERILATOR_ARGS}")
getarg(TEST_VERILATOR_ARGS_NORM "-prefix" TEST_PREFIX)
getarg(TEST_VERILATOR_ARGS_NORM "-threads" TEST_THREADS)
# Strip unwanted args with 1 parameter
string(REGEX REPLACE "(^|;)--?(Mdir|make|prefix|threads);[^;]*" ""
TEST_VERILATOR_ARGS
"${TEST_VERILATOR_ARGS}")
# Strip unwanted args
string(REGEX REPLACE "(^|;)--?(sc|cc)" ""
TEST_VERILATOR_ARGS
"${TEST_VERILATOR_ARGS}")
separate_arguments(TEST_VERILATOR_SOURCES UNIX_COMMAND "${TEST_VERILATOR_SOURCES}")
# filter out empty sources
list(FILTER TEST_VERILATOR_SOURCES EXCLUDE REGEX "$^")
find_package(verilator REQUIRED HINTS ${TEST_VERILATOR_ROOT})
set(verilate_ARGS MAIN)
if(TEST_PREFIX)
list(APPEND verilate_ARGS PREFIX ${TEST_PREFIX})
endif()
if(TEST_OPT_FAST)
list(APPEND verilate_ARGS OPT_FAST ${TEST_OPT_FAST})
endif()
if(TEST_THREADS)
list(APPEND verilate_ARGS THREADS ${TEST_THREADS})
endif()
if(TEST_SYSTEMC)
list(APPEND verilate_ARGS SYSTEMC)
endif()
set(TARGET_NAME "V${TEST_NAME}")
add_executable(${TARGET_NAME} ${TEST_CSOURCES})
if(TEST_VERILATION)
verilate(${TARGET_NAME} ${verilate_ARGS}
VERILATOR_ARGS ${TEST_VERILATOR_ARGS}
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
SOURCES ${TEST_VERILATOR_SOURCES})
endif()
if(TEST_SYSTEMC)
verilator_link_systemc("${TARGET_NAME}")
endif()
string(TOUPPER "${TEST_NAME}" TEST_NAME_UC)
target_compile_definitions(${TARGET_NAME} PRIVATE
"TEST_OBJ_DIR=${CMAKE_CURRENT_BINARY_DIR}"
"VM_PREFIX=${TEST_PREFIX}"
"VM_PREFIX_INCLUDE=<${TEST_PREFIX}.h>"
"${TEST_NAME_UC}"
)

View File

@ -19,6 +19,7 @@ use Data::Dumper; $Data::Dumper::Sortkeys=1;
use FindBin qw($RealBin);
use strict;
use vars qw($Debug %Vars $Driver $Fork);
use version;
use POSIX qw(strftime);
use lib ".";
use Time::HiRes qw(usleep);
@ -601,6 +602,7 @@ sub new {
verilator_flags2 => [],
verilator_flags3 => ["--clk clk"],
verilator_make_gmake => 1,
verilator_make_cmake => 0,
verilated_debug => $Opt_Verilated_Debug,
stdout_filename => undef, # Redirect stdout
%$self};
@ -768,6 +770,21 @@ sub _read_status {
#----------------------------------------------------------------------
# Methods invoked by tests
sub compile_vlt_cmd {
my $self = (ref $_[0]? shift : $Self);
my %param = (%{$self}, @_); # Default arguments are from $self
return 1 if $self->errors || $self->skips || $self->unsupporteds;
my @vlt_cmd = (
"perl", "$ENV{VERILATOR_ROOT}/bin/verilator",
$self->compile_vlt_flags(%param),
$param{top_filename},
@{$param{v_other_filenames}},
$param{stdout_filename}?"> ".$param{stdout_filename}:""
);
return @vlt_cmd;
}
sub compile_vlt_flags {
my $self = (ref $_[0]? shift : $Self);
my %param = (%{$self}, @_); # Default arguments are from $self
@ -798,6 +815,8 @@ sub compile_vlt_flags {
unshift @verilator_flags, "--threads $threads" if $param{vltmt} && $checkflags !~ /-threads /;
unshift @verilator_flags, "--trace-fst-thread" if $param{vltmt} && $checkflags =~ /-trace-fst/;
unshift @verilator_flags, "--debug-partition" if $param{vltmt};
unshift @verilator_flags, "--make gmake" if $param{verilator_make_gmake};
unshift @verilator_flags, "--make cmake" if $param{verilator_make_cmake};
if (defined $opt_optimize) {
my $letters = "";
if ($opt_optimize =~ /[a-zA-Z]/) {
@ -812,7 +831,7 @@ sub compile_vlt_flags {
unshift @verilator_flags, "--O".$letters;
}
my @cmdargs = ("perl", "$ENV{VERILATOR_ROOT}/bin/verilator",
my @cmdargs = (
"--prefix ".$param{VM_PREFIX},
@verilator_flags,
@{$param{verilator_flags2}},
@ -822,9 +841,6 @@ sub compile_vlt_flags {
# Flags from driver cmdline override default flags and
# flags from the test itself
@Opt_Driver_Verilator_Flags,
$param{top_filename},
@{$param{v_other_filenames}},
($param{stdout_filename}?"> ".$param{stdout_filename}:""),
);
return @cmdargs;
}
@ -849,7 +865,7 @@ sub compile {
return 1 if $self->errors || $self->skips || $self->unsupporteds;
$self->oprint("Compile\n") if $self->{verbose};
compile_vlt_flags(%param);
compile_vlt_cmd(%param);
if (!$self->{make_top_shell}) {
$param{top_shell_filename}
@ -972,7 +988,6 @@ sub compile {
]);
}
elsif ($param{vlt_all}) {
my @cmdargs = $self->compile_vlt_flags(%param);
if ($self->sc && !$self->have_sc) {
$self->skip("Test requires SystemC; ignore error since not installed\n");
@ -984,33 +999,79 @@ sub compile {
return 1;
}
if ($param{verilator_make_cmake} && !$self->have_cmake) {
$self->skip("Test requires CMake; ignore error since not available or version too old\n");
return 1;
}
if (!$param{fails} && $param{make_main}) {
$self->_make_main();
}
$self->_run(logfile=>"$self->{obj_dir}/vlt_compile.log",
fails=>$param{fails},
tee=>$param{tee},
expect=>$param{expect},
expect_filename=>$param{expect_filename},
cmd=>\@cmdargs) if $::Opt_Verilation;
return 1 if $self->errors || $self->skips || $self->unsupporteds;
if ($param{verilator_make_gmake}
|| (!$param{verilator_make_gmake} && !$param{verilator_make_cmake})) {
my @vlt_cmd = $self->compile_vlt_cmd(%param);
$self->oprint("Running Verilator (gmake)\n") if $self->{verbose};
$self->_run(logfile => "$self->{obj_dir}/vlt_compile.log",
fails => $param{fails},
tee => $param{tee},
expect => $param{expect},
expect_filename => $param{expect_filename},
cmd => \@vlt_cmd) if $::Opt_Verilation;
return 1 if $self->errors || $self->skips || $self->unsupporteds;
}
if ($param{verilator_make_cmake}) {
my @vlt_args = $self->compile_vlt_flags(%param);
$self->oprint("Running cmake\n") if $self->{verbose};
mkdir $self->{obj_dir};
my @csources = ();
unshift @csources, $self->{main_filename} if $param{make_main};
$self->_run(logfile => "$self->{obj_dir}/vlt_cmake.log",
fails => $param{fails},
tee => $param{tee},
expect => $param{expect},
expect_filename => $param{expect_filename},
cmd => ["cd \"".$self->{obj_dir}."\" && cmake",
"\"".$self->{t_dir}."/..\"",
"-DTEST_VERILATOR_ROOT=$ENV{VERILATOR_ROOT}",
"-DTEST_NAME=$self->{name}",
"-DTEST_CSOURCES=\"@csources\"",
"-DTEST_VERILATOR_ARGS=\"@vlt_args\"",
"-DTEST_VERILATOR_SOURCES=\"$param{top_filename} @{$param{v_other_filenames}}\"",
"-DTEST_VERBOSE=\"".($self->{verbose} ? 1 : 0)."\"",
"-DTEST_SYSTEMC=\"" .($self->sc ? 1 : 0). "\"",
"-DCMAKE_PREFIX_PATH=\"".(($ENV{SYSTEMC_INCLUDE}||$ENV{SYSTEMC}||'')."/..\""),
"-DTEST_OPT_FAST=\"" . ($param{benchmark}?"-O2":"") . "\"",
"-DTEST_VERILATION=\"" . $::Opt_Verilation . "\"",
]);
return 1 if $self->errors || $self->skips || $self->unsupporteds;
}
if (!$param{fails} && $param{verilator_make_gmake}) {
$self->oprint("GCC\n") if $self->{verbose};
$self->_run(logfile=>"$self->{obj_dir}/vlt_gcc.log",
cmd=>["make",
"-C ".$self->{obj_dir},
"-f ".$::RealBin."/Makefile_obj",
($self->{verbose} ? "" : "--no-print-directory"),
"VM_PREFIX=$self->{VM_PREFIX}",
"TEST_OBJ_DIR=$self->{obj_dir}",
"CPPFLAGS_DRIVER=-D".uc($self->{name}),
($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""),
($param{make_main}?"":"MAKE_MAIN=0"),
($param{benchmark}?"OPT_FAST=-O2":""),
"$self->{VM_PREFIX}", # bypass default rule, as we don't need archive
($param{make_flags}||""),
$self->oprint("Running make (gmake)\n") if $self->{verbose};
$self->_run(logfile => "$self->{obj_dir}/vlt_gcc.log",
cmd => ["make",
"-C ".$self->{obj_dir},
"-f ".$::RealBin."/Makefile_obj",
($self->{verbose} ? "" : "--no-print-directory"),
"VM_PREFIX=$self->{VM_PREFIX}",
"TEST_OBJ_DIR=$self->{obj_dir}",
"CPPFLAGS_DRIVER=-D".uc($self->{name}),
($opt_verbose ? "CPPFLAGS_DRIVER2=-DTEST_VERBOSE=1":""),
($param{make_main}?"":"MAKE_MAIN=0"),
($param{benchmark}?"OPT_FAST=-O2":""),
"$self->{VM_PREFIX}", # bypass default rule, as we don't need archive
($param{make_flags}||""),
]);
}
if (!$param{fails} && $param{verilator_make_cmake}) {
$self->oprint("Running cmake --build\n") if $self->{verbose};
$self->_run(logfile => "$self->{obj_dir}/vlt_cmake_build.log",
cmd => ["cmake",
"--build", $self->{obj_dir},
($self->{verbose}?"--verbose":""),
]);
}
}
@ -1273,6 +1334,23 @@ sub have_sc {
return 0;
}
sub have_cmake {
return cmake_version() >= version->declare("3.8");
}
sub cmake_version {
chomp(my $cmake_bin = `which cmake`);
if (!$cmake_bin) {
return undef;
}
my $cmake_version = `cmake --version`;
if ($cmake_version !~ /cmake version (\d+)\.(\d+)/) {
return undef;
}
$cmake_version = "$1.$2";
return version->declare($cmake_version);
}
sub trace_filename {
my $self = shift;
return "$self->{obj_dir}/simx.fst" if $self->{trace_format} =~ /^fst/;

View File

@ -17,7 +17,7 @@ mkdir $child_dir;
# Compile the child
{
my @cmdargs = $Self->compile_vlt_flags
my @cmdargs = $Self->compile_vlt_cmd
(VM_PREFIX => "$Self->{VM_PREFIX}_child",
top_filename => "$Self->{name}_child.v",
verilator_flags => ["-cc", "-Mdir", "${child_dir}", "--debug-check"],

View File

@ -0,0 +1,28 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2008 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
scenarios(simulator => 1);
compile(
verilator_make_gmake => 0,
verilator_make_cmake => 1,
);
my $cmakecache = $Self->{obj_dir}."/CMakeCache.txt";
if (! -e $cmakecache) {
error("$cmakecache does not exist")
}
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,16 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
always @ (posedge clk) begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,25 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
# This test tests CMake support for SystemC
scenarios(simulator => 1);
compile(
verilator_make_gmake => 0,
verilator_make_cmake => 1,
verilator_flags2 => ["-sc"],
);
execute(
check_finished => 1,
);
ok(1);
1;

View File

@ -0,0 +1,16 @@
// DESCRIPTION: Verilator: Verilog Test module
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2019 by Wilson Snyder.
module t (/*AUTOARG*/
// Inputs
clk
);
input clk;
always @ (posedge clk) begin
$write("*-* All Finished *-*\n");
$finish;
end
endmodule

View File

@ -0,0 +1,26 @@
######################################################################
#
# DESCRIPTION: CMake version configuration file for Verilator
#
# This allows specifying a minimum Verilator version.
# Include it in your CMakeLists.txt using:
#
# find_package(verilate 4.0)
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
set(PACKAGE_VERSION "@PACKAGE_VERSION@")
if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()
set(PACKAGE_VERSION_COMPATIBLE TRUE)
if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
set(PACKAGE_VERSION_EXACT TRUE)
endif()
endif()

392
verilator-config.cmake.in Normal file
View File

@ -0,0 +1,392 @@
######################################################################
#
# DESCRIPTION: CMake configuration file for Verilator
#
# Include it in your CMakeLists.txt using:
#
# find_package(verilate)
#
# This script adds a verilate function.
#
# add_executable(simulator <your-c-sources>)
# verilate(simulator SOURCES <your-hdl-sources>)
#
# Copyright 2003-2019 by Wilson Snyder. This program is free software; you can
# redistribute it and/or modify it under the terms of either the GNU
# Lesser General Public License Version 3 or the Perl Artistic License
# Version 2.0.
#
######################################################################
cmake_minimum_required(VERSION 3.8)
# Prefer VERILATOR_ROOT from environment
if (DEFINED ENV{VERILATOR_ROOT})
set(VERILATOR_ROOT "$ENV{VERILATOR_ROOT}" CACHE PATH "VERILATOR_ROOT")
endif()
set(VERILATOR_ROOT "${CMAKE_CURRENT_LIST_DIR}" CACHE PATH "VERILATOR_ROOT")
find_program(VERILATOR_BIN NAMES verilator_bin verilator_bin.exe
HINTS ${VERILATOR_ROOT}/bin ENV VERILATOR_ROOT
NO_CMAKE_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_SYSTEM_PATH)
if (NOT VERILATOR_ROOT)
message(FATAL_ERROR "VERILATOR_ROOT cannot be detected. Set it to the appropriate directory (e.g. /usr/share/verilator) as an environment variable or CMake define.")
endif()
if (NOT VERILATOR_BIN)
message(FATAL_ERROR "Cannot find verilator_bin excecutable.")
endif()
set(verilator_FOUND 1)
include(CheckCXXSourceCompiles)
function(_verilator_check_cxx_libraries LIBRARIES RESVAR)
# Check whether a particular link option creates a valid executable
set(_VERILATOR_CHECK_CXX_LINK_OPTIONS_SRC "int main() {return 0;}\n")
set(CMAKE_REQUIRED_FLAGS)
set(CMAKE_REQUIRED_DEFINITIONS)
set(CMAKE_REQUIRED_INCLUDES)
set(CMAKE_REQUIRED_LINK_OPTIONS)
set(CMAKE_REQUIRED_LIBRARIES ${LIBRARIES})
set(CMAKE_REQUIRED_QUIET)
check_cxx_source_compiles("${_VERILATOR_CHECK_CXX_LINK_OPTIONS_SRC}" "${RESVAR}")
set("${RESVAR}" "${${RESVAR}}" PARENT_SCOPE)
endfunction()
# Check compiler flag support. Skip on MSVC, these are all GCC flags.
if (NOT CMAKE_CXX_COMPILER_ID MATCHES MSVC)
if (NOT DEFINED VERILATOR_CFLAGS OR NOT DEFINED VERILATOR_MT_CFLAGS)
include(CheckCXXCompilerFlag)
foreach (FLAG @CFG_CXX_FLAGS_CMAKE@)
string(MAKE_C_IDENTIFIER ${FLAG} FLAGNAME)
check_cxx_compiler_flag(${FLAG} ${FLAGNAME})
if (${FLAGNAME})
list(APPEND VERILATOR_CFLAGS ${FLAG})
endif()
endforeach()
foreach (FLAG @CFG_LDFLAGS_THREADS_CMAKE@)
string(MAKE_C_IDENTIFIER ${FLAG} FLAGNAME)
_verilator_check_cxx_libraries("${FLAG}" ${FLAGNAME})
if (${FLAGNAME})
list(APPEND VERILATOR_MT_CFLAGS ${FLAG})
endif()
endforeach()
endif()
endif()
define_property(TARGET
PROPERTY VERILATOR_THREADED
BRIEF_DOCS "Verilator multithreading enabled"
FULL_DOCS "Verilator multithreading enabled"
)
define_property(TARGET
PROPERTY VERILATOR_COVERAGE
BRIEF_DOCS "Verilator coverage enabled"
FULL_DOCS "Verilator coverage enabled"
)
define_property(TARGET
PROPERTY VERILATOR_TRACE
BRIEF_DOCS "Verilator trace enabled"
FULL_DOCS "Verilator trace enabled"
)
define_property(TARGET
PROPERTY VERILATOR_TRACE_VCD
BRIEF_DOCS "Verilator VCD trace enabled"
FULL_DOCS "Verilator VCD trace enabled"
)
define_property(TARGET
PROPERTY VERILATOR_TRACE_FST
BRIEF_DOCS "Verilator FST trace enabled"
FULL_DOCS "Verilator FST trace enabled"
)
define_property(TARGET
PROPERTY VERILATOR_SYSTEMC
BRIEF_DOCS "Verilator SystemC enabled"
FULL_DOCS "Verilator SystemC enabled"
)
function(verilate TARGET)
cmake_parse_arguments(VERILATE "COVERAGE;TRACE;TRACE_FST;SYSTEMC"
"PREFIX;TOP_MODULE;THREADS;DIRECTORY"
"SOURCES;VERILATOR_ARGS;INCLUDE_DIRS;OPT_SLOW;OPT_FAST"
${ARGN})
if (NOT VERILATE_SOURCES)
message(FATAL_ERROR "Need at least one source")
endif()
if (NOT VERILATE_PREFIX)
list(GET VERILATE_SOURCES 0 TOPSRC)
get_filename_component(_SRC_NAME ${TOPSRC} NAME_WE)
set(VERILATE_PREFIX V${_SRC_NAME})
endif()
if (VERILATE_TOP_MODULE)
list(APPEND VERILATOR_ARGS --top-module ${VERILATE_TOP_MODULE})
endif()
if (VERILATE_THREADS)
list(APPEND VERILATOR_ARGS --threads ${VERILATE_THREADS})
endif()
if (VERILATE_COVERAGE)
list(APPEND VERILATOR_ARGS --coverage)
endif()
if (VERILATE_TRACE AND VERILATE_TRACE_FST)
message(FATAL_ERROR "Cannot have both TRACE and TRACE_FST")
endif()
if (VERILATE_TRACE)
list(APPEND VERILATOR_ARGS --trace)
endif()
if (VERILATE_TRACE_FST)
list(APPEND VERILATOR_ARGS --trace-fst)
endif()
if (VERILATE_SYSTEMC)
list(APPEND VERILATOR_ARGS --sc)
else()
list(APPEND VERILATOR_ARGS --cc)
endif()
foreach(INC ${VERILATE_INCLUDE_DIRS})
list(APPEND VERILATOR_ARGS -y "${INC}")
endforeach()
string(TOLOWER ${CMAKE_CXX_COMPILER_ID} COMPILER)
if (NOT COMPILER MATCHES "msvc|clang")
set(COMPILER gcc)
endif()
get_target_property(BINARY_DIR "${TARGET}" BINARY_DIR)
get_target_property(TARGET_NAME "${TARGET}" NAME)
set(VDIR "${BINARY_DIR}/CMakeFiles/${TARGET_NAME}.dir/${VERILATE_PREFIX}.dir")
if (VERILATE_DIRECTORY)
set(VDIR "${VERILATE_DIRECTORY}")
endif()
file(MAKE_DIRECTORY ${VDIR})
set(VERILATOR_COMMAND "${VERILATOR_BIN}" --compiler ${COMPILER}
--prefix ${VERILATE_PREFIX} --Mdir ${VDIR} --make cmake
${VERILATOR_ARGS} ${VERILATE_VERILATOR_ARGS}
${VERILATE_SOURCES})
set(VARGS_FILE "${VDIR}/verilator_args.txt")
set(VCMAKE "${VDIR}/${VERILATE_PREFIX}.cmake")
set(VCMAKE_COPY "${VDIR}/${VERILATE_PREFIX}_copy.cmake")
if (NOT EXISTS "${VARGS_FILE}" OR NOT EXISTS "${VCMAKE_COPY}")
set(VERILATOR_OUTDATED ON)
else()
file(READ "${VARGS_FILE}" PREVIOUS_VERILATOR_COMMAND)
if(NOT VERILATOR_COMMAND STREQUAL PREVIOUS_VERILATOR_COMMAND)
set(VERILATOR_OUTDATED ON)
endif()
endif()
if (VERILATOR_OUTDATED)
message(STATUS "Executing Verilator...")
execute_process(
COMMAND ${VERILATOR_COMMAND}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
RESULT_VARIABLE _VERILATOR_RC
OUTPUT_VARIABLE _VERILATOR_OUTPUT
ERROR_VARIABLE _VERILATOR_OUTPUT)
if (_VERILATOR_RC)
string(REPLACE ";" " " VERILATOR_COMMAND_READABLE "${VERILATOR_COMMAND}")
message("Verilator command: \"${VERILATOR_COMMAND_READABLE}\"")
message("Output:\n${_VERILATOR_OUTPUT}")
message(FATAL_ERROR "Verilator command failed (return code=${_VERILATOR_RC})")
endif()
execute_process(COMMAND "${CMAKE_COMMAND}" -E copy "${VCMAKE}" "${VCMAKE_COPY}")
endif()
file(WRITE "${VARGS_FILE}" "${VERILATOR_COMMAND}")
include("${VCMAKE_COPY}")
set(GENERATED_C_SOURCES ${${VERILATE_PREFIX}_CLASSES_FAST}
${${VERILATE_PREFIX}_CLASSES_SLOW}
${${VERILATE_PREFIX}_SUPPORT_FAST}
${${VERILATE_PREFIX}_SUPPORT_SLOW})
foreach(GENERATED_C_SOURCE ${GENERATED_C_SOURCES})
get_filename_component(C_OUTPUT_NAME_WE "${GENERATED_C_SOURCE}" NAME_WE)
if(C_OUTPUT_NAME_WE MATCHES ".*Trace.*")
continue()
endif()
list(APPEND GENERATED_H_SOURCES "${VDIR}/${C_OUTPUT_NAME_WE}.h")
endforeach()
set(GENERATED_SOURCES ${GENERATED_C_SOURCES} ${GENERATED_H_SOURCES})
add_custom_command(OUTPUT ${GENERATED_SOURCES} "${VCMAKE}"
COMMAND ${VERILATOR_COMMAND}
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
DEPENDS "${VERILATOR_BIN}" ${${VERILATE_PREFIX}_DEPS} VERBATIM)
# Reconfigure if file list has changed
# (check contents rather than modified time to avoid unnecessary reconfiguration)
add_custom_command(OUTPUT "${VCMAKE_COPY}"
COMMAND "${CMAKE_COMMAND}" -E copy_if_different
"${VCMAKE}" "${VCMAKE_COPY}"
DEPENDS "${VCMAKE}" VERBATIM)
if (${VERILATE_PREFIX}_THREADS)
# If any verilate() call specifies THREADS, define VL_THREADED in the final build
set_property(TARGET ${TARGET} PROPERTY VERILATOR_THREADED ON)
endif()
if (${VERILATE_PREFIX}_COVERAGE)
# If any verilate() call specifies COVERAGE, define VM_COVERAGE in the final build
set_property(TARGET ${TARGET} PROPERTY VERILATOR_COVERAGE ON)
endif()
if (${VERILATE_PREFIX}_TRACE_VCD)
# If any verilate() call specifies TRACE, define VM_TRACE in the final build
set_property(TARGET ${TARGET} PROPERTY VERILATOR_TRACE ON)
set_property(TARGET ${TARGET} PROPERTY VERILATOR_TRACE_VCD ON)
endif()
if (${VERILATE_PREFIX}_TRACE_FST)
# If any verilate() call specifies TRACE_FST, define VM_TRACE_FST in the final build
set_property(TARGET ${TARGET} PROPERTY VERILATOR_TRACE ON)
set_property(TARGET ${TARGET} PROPERTY VERILATOR_TRACE_FST ON)
endif()
if (${VERILATE_PREFIX}_SC)
# If any verilate() call specifies SYSTEMC, define VM_SC in the final build
set_property(TARGET ${TARGET} PROPERTY VERILATOR_SYSTEMC ON)
endif()
# Add the compile flags only on Verilated sources
target_include_directories(${TARGET} PUBLIC ${VDIR})
target_sources(${TARGET} PRIVATE ${GENERATED_SOURCES} "${VCMAKE_COPY}"
${${VERILATE_PREFIX}_GLOBAL}
${${VERILATE_PREFIX}_USER_CLASSES})
foreach(_VSOURCE ${VERILATE_SOURCES} ${${VERILATE_PREFIX}_DEPS})
get_filename_component(_VSOURCE "${_VSOURCE}" ABSOLUTE BASE_DIR)
list(APPEND VHD_SOURCES "${_VSOURCE}")
endforeach()
target_sources(${TARGET} PRIVATE ${VHD_SOURCES})
# Add the compile flags only on Verilated sources
foreach(VSLOW ${${VERILATE_PREFIX}_CLASSES_SLOW} ${${VERILATE_PREFIX}_SUPPORT_SLOW})
foreach(OPT_SLOW ${VERILATE_OPT_SLOW} ${${VERILATE_PREFIX}_USER_CFLAGS})
set_property(SOURCE "${VSLOW}" APPEND_STRING PROPERTY COMPILE_FLAGS " ${OPT_SLOW}")
endforeach()
endforeach()
foreach(VFAST ${${VERILATE_PREFIX}_CLASSES_FAST} ${${VERILATE_PREFIX}_SUPPORT_FAST})
foreach(OPT_FAST ${VERILATE_OPT_FAST} ${${VERILATE_PREFIX}_USER_CFLAGS})
set_property(SOURCE "${VFAST}" APPEND_STRING PROPERTY COMPILE_FLAGS " ${OPT_FAST}")
endforeach()
endforeach()
target_include_directories(${TARGET} PUBLIC "${VERILATOR_ROOT}/include"
"${VERILATOR_ROOT}/include/vltstd")
target_compile_definitions(${TARGET} PRIVATE
VM_COVERAGE=$<BOOL:$<TARGET_PROPERTY:VERILATOR_COVERAGE>>
VM_SC=$<BOOL:$<TARGET_PROPERTY:VERILATOR_SYSTEMC>>
$<$<BOOL:$<TARGET_PROPERTY:VERILATOR_THREADED>>:VL_THREADED>
VM_TRACE=$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE>>
VM_TRACE_VCD=$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE_VCD>>
VM_TRACE_FST=$<BOOL:$<TARGET_PROPERTY:VERILATOR_TRACE_FST>>
)
target_link_libraries(${TARGET} PUBLIC
${${VERILATE_PREFIX}_USER_LDLIBS}
"$<$<BOOL:$<TARGET_PROPERTY:VERILATOR_THREADED>>:${VERILATOR_MT_CFLAGS}>"
)
# SystemC requires the C++ version to match the library version, avoid setting anything here
set(GEN_THREADED $<BOOL:$<TARGET_PROPERTY:VERILATOR_THREADED>>)
set(GEN_SYSTEMC $<BOOL:$<TARGET_PROPERTY:VERILATOR_SYSTEMC>>)
target_compile_features(${TARGET} PRIVATE
$<$<AND:${GEN_THREADED},$<NOT:${GEN_SYSTEMC}>>:cxx_std_11>
)
endfunction()
function(_verilator_find_systemc)
if (NOT TARGET Verilator::systemc)
# Find SystemC include file "systemc.h" in the following order:
# 1. SYSTEMC_INCLUDE (environment) variable
# 2. SYSTEMC_ROOT (environment) variable
# 3. SYSTEMC (environment) variable
# 4. Use CMake module provided by SystemC installation
# (eventually requires CMAKE_PREFIX_PATH set)
find_path(SYSTEMC_INCLUDEDIR NAMES systemc.h
HINTS "${SYSTEMC_INCLUDE} " ENV SYSTEMC_INCLUDE)
find_path(SYSTEMC_INCLUDEDIR NAMES systemc.h
HINTS "${SYSTEMC_ROOT}" ENV SYSTEMC_ROOT
PATH_SUFFIXES include)
find_path(SYSTEMC_INCLUDEDIR NAMES systemc.h
HINTS "${SYSTEMC}" ENV SYSTEMC
PATH_SUFFIXES include)
# Find SystemC library in the following order:
# 1. SYSTEMC_LIBDIR (environment) variable
# 2. SYSTEMC_ROOT (environment) variable
# 3. SYSTEMC (environment) variable
# 4. Use CMake module provided by SystemC installation
# (eventually requires CMAKE_PREFIX_PATH set)
# Find SystemC using include and library paths
find_library(SYSTEMC_LIBRARY NAMES systemc
HINTS "${SYSTEMC_LIBDIR}" ENV SYSTEMC_LIBDIR)
find_library(SYSTEMC_LIBRARY NAMES systemc
HINTS "${SYSTEMC_ROOT}" ENV SYSTEMC_ROOT
PATH_SUFFIXES lib)
find_library(SYSTEMC_LIBRARY NAMES systemc
HINTS "${SYSTEMC}" ENV SYSTEMC
PATH_SUFFIXES lib)
if (SYSTEMC_INCLUDEDIR AND SYSTEMC_LIBRARY)
add_library(Verilator::systemc INTERFACE IMPORTED)
set_target_properties(Verilator::systemc
PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${SYSTEMC_INCLUDEDIR}"
INTERFACE_LINK_LIBRARIES "${SYSTEMC_LIBRARY}")
return()
endif()
find_package(SystemCLanguage QUIET)
if (SystemCLanguage_FOUND)
add_library(Verilator::systemc INTERFACE IMPORTED)
set_target_properties(Verilator::systemc
PROPERTIES
INTERFACE_LINK_LIBRARIES "SystemC::systemc")
return()
endif()
message("SystemC not found. This can be fixed by doing either of the following steps:")
message("- set the SYSTEMC_INCLUDE and SYSTEMC_LIBDIR (environment) variables; or")
message("- set SYSTEMC_ROOT (environment) variable; or")
message("- set SYSTEMC (environment) variable; or")
message("- use the CMake module of your SystemC installation (may require CMAKE_PREFIX_PATH)")
message(FATAL_ERROR "SystemC not found")
endif()
endfunction()
function(verilator_link_systemc TARGET)
_verilator_find_systemc()
target_link_libraries("${TARGET}" PUBLIC Verilator::systemc)
target_compile_options(${TARGET} PRIVATE $ENV{SYSTEMC_CXX_FLAGS} ${SYSTEMC_CXX_FLAGS})
endfunction()
function(verilator_generate_key OUTPUT_VARIABLE)
execute_process(COMMAND ${VERILATOR_BIN} --generate-key
OUTPUT_VARIABLE KEY_VAL
RESULT_VARIABLE KEY_RET)
if (KEY_RET)
message(FATAL_ERROR "verilator --generate-key failed")
endif()
string(STRIP ${KEY_VAL} KEY_VAL)
set(${OUTPUT_VARIABLE} ${KEY_VAL} PARENT_SCOPE)
endfunction()