23 #ifdef YOSYS_ENABLE_READLINE
24 # include <readline/readline.h>
25 # include <readline/history.h>
33 #if !defined(_WIN32) || defined(__MINGW32__)
37 int optind = 1, optcur = 1;
38 int getopt(
int argc,
char **argv,
const char *optstring)
40 if (optind >= argc || argv[optind][0] !=
'-')
43 bool takes_arg =
false;
44 int opt = argv[optind][optcur];
45 for (
int i = 0; optstring[i]; i++)
46 if (opt == optstring[i] && optstring[i + 1] ==
':')
50 if (argv[optind][++optcur] == 0)
55 if (argv[optind][++optcur]) {
56 optarg = argv[optind++] + optcur;
61 optarg = argv[++optind];
70 int main(
int argc,
char **argv)
72 std::string frontend_command =
"auto";
73 std::string backend_command =
"auto";
74 std::vector<std::string> passes_commands;
75 std::vector<std::string> plugin_filenames;
76 std::string output_filename =
"";
77 std::string scriptfile =
"";
78 bool scriptfile_tcl =
false;
79 bool got_output_filename =
false;
80 bool print_banner =
true;
81 bool print_stats =
true;
82 bool call_abort =
false;
84 #ifdef YOSYS_ENABLE_READLINE
85 int history_offset = 0;
86 std::string history_file;
87 if (getenv(
"HOME") !=
NULL) {
88 history_file =
stringf(
"%s/.yosys_history", getenv(
"HOME"));
89 read_history(history_file.c_str());
90 history_offset = where_history();
95 while ((opt = getopt(argc, argv,
"AQTVSm:f:Hh:b:o:p:l:qv:ts:c:")) != -1)
103 print_banner =
false;
112 passes_commands.push_back(
"synth");
115 plugin_filenames.push_back(optarg);
118 frontend_command = optarg;
121 passes_commands.push_back(
"help");
124 passes_commands.push_back(
stringf(
"help %s", optarg));
127 backend_command = optarg;
130 passes_commands.push_back(optarg);
133 output_filename = optarg;
134 got_output_filename =
true;
137 log_files.push_back(fopen(optarg,
"wt"));
139 fprintf(stderr,
"Can't open log file `%s' for writing!\n", optarg);
157 scriptfile_tcl =
false;
161 scriptfile_tcl =
true;
164 fprintf(stderr,
"\n");
165 fprintf(stderr,
"Usage: %s [-V -S -Q -T -q] [-v <level>[-t] [-l <logfile>] [-o <outfile>] [-f <frontend>] [-h cmd] \\\n", argv[0]);
166 fprintf(stderr,
" %*s[{-s|-c} <scriptfile>] [-p <pass> [-p ..]] [-b <backend>] [-m <module_file>] [<infile> [..]]\n",
int(strlen(argv[0])+1),
"");
167 fprintf(stderr,
"\n");
168 fprintf(stderr,
" -Q\n");
169 fprintf(stderr,
" suppress printing of banner (copyright, disclaimer, version)\n");
170 fprintf(stderr,
"\n");
171 fprintf(stderr,
" -T\n");
172 fprintf(stderr,
" suppress printing of footer (log hash, version, timing statistics)\n");
173 fprintf(stderr,
"\n");
174 fprintf(stderr,
" -q\n");
175 fprintf(stderr,
" quiet operation. only write warnings and error messages to console\n");
176 fprintf(stderr,
" use this option twice to also quiet warning messages\n");
177 fprintf(stderr,
"\n");
178 fprintf(stderr,
" -v <level>\n");
179 fprintf(stderr,
" print log headers up to level <level> to the console. (implies -q)\n");
180 fprintf(stderr,
"\n");
181 fprintf(stderr,
" -t\n");
182 fprintf(stderr,
" annotate all log messages with a time stamp\n");
183 fprintf(stderr,
"\n");
184 fprintf(stderr,
" -l logfile\n");
185 fprintf(stderr,
" write log messages to the specified file\n");
186 fprintf(stderr,
"\n");
187 fprintf(stderr,
" -o outfile\n");
188 fprintf(stderr,
" write the design to the specified file on exit\n");
189 fprintf(stderr,
"\n");
190 fprintf(stderr,
" -b backend\n");
191 fprintf(stderr,
" use this backend for the output file specified on the command line\n");
192 fprintf(stderr,
"\n");
193 fprintf(stderr,
" -f backend\n");
194 fprintf(stderr,
" use the specified front for the input files on the command line\n");
195 fprintf(stderr,
"\n");
196 fprintf(stderr,
" -H\n");
197 fprintf(stderr,
" print the command list\n");
198 fprintf(stderr,
"\n");
199 fprintf(stderr,
" -h command\n");
200 fprintf(stderr,
" print the help message for the specified command\n");
201 fprintf(stderr,
"\n");
202 fprintf(stderr,
" -s scriptfile\n");
203 fprintf(stderr,
" execute the commands in the script file\n");
204 fprintf(stderr,
"\n");
205 fprintf(stderr,
" -c tcl_scriptfile\n");
206 fprintf(stderr,
" execute the commands in the tcl script file (see 'help tcl' for details)\n");
207 fprintf(stderr,
"\n");
208 fprintf(stderr,
" -p command\n");
209 fprintf(stderr,
" execute the commands\n");
210 fprintf(stderr,
"\n");
211 fprintf(stderr,
" -m module_file\n");
212 fprintf(stderr,
" load the specified module (aka plugin)\n");
213 fprintf(stderr,
"\n");
214 fprintf(stderr,
" -A\n");
215 fprintf(stderr,
" will call abort() at the end of the script. useful for debugging\n");
216 fprintf(stderr,
"\n");
217 fprintf(stderr,
" -V\n");
218 fprintf(stderr,
" print version information and exit\n");
219 fprintf(stderr,
"\n");
220 fprintf(stderr,
"The option -S is an shortcut for calling the \"synth\" command, a default\n");
221 fprintf(stderr,
"script for transforming the verilog input to a gate-level netlist. For example:\n");
222 fprintf(stderr,
"\n");
223 fprintf(stderr,
" yosys -o output.blif -S input.v\n");
224 fprintf(stderr,
"\n");
225 fprintf(stderr,
"For more complex synthesis jobs it is recommended to use the read_* and write_*\n");
226 fprintf(stderr,
"commands in a script file instead of specifying input and output files on the\n");
227 fprintf(stderr,
"command line.\n");
228 fprintf(stderr,
"\n");
229 fprintf(stderr,
"When no commands, script files or input files are specified on the command\n");
230 fprintf(stderr,
"line, yosys automatically enters the interactive command mode. Use the 'help'\n");
231 fprintf(stderr,
"command to get information on the individual commands.\n");
232 fprintf(stderr,
"\n");
242 log(
" /----------------------------------------------------------------------------\\\n");
244 log(
" | yosys -- Yosys Open SYnthesis Suite |\n");
246 log(
" | Copyright (C) 2012 Clifford Wolf <clifford@clifford.at> |\n");
248 log(
" | Permission to use, copy, modify, and/or distribute this software for any |\n");
249 log(
" | purpose with or without fee is hereby granted, provided that the above |\n");
250 log(
" | copyright notice and this permission notice appear in all copies. |\n");
252 log(
" | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |\n");
253 log(
" | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |\n");
254 log(
" | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |\n");
255 log(
" | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |\n");
256 log(
" | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |\n");
257 log(
" | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |\n");
258 log(
" | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |\n");
260 log(
" \\----------------------------------------------------------------------------/\n");
271 for (
auto &fn : plugin_filenames)
274 if (optind == argc && passes_commands.size() == 0 && scriptfile.empty()) {
275 if (!got_output_filename)
276 backend_command =
"";
280 while (optind < argc)
283 if (!scriptfile.empty()) {
284 if (scriptfile_tcl) {
285 #ifdef YOSYS_ENABLE_TCL
286 if (Tcl_EvalFile(yosys_get_tcl_interp(), scriptfile.c_str()) != TCL_OK)
287 log_error(
"TCL interpreter returned an error: %s\n", Tcl_GetStringResult(yosys_get_tcl_interp()));
289 log_error(
"Can't exectue TCL script: this version of yosys is not built with TCL support enabled.\n");
295 for (
auto it = passes_commands.begin(); it != passes_commands.end(); it++)
298 if (!backend_command.empty())
309 log(
"End of script. Logfile hash: %s\n", hash.c_str());
311 struct rusage ru_buffer;
312 getrusage(RUSAGE_SELF, &ru_buffer);
313 log(
"End of script. Logfile hash: %s, CPU: user %.2fs system %.2fs\n", hash.c_str(),
314 ru_buffer.ru_utime.tv_sec + 1e-6 * ru_buffer.ru_utime.tv_usec,
315 ru_buffer.ru_stime.tv_sec + 1e-6 * ru_buffer.ru_stime.tv_usec);
319 int64_t total_ns = 0;
320 std::set<std::tuple<int64_t, int, std::string>> timedat;
323 if (it.second->call_counter) {
324 total_ns += it.second->runtime_ns + 1;
325 timedat.insert(make_tuple(it.second->runtime_ns + 1, it.second->call_counter, it.first));
330 for (
auto it = timedat.rbegin(); it != timedat.rend() && out_count < 4; it++, out_count++) {
331 if (out_count >= 2 && (std::get<0>(*it) < 1000000000 ||
int(100*std::get<0>(*it) / total_ns) < 20)) {
335 log(
"%s %d%% %dx %s (%d sec)", out_count ?
"," :
"",
int(100*std::get<0>(*it) / total_ns),
336 std::get<1>(*it), std::get<2>(*it).c_str(), int(std::get<0>(*it) / 1000000000));
338 log(
"%s\n", out_count ?
"" :
" no commands executed");
341 #ifdef YOSYS_ENABLE_COVER
342 if (getenv(
"YOSYS_COVER_DIR") || getenv(
"YOSYS_COVER_FILE"))
344 char filename_buffer[4096];
347 if (getenv(
"YOSYS_COVER_DIR")) {
348 snprintf(filename_buffer, 4096,
"%s/yosys_cover_%d_XXXXXX.txt", getenv(
"YOSYS_COVER_DIR"), getpid());
349 f = fdopen(mkstemps(filename_buffer, 4),
"w");
351 snprintf(filename_buffer, 4096,
"%s", getenv(
"YOSYS_COVER_FILE"));
352 f = fopen(filename_buffer,
"a+");
356 log_error(
"Can't create coverage file `%s'.\n", filename_buffer);
358 log(
"<writing coverage file \"%s\">\n", filename_buffer);
360 for (
auto &it : get_coverage_data())
361 fprintf(f,
"%-60s %10d %s\n", it.second.first.c_str(), it.second.second, it.first.c_str());
370 #ifdef YOSYS_ENABLE_READLINE
371 if (!history_file.empty()) {
372 if (history_offset > 0) {
373 history_truncate_file(history_file.c_str(), 100);
374 append_history(where_history() - history_offset, history_file.c_str());
376 write_history(history_file.c_str());
380 HIST_ENTRY **hist_list = history_list();
381 if (hist_list != NULL)
const char * yosys_version_str
std::string stringf(const char *fmt,...)
RTLIL::Design * yosys_design
void log_error(const char *format,...)
YOSYS_NAMESPACE_BEGIN std::vector< FILE * > log_files
static uint32_t hash(uint32_t x)
#define USING_YOSYS_NAMESPACE
USING_YOSYS_NAMESPACE int main(int argc, char **argv)
void load_plugin(std::string filename, std::vector< std::string > aliases)
void shell(RTLIL::Design *design)
void log(const char *format,...)
void run_backend(std::string filename, std::string command, RTLIL::Design *design)
std::map< std::string, Pass * > pass_register
void run_pass(std::string command, RTLIL::Design *design)
void run_frontend(std::string filename, std::string command, RTLIL::Design *design, std::string *backend_command, std::string *from_to_label)