Skip to content

Commit

Permalink
Implement LCS2016_007 sequential block statements
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jul 30, 2023
1 parent 1261881 commit 6fb78ea
Show file tree
Hide file tree
Showing 12 changed files with 194 additions and 4 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
elaboration option. For example `-g uut.value=42`.
- Implemented the `'reflect` attribute and associated protected types
from VHDL-2019.
- Added support for VHDL-2019 sequential block statements.

## Version 1.10.1 - 2023-07-28
- Fixed incorrect sensitivity list generation with concurrent statements
Expand Down
1 change: 1 addition & 0 deletions src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -1610,6 +1610,7 @@ static bool is_static(tree_t expr)
tree_t decl = tree_ref(expr);
switch (tree_kind(decl)) {
case T_CONST_DECL:
return !(tree_flags(decl) & TREE_F_SEQ_BLOCK);
case T_UNIT_DECL:
case T_ENUM_LIT:
case T_GENERIC_DECL:
Expand Down
9 changes: 8 additions & 1 deletion src/lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -6971,6 +6971,13 @@ static void lower_match_case(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops)
}
}

static void lower_sequential_block(lower_unit_t *lu, tree_t stmt,
loop_stack_t *loops)
{
lower_decls(lu, stmt);
lower_sequence(lu, stmt, loops);
}

static void lower_stmt(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops)
{
PUSH_DEBUG_INFO(stmt);
Expand Down Expand Up @@ -7024,7 +7031,7 @@ static void lower_stmt(lower_unit_t *lu, tree_t stmt, loop_stack_t *loops)
lower_for(lu, stmt, loops);
break;
case T_SEQUENCE:
lower_sequence(lu, stmt, loops);
lower_sequential_block(lu, stmt, loops);
break;
case T_EXIT:
case T_NEXT:
Expand Down
65 changes: 63 additions & 2 deletions src/parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -9872,13 +9872,70 @@ static tree_t p_case_statement(ident_t label)
return t;
}

static void p_sequential_block_declarative_part(tree_t block)
{
// { process_declarative_item }

BEGIN("sequential block declarative part");

while (not_at_token(tBEGIN))
p_process_declarative_item(block);
}

static void p_sequential_block_statement_part(tree_t block)
{
// { sequential_statement }

BEGIN("sequential block statement part");

p_sequence_of_statements(block);
}

static tree_t p_sequential_block_statement(ident_t label)
{
// [ label : ] block [ is ] sequential_block_declarative_part
// begin sequential_block_statement_part end [ block ] [ label ] ;

BEGIN("sequential block statement");

consume(tBLOCK);
optional(tIS);

require_std(STD_19, "sequential block statements");

push_scope(nametab);

tree_t t = tree_new(T_SEQUENCE);

scope_set_container(nametab, t);
set_label_and_loc(t, label, CURRENT_LOC);

p_sequential_block_declarative_part(t);

consume(tBEGIN);

p_sequential_block_statement_part(t);

consume(tEND);
optional(tBLOCK);

p_trailing_label(label);
consume(tSEMI);

tree_set_loc(t, CURRENT_LOC);
sem_check(t, nametab);
pop_scope(nametab);

return t;
}

static tree_t p_sequential_statement(void)
{
// wait_statement | assertion_statement | report_statement
// | signal_assignment_statement | variable_assignment_statement
// | procedure_call_statement | if_statement | case_statement
// | loop_statement | next_statement | exit_statement | return_statement
// | null_statement
// | null_statement | 2019: sequential_block_statement

BEGIN("sequential statement");

Expand Down Expand Up @@ -9945,8 +10002,12 @@ static tree_t p_sequential_statement(void)
}
}

case tBLOCK:
return p_sequential_block_statement(label);

default:
expect(tWAIT, tID);
expect(tWAIT, tID, tASSERT, tREPORT, tIF, tNULL, tRETURN, tCASE, tWHILE,
tFOR, tLOOP, tEXIT, tNEXT, tWITH, tLTLT, tLPAREN, tBLOCK);
drop_tokens_until(tSEMI);
return tree_new(T_NULL);
}
Expand Down
16 changes: 16 additions & 0 deletions src/sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -5947,6 +5947,20 @@ static bool sem_check_cond_value(tree_t t, nametab_t *tab)
return true;
}

static bool sem_check_sequence(tree_t t, nametab_t *tab)
{
const int ndecls = tree_decls(t);
for (int i = 0; i < ndecls; i++) {
// Mark all constant declarations as they need to be treated
// specially when calculating longest static prefix
tree_t d = tree_decl(t, i);
if (tree_kind(d) == T_CONST_DECL)
tree_set_flag(d, TREE_F_SEQ_BLOCK);
}

return true;
}

bool sem_check(tree_t t, nametab_t *tab)
{
switch (tree_kind(t)) {
Expand Down Expand Up @@ -6119,6 +6133,8 @@ bool sem_check(tree_t t, nametab_t *tab)
return sem_check_view_decl(t, tab);
case T_COND_VALUE:
return sem_check_cond_value(t, tab);
case T_SEQUENCE:
return sem_check_sequence(t, tab);
default:
sem_error(t, "cannot check %s", tree_kind_str(tree_kind(t)));
}
Expand Down
1 change: 1 addition & 0 deletions src/tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,6 +385,7 @@ typedef enum {
TREE_F_IMPURE_FILE = (1 << 22),
TREE_F_IMPURE_SHARED = (1 << 23),
TREE_F_HIDDEN = (1 << 24),
TREE_F_SEQ_BLOCK = (1 << 25),
} tree_flags_t;

tree_t tree_new(tree_kind_t kind);
Expand Down
24 changes: 24 additions & 0 deletions test/regress/seqblock1.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
entity seqblock1 is
end entity;

architecture test of seqblock1 is
begin

process is
variable a : natural;
begin
for i in 1 to 100 loop
a := i;
block is
constant c : natural := a + 1;
variable a : integer := 99;
begin
wait for 1 ns;
assert c = i + 1;
assert a = 99;
end block;
end loop;
wait;
end process;

end architecture;
33 changes: 33 additions & 0 deletions test/regress/seqblock2.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
-- https://gitlab.com/IEEE-P1076/VHDL-Issues/-/issues/281
entity seqblock2 is
end entity;

library ieee;
use ieee.std_logic_1164.all;

architecture test of seqblock2 is
signal x : std_logic_vector(1 to 3) := "ZZZ";
begin

process is
begin
for i in 1 to 3 loop
block is
constant c : natural := i;
begin
x(c) <= '1';
end block;
end loop;
wait;
end process;

x(1) <= '0';

process is
begin
wait for 1 ns;
assert x = "X11";
wait;
end process;

end architecture;
2 changes: 2 additions & 0 deletions test/regress/testlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -831,3 +831,5 @@ protected11 fail,gold,2002
issue744 normal,vhpi
reflect4 normal,2019
reflect5 normal,2019
seqblock1 normal,2019
seqblock2 normal,2019
24 changes: 24 additions & 0 deletions test/sem/lcs2016_07.vhd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
entity lcs2016_07 is
end entity;

architecture test of lcs2016_07 is
begin

p1: process is
variable v : bit := '1';
begin
b1: block is -- OK
variable v : integer := 1;
constant c : boolean := true;
begin
v := 6;
end block b1;
assert c; -- Error
block is
shared variable v : integer; -- Error
begin
end block;
wait;
end process;

end architecture;
20 changes: 20 additions & 0 deletions test/test_sem.c
Original file line number Diff line number Diff line change
Expand Up @@ -3150,6 +3150,25 @@ START_TEST(test_lcs2016_19)
}
END_TEST

START_TEST(test_lcs2016_07)
{
set_standard(STD_19);

input_from_file(TESTDIR "/sem/lcs2016_07.vhd");

const error_t expect[] = {
{ 16, "no visible declaration for C" },
{ 18, "unexpected shared while parsing process declarative item" },
{ -1, NULL }
};
expect_errors(expect);

parse_and_check(T_ENTITY, T_ARCH);

check_expected_errors();
}
END_TEST

Suite *get_sem_tests(void)
{
Suite *s = suite_create("sem");
Expand Down Expand Up @@ -3303,6 +3322,7 @@ Suite *get_sem_tests(void)
tcase_add_test(tc_core, test_lcs2016_41);
tcase_add_test(tc_core, test_lcs2016_14a);
tcase_add_test(tc_core, test_lcs2016_19);
tcase_add_test(tc_core, test_lcs2016_07);
suite_add_tcase(s, tc_core);

return s;
Expand Down
2 changes: 1 addition & 1 deletion www/features.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ table below.
<td><a href="http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/LCS2016_007">
LCS2016-007</td>
<td>Sequential declaration regions</td>
<td class="feature-missing"></td>
<td class="feature-done">master</td>
</tr>
<tr>
<td><a href="http://www.eda-twiki.org/cgi-bin/view.cgi/P1076/LCS2016_011">
Expand Down

0 comments on commit 6fb78ea

Please sign in to comment.