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:
parent
1a127a479c
commit
157948c552
|
|
@ -170,6 +170,8 @@ DISTFILES_INC = $(INFOS) .gitignore \
|
|||
test_regress/t/t*/*.v* \
|
||||
test_regress/t/t*/*/*.sv* \
|
||||
test_regress/t/t*/*/*.v* \
|
||||
test_regress/t/t*/*.cpp \
|
||||
test_regress/t/t*/CMakeLists.txt \
|
||||
test_regress/t/*.cpp \
|
||||
test_regress/t/*.h \
|
||||
test_regress/t/*.dat \
|
||||
|
|
|
|||
|
|
@ -204,15 +204,14 @@ class CMakeEmitter {
|
|||
*of << "# Verilate hierarchical blocks\n";
|
||||
// Sorted hierarchical blocks in order of leaf-first.
|
||||
const V3HierBlockPlan::HierVector& hierBlocks = planp->hierBlocksSorted();
|
||||
const string topTarget = v3Global.opt.protectLib().empty() ? v3Global.opt.prefix()
|
||||
: v3Global.opt.protectLib();
|
||||
*of << "get_target_property(TOP_TARGET_NAME \"${TARGET}\" NAME)\n";
|
||||
for (V3HierBlockPlan::HierVector::const_iterator it = hierBlocks.begin();
|
||||
it != hierBlocks.end(); ++it) {
|
||||
const V3HierBlock* hblockp = *it;
|
||||
const V3HierBlock::HierBlockSet& children = hblockp->children();
|
||||
const string prefix = hblockp->hierPrefix();
|
||||
*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()) {
|
||||
*of << "target_link_libraries(" << prefix << " INTERFACE";
|
||||
for (V3HierBlock::HierBlockSet::const_iterator child = children.begin();
|
||||
|
|
@ -223,16 +222,17 @@ class CMakeEmitter {
|
|||
}
|
||||
*of << "verilate(" << prefix << " PREFIX " << prefix << " TOP_MODULE "
|
||||
<< 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();
|
||||
child != children.end(); ++child) {
|
||||
*of << deslash(" ${CMAKE_CURRENT_BINARY_DIR}/" + (*child)->hierWrapper(true));
|
||||
*of << " "
|
||||
<< deslash(v3Global.opt.makeDir() + "/" + (*child)->hierWrapper(true));
|
||||
}
|
||||
*of << " ";
|
||||
const string vFile = hblockp->vFileIfNecessary();
|
||||
if (!vFile.empty()) *of << vFile << " ";
|
||||
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 << "-f " << deslash(hblockp->commandArgsFileName(true))
|
||||
<< " -CFLAGS -fPIC" // hierarchical block will be static, but may be linked
|
||||
|
|
@ -240,11 +240,12 @@ class CMakeEmitter {
|
|||
<< ")\n";
|
||||
}
|
||||
*of << "\n# Verilate the top module that refers protect-lib wrappers of above\n";
|
||||
*of << "verilate(" << topTarget << " PREFIX " << v3Global.opt.prefix()
|
||||
<< " TOP_MODULE " << v3Global.rootp()->topModulep()->name() << " DIRECTORY "
|
||||
<< deslash("${CMAKE_CURRENT_BINARY_DIR}/" + topTarget + ".dir") << " SOURCES ";
|
||||
*of << "verilate(${TOP_TARGET_NAME} PREFIX " << v3Global.opt.prefix() << " TOP_MODULE "
|
||||
<< v3Global.rootp()->topModulep()->name() << " DIRECTORY "
|
||||
<< deslash(v3Global.opt.makeDir()) << " SOURCES ";
|
||||
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 << " VERILATOR_ARGS ";
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ void V3HierBlock::writeCommandArgsFile(bool forCMake) const {
|
|||
child != m_children.end(); ++child) {
|
||||
*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);
|
||||
const V3StringList& commandOpts = commandArgs(false);
|
||||
for (const string& opt : commandOpts) *of << opt << "\n";
|
||||
|
|
|
|||
|
|
@ -13,38 +13,28 @@ clean_objs();
|
|||
scenarios(simulator => 1);
|
||||
top_filename("t/t_hier_block.v");
|
||||
|
||||
# Travis environment offers 2 VCPUs, 2 thread setting causes the following warning.
|
||||
# %Warning-UNOPTTHREADS: Thread scheduler is unable to provide requested parallelism; consider asking for fewer threads.
|
||||
# So use 6 threads here though it's not optimal in performace wise, but ok.
|
||||
compile(
|
||||
verilator_make_gmake => 0,
|
||||
verilator_make_cmake => 1,
|
||||
v_flags2 => ['t/t_hier_block.cpp'],
|
||||
verilator_flags2 => ['--stats',
|
||||
'--hierarchical',
|
||||
'--CFLAGS', "'-pipe -DCPP_MACRO=cplusplus '",
|
||||
'--make cmake',
|
||||
($Self->{vltmt} ? ' --threads 6' : '')],
|
||||
if (!$Self->have_cmake) {
|
||||
$Self->skip("Test requires CMake; ignore error since not available or version too old\n");
|
||||
} else {
|
||||
run(logfile => "$Self->{obj_dir}/cmake.log",
|
||||
cmd => ['cd "' . $Self->{obj_dir} . '" && cmake ' . $Self->{t_dir} . '/t_hier_block_cmake',
|
||||
"-DCMAKE_PREFIX_PATH=$ENV{VERILATOR_ROOT}",
|
||||
($Self->{vltmt} ? '-DTEST_THREADS=6' : '')
|
||||
]);
|
||||
|
||||
run(logfile => "$Self->{obj_dir}/build.log",
|
||||
cmd => ['cd "' . $Self->{obj_dir} . '" && cmake --build', '.']
|
||||
);
|
||||
|
||||
if (!$Self->have_cmake) {
|
||||
skip("cmake is not installed");
|
||||
} else {
|
||||
my $cmakecache = $Self->{obj_dir}."/CMakeCache.txt";
|
||||
if (! -e $cmakecache) {
|
||||
error("$cmakecache does not exist.")
|
||||
}
|
||||
|
||||
execute(
|
||||
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");
|
||||
|
||||
run(logfile => "$Self->{obj_dir}/run.log",
|
||||
cmd => ['cd "' . $Self->{obj_dir} . '" && ./t_hier_block_cmake', '.']
|
||||
);
|
||||
my $target_dir = $Self->{obj_dir} .'/CMakeFiles/t_hier_block_cmake.dir/Vt_hier_block.dir/';
|
||||
file_grep($target_dir . 'Vsub0/sub0.sv', /^module\s+(\S+)\s+/, "sub0");
|
||||
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);
|
||||
file_grep($Self->{obj_dir} . '/run.log', qr/MACRO:(\S+) is defined/i, "cplusplus");
|
||||
}
|
||||
|
||||
ok(1);
|
||||
|
|
|
|||
|
|
@ -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 )
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
Loading…
Reference in New Issue