Skip to content

Allow protected type objects to be declared before the protected body is elaborated#1471

Open
marph91 wants to merge 1 commit into
nickg:masterfrom
marph91:allow-protected-before-body
Open

Allow protected type objects to be declared before the protected body is elaborated#1471
marph91 wants to merge 1 commit into
nickg:masterfrom
marph91:allow-protected-before-body

Conversation

@marph91
Copy link
Copy Markdown

@marph91 marph91 commented Mar 31, 2026

Resolves #1432

We would like to try nvc, but got the same issue in a central component of our codebase. So I took a try in extending the --relaxed flag. I would be glad about feedback.

I tested manual with this minimal example (not certain where to add this in the automated tests):

package prot_pkg is
  type t_prot is protected
    impure function get return natural;
  end protected t_prot;

  shared variable shared_var_prot : t_prot;
end package prot_pkg;

package body prot_pkg is
  type t_prot is protected body
    impure function get return natural is
    begin
      return 1;
    end function get;
  end protected body t_prot;
end package body prot_pkg;

----------

entity issue_1432 is end entity;

architecture arch of issue_1432 is
begin
  tb : process
  begin
    report "access shared variable: " & integer'image(work.prot_pkg.shared_var_prot.get);
    wait;
  end process;
end architecture;

Strict

$ ./bin/nvc -L ./lib -a ../shared_variable_example/issue_1432.vhd -e issue_1432 -r
** Error: cannot declare instance of protected type T_PROT before its body has been elaborated
   > ../shared_variable_example/issue_1432.vhd:6
   |
 2 |   type t_prot is protected
   |                  ^ T_PROT declared here
 ...
 6 |   shared variable shared_var_prot : t_prot;
   |                   ^^^^^^^^^^^^^^^ error occurred here
   |
   = Help: IEEE Std 1076-2008 section 14.4.2 "Elaboration of a declaration"
** Error: design unit depends on WORK.PROT_PKG which was analysed with errors
   > ../shared_variable_example/issue_1432.vhd:9
   |
 9 | package body prot_pkg is
   | ^^^^^^^^^^^^^^^^^^^^^
** Error: design unit depends on WORK.PROT_PKG which was analysed with errors
    > ../shared_variable_example/issue_1432.vhd:27
    |
 27 |     report "access shared variable: " & integer'image(work.prot_pkg.shared_var_prot.get);
    |

With --relaxed

$ ./bin/nvc -L ./lib -a ../shared_variable_example/issue_1432.vhd --relaxed -e issue_1432 -r
** Note: 0ms+0: access shared variable: 1
   Process :issue_1432:tb at ../shared_variable_example/issue_1432.vhd:25

@nickg
Copy link
Copy Markdown
Owner

nickg commented Apr 8, 2026

This rule exists in the LRM to avoid problems with circular definitions like:

package pack is
    type pt is protected
        function get_x return integer;
        function get_z return integer;
    end protected;

    shared variable sv : pt;

    constant x : integer := sv.get_x;  -- Definition of X depends on X
    constant y : integer := sv.get_z;  -- Definition of Y depends on Z which is elaborated later
    constant z : integer := 42;
end package;

package body pack is
    type pt is protected body
        function get_x return integer is
        begin
            return x;
        end function;

        function get_z return integer is
        begin
            return z;
        end function;
    end protected body;
end package body;

I think the normal pattern to handle this "singleton protected type" case is to add wrapper procedures and functions in the package which then call the PT methods inside the body. Something like:

package prot_pkg is
  impure function get return natural;
end package prot_pkg;

package body prot_pkg is
  type t_prot is protected
    impure function get return natural;
  end protected t_prot;

  type t_prot is protected body
    impure function get return natural is
    begin
      return 1;
    end function get;
  end protected body t_prot;

  shared variable shared_var_prot : t_prot;

  impure function get return natural is
  begin
    return shared_var_prot.get;
  end function.
end package body prot_pkg;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Protected type instance requires body elaboration (request for -allowProtectedBeforeBody compatibility)

2 participants