PandA-2024.02
modelsimWrapper.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  */
44 #include "modelsimWrapper.hpp"
45 
46 #include "Parameter.hpp"
47 #include "constant_strings.hpp"
48 #include "custom_set.hpp"
49 #include "dbgPrintHelper.hpp"
50 #include "exceptions.hpp"
51 #include "fileIO.hpp"
52 #include "language_writer.hpp"
53 #include "utility.hpp"
54 
55 #include <boost/algorithm/string.hpp>
56 #include <cerrno>
57 #include <cstdlib>
58 #include <filesystem>
59 #include <fstream>
60 #include <unistd.h>
61 #include <utility>
62 
63 #define MODELSIM_BIN \
64  (Param->isOption(OPT_mentor_modelsim_bin) ? Param->getOption<std::string>(OPT_mentor_modelsim_bin) + "/" : \
65  std::string(""))
66 
67 #define MODELSIM_VDEL (MODELSIM_BIN + "vdel")
68 #define MODELSIM_VLIB (MODELSIM_BIN + "vlib")
69 #define MODELSIM_VMAP (MODELSIM_BIN + "vmap")
70 #define MODELSIM_VCOM (MODELSIM_BIN + "vcom")
71 #define MODELSIM_VLOG (MODELSIM_BIN + "vlog")
72 #define MODELSIM_VSIM (MODELSIM_BIN + "vsim")
73 
74 #define SIM_SUBDIR (Param->getOption<std::string>(OPT_output_directory) + std::string("/modelsim"))
75 
76 // constructor
77 modelsimWrapper::modelsimWrapper(const ParameterConstRef& _Param, const std::string& _suffix,
78  const std::string& _top_fname, const std::string& _inc_dirs)
79  : SimulationTool(_Param, _top_fname, _inc_dirs), suffix(_suffix)
80 {
81  PRINT_DBG_MEX(DEBUG_LEVEL_VERBOSE, debug_level, "Creating the modelsim wrapper...");
82  const auto lic_path = std::getenv("LM_LICENSE_FILE");
83  if(!lic_path || std::string(lic_path) == "")
84  {
85  THROW_WARNING("Mentor license file has not been specified. User must set LM_LICENSE_FILE variable to point to "
86  "the license file location.");
87  }
88  std::filesystem::create_directory(SIM_SUBDIR + suffix + "/");
89 }
90 
91 // destructor
93 
95 {
96 }
97 
98 std::string modelsimWrapper::GenerateScript(std::ostream& script, const std::string& top_filename,
99  const std::list<std::string>& file_list)
100 {
101  THROW_ASSERT(!file_list.empty(), "File list is empty");
102  script << "BEH_DIR=\"" << SIM_SUBDIR << suffix << "\"" << std::endl;
103  const auto modelsim_bin = MODELSIM_BIN;
104  std::string beh_cflags = "-DMODEL_TECH " + (modelsim_bin.size() ? ("-isystem " + modelsim_bin + "../include") : "");
105  const auto cflags = GenerateLibraryBuildScript(script, "${BEH_DIR}", beh_cflags);
106  const auto vflags = [&]() {
107  std::string flags;
108  if(cflags.find("-m32") != std::string::npos)
109  {
110  flags += " +define+__M32";
111  }
112  else if(cflags.find("-mx32") != std::string::npos)
113  {
114  flags += " +define+__MX32";
115  }
116  else if(cflags.find("-m64") != std::string::npos)
117  {
118  flags += " +define+__M64";
119  }
120  if(Param->isOption(OPT_generate_vcd) && Param->getOption<bool>(OPT_generate_vcd))
121  {
122  flags += " +define+GENERATE_VCD";
123  }
124  if(Param->isOption(OPT_discrepancy) && Param->getOption<bool>(OPT_discrepancy))
125  {
126  flags += " +define+GENERATE_VCD_DISCREPANCY";
127  }
128  const auto inc_dir_list = string_to_container<std::vector<std::string>>(inc_dirs, ",");
129  for(const auto& inc : inc_dir_list)
130  {
131  flags += " +incdir+" + inc;
132  }
133  return flags;
134  }();
135 
136  std::string MODELSIM_OPTIMIZER_FLAGS_DEF = "";
137  if(Param->getOption<bool>(OPT_mentor_optimizer))
138  {
139  MODELSIM_OPTIMIZER_FLAGS_DEF = "-O5";
140  }
141  script << "work_dir=\"${BEH_DIR}/modelsim_work\"" << std::endl;
142  script << "if [ ! -d ${BEH_DIR} ]; then" << std::endl;
143  script << " mkdir -p ${BEH_DIR}" << std::endl;
144  script << "fi" << std::endl << std::endl;
145 
146  log_file = "${BEH_DIR}/" + top_filename + "_modelsim.log";
147 
148  script << "if [ -d ${work_dir} ]; then" << std::endl;
149  script << " " << MODELSIM_VDEL << " -all -lib ${work_dir}" << std::endl;
150  script << "fi" << std::endl << std::endl;
151 
152  script << MODELSIM_VLIB << " ${work_dir}";
154  {
155  script << " > /dev/null 2>&1 ";
156  }
157  script << std::endl << std::endl;
158 
159  script << MODELSIM_VMAP << " work ${work_dir}" << std::endl << std::endl;
160 
161  script << "sed -i 's/; AssertionFailAction = 1/AssertionFailAction = 2/g' modelsim.ini" << std::endl << std::endl;
162 
164  for(const auto& file : file_list)
165  {
167  std::filesystem::path file_path(file);
168  const auto extension = file_path.extension().string();
169  if(extension == ".vhd" || extension == ".vhdl" || extension == ".VHD" || extension == ".VHDL")
170  {
171  script << MODELSIM_VCOM << " " << vflags << " " << MODELSIM_OPTIMIZER_FLAGS_DEF;
172  if(Param->isOption(OPT_assert_debug) && Param->getOption<bool>(OPT_assert_debug))
173  {
174  script << " -lint -check_synthesis -fsmsingle -fsmverbose w";
175  }
176  script << " -work work -2008 " << file << std::endl;
177  }
178  else if(extension == ".v" || extension == ".V" || extension == ".sv" || extension == ".SV")
179  {
180  script << MODELSIM_VLOG << " " << vflags << " " << MODELSIM_OPTIMIZER_FLAGS_DEF << " -sv";
181  if(Param->isOption(OPT_assert_debug) && Param->getOption<bool>(OPT_assert_debug))
182  {
183  script << " -lint -fsmsingle -hazards -pedanticerrors -fsmverbose w";
184  }
185  script << " -work work " << file << std::endl;
186  }
187  else if(extension == ".c" || extension == ".cpp")
188  {
189  script << MODELSIM_VLOG << " " << MODELSIM_OPTIMIZER_FLAGS_DEF << " -sv -ccflags \"" << beh_cflags
190  << "\" -work work " << file << std::endl;
191  }
192  else
193  {
194  THROW_UNREACHABLE("Extension not recognized! " + file_path.string());
195  }
196  script << "if [ $? -ne 0 ]; then exit 1; fi" << std::endl << std::endl;
197  }
198 
199  std::string sim_cmd = MODELSIM_VSIM + " " + vflags + " -noautoldlibpath";
200  if(Param->isOption(OPT_assert_debug) && Param->getOption<bool>(OPT_assert_debug))
201  {
202  sim_cmd += " -pedanticerrors -assertdebug";
203  MODELSIM_OPTIMIZER_FLAGS_DEF = "+acc -hazards " + MODELSIM_OPTIMIZER_FLAGS_DEF;
204  }
205  sim_cmd += " -c";
206  if(!MODELSIM_OPTIMIZER_FLAGS_DEF.empty())
207  {
208  sim_cmd += " -voptargs=\"" + MODELSIM_OPTIMIZER_FLAGS_DEF + "\"";
209  }
210  sim_cmd += " -do \"set StdArithNoWarnings 1; set StdNumNoWarnings 1; set NumericStdNoWarnings 1; onerror {quit -f "
211  "-code 1;}; run -all; exit -f;\" work.clocked_bambu_testbench 2>&1 | tee " +
212  log_file;
213  return sim_cmd;
214 }
215 
217 {
218  if(std::filesystem::exists(SIM_SUBDIR + suffix))
219  {
220  std::filesystem::remove_all(SIM_SUBDIR + suffix);
221  }
222 }
#define MODELSIM_VLOG
#define DEBUG_LEVEL_VERY_PEDANTIC
extremely verbose debugging print is performed.
#define INDENT_DBG_MEX(dbgLevel, curDbgLevel, mex)
We are producing a debug version of the program, so the message is printed;.
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;.
#define MODELSIM_VCOM
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
#define MODELSIM_VDEL
exceptions managed by PandA
#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
#define THROW_UNREACHABLE(str_expr)
helper function used to specify that some points should never be reached
Definition: exceptions.hpp:292
#define MODELSIM_VLIB
This class writes different HDL based descriptions (VHDL, Verilog, SystemC) starting from a structura...
std::string GenerateLibraryBuildScript(std::ostream &script, const std::string &libtb_filename, std::string &beh_cflags) const
redefinition of set to manage ordered/unordered structures
utility function used to read files.
std::string suffix
suffix added to the SIM dir
Wrapper to modelsim.
std::string GenerateScript(std::ostream &script, const std::string &top_filename, const std::list< std::string > &file_list) override
Generates the proper simulation script.
This file collects some utility functions and macros.
modelsimWrapper(const ParameterConstRef &Param, const std::string &suffix, const std::string &top_fname, const std::string &inc_dirs)
Constructor.
int debug_level
debug level of the class
#define MODELSIM_BIN
#define OUTPUT_LEVEL_VERY_PEDANTIC
verbose debugging print is performed.
unsigned int output_level
verbosity level of the class
#define MODELSIM_VMAP
Template borrowed from the ANTLR library by Terence Parr (http://www.jGuru.com - Software rights: htt...
Definition: refcount.hpp:94
this class is used to manage the command-line or XML options.
constant strings
#define SIM_SUBDIR
~modelsimWrapper() override
Destructor.
#define DEBUG_LEVEL_VERBOSE
verbose debugging print is performed.
#define MODELSIM_VSIM
void Clean() const override
Remove files created during simulation.
const std::string inc_dirs
comma separated list of include dirs
#define THROW_ASSERT(cond, str_expr)
helper function used to check an assert and if needed to throw an error in a standard way ...
Definition: exceptions.hpp:289

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