I'm new to VHDL and currently try to get more complex data types working, so that code becomes more readable… However, it seems that I cannot define a type in VHDL before the entity
statement, which is using the type inside it's port statement.
Hence, it seems I need to somehow write my own library for that. I assume this must work, as types as std_logic_vector must be defined somehow too. Or did they hardcode these types into the VDHL compiler… and if so, why do we still need to include the libraries for it?
I want to do something like in the following code example. However, the compiler doesn't let my define the type in Test.vhdl as mentioned above. Anyhow, it seems to be valid to define the component in TOP.vhdl.
I also would like to avoid to redefine the component and the data type in TOP.vhdl anyway. Is there a way to do this?
Test.vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
type MyRecordType is record -- Compiler complains about this!
x : std_logic_vector(2 downto 0); -- expects 'entity' or 'architecture'
y : std_logic_vector(2 downto 0);
end record;
entity Test is
port(
clk : in std_logic;
input : in MyRecordType;
output : out std_logic
);
end entity;
architecture RTL of Test is
begin
process (clk) is
begin
if rising_edge(clk) then
if (input.x = input.y) then
output <= '1';
else
output <= '0';
end if;
end if;
end process;
end;
TOP.vhdl
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
entity TOP is
end entity;
architecture SIM of TOP is
type MyRecordType is record
x : std_logic_vector(2 downto 0);
y : std_logic_vector(2 downto 0);
end record;
component Test is
port(
clk : in std_logic;
input : in MyRecordType;
output : out std_logic
);
end component;
constant period : time := 20 ns;
signal clk : std_logic;
signal result : std_logic;
signal myRecord : MyRecordType;
begin
dut : Test port map(clk => clk, input => myRecord, output => result);
clk <= not clk after period / 2;
process is
begin
myRecord.x <= "000";
myRecord.y <= "000";
wait for 20 ns;
if result = 0 then
report "TEST 1 - FAILED.";
else
report "TEST 1 - PASSED.";
end if;
myRecord.x <= "000";
myRecord.y <= "010";
wait for 20 ns;
if result = 1 then
report "TEST 2 - FAILED.";
else
report "TEST 2 - PASSED.";
end if;
wait;
end process;
end architecture;
Best Answer
To use a user defined type in a port declaration, you need to specify the type in a package and use that package in the context before the entity.
Utilities.vhdl
Test.vhdl
Top.vhdl
Further hints:
std_logic_unsigned
, usenumeric_std
instead.myRecord
at the beginning of the simulation, then initialize it when you declare the signal. UsingmyRecord.x <= "000";
has a delay of one delta cycle!result = 0
, becauseresult
is no integer, you need to compare with'0'
.wait for 20 ns;
. Usewait for period;
.