yosys-master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
vhdl2verilog.cc
Go to the documentation of this file.
1 /*
2  * yosys -- Yosys Open SYnthesis Suite
3  *
4  * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
5  *
6  * Permission to use, copy, modify, and/or distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  *
18  */
19 
20 #include "kernel/register.h"
21 #include "kernel/sigtools.h"
22 #include "kernel/log.h"
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <limits.h>
28 
29 #ifndef _WIN32
30 # include <unistd.h>
31 # include <dirent.h>
32 #endif
33 
35 
36 struct Vhdl2verilogPass : public Pass {
37  Vhdl2verilogPass() : Pass("vhdl2verilog", "importing VHDL designs using vhdl2verilog") { }
38  virtual void help()
39  {
40  // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
41  log("\n");
42  log(" vhdl2verilog [options] <vhdl-file>..\n");
43  log("\n");
44  log("This command reads VHDL source files using the 'vhdl2verilog' tool and the\n");
45  log("Yosys Verilog frontend.\n");
46  log("\n");
47  log(" -out <out_file>\n");
48  log(" do not import the vhdl2verilog output. instead write it to the\n");
49  log(" specified file.\n");
50  log("\n");
51  log(" -vhdl2verilog_dir <directory>\n");
52  log(" do use the specified vhdl2verilog installation. this is the directory\n");
53  log(" that contains the setup_env.sh file. when this option is not present,\n");
54  log(" it is assumed that vhdl2verilog is in the PATH environment variable.\n");
55  log("\n");
56  log(" -top <top-entity-name>\n");
57  log(" The name of the top entity. This option is mandatory.\n");
58  log("\n");
59  log("The following options are passed as-is to vhdl2verilog:\n");
60  log("\n");
61  log(" -arch <architecture_name>\n");
62  log(" -unroll_generate\n");
63  log(" -nogenericeval\n");
64  log(" -nouniquify\n");
65  log(" -oldparser\n");
66  log(" -suppress <list>\n");
67  log(" -quiet\n");
68  log(" -nobanner\n");
69  log(" -mapfile <file>\n");
70  log("\n");
71  log("vhdl2verilog can be obtained from:\n");
72  log("http://www.edautils.com/vhdl2verilog.html\n");
73  log("\n");
74  }
75  virtual void execute(std::vector<std::string> args, RTLIL::Design *design)
76  {
77  log_header("Executing VHDL2VERILOG (importing VHDL designs using vhdl2verilog).\n");
78  log_push();
79 
80  std::string out_file, top_entity;
81  std::string vhdl2verilog_dir;
82  std::string extra_opts;
83 
84  size_t argidx;
85  for (argidx = 1; argidx < args.size(); argidx++) {
86  if (args[argidx] == "-out" && argidx+1 < args.size()) {
87  out_file = args[++argidx];
88  continue;
89  }
90  if (args[argidx] == "-top" && argidx+1 < args.size()) {
91  top_entity = args[++argidx];
92  continue;
93  }
94  if (args[argidx] == "-vhdl2verilog_dir" && argidx+1 < args.size()) {
95  vhdl2verilog_dir = args[++argidx];
96  continue;
97  }
98  if ((args[argidx] == "-arch" || args[argidx] == "-suppress" || args[argidx] == "-mapfile") && argidx+1 < args.size()) {
99  if (args[argidx] == "-mapfile" && !args[argidx+1].empty() && args[argidx+1][0] != '/') {
100  char pwd[PATH_MAX];
101  if (!getcwd(pwd, sizeof(pwd))) {
102  log_cmd_error("getcwd failed: %s", strerror(errno));
103  log_abort();
104  }
105  args[argidx+1] = pwd + ("/" + args[argidx+1]);
106  }
107  extra_opts += std::string(" ") + args[argidx];
108  extra_opts += std::string(" '") + args[++argidx] + std::string("'");
109  continue;
110  }
111  if (args[argidx] == "-unroll_generate" || args[argidx] == "-nogenericeval" || args[argidx] == "-nouniquify" ||
112  args[argidx] == "-oldparser" || args[argidx] == "-quiet" || args[argidx] == "-nobanner") {
113  extra_opts += std::string(" ") + args[argidx];
114  continue;
115  }
116  break;
117  }
118 
119  if (argidx == args.size())
120  cmd_error(args, argidx, "Missing filenames.");
121  if (args[argidx].substr(0, 1) == "-")
122  cmd_error(args, argidx, "Unknown option.");
123  if (top_entity.empty())
124  log_cmd_error("Missing -top option.\n");
125 
126  std::string tempdir_name = make_temp_dir("/tmp/yosys-vhdl2verilog-XXXXXX");
127  log("Using temp directory %s.\n", tempdir_name.c_str());
128 
129  if (!out_file.empty() && out_file[0] != '/') {
130  char pwd[PATH_MAX];
131  if (!getcwd(pwd, sizeof(pwd))) {
132  log_cmd_error("getcwd failed: %s", strerror(errno));
133  log_abort();
134  }
135  out_file = pwd + ("/" + out_file);
136  }
137 
138  FILE *f = fopen(stringf("%s/files.list", tempdir_name.c_str()).c_str(), "wt");
139  while (argidx < args.size()) {
140  std::string file = args[argidx++];
141  if (file.empty())
142  continue;
143  if (file[0] != '/') {
144  char pwd[PATH_MAX];
145  if (!getcwd(pwd, sizeof(pwd))) {
146  log_cmd_error("getcwd failed: %s", strerror(errno));
147  log_abort();
148  }
149  file = pwd + ("/" + file);
150  }
151  fprintf(f, "%s\n", file.c_str());
152  log("Adding '%s' to the file list.\n", file.c_str());
153  }
154  fclose(f);
155 
156  std::string command = "exec 2>&1; ";
157  if (!vhdl2verilog_dir.empty())
158  command += stringf("cd '%s'; . ./setup_env.sh; ", vhdl2verilog_dir.c_str());
159  command += stringf("cd '%s'; vhdl2verilog -out '%s' -filelist files.list -top '%s'%s", tempdir_name.c_str(),
160  out_file.empty() ? "vhdl2verilog_output.v" : out_file.c_str(), top_entity.c_str(), extra_opts.c_str());
161 
162  log("Running '%s'..\n", command.c_str());
163 
164  int ret = run_command(command, [](const std::string &line) { log("%s", line.c_str()); });
165  if (ret != 0)
166  log_error("Execution of command \"%s\" failed: return code %d.\n", command.c_str(), ret);
167 
168  if (out_file.empty()) {
169  std::ifstream ff;
170  ff.open(stringf("%s/vhdl2verilog_output.v", tempdir_name.c_str()).c_str());
171  if (ff.fail())
172  log_error("Can't open vhdl2verilog output file `vhdl2verilog_output.v'.\n");
173  Frontend::frontend_call(design, &ff, stringf("%s/vhdl2verilog_output.v", tempdir_name.c_str()), "verilog");
174  }
175 
176  log_header("Removing temp directory `%s':\n", tempdir_name.c_str());
177  remove_directory(tempdir_name);
178  log_pop();
179  }
181 
183 
void cmd_error(const std::vector< std::string > &args, size_t argidx, std::string msg)
Definition: register.cc:110
std::string stringf(const char *fmt,...)
Definition: yosys.cc:58
void remove_directory(std::string dirname)
Definition: yosys.cc:308
void log_header(const char *format,...)
Definition: log.cc:188
#define YOSYS_NAMESPACE_END
Definition: yosys.h:100
static void frontend_call(RTLIL::Design *design, std::istream *f, std::string filename, std::string command)
Definition: register.cc:375
void log_error(const char *format,...)
Definition: log.cc:204
void log_pop()
Definition: log.cc:237
#define log_abort()
Definition: log.h:84
int run_command(const std::string &command, std::function< void(const std::string &)> process_line)
Definition: yosys.cc:195
Vhdl2verilogPass Vhdl2verilogPass
std::string make_temp_dir(std::string template_str)
Definition: yosys.cc:273
virtual void execute(std::vector< std::string > args, RTLIL::Design *design)
Definition: vhdl2verilog.cc:75
Definition: register.h:27
void log_cmd_error(const char *format,...)
Definition: log.cc:211
#define YOSYS_NAMESPACE_BEGIN
Definition: yosys.h:99
void log(const char *format,...)
Definition: log.cc:180
void log_push()
Definition: log.cc:232
virtual void help()
Definition: vhdl2verilog.cc:38