Skip to content

Commit d10d53e

Browse files
authored
12 najaverilogverilogexception parser error syntax error unexpected expecting (#13)
* Adding failing associated test * Adding support for defparam, working on tests * More testing * Exclude coverage from non constant number * remove throw from coverage
1 parent d5f980f commit d10d53e

11 files changed

+1029
-21
lines changed

src/NajaVerilogSnippet.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "VerilogConstructor.h"
66

77
#include <iostream>
8+
#include <sstream>
89

910
namespace {
1011

@@ -44,6 +45,20 @@ class VerilogConstructorExample: public naja::verilog::VerilogConstructor {
4445
void addParameterAssignment(const naja::verilog::Identifier& parameter, const naja::verilog::Expression& expression) override {
4546
std::cout << "addParameterAssignment: " << parameter.getString() << ": " << expression.getString() << std::endl;
4647
}
48+
virtual void addDefParameterAssignment(
49+
const naja::verilog::Identifiers& hierarchicalParameter,
50+
const naja::verilog::Expression& expression) override {
51+
std::ostringstream oss;
52+
for (size_t i = 0; i < hierarchicalParameter.size(); i++) {
53+
oss << hierarchicalParameter[i].getString();
54+
if (i < hierarchicalParameter.size() - 1) {
55+
oss << ".";
56+
}
57+
}
58+
std::cout << "addDefParameterAssignment: "
59+
<< oss.str()
60+
<< ": " << expression.getString() << std::endl;
61+
}
4762
void endModule() override {
4863
std::cout << "endModule" << std::endl;
4964
}

src/VerilogConstructor.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,9 @@ class VerilogConstructor {
6464
virtual void addOrderedInstanceConnection(size_t portIndex, const Expression& expression) {}
6565
virtual void endInstantiation() {}
6666
virtual void addParameterAssignment(const naja::verilog::Identifier& parameter, const Expression& expression) {}
67+
virtual void addDefParameterAssignment(
68+
const naja::verilog::Identifiers& hierarchicalParameter,
69+
const naja::verilog::Expression& expression) {}
6770
virtual void endModule() {}
6871
//LCOV_EXCL_STOP
6972
private:

src/VerilogParser.yy

Lines changed: 69 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ static naja::verilog::Number generateNumber(
126126
%token SUPPLY1_KW
127127
%token WIRE_KW
128128
%token ASSIGN_KW
129+
%token DEFPARAM_KW
129130
%token END 0 "end of file"
130131

131132
%token<std::string> IDENTIFIER_TK
@@ -136,7 +137,6 @@ static naja::verilog::Number generateNumber(
136137

137138
%type<naja::verilog::Identifier> identifier;
138139
//no support for XMRs for the moment
139-
%type<naja::verilog::Identifier> hierarchical_identifier;
140140
%type<naja::verilog::Identifier> hierarchical_net_identifier;
141141
%type<naja::verilog::Identifier> module_identifier;
142142
%type<naja::verilog::Identifier> name_of_module_instance;
@@ -151,16 +151,19 @@ static naja::verilog::Number generateNumber(
151151
%type<naja::verilog::Range> constant_range_expression.opt;
152152
%type<naja::verilog::Identifier> net_identifier;
153153
%type<naja::verilog::Identifiers> list_of_identifiers;
154+
%type<naja::verilog::Identifiers> hierarchical_identifier;
155+
%type<naja::verilog::Identifiers> hierarchical_parameter_identifier;
154156
%type<naja::verilog::RangeIdentifiers> net_lvalue;
155157
%type<naja::verilog::RangeIdentifiers> list_of_net_lvalues;
156158
%type<naja::verilog::Identifier> module_instance;
157159
%type<naja::verilog::Identifier> port_identifier;
158160

159161
%type<naja::verilog::Number> number;
160-
%type<naja::verilog::Number> constant_primary;
161-
%type<naja::verilog::Number> constant_expression;
162+
%type<naja::verilog::Expression> constant_mintypmax_expression;
162163
%type<std::string> unary_operator;
163164
%type<naja::verilog::Expression> primary;
165+
%type<naja::verilog::Expression> constant_primary;
166+
%type<naja::verilog::Expression> constant_expression;
164167
%type<naja::verilog::Expression> expression;
165168
%type<naja::verilog::Expression> expression.opt;
166169
%type<naja::verilog::Expression> mintypmax_expression;
@@ -186,20 +189,48 @@ identifier
186189
$$ = naja::verilog::Identifier(escaped, true);
187190
}
188191

189-
constant_primary: number
192+
primary
193+
: number {
194+
$$.valid_ = true; $$.value_ = $1; }
195+
//no support for XMRs for the moment: should be hierarchical_identifier below
196+
| identifier constant_range_expression.opt {
197+
$$.valid_ = true; $$.value_ = naja::verilog::RangeIdentifier($1, $2); }
198+
| STRING_TK { $$.valid_ = true; $$.value_ = $1.substr(1, $1.size()-2); }
199+
| concatenation { $$.valid_ = true; $$.value_ = naja::verilog::Concatenation($1); }
200+
;
201+
202+
constant_primary
203+
: number {
204+
$$.valid_ = true; $$.value_ = $1; }
205+
| STRING_TK { $$.valid_ = true; $$.value_ = $1.substr(1, $1.size()-2); }
206+
;
190207

191208
unary_operator: SIGN_TK;
192209

193210
constant_expression: constant_primary {
194211
$$ = $1;
195212
}
196213
| unary_operator constant_primary {
197-
$$ = $2;
198-
if ($1 == "-") { $$.sign_ = false; }
214+
auto expression = $2;
215+
if (expression.value_.index() == naja::verilog::Expression::NUMBER) {
216+
auto number = std::get<naja::verilog::Number>(expression.value_);
217+
if ($1 == "-") { number.sign_ = false; }
218+
$$.valid_ = true;
219+
$$.value_ = number;
220+
} else {
221+
throw VerilogException("Only constant number expression are supported"); //LCOV_EXCL_LINE
222+
}
199223
}
200224

201225
range: '[' constant_expression ':' constant_expression ']' {
202-
$$ = Range($2.getInt(), $4.getInt());
226+
if ($2.value_.index() == naja::verilog::Expression::NUMBER and
227+
$4.value_.index() == naja::verilog::Expression::NUMBER) {
228+
auto number1 = std::get<naja::verilog::Number>($2.value_);
229+
auto number2 = std::get<naja::verilog::Number>($4.value_);
230+
$$ = Range(number1.getInt(), number2.getInt());
231+
} else {
232+
throw VerilogException("Only constant number expression are supported"); //LCOV_EXCL_LINE
233+
}
203234
}
204235

205236
range.opt: %empty { $$.valid_ = false; } | range { $$ = $1; }
@@ -221,7 +252,20 @@ port_type_io
221252
| OUTPUT_KW { $$ = naja::verilog::Port::Direction::Output; }
222253
;
223254

224-
non_port_module_item : module_or_generate_item;
255+
non_port_module_item: module_or_generate_item;
256+
257+
hierarchical_parameter_identifier: hierarchical_identifier;
258+
259+
constant_mintypmax_expression: constant_expression;
260+
261+
defparam_assignment: hierarchical_parameter_identifier '=' constant_mintypmax_expression {
262+
constructor->setCurrentLocation(@$.begin.line, @$.begin.column);
263+
constructor->addDefParameterAssignment($1, $3);
264+
}
265+
266+
list_of_defparam_assignments: defparam_assignment| list_of_defparam_assignments defparam_assignment;
267+
268+
parameter_override: DEFPARAM_KW list_of_defparam_assignments ';'
225269

226270
hierarchical_net_identifier: identifier;
227271

@@ -253,6 +297,7 @@ continuous_assign: ASSIGN_KW list_of_net_assignments ';'
253297
module_or_generate_item:
254298
module_or_generate_item_declaration
255299
| module_instantiation
300+
| parameter_override
256301
| continuous_assign
257302
;
258303

@@ -298,13 +343,26 @@ number
298343
$$ = Number($1);
299344
}
300345

301-
//no support for XMRs for the moment
302-
hierarchical_identifier: identifier;
346+
//hierarchical_identifier ::=
347+
//{ identifier [ [ constant_expression ] ] . } identifier
348+
hierarchical_identifier
349+
: identifier {
350+
$$ = { $1 };
351+
}
352+
| hierarchical_identifier '.' identifier {
353+
$1.push_back($3);
354+
$$ = $1;
355+
}
303356

304357
//only numeric values (one bit) [4] or [4:5] are supported
305358
constant_range_expression.opt: %empty { $$.valid_ = false; }
306359
| '[' constant_expression ']' {
307-
$$ = Range($2.getInt());
360+
if ($2.value_.index() == naja::verilog::Expression::NUMBER) {
361+
auto number = std::get<naja::verilog::Number>($2.value_);
362+
$$ = Range(number.getInt());
363+
} else {
364+
throw VerilogException("Only constant number expression are supported"); //LCOV_EXCL_LINE
365+
}
308366
}
309367
| range {
310368
$$ = $1;
@@ -321,15 +379,6 @@ expression {
321379

322380
concatenation: '{' list_of_expressions '}' { $$ = $2; }
323381

324-
primary
325-
: number {
326-
$$.valid_ = true; $$.value_ = $1; }
327-
| hierarchical_identifier constant_range_expression.opt {
328-
$$.valid_ = true; $$.value_ = naja::verilog::RangeIdentifier($1, $2); }
329-
| STRING_TK { $$.valid_ = true; $$.value_ = $1.substr(1, $1.size()-2); }
330-
| concatenation { $$.valid_ = true; $$.value_ = naja::verilog::Concatenation($1); }
331-
;
332-
333382
expression: primary { $$ = $1; }
334383

335384
expression.opt: %empty { $$.valid_ = false; } | expression { $$ = $1; }

src/VerilogScanner.ll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ wire { return token::WIRE_KW; }
120120
supply0 { return token::SUPPLY0_KW; }
121121
supply1 { return token::SUPPLY1_KW; }
122122
assign { return token::ASSIGN_KW; }
123+
defparam { return token::DEFPARAM_KW; }
123124

124125
{IDENTIFIER} { yylval->build<std::string>( yytext ); return token::IDENTIFIER_TK; }
125126
{ESCAPED_IDENTIFIER} {

test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ set(tests
1616
NajaVerilogTest9.cpp
1717
NajaVerilogTest10.cpp
1818
NajaVerilogTest11.cpp
19+
NajaVerilogTest12.cpp
20+
NajaVerilogTest13.cpp
1921
NajaVerilogTestMultipleFiles.cpp
2022
NajaVerilogTestErrors.cpp
2123
)

test/NajaVerilogTest12.cpp

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SPDX-FileCopyrightText: 2024 The Naja verilog authors <https://github.com/najaeda/naja-verilog/blob/main/AUTHORS>
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include "gtest/gtest.h"
6+
7+
#include <filesystem>
8+
#include <fstream>
9+
10+
#include "VerilogConstructor.h"
11+
12+
using namespace naja::verilog;
13+
14+
#include "VerilogConstructorTest.h"
15+
16+
#ifndef NAJA_VERILOG_BENCHMARKS
17+
#define NAJA_VERILOG_BENCHMARKS "Undefined"
18+
#endif
19+
20+
TEST(NajaVerilogTest12, test) {
21+
VerilogConstructorTest constructor;
22+
std::filesystem::path test12Path(
23+
std::filesystem::path(NAJA_VERILOG_BENCHMARKS)
24+
/ std::filesystem::path("benchmarks")
25+
/ std::filesystem::path("test12.v"));
26+
27+
constructor.setFirstPass(true);
28+
constructor.parse(test12Path);
29+
ASSERT_EQ(1, constructor.modules_.size());
30+
auto test = constructor.modules_[0];
31+
EXPECT_TRUE(test->ports_.empty());
32+
EXPECT_TRUE(test->nets_.empty());
33+
EXPECT_TRUE(test->assigns_.empty());
34+
EXPECT_TRUE(test->instances_.empty());
35+
36+
constructor.setFirstPass(false);
37+
constructor.parse(test12Path);
38+
ASSERT_EQ(1, constructor.modules_.size());
39+
EXPECT_TRUE(test->ports_.empty());
40+
EXPECT_TRUE(test->assigns_.empty());
41+
ASSERT_EQ(2, test->nets_.size());
42+
ASSERT_EQ(3, test->instances_.size());
43+
44+
auto ins1 = test->instances_[0];
45+
EXPECT_EQ("ins1", ins1.identifier_.name_);
46+
EXPECT_FALSE(ins1.identifier_.escaped_);
47+
EXPECT_EQ("CFG1", ins1.model_.name_);
48+
EXPECT_TRUE(ins1.parameterAssignments_.empty());
49+
50+
auto mem = test->instances_[1];
51+
EXPECT_EQ("mem_regfile_mem_regfile_0_0", mem.identifier_.name_);
52+
EXPECT_FALSE(mem.identifier_.escaped_);
53+
EXPECT_EQ("RAM64x18", mem.model_.name_);
54+
EXPECT_TRUE(mem.parameterAssignments_.empty());
55+
56+
auto ins2 = test->instances_[2];
57+
EXPECT_EQ("$$ins2@@", ins2.identifier_.name_);
58+
EXPECT_FALSE(ins2.identifier_.escaped_);
59+
EXPECT_EQ("CFG1", ins2.model_.name_);
60+
EXPECT_TRUE(ins2.parameterAssignments_.empty());
61+
62+
EXPECT_EQ(3, test->defParameterAssignments_.size());
63+
auto def0Path = test->defParameterAssignments_[0].first;
64+
auto def0Value = test->defParameterAssignments_[0].second;
65+
EXPECT_EQ(2, def0Path.size());
66+
EXPECT_EQ("ins1", def0Path[0].name_);
67+
EXPECT_FALSE(def0Path[0].escaped_);
68+
EXPECT_EQ("INIT", def0Path[1].name_);
69+
EXPECT_FALSE(def0Path[1].escaped_);
70+
EXPECT_EQ("2'h1", def0Value.getString());
71+
EXPECT_EQ(Expression::Type::NUMBER ,def0Value.value_.index());
72+
73+
auto def1Path = test->defParameterAssignments_[1].first;
74+
auto def1Value = test->defParameterAssignments_[1].second;
75+
EXPECT_EQ(2, def1Path.size());
76+
EXPECT_EQ("mem_regfile_mem_regfile_0_0", def1Path[0].name_);
77+
EXPECT_FALSE(def1Path[0].escaped_);
78+
EXPECT_EQ("RAMINDEX", def1Path[1].name_);
79+
EXPECT_FALSE(def1Path[1].escaped_);
80+
EXPECT_EQ(Expression::Type::STRING ,def1Value.value_.index());
81+
EXPECT_EQ("mem_regfile[7:0]%32%8%SPEED%0%0%MICRO_RAM", def1Value.getString());
82+
83+
auto def2Path = test->defParameterAssignments_[2].first;
84+
auto def2Value = test->defParameterAssignments_[2].second;
85+
EXPECT_EQ(2, def2Path.size());
86+
EXPECT_EQ("$$ins2@@", def2Path[0].name_);
87+
EXPECT_TRUE(def2Path[0].escaped_);
88+
EXPECT_EQ("INIT", def2Path[1].name_);
89+
EXPECT_FALSE(def2Path[1].escaped_);
90+
EXPECT_EQ(Expression::Type::NUMBER ,def2Value.value_.index());
91+
EXPECT_EQ("2'h2", def2Value.getString());
92+
}

test/NajaVerilogTest13.cpp

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// SPDX-FileCopyrightText: 2024 The Naja verilog authors <https://github.com/najaeda/naja-verilog/blob/main/AUTHORS>
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include "gtest/gtest.h"
6+
7+
#include <filesystem>
8+
#include <fstream>
9+
10+
#include "VerilogConstructor.h"
11+
12+
using namespace naja::verilog;
13+
14+
#include "VerilogConstructorTest.h"
15+
16+
#ifndef NAJA_VERILOG_BENCHMARKS
17+
#define NAJA_VERILOG_BENCHMARKS "Undefined"
18+
#endif
19+
20+
TEST(NajaVerilogTest13, test) {
21+
VerilogConstructorTest constructor;
22+
std::filesystem::path test13Path(
23+
std::filesystem::path(NAJA_VERILOG_BENCHMARKS)
24+
/ std::filesystem::path("benchmarks")
25+
/ std::filesystem::path("test13.v"));
26+
27+
constructor.setFirstPass(true);
28+
constructor.parse(test13Path);
29+
ASSERT_EQ(1, constructor.modules_.size());
30+
auto test = constructor.modules_[0];
31+
ASSERT_EQ(27, test->ports_.size());
32+
EXPECT_TRUE(test->nets_.empty());
33+
EXPECT_TRUE(test->assigns_.empty());
34+
EXPECT_TRUE(test->instances_.empty());
35+
36+
constructor.setFirstPass(false);
37+
constructor.parse(test13Path);
38+
ASSERT_EQ(1, constructor.modules_.size());
39+
ASSERT_EQ(27, test->ports_.size());
40+
ASSERT_EQ(67, test->nets_.size());
41+
EXPECT_TRUE(test->assigns_.empty());
42+
EXPECT_EQ(69, test->instances_.size());
43+
#if 0
44+
EXPECT_EQ("ins", instance.identifier_.name_);
45+
EXPECT_EQ("MOD", instance.model_.name_);
46+
EXPECT_EQ(2, instance.parameterAssignments_.size());
47+
using Parameters = std::vector<std::pair<std::string, std::string>>;
48+
Parameters parameters;
49+
for (const auto& [parameter, value]: instance.parameterAssignments_) {
50+
parameters.push_back({parameter, value});
51+
}
52+
EXPECT_EQ("elem10", parameters[0].first);
53+
EXPECT_EQ("'o0", parameters[0].second);
54+
EXPECT_EQ("elem11", parameters[1].first);
55+
EXPECT_EQ("8'o84", parameters[1].second);
56+
#endif
57+
}

test/VerilogConstructorTest.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,13 @@ void VerilogConstructorTest::addAssign(
122122
if (not inFirstPass()) {
123123
currentModule_->assigns_.push_back(Assign(identifiers, expression));
124124
}
125+
}
126+
127+
void VerilogConstructorTest::addDefParameterAssignment(
128+
const naja::verilog::Identifiers& hierarchicalParameter,
129+
const naja::verilog::Expression& expression) {
130+
if (not inFirstPass()) {
131+
currentModule_->defParameterAssignments_.push_back(
132+
VerilogConstructorTest::Module::DefParameterAssignment(hierarchicalParameter, expression));
133+
}
125134
}

0 commit comments

Comments
 (0)