87 if (ch !=
' ' && ch !=
'\t') {
113 if (ch ==
' ' || ch ==
'\t')
116 if (ch !=
' ' && ch !=
'\t') {
134 if (token ==
"\"\"" && (ch =
next_char()) != 0) {
152 if (last_ch !=
'*' || ch !=
'/') {
159 else if (ch ==
'*') {
161 int newline_count = 0;
169 if (last_ch ==
'*' && ch ==
'/')
173 while (newline_count-- > 0)
182 const char *ok =
"abcdefghijklmnopqrstuvwxyz_ABCDEFGHIJKLMNOPQRSTUVWXYZ$0123456789";
183 if (ch ==
'`' || strchr(ok, ch) !=
NULL)
185 if (strchr(ok, ch) ==
NULL) {
196 static void input_file(std::istream &f, std::string filename)
204 input_buffer.insert(it,
"`file_push " + filename +
"\n");
205 while ((rc =
readsome(f, buffer,
sizeof(buffer)-1)) > 0) {
212 std::string
frontend_verilog_preproc(std::istream &f, std::string filename,
const std::map<std::string, std::string> pre_defines_map,
const std::list<std::string> include_dirs)
214 std::set<std::string> defines_with_args;
215 std::map<std::string, std::string> defines_map(pre_defines_map);
216 int ifdef_fail_level = 0;
217 bool in_elseif =
false;
224 defines_map[
"__YOSYS__"] =
"1";
231 if (tok ==
"`endif") {
232 if (ifdef_fail_level > 0)
234 if (ifdef_fail_level == 0)
239 if (tok ==
"`else") {
240 if (ifdef_fail_level == 0)
241 ifdef_fail_level = 1;
242 else if (ifdef_fail_level == 1 && !in_elseif)
243 ifdef_fail_level = 0;
247 if (tok ==
"`elsif") {
250 if (ifdef_fail_level == 0)
251 ifdef_fail_level = 1, in_elseif =
true;
252 else if (ifdef_fail_level == 1 && defines_map.count(name) != 0)
253 ifdef_fail_level = 0, in_elseif =
true;
257 if (tok ==
"`ifdef") {
260 if (ifdef_fail_level > 0 || defines_map.count(name) == 0)
265 if (tok ==
"`ifndef") {
268 if (ifdef_fail_level > 0 || defines_map.count(name) != 0)
273 if (ifdef_fail_level > 0) {
279 if (tok ==
"`include") {
283 size_t pos = fn.find(
'"');
284 if (pos == std::string::npos)
289 fn = fn.substr(0, pos) + fn.substr(pos+1);
294 if (ff.fail() && fn.size() > 0 && fn[0] !=
'/' && filename.find(
'/') != std::string::npos) {
298 ff.open(filename.substr(0, filename.rfind(
'/')+1) + fn);
300 if (ff.fail() && fn.size() > 0 && fn[0] !=
'/') {
303 for (
auto incdir : include_dirs) {
305 ff.open(incdir +
'/' + fn);
306 if (!ff.fail())
break;
316 if (tok ==
"`define") {
317 std::string name, value;
318 std::map<std::string, int>
args;
321 bool here_doc_mode =
false;
322 int newline_count = 0;
326 while (!tok.empty()) {
328 if (tok ==
"\"\"\"") {
329 here_doc_mode = !here_doc_mode;
332 if (state == 0 && tok ==
"(") {
339 else if (tok !=
",") {
340 int arg_idx = args.size()+1;
362 value += std::string(
"\\");
366 if (args.count(tok) > 0)
367 value +=
stringf(
"`macro_%s_arg%d", name.c_str(), args.at(tok));
372 while (newline_count-- > 0)
375 defines_map[name] = value;
377 defines_with_args.insert(name);
379 defines_with_args.erase(name);
383 if (tok ==
"`undef") {
388 defines_map.erase(name);
389 defines_with_args.erase(name);
393 if (tok ==
"`timescale") {
395 while (!tok.empty() && tok !=
"\n")
402 if (tok.size() > 1 && tok[0] ==
'`' && defines_map.count(tok.substr(1)) > 0) {
403 std::string name = tok.substr(1);
407 if (tok ==
"(" && defines_with_args.count(name) > 0) {
409 std::vector<std::string>
args;
410 args.push_back(std::string());
414 if (tok ==
")" || tok ==
"}" || tok ==
"]")
418 if (level == 1 && tok ==
",")
419 args.push_back(std::string());
422 if (tok ==
"(" || tok ==
"{" || tok ==
"[")
425 for (
int i = 0; i <
GetSize(args); i++)
426 defines_map[
stringf(
"macro_%s_arg%d", name.c_str(), i+1)] = args[i];
static std::string next_token(bool pass_newline=false)
std::string stringf(const char *fmt,...)
#define YOSYS_NAMESPACE_END
std::string frontend_verilog_preproc(std::istream &f, std::string filename, const std::map< std::string, std::string > pre_defines_map, const std::list< std::string > include_dirs)
static std::string skip_spaces()
int GetSize(RTLIL::Wire *wire)
#define log_assert(_assert_expr_)
int readsome(std::istream &f, char *s, int n)
static void return_char(char ch)
static size_t input_buffer_charp
#define YOSYS_NAMESPACE_BEGIN
static std::list< std::string > input_buffer
static void insert_input(std::string str)
static void input_file(std::istream &f, std::string filename)
static YOSYS_NAMESPACE_BEGIN std::list< std::string > output_code