aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--frontends/verilog/preproc.cc49
-rw-r--r--tests/simple/ifdef_1.v88
-rw-r--r--tests/simple/ifdef_2.v21
-rw-r--r--tests/verilog/include_self.v30
-rw-r--r--tests/verilog/include_self.ys2
-rw-r--r--tests/verilog/unmatched_else.ys6
-rw-r--r--tests/verilog/unmatched_elsif.ys6
-rw-r--r--tests/verilog/unmatched_endif.ys6
8 files changed, 197 insertions, 11 deletions
diff --git a/frontends/verilog/preproc.cc b/frontends/verilog/preproc.cc
index de707593f..84966e501 100644
--- a/frontends/verilog/preproc.cc
+++ b/frontends/verilog/preproc.cc
@@ -727,7 +727,8 @@ frontend_verilog_preproc(std::istream &f,
std::vector<std::string> filename_stack;
int ifdef_fail_level = 0;
- bool in_elseif = false;
+ int ifdef_pass_level = 0;
+ bool ifdef_already_satisfied = false;
output_code.clear();
input_buffer.clear();
@@ -743,42 +744,68 @@ frontend_verilog_preproc(std::istream &f,
if (tok == "`endif") {
if (ifdef_fail_level > 0)
ifdef_fail_level--;
- if (ifdef_fail_level == 0)
- in_elseif = false;
+ else if (ifdef_pass_level > 0)
+ ifdef_already_satisfied = --ifdef_pass_level;
+ else
+ log_error("Found %s outside of macro conditional branch!\n", tok.c_str());
continue;
}
if (tok == "`else") {
- if (ifdef_fail_level == 0)
+ if (ifdef_fail_level == 0) {
+ if (ifdef_pass_level == 0)
+ log_error("Found %s outside of macro conditional branch!\n", tok.c_str());
+ log_assert(ifdef_already_satisfied);
ifdef_fail_level = 1;
- else if (ifdef_fail_level == 1 && !in_elseif)
+ } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied) {
ifdef_fail_level = 0;
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
continue;
}
if (tok == "`elsif") {
skip_spaces();
std::string name = next_token(true);
- if (ifdef_fail_level == 0)
- ifdef_fail_level = 1, in_elseif = true;
- else if (ifdef_fail_level == 1 && defines.find(name))
- ifdef_fail_level = 0, in_elseif = true;
+ if (ifdef_fail_level == 0) {
+ if (ifdef_pass_level == 0)
+ log_error("Found %s outside of macro conditional branch!\n", tok.c_str());
+ log_assert(ifdef_already_satisfied);
+ ifdef_fail_level = 1;
+ } else if (ifdef_fail_level == 1 && !ifdef_already_satisfied && defines.find(name)) {
+ ifdef_fail_level = 0;
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
continue;
}
if (tok == "`ifdef") {
skip_spaces();
std::string name = next_token(true);
- if (ifdef_fail_level > 0 || !defines.find(name))
+ if (ifdef_fail_level > 0 || !defines.find(name)) {
ifdef_fail_level++;
+ } else {
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
+ if (ifdef_fail_level == 1)
+ ifdef_already_satisfied = false;
continue;
}
if (tok == "`ifndef") {
skip_spaces();
std::string name = next_token(true);
- if (ifdef_fail_level > 0 || defines.find(name))
+ if (ifdef_fail_level > 0 || defines.find(name)) {
ifdef_fail_level++;
+ } else {
+ ifdef_pass_level++;
+ ifdef_already_satisfied = true;
+ }
+ if (ifdef_fail_level == 1)
+ ifdef_already_satisfied = false;
continue;
}
diff --git a/tests/simple/ifdef_1.v b/tests/simple/ifdef_1.v
new file mode 100644
index 000000000..fa962355c
--- /dev/null
+++ b/tests/simple/ifdef_1.v
@@ -0,0 +1,88 @@
+module top(o1, o2, o3, o4);
+
+`define FAIL input wire not_a_port;
+
+`ifdef COND_1
+ `FAIL
+`elsif COND_2
+ `FAIL
+`elsif COND_3
+ `FAIL
+`elsif COND_4
+ `FAIL
+`else
+
+ `define COND_4
+ output wire o4;
+
+ `ifdef COND_1
+ `FAIL
+ `elsif COND_2
+ `FAIL
+ `elsif COND_3
+ `FAIL
+ `elsif COND_4
+
+ `define COND_3
+ output wire o3;
+
+ `ifdef COND_1
+ `FAIL
+ `elsif COND_2
+ `FAIL
+ `elsif COND_3
+
+ `define COND_2
+ output wire o2;
+
+ `ifdef COND_1
+ `FAIL
+ `elsif COND_2
+
+ `define COND_1
+ output wire o1;
+
+ `ifdef COND_1
+
+ `ifdef COND_1
+ `elsif COND_2
+ `FAIL
+ `elsif COND_3
+ `FAIL
+ `elsif COND_4
+ `FAIL
+ `else
+ `FAIL
+ `endif
+
+ `elsif COND_2
+ `FAIL
+ `elsif COND_3
+ `FAIL
+ `elsif COND_4
+ `FAIL
+ `else
+ `FAIL
+ `endif
+
+ `elsif COND_3
+ `FAIL
+ `elsif COND_4
+ `FAIL
+ `else
+ `FAIL
+ `endif
+
+ `elsif COND_4
+ `FAIL
+ `else
+ `FAIL
+ `endif
+
+ `else
+ `FAIL
+ `endif
+
+`endif
+
+endmodule
diff --git a/tests/simple/ifdef_2.v b/tests/simple/ifdef_2.v
new file mode 100644
index 000000000..6dd89efed
--- /dev/null
+++ b/tests/simple/ifdef_2.v
@@ -0,0 +1,21 @@
+module top(o1, o2, o3);
+
+output wire o1;
+
+`define COND_1
+`define COND_2
+`define COND_3
+
+`ifdef COND_1
+ output wire o2;
+`elsif COND_2
+ input wire dne1;
+`elsif COND_3
+ input wire dne2;
+`else
+ input wire dne3;
+`endif
+
+output wire o3;
+
+endmodule
diff --git a/tests/verilog/include_self.v b/tests/verilog/include_self.v
new file mode 100644
index 000000000..23ffc7104
--- /dev/null
+++ b/tests/verilog/include_self.v
@@ -0,0 +1,30 @@
+`ifdef GUARD_5
+module top;
+ wire x;
+endmodule
+
+`elsif GUARD_4
+`define GUARD_5
+`include "include_self.v"
+
+`elsif GUARD_3
+`define GUARD_4
+`include "include_self.v"
+
+`elsif GUARD_2
+`define GUARD_3
+`include "include_self.v"
+
+`elsif GUARD_1
+`define GUARD_2
+`include "include_self.v"
+
+`elsif GUARD_0
+`define GUARD_1
+`include "include_self.v"
+
+`else
+`define GUARD_0
+`include "include_self.v"
+
+`endif
diff --git a/tests/verilog/include_self.ys b/tests/verilog/include_self.ys
new file mode 100644
index 000000000..07d840d68
--- /dev/null
+++ b/tests/verilog/include_self.ys
@@ -0,0 +1,2 @@
+read_verilog include_self.v
+select -assert-count 1 top/x
diff --git a/tests/verilog/unmatched_else.ys b/tests/verilog/unmatched_else.ys
new file mode 100644
index 000000000..413f413c3
--- /dev/null
+++ b/tests/verilog/unmatched_else.ys
@@ -0,0 +1,6 @@
+logger -expect error "Found `else outside of macro conditional branch!" 1
+read_verilog <<EOT
+module top;
+`else
+endmodule
+EOT
diff --git a/tests/verilog/unmatched_elsif.ys b/tests/verilog/unmatched_elsif.ys
new file mode 100644
index 000000000..e0ed0aa49
--- /dev/null
+++ b/tests/verilog/unmatched_elsif.ys
@@ -0,0 +1,6 @@
+logger -expect error "Found `elsif outside of macro conditional branch!" 1
+read_verilog <<EOT
+module top;
+`elsif
+endmodule
+EOT
diff --git a/tests/verilog/unmatched_endif.ys b/tests/verilog/unmatched_endif.ys
new file mode 100644
index 000000000..39d60381d
--- /dev/null
+++ b/tests/verilog/unmatched_endif.ys
@@ -0,0 +1,6 @@
+logger -expect error "Found `endif outside of macro conditional branch!" 1
+read_verilog <<EOT
+module top;
+`endif
+endmodule
+EOT