{
std::map<std::string, std::string> defines_map(pre_defines_map);
int ifdef_fail_level = 0;
+ bool in_elseif = false;
output_code.clear();
input_buffer.clear();
if (tok == "`endif") {
if (ifdef_fail_level > 0)
ifdef_fail_level--;
+ if (ifdef_fail_level == 0)
+ in_elseif = false;
continue;
}
if (tok == "`else") {
if (ifdef_fail_level == 0)
ifdef_fail_level = 1;
- else if (ifdef_fail_level == 1)
+ else if (ifdef_fail_level == 1 && !in_elseif)
ifdef_fail_level = 0;
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_map.count(name) != 0)
+ ifdef_fail_level = 0, in_elseif = true;
+ continue;
+ }
+
if (tok == "`ifdef") {
skip_spaces();
std::string name = next_token(true);
-module test(a, y);
+
+module test_def(a, y);
+
`define MSB_LSB_SEP :
`define get_msb(off, len) ((off)+(len)-1)
`define get_lsb(off, len) (off)
`define sel_bits(offset, len) `get_msb(offset, len) `MSB_LSB_SEP `get_lsb(offset, len)
+
input [31:0] a;
output [7:0] y;
+
assign y = a[`sel_bits(16, 8)];
+
+endmodule
+
+// ---------------------------------------------------
+
+module test_ifdef(a, y);
+
+input [2:0] a;
+output reg [31:0] y;
+
+always @* begin
+ y = 0;
+
+ `undef X
+ `ifdef X
+ y = y + 42;
+ `else
+ `undef A
+ `undef B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `undef A
+ `define B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `undef B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `define B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ // ------------------------------------
+ `undef A
+ `undef B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `undef A
+ `define B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `undef B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `define B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ // ------------------------------------
+ `undef A
+ `ifdef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `ifdef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ // ------------------------------------
+ `undef A
+ `ifndef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `ifndef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `endif
+
+ `define X
+ `ifdef X
+ `undef A
+ `undef B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `undef A
+ `define B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `undef B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `define B
+ `ifdef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ // ------------------------------------
+ `undef A
+ `undef B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `undef A
+ `define B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `undef B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `define B
+ `ifndef A
+ y = (y << 1) | a[0];
+ `elsif B
+ y = (y << 1) | a[1];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ // ------------------------------------
+ `undef A
+ `ifdef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `ifdef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ // ------------------------------------
+ `undef A
+ `ifndef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `define A
+ `ifndef A
+ y = (y << 1) | a[0];
+ `else
+ y = (y << 1) | a[2];
+ `endif
+ `else
+ y = y + 42;
+ `endif
+end
+
endmodule