diff --git a/CHANGELOG b/CHANGELOG index bbc34a6b..43e8b92d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,7 @@ # EBMC 5.7 +* Verilog: `elsif preprocessor directive + # EBMC 5.6 * SystemVerilog: [*] and [+] SVA operators diff --git a/regression/verilog/preprocessor/elsif1.desc b/regression/verilog/preprocessor/elsif1.desc index cfb64923..ca1759e3 100644 --- a/regression/verilog/preprocessor/elsif1.desc +++ b/regression/verilog/preprocessor/elsif1.desc @@ -1,8 +1,10 @@ -KNOWNBUG +CORE elsif1.v - +--preprocess +^IFDEF$ ^EXIT=0$ ^SIGNAL=0$ -- +^ELSIF$ -- The elsif directive is not implemented. diff --git a/regression/verilog/preprocessor/elsif1.v b/regression/verilog/preprocessor/elsif1.v index e909c62a..19f1b623 100644 --- a/regression/verilog/preprocessor/elsif1.v +++ b/regression/verilog/preprocessor/elsif1.v @@ -1,5 +1,6 @@ `define X 1 `ifdef X +IFDEF `elsif Y ELSIF `endif diff --git a/regression/verilog/preprocessor/elsif2.desc b/regression/verilog/preprocessor/elsif2.desc new file mode 100644 index 00000000..22a24b80 --- /dev/null +++ b/regression/verilog/preprocessor/elsif2.desc @@ -0,0 +1,9 @@ +CORE +elsif2.v +--preprocess +^ELSIF$ +^EXIT=0$ +^SIGNAL=0$ +-- +^IFDEF$ +-- diff --git a/regression/verilog/preprocessor/elsif2.v b/regression/verilog/preprocessor/elsif2.v new file mode 100644 index 00000000..5a44ff4e --- /dev/null +++ b/regression/verilog/preprocessor/elsif2.v @@ -0,0 +1,5 @@ +`define Y 1 +`ifdef X +`elsif Y +ELSIF +`endif diff --git a/src/verilog/verilog_preprocessor.cpp b/src/verilog/verilog_preprocessor.cpp index 2cd68e03..5055ede8 100644 --- a/src/verilog/verilog_preprocessor.cpp +++ b/src/verilog/verilog_preprocessor.cpp @@ -551,6 +551,37 @@ void verilog_preprocessort::directive() conditional.else_part=true; condition=conditional.get_cond(); } + else if(text == "elsif") + { + if(conditionals.empty()) + throw verilog_preprocessor_errort() << "`elsif without `ifdef/`ifndef"; + + // skip whitespace + tokenizer().skip_ws(); + + // we expect an identifier + const auto identifier_token = tokenizer().next_token(); + + if(!identifier_token.is_identifier()) + throw verilog_preprocessor_errort() + << "expecting an identifier after `elsif"; + + auto &identifier = identifier_token.text; + + tokenizer().skip_until_eol(); + + bool defined = defines.find(identifier) != defines.end(); + + conditionalt &conditional = conditionals.back(); + + if(conditional.else_part) + { + throw verilog_preprocessor_errort() << "`elsif after `else"; + } + + conditional.condition = defined; + condition = conditional.get_cond(); + } else if(text=="endif") { if(conditionals.empty())