Added elsif preproc support
authorClifford Wolf <clifford@clifford.at>
Wed, 18 Dec 2013 12:41:36 +0000 (13:41 +0100)
committerClifford Wolf <clifford@clifford.at>
Wed, 18 Dec 2013 12:41:36 +0000 (13:41 +0100)
frontends/verilog/preproc.cc
tests/simple/macros.v

index e17531be2ef47db4089a4911d2c6c16cc5ca876b..023c4dbcc4d25389a2ed986b1680a19c12b8fb42 100644 (file)
@@ -206,6 +206,7 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m
 {
        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();
@@ -222,17 +223,29 @@ std::string frontend_verilog_preproc(FILE *f, std::string filename, const std::m
                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);
index e2025717f4e2ea34957961924d090514161658dc..cda46cb48d2d1dd089c197d5d25fba0b73da932d 100644 (file)
@@ -1,9 +1,237 @@
-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