PandA-2024.02
VerilatorWrapper.cpp
Go to the documentation of this file.
1 /*
2  *
3  * _/_/_/ _/_/ _/ _/ _/_/_/ _/_/
4  * _/ _/ _/ _/ _/_/ _/ _/ _/ _/ _/
5  * _/_/_/ _/_/_/_/ _/ _/_/ _/ _/ _/_/_/_/
6  * _/ _/ _/ _/ _/ _/ _/ _/ _/
7  * _/ _/ _/ _/ _/ _/_/_/ _/ _/
8  *
9  * ***********************************************
10  * PandA Project
11  * URL: http://panda.dei.polimi.it
12  * Politecnico di Milano - DEIB
13  * System Architectures Group
14  * ***********************************************
15  * Copyright (C) 2004-2024 Politecnico di Milano
16  *
17  * This file is part of the PandA framework.
18  *
19  * The PandA framework is free software; you can redistribute it and/or modify
20  * it under the terms of the GNU General Public License as published by
21  * the Free Software Foundation; either version 3 of the License, or
22  * (at your option) any later version.
23  *
24  * This program is distributed in the hope that it will be useful,
25  * but WITHOUT ANY WARRANTY; without even the implied warranty of
26  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27  * GNU General Public License for more details.
28  *
29  * You should have received a copy of the GNU General Public License
30  * along with this program. If not, see <http://www.gnu.org/licenses/>.
31  *
32  */
43 #include "VerilatorWrapper.hpp"
44 
45 #include "Parameter.hpp"
46 #include "constant_strings.hpp"
47 #include "dbgPrintHelper.hpp"
48 #include "exceptions.hpp"
49 #include "fileIO.hpp"
50 #include "file_IO_constants.hpp"
51 #include "utility.hpp"
52 
53 #include <cerrno>
54 #include <filesystem>
55 #include <fstream>
56 #include <unistd.h>
57 #include <utility>
58 
59 #define SIM_SUBDIR (Param->getOption<std::string>(OPT_output_directory) + std::string("/verilator"))
60 
61 // constructor
62 VerilatorWrapper::VerilatorWrapper(const ParameterConstRef& _Param, const std::string& _suffix,
63  const std::string& _top_fname, const std::string& _inc_dirs)
64  : SimulationTool(_Param, _top_fname, _inc_dirs), suffix(_suffix)
65 {
66  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Creating the VERILATOR wrapper...");
67  std::string verilator_beh_dir = SIM_SUBDIR + suffix;
68  if(std::filesystem::exists(verilator_beh_dir))
69  {
70  std::filesystem::remove_all(verilator_beh_dir);
71  }
72  std::filesystem::create_directory(verilator_beh_dir + "/");
73 }
74 
75 // destructor
77 
79 {
80 }
81 
82 std::string VerilatorWrapper::GenerateScript(std::ostream& script, const std::string& top_filename,
83  const std::list<std::string>& file_list)
84 {
85  for(const auto& file : file_list)
86  {
87  if(file.find(".vhd") != std::string::npos)
88  {
89  THROW_ERROR_CODE(NODE_NOT_YET_SUPPORTED_EC, "Mixed simulation not supported by Verilator");
90  }
91  }
92  const auto generate_vcd_output = (Param->isOption(OPT_generate_vcd) && Param->getOption<bool>(OPT_generate_vcd)) ||
93  (Param->isOption(OPT_discrepancy) && Param->getOption<bool>(OPT_discrepancy)) ||
94  (Param->isOption(OPT_discrepancy_hw) && Param->getOption<bool>(OPT_discrepancy_hw));
95  const auto output_directory = Param->getOption<std::string>(OPT_output_directory);
96  log_file = "${BEH_DIR}/" + top_filename + "_verilator.log";
97  script << "export VM_PARALLEL_BUILDS=1" << std::endl
98  << "BEH_DIR=\"" << SIM_SUBDIR << suffix << "\"" << std::endl
99  << "BEH_CC=\"${CC}\"" << std::endl
100  << "obj_dir=\"${BEH_DIR}/verilator_obj\"" << std::endl
101  << std::endl;
102  std::string beh_cflags = "-DVERILATOR -isystem $(dirname $(which verilator))/../share/verilator/include/vltstd";
103  const auto cflags = GenerateLibraryBuildScript(script, "${BEH_DIR}", beh_cflags);
104  const auto vflags = [&]() {
105  std::string flags;
106  if(cflags.find("-m32") != std::string::npos)
107  {
108  flags += " +define+__M32";
109  }
110  else if(cflags.find("-mx32") != std::string::npos)
111  {
112  flags += " +define+__MX32";
113  }
114  else if(cflags.find("-m64") != std::string::npos)
115  {
116  flags += " +define+__M64";
117  }
118  const auto inc_dir_list = string_to_container<std::vector<std::string>>(inc_dirs, ",");
119  for(const auto& inc : inc_dir_list)
120  {
121  flags += " +incdir+" + inc;
122  }
123  return flags;
124  }();
125 
126 #ifdef _WIN32
127  script << "verilator_bin"
129 #else
130  script << "verilator"
131 #endif
132  << " --cc --exe --Mdir ${obj_dir} -Wno-fatal -Wno-lint -sv " << vflags
133  << " ${BEH_DIR}/libmdpi.so -O3 --output-split-cfuncs 3000 --output-split-ctrace 3000";
134  if(!generate_vcd_output)
135  {
136  script << " --x-assign fast --x-initial fast --noassert";
137  }
138 
139  auto nThreadsVerilator = 1;
140  if(Param->isOption(OPT_verilator_parallel) && Param->getOption<int>(OPT_verilator_parallel) > 1)
141  {
142  const auto thread_support =
143  system("bash -c \"if [ $(verilator --version | grep Verilator | sed -E 's/Verilator ([0-9]+).*/\1/') -ge 4 "
144  "]; then exit 0; else exit 1; fi\" > /dev/null 2>&1") == 0;
145  THROW_WARNING("Installed version of Verilator does not support multi-threading.");
146  if(thread_support)
147  {
148  nThreadsVerilator = Param->getOption<int>(OPT_verilator_parallel);
149  }
150  }
151 
152  if(nThreadsVerilator > 1)
153  {
154  script << " --threads " << nThreadsVerilator;
155  }
156  if(generate_vcd_output)
157  {
158  script << " --trace --trace-underscore"; // --trace-params
159  auto is_verilator_l2_name =
160  system("bash -c \"if [[ \\\"x$(verilator --l2-name v 2>&1 | head -n1 | grep -i 'Invalid Option')\\\" = "
161  "\\\"x\\\" ]]; then exit 0; else exit 1; fi\" > /dev/null 2>&1") == 0;
162  if(is_verilator_l2_name)
163  {
164  script << " --l2-name bambu_testbench";
165  }
166  }
167  for(const auto& file : file_list)
168  {
169  if(ends_with(file, "mdpi.c"))
170  {
171  script << " ${BEH_DIR}/libmdpi.so";
172  }
173  else
174  {
175  script << " " << file;
176  }
177  }
178  script << " --top-module bambu_testbench" << std::endl
179  << "if [ $? -ne 0 ]; then exit 1; fi" << std::endl
180  << std::endl
181  << std::endl
182  << "ln -sf " + output_directory + " ${obj_dir}\n";
183 
184  const auto nThreadsMake =
185  Param->isOption(OPT_verilator_parallel) ? Param->getOption<int>(OPT_verilator_parallel) : 1;
186  script << "make -C ${obj_dir}"
187  << " -j " << nThreadsMake << " OPT=\"-fstrict-aliasing\""
188  << " -f Vbambu_testbench.mk Vbambu_testbench";
189 #ifdef _WIN32
190  script << " VM_PARALLEL_BUILDS=1 CFG_CXXFLAGS_NO_UNUSED=\"\"";
192 #endif
193  script << std::endl << std::endl;
194 
195  return "${obj_dir}/Vbambu_testbench 2>&1 | tee " + log_file;
196 }
197 
199 {
200 }
File containing functions and utilities to support the printing of debug messagges.
#define PRINT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
std::string log_file
log file
void CheckExecution() override
Checks if the current specification can be executed or not.
const ParameterConstRef Param
class containing all the parameters
exceptions managed by PandA
Node not yet supported.
Definition: exceptions.hpp:323
#define SIM_SUBDIR
#define THROW_WARNING(str_expr)
helper function used to throw a warning in a standard way: though it uses PRINT_DBG_MEX, the debug level used is such that the message is always printed
Definition: exceptions.hpp:300
~VerilatorWrapper() override
Destructor.
Wrapper to Verilator simulator.
constants used in Input/Output
std::string GenerateLibraryBuildScript(std::ostream &script, const std::string &libtb_filename, std::string &beh_cflags) const
utility function used to read files.
VerilatorWrapper(const ParameterConstRef &Param, const std::string &suffix, const std::string &top_fname, const std::string &inc_dirs)
Constructor.
bool ends_with(const std::string &str, const std::string &pattern)
This file collects some utility functions and macros.
std::string suffix
suffix added to the SIM dir
std::string GenerateScript(std::ostream &script, const std::string &top_filename, const std::list< std::string > &file_list) override
Generates the proper simulation script.
int debug_level
debug level of the class
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
#define THROW_ERROR_CODE(code, str_expr)
helper function used to throw an error with a code error
Definition: exceptions.hpp:266
this class is used to manage the command-line or XML options.
constant strings
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
void Clean() const override
Remove files created during simulation.
const std::string inc_dirs
comma separated list of include dirs

Generated on Mon Feb 12 2024 13:02:56 for PandA-2024.02 by doxygen 1.8.13