Skip to content

Parse ANSI parameters declaration #1160

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/lexer.l
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,7 @@ BEFORE ?i:before
<UDP>{UDP_EDGE} { yylval.i64 = yytext[0]; return tUDPEDGE; }
<UDP>{UDP_INDICATOR} { yylval.str = xstrdup(yytext); return tUDPIND; }

<*>"#(" { TOKEN(tHASHLPAREN); }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think #( is a single token. It's shown with a space between it them the grammar in the standard (e.g. page 1138 of 1800-2017) and also here:

https://www.sigasi.com/tech/systemverilog.ebnf/#module-parameters-and-ports

Icarus Verilog and Verilator also both treat the # and ( as separate tokens.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok thanks for the review I wasn't aware that they were separate tokens, I'll try to look better into the syntax and adjust the code. It's gonna take a bit of time though

<*>"(" { TOKEN(tLPAREN); }
<*>")" { TOKEN(tRPAREN); }
<*>"[" { TOKEN(tLSQUARE); }
Expand Down
2 changes: 1 addition & 1 deletion src/scan.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ const char *token_str(token_t tok)
"endtask", "endfunction", "`begin_keywords", "`end_keywords", "real",
"shortreal", "realtime", "`__nvc_push", "`__nvc_pop", "++", "--",
"var", "`default_nettype", "tri", "tri0", "tri1", "wand", "triand",
"wor", "trior", "trireg", "uwire", "none",
"wor", "trior", "trireg", "uwire", "none", "#("
};

if (tok >= 200 && tok - 200 < ARRAY_LEN(token_strs))
Expand Down
1 change: 1 addition & 0 deletions src/scan.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,5 +436,6 @@ void reset_sdf_parser(void);
#define tTRIREG 535
#define tUWIRE 536
#define tNONE 537
#define tHASHLPAREN 538

#endif // _SCAN_H
30 changes: 30 additions & 0 deletions src/vlog/vlog-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -3260,6 +3260,33 @@ static void p_list_of_port_declarations(vlog_node_t mod)
consume(tRPAREN);
}

static void p_ansi_parameter_declaration(vlog_node_t mod)
{
// parameter data_type_or_implicit parameter_assigment

BEGIN("ANSI parameter declaration");

consume(tPARAMETER);

vlog_node_t dt = p_data_type_or_implicit();
vlog_add_decl(mod, p_param_assignment(dt));
}

static void p_list_of_param_declarations(vlog_node_t mod)
{
// parameter_port_list ::= ansi_param_assignments { , ansi_param_assignments }
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm using the System Verilog grammar rather than the traditional Verilog one


BEGIN("list of parameter declarations");

consume(tHASHLPAREN);

do {
p_ansi_parameter_declaration(mod);
} while (optional(tCOMMA));

consume(tRPAREN);
}

static void p_module_ansi_header(vlog_node_t mod)
{
// { attribute_instance } module_keyword [ lifetime ] module_identifier
Expand All @@ -3268,6 +3295,9 @@ static void p_module_ansi_header(vlog_node_t mod)

EXTEND("module ANSI header");

if (peek() == tHASHLPAREN)
p_list_of_param_declarations(mod);

if (peek() == tLPAREN)
p_list_of_port_declarations(mod);

Expand Down
23 changes: 23 additions & 0 deletions test/test_vlog.c
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,28 @@ START_TEST(test_param1)
}
END_TEST

START_TEST(test_param2)
{
input_from_file(TESTDIR "/vlog/param2.v");

const error_t expect[] = {
{ 6, "duplicate declaration" },
{ -1, NULL }
};
expect_errors(expect);

vlog_node_t m = vlog_parse();
fail_if(m == NULL);
fail_unless(vlog_kind(m) == V_MODULE);

vlog_check(m);

fail_unless(vlog_parse() == NULL);

check_expected_errors();
}
END_TEST

START_TEST(test_pp3)
{
input_from_file(TESTDIR "/vlog/pp3.v");
Expand Down Expand Up @@ -758,6 +780,7 @@ Suite *get_vlog_tests(void)
tcase_add_test(tc, test_enum1);
tcase_add_test(tc, test_union1);
tcase_add_test(tc, test_param1);
tcase_add_test(tc, test_param2);
tcase_add_test(tc, test_pp3);
tcase_add_test(tc, test_concat1);
tcase_add_test(tc, test_pp4);
Expand Down
7 changes: 7 additions & 0 deletions test/vlog/param2.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module param2 #(
parameter [7:0] p1 = 8'd5,
parameter p2 = 8
);
assign w1 = p1; // OK
parameter logic p1 = 1; // Error
endmodule // param2
Loading