I have a rather large project, comprised of many modules integrated into one top-level component. I've created test-benches for these modules which make use of API packages (which I've created alongside them). I also have a top-level test-bench that tests the integrated system as a whole.
For one of the components, I'm interested in using VHDL-2008 Hierarchical Names within its MyModuleAPIPackage
in order to access the internal signals from the top level testbench. Since I'm trying to write modular and re-usable code, I'd like to be able to instantiate the package so that it references the signals of the module within the component-level test (where the module is at the top level)
<<signal .MyComponent.MySignal : std_logic>>
and also within the top-level test (where there is an underlying structure)
<<signal .MySystem.MySubSystem.MyComponent.MySignal : std_logic>>
Perhaps this could be attainable through a combination of Hierarchical Names and generics?
Here is some (pseudo) code exemplifying what I'm trying to achieve.
MyModule.vhd
-- MyModule.vhd
entity MyModule is
port(
CLK : in std_logic;
RST : in std_logic;
DATA_IN : in std_logic_vector(7 downto 0);
DATA_OUT : out std_logic_vector(7 downto 0)
);
end entity MyModule;
architecture behavioral of MyModule is
-- Signal and constant definitions here.
begin
-- Describes how MyModule behaves.
end architecture behavioral;
----------------------
-- MyModule Test-Bench
----------------------
entity MyModule_tb is
end entity MyModule_tb;
architecture test of MyModule_tb is
-- Signal and constant definitions here
signal CLK, RST : std_logic := '0';
signal DATA_IN, DATA_OUT : std_logic_vector(7 downto 0) := (others = '0');
procedure DoComplexStuff(
InstructionCode : natural
)
is
begin
case InstructionCode is
when 0 =>
DATA_IN <= "01010101";
wait until CLK = '1';
DATA_IN <= "00110011";
wait until CLK = '1';
-- Lots of pretty complex stimuli
assert DATA_OUT = "00110011"
report "Output mismatch!"
severity failure;
when 1 =>
-- Lots of pretty complex stimuli
-- when ... =>
-- Plenty more instruction codes
others =>
null;
end procedure DoComplexStuff;
begin
CLK <= not CLK after 1 ms;
MainTestProc:
process
begin
for i in 0 to 99 loop
DoComplexStuff(i);
end loop;
end;
DUT: entity work.MyModule(behavioral)
port map(
CLK => CLK,
RST => RST,
DATA_IN => DATA_IN,
DATA_OUT => DATA_OUT
);
end architecture test;
I wish for procedure DoComplexStuff
to be available at the top-level.
MyModuleApi.vhd
package MyModuleAPI is
generic(
-- Programatically defined aliases
PATH : path;
)
alias CLK is <<signal PATH.CLK : std_logic);
alias RST is <<signal PATH.RST : std_logic);
alias DATA_IN is <<signal PATH.DATA_IN : std_logic_vector(7 downto 0));
alias DATA_OUTis <<signal PATH.DATA_OUT : std_logic_vector(7 downto 0));
procedure DoComplexStuff(
InstructionCode : in natural
);
end package;
package body MyModuleAPI is
-- I can now include this package within MyModule_tb and
-- MyTopLevelComponent_tb and call DoComplexStuff to interact with the signals
-- from MyModule
procedure DoComplexStuff(
InstructionCode : natural
)
is
begin
case InstructionCode is
when 0 =>
DATA_IN <= "01010101";
wait until CLK = '1';
DATA_IN <= "00110011";
wait until CLK = '1';
-- Lots of pretty complex stimuli
assert DATA_OUT = "00110011"
report "Output mismatch!"
severity failure;
when 1 =>
-- Lots of pretty complex stimuli
-- when ... =>
-- Plenty more instruction codes
others =>
null;
end procedure DoComplexStuff;
end package body MyModuleAPI;
Therefore, MyModule_tb would include the package MyModuleAPI with a parameter specifying itself as the top level component and MyTopLevel_tb would include the same package with a parameter properly specifying the path to MyModule. (?)
NOTE: yes, my intention is to modify (bit-bang) internal signals during a top-level test. This would be similar to using ModelSim's "signal_force" and "signal_release" commands.
Thanks in advance for your guidance!