Fix cmake build with --hierarchical option (#2560)

* hier_block with cmake test doesn't assume prefix now.

* Add space between files

* don't set -Mdir on cmake build as it will be set by DIRECTORY option

* Use top target name instead of prefix
This commit is contained in:
Yutetsu TAKATSUKASA 2020-09-20 07:48:05 +09:00 committed by GitHub
parent 1a127a479c
commit 157948c552
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 88 additions and 41 deletions

View File

@ -170,6 +170,8 @@ DISTFILES_INC = $(INFOS) .gitignore \
test_regress/t/t*/*.v* \ test_regress/t/t*/*.v* \
test_regress/t/t*/*/*.sv* \ test_regress/t/t*/*/*.sv* \
test_regress/t/t*/*/*.v* \ test_regress/t/t*/*/*.v* \
test_regress/t/t*/*.cpp \
test_regress/t/t*/CMakeLists.txt \
test_regress/t/*.cpp \ test_regress/t/*.cpp \
test_regress/t/*.h \ test_regress/t/*.h \
test_regress/t/*.dat \ test_regress/t/*.dat \

View File

@ -204,15 +204,14 @@ class CMakeEmitter {
*of << "# Verilate hierarchical blocks\n"; *of << "# Verilate hierarchical blocks\n";
// Sorted hierarchical blocks in order of leaf-first. // Sorted hierarchical blocks in order of leaf-first.
const V3HierBlockPlan::HierVector& hierBlocks = planp->hierBlocksSorted(); const V3HierBlockPlan::HierVector& hierBlocks = planp->hierBlocksSorted();
const string topTarget = v3Global.opt.protectLib().empty() ? v3Global.opt.prefix() *of << "get_target_property(TOP_TARGET_NAME \"${TARGET}\" NAME)\n";
: v3Global.opt.protectLib();
for (V3HierBlockPlan::HierVector::const_iterator it = hierBlocks.begin(); for (V3HierBlockPlan::HierVector::const_iterator it = hierBlocks.begin();
it != hierBlocks.end(); ++it) { it != hierBlocks.end(); ++it) {
const V3HierBlock* hblockp = *it; const V3HierBlock* hblockp = *it;
const V3HierBlock::HierBlockSet& children = hblockp->children(); const V3HierBlock::HierBlockSet& children = hblockp->children();
const string prefix = hblockp->hierPrefix(); const string prefix = hblockp->hierPrefix();
*of << "add_library(" << prefix << " STATIC)\n"; *of << "add_library(" << prefix << " STATIC)\n";
*of << "target_link_libraries(" << topTarget << " PRIVATE " << prefix << ")\n"; *of << "target_link_libraries(${TOP_TARGET_NAME} PRIVATE " << prefix << ")\n";
if (!children.empty()) { if (!children.empty()) {
*of << "target_link_libraries(" << prefix << " INTERFACE"; *of << "target_link_libraries(" << prefix << " INTERFACE";
for (V3HierBlock::HierBlockSet::const_iterator child = children.begin(); for (V3HierBlock::HierBlockSet::const_iterator child = children.begin();
@ -223,16 +222,17 @@ class CMakeEmitter {
} }
*of << "verilate(" << prefix << " PREFIX " << prefix << " TOP_MODULE " *of << "verilate(" << prefix << " PREFIX " << prefix << " TOP_MODULE "
<< hblockp->modp()->name() << " DIRECTORY " << hblockp->modp()->name() << " DIRECTORY "
<< deslash("${CMAKE_CURRENT_BINARY_DIR}/" + prefix) << " SOURCES "; << deslash(v3Global.opt.makeDir() + "/" + prefix) << " SOURCES ";
for (V3HierBlock::HierBlockSet::const_iterator child = children.begin(); for (V3HierBlock::HierBlockSet::const_iterator child = children.begin();
child != children.end(); ++child) { child != children.end(); ++child) {
*of << deslash(" ${CMAKE_CURRENT_BINARY_DIR}/" + (*child)->hierWrapper(true)); *of << " "
<< deslash(v3Global.opt.makeDir() + "/" + (*child)->hierWrapper(true));
} }
*of << " "; *of << " ";
const string vFile = hblockp->vFileIfNecessary(); const string vFile = hblockp->vFileIfNecessary();
if (!vFile.empty()) *of << vFile << " "; if (!vFile.empty()) *of << vFile << " ";
const V3StringList& vFiles = v3Global.opt.vFiles(); const V3StringList& vFiles = v3Global.opt.vFiles();
for (const string& i : vFiles) *of << V3Os::filenameRealPath(i); for (const string& i : vFiles) *of << V3Os::filenameRealPath(i) << " ";
*of << " VERILATOR_ARGS "; *of << " VERILATOR_ARGS ";
*of << "-f " << deslash(hblockp->commandArgsFileName(true)) *of << "-f " << deslash(hblockp->commandArgsFileName(true))
<< " -CFLAGS -fPIC" // hierarchical block will be static, but may be linked << " -CFLAGS -fPIC" // hierarchical block will be static, but may be linked
@ -240,11 +240,12 @@ class CMakeEmitter {
<< ")\n"; << ")\n";
} }
*of << "\n# Verilate the top module that refers protect-lib wrappers of above\n"; *of << "\n# Verilate the top module that refers protect-lib wrappers of above\n";
*of << "verilate(" << topTarget << " PREFIX " << v3Global.opt.prefix() *of << "verilate(${TOP_TARGET_NAME} PREFIX " << v3Global.opt.prefix() << " TOP_MODULE "
<< " TOP_MODULE " << v3Global.rootp()->topModulep()->name() << " DIRECTORY " << v3Global.rootp()->topModulep()->name() << " DIRECTORY "
<< deslash("${CMAKE_CURRENT_BINARY_DIR}/" + topTarget + ".dir") << " SOURCES "; << deslash(v3Global.opt.makeDir()) << " SOURCES ";
for (V3HierBlockPlan::const_iterator it = planp->begin(); it != planp->end(); ++it) { for (V3HierBlockPlan::const_iterator it = planp->begin(); it != planp->end(); ++it) {
*of << deslash(" ${CMAKE_CURRENT_BINARY_DIR}/" + it->second->hierWrapper(true)); *of << " "
<< deslash(v3Global.opt.makeDir() + "/" + it->second->hierWrapper(true));
} }
*of << " " << deslash(cmake_list(v3Global.opt.vFiles())); *of << " " << deslash(cmake_list(v3Global.opt.vFiles()));
*of << " VERILATOR_ARGS "; *of << " VERILATOR_ARGS ";

View File

@ -218,8 +218,8 @@ void V3HierBlock::writeCommandArgsFile(bool forCMake) const {
child != m_children.end(); ++child) { child != m_children.end(); ++child) {
*of << v3Global.opt.makeDir() << "/" << (*child)->hierWrapper(true) << "\n"; *of << v3Global.opt.makeDir() << "/" << (*child)->hierWrapper(true) << "\n";
} }
*of << "-Mdir " << v3Global.opt.makeDir() << "/" << hierPrefix() << " \n";
} }
*of << "-Mdir " << v3Global.opt.makeDir() << "/" << hierPrefix() << " \n";
V3HierWriteCommonInputs(this, of.get(), forCMake); V3HierWriteCommonInputs(this, of.get(), forCMake);
const V3StringList& commandOpts = commandArgs(false); const V3StringList& commandOpts = commandArgs(false);
for (const string& opt : commandOpts) *of << opt << "\n"; for (const string& opt : commandOpts) *of << opt << "\n";

View File

@ -13,38 +13,28 @@ clean_objs();
scenarios(simulator => 1); scenarios(simulator => 1);
top_filename("t/t_hier_block.v"); top_filename("t/t_hier_block.v");
# Travis environment offers 2 VCPUs, 2 thread setting causes the following warning. if (!$Self->have_cmake) {
# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads. $Self->skip("Test requires CMake; ignore error since not available or version too old\n");
# So use 6 threads here though it's not optimal in performace wise, but ok. } else {
compile( run(logfile => "$Self->{obj_dir}/cmake.log",
verilator_make_gmake => 0, cmd => ['cd "' . $Self->{obj_dir} . '" && cmake ' . $Self->{t_dir} . '/t_hier_block_cmake',
verilator_make_cmake => 1, "-DCMAKE_PREFIX_PATH=$ENV{VERILATOR_ROOT}",
v_flags2 => ['t/t_hier_block.cpp'], ($Self->{vltmt} ? '-DTEST_THREADS=6' : '')
verilator_flags2 => ['--stats', ]);
'--hierarchical',
'--CFLAGS', "'-pipe -DCPP_MACRO=cplusplus '", run(logfile => "$Self->{obj_dir}/build.log",
'--make cmake', cmd => ['cd "' . $Self->{obj_dir} . '" && cmake --build', '.']
($Self->{vltmt} ? ' --threads 6' : '')],
); );
if (!$Self->have_cmake) { run(logfile => "$Self->{obj_dir}/run.log",
skip("cmake is not installed"); cmd => ['cd "' . $Self->{obj_dir} . '" && ./t_hier_block_cmake', '.']
} else { );
my $cmakecache = $Self->{obj_dir}."/CMakeCache.txt"; my $target_dir = $Self->{obj_dir} .'/CMakeFiles/t_hier_block_cmake.dir/Vt_hier_block.dir/';
if (! -e $cmakecache) { file_grep($target_dir . 'Vsub0/sub0.sv', /^module\s+(\S+)\s+/, "sub0");
error("$cmakecache does not exist.") file_grep($target_dir . 'Vsub1/sub1.sv', /^module\s+(\S+)\s+/, "sub1");
} file_grep($target_dir . 'Vsub2/sub2.sv', /^module\s+(\S+)\s+/, "sub2");
file_grep($target_dir . 'Vt_hier_block__stats.txt', qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10);
execute( file_grep($Self->{obj_dir} . '/run.log', qr/MACRO:(\S+) is defined/i, "cplusplus");
check_finished => 1,
);
file_grep($Self->{obj_dir} . "/Vsub0/sub0.sv", /^module\s+(\S+)\s+/, "sub0");
file_grep($Self->{obj_dir} . "/Vsub1/sub1.sv", /^module\s+(\S+)\s+/, "sub1");
file_grep($Self->{obj_dir} . "/Vsub2/sub2.sv", /^module\s+(\S+)\s+/, "sub2");
file_grep($Self->{obj_dir} . '/Vt_hier_block_cmake__stats.txt', qr/HierBlock,\s+Hierarchical blocks\s+(\d+)/i, 10);
file_grep($Self->{run_log_filename}, qr/MACRO:(\S+) is defined/i, "cplusplus");
} }
ok(1); ok(1);

View File

@ -0,0 +1,27 @@
######################################################################
#
# DESCRIPTION: CMake script for t_hier_block_cmake
#
# Copyright 2003-2020 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.
# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
#
######################################################################
cmake_minimum_required (VERSION 3.8)
project (t_hier_block_cmake)
find_package(verilator REQUIRED)
add_executable(t_hier_block_cmake main.cpp ../t_hier_block.cpp)
if(TEST_THREADS)
set(VERILATOR_OPTIONS "${VERILATOR_OPTIONS}" --threads ${TEST_THREADS})
endif()
set(VERILATOR_OPTIONS "${VERILATOR_OPTIONS}" --hierarchical --stats --CFLAGS "-pipe -DCPP_MACRO=cplusplus")
verilate(t_hier_block_cmake VERILATOR_ARGS ${VERILATOR_OPTIONS} SOURCES
../t_hier_block.v )

View File

@ -0,0 +1,27 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//*************************************************************************
//
// Copyright 2020 by Yutetsu TAKATSUKASA. 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.
// SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0
//
//*************************************************************************
#include <memory>
#include "Vt_hier_block.h"
int main(int argc, char *argv[]) {
std::unique_ptr<Vt_hier_block> top{new Vt_hier_block("top")};
Verilated::commandArgs(argc, argv);
for (int i = 0; i < 100 && !Verilated::gotFinish(); ++i) {
top->eval();
top->clk ^= 1;
}
if (!Verilated::gotFinish()) {
vl_fatal(__FILE__, __LINE__, "main", "%Error: Timeout; never got a $finish");
}
top->final();
return 0;
}