Skip to content

VHDL: parsing component declarations inside entities #7

Open
@vvvverre

Description

@vvvverre

This bug was passed to me by someone else, but I am posting it as an issue so we can track it.

Currently pyHDLparser does not parse component declarations inside the architecture of an entity correctly. I have attached below a simple example of a VHDL file that recreates this bug.

library ieee;
use ieee.std_logic_1164.all;

entity three_bit_adder is
    port (
        a       : in std_logic_vector(2 downto 0);
        b       : in std_logic_vector(2 downto 0);
        cin     : out std_logic;
        s       : out std_logic_vector(2 downto 0);
        cout    : out std_logic
    );
end entity three_bit_adder;

architecture arch of three_bit_adder is

    component full_adder is
        port (
            x, y, ci: in std_logic;
            q, co: out std_logic
        );
    end component; 
    
    signal c: std_logic_vector(3 downto 0);
begin

    c(0) <= cin;

    FA0: full_adder port map(a => a(0), b => b(0), cin => c(0), cout => c(1));
    FA1: full_adder port map(a => a(1), b => b(1), cin => c(1), cout => c(2));
    FA2: full_adder port map(a => a(2), b => b(2), cin => c(2), cout => c(3));
    
    cout <= c(3);
    
end arch;

I used the following python code to recreate the bugs.

import hdlparse.vhdl_parser as vhdl

vhdl_code = """
<SEE SNIPPET ABOVE>
"""

vhdl_ex = vhdl.VhdlExtractor()
vhdl_objs = vhdl_ex.extract_objects_from_source(vhdl_code)

for o in vhdl_objs:
    o.dump()

The output I would expect for this is as follows:

VHDL entity: three_bit_adder
	a (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	b (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	cin (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	s (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	cout (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
VHDL component: full_adder
	x (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	y (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	ci (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	q (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	co (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)

Instead the output is as follows:

VHDL entity: three_bit_adder
	a (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	b (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	cin (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	s (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	cout (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	x (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	y (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	ci (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	q (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	co (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)

There are two issues here:

  1. The component declaration for the component full_adder is never recognized
  2. The ports of the full_adder component are added to the ports of the entity

I believe the first issue is caused by an incorrect regex, which would only trigger on the syntax end three_bit_adder; but not end entity three_bit_adder;. I think this can be fixed like this:

@@ -87,7 +94,7 @@ vhdl_tokens = {
     'entity': [
         (r'generic\s*\(', None, 'generic_list'),
         (r'port\s*\(', None, 'port_list'),
-        (r'end\s+\w+\s*;', 'end_entity', '#pop'),
+        (r'end\s+(entity\s+)?\w+\s*;', 'end_entity', '#pop'),
         (r'/\*', 'block_comment', 'block_comment'),
         (r'--.*\n', None),
     ],

This changes the output to:

VHDL entity: three_bit_adder
	a (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	b (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	cin (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	s (<class 'str'>), VhdlParameterType('std_logic_vector','(2 downto 0)') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)
	cout (<class 'str'>), VhdlParameterType('std_logic','') (<class 'hdlparse.vhdl_parser.VhdlParameterType'>)

Which is more correct, but still misses the component declaration.
Adding the following token gives the expected output:

@@ -95,6 +102,7 @@ vhdl_tokens = {
         (r'end\s+\w+\s*;', 'end_arch', '#pop'),
         (r'/\*', 'block_comment', 'block_comment'),
         (r'type\s+(\w+)\s*is', 'type', 'type_decl'),
+        (r'component\s+(\w+)\s*is', 'component', 'component'),
         (r'--.*\n', None),
     ],
     'generic_list': [

One outstanding question I have is whether there should be some way of indicating that the VHDL component is declared inside the architecture?

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions