Files
SpriteChannel/test/YHitCheck_tb.vhd

166 lines
5.3 KiB
VHDL

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.env.stop;
use work.SpriteRom.all;
entity YHitCheck_tb is
end;
architecture bench of YHitCheck_tb is
-- Clock period
constant K_CLKPeriod : time := 10 ns;
-- Generics
constant G_YWidth : integer := 10;
constant G_SpriteHeight : integer := 16;
-- Ports
signal I_CLK : std_logic := '0';
signal I_CE : std_logic;
signal O_Ready : std_logic;
signal I_Valid : std_logic;
signal I_YToCheck : std_logic_vector(G_YWidth - 1 downto 0);
signal I_Y : std_logic_vector(G_YWidth - 1 downto 0);
signal I_Ready : std_logic;
signal O_Valid : std_logic;
signal O_IsVisible : std_logic;
signal O_Offset : std_logic_vector(7 downto 0);
type T_TestData is record
YToCheck : integer;
SpriteY : integer;
ExpectedVisible : std_logic;
ExpectedOffset : integer; -- NEU
end record;
type T_TestArray is array (natural range <>) of T_TestData;
constant TestValues : T_TestArray := (
(10, 10, '1', 0),
(25, 10, '1', K_SPRITE_ROW_OFFSETS(15)),
(26, 10, '0', 0),
(9, 10, '0', 0),
(15, 0, '1', K_SPRITE_ROW_OFFSETS(15)),
(31, 16, '1', K_SPRITE_ROW_OFFSETS(15)),
(32, 16, '0', 0),
(984, 459, '0', 0),
(360, 972, '0', 0),
(160, 434, '0', 0),
(996, 713, '0', 0),
(63, 184, '0', 0),
(700, 376, '0', 0),
(702, 69, '0', 0),
(583, 181, '0', 0),
(302, 974, '0', 0),
(985, 392, '0', 0),
(0, 0, '1', 0),
(15, 0, '1', K_SPRITE_ROW_OFFSETS(15)),
(16, 0, '0', 0),
(0, 1, '0', 0),
(1023, 1008, '1', K_SPRITE_ROW_OFFSETS(15)),
(1023, 1007, '0', 0),
(1007, 1007, '1', 0),
(1008, 1008, '1', 0),
(1009, 1008, '1', K_SPRITE_ROW_OFFSETS(1)),
(1023, 1008, '1', K_SPRITE_ROW_OFFSETS(15))
);
signal TestDone : boolean := false;
begin
ClockProc : process
begin
while TestDone = false loop
I_CLK <= '0';
wait for K_CLKPeriod / 2;
I_CLK <= '1';
wait for K_CLKPeriod / 2;
end loop;
I_CLK <= '0';
stop(0);
wait;
end process;
SpriteChannel_YHitCheck_inst : entity work.VerticalSpritePipeline
generic map(
G_Y_Width => G_YWidth,
G_Sprite_Height => G_SpriteHeight
)
port map(
I_CLK => I_CLK,
I_CE => I_CE,
O_Ready => O_Ready,
I_Valid => I_Valid,
I_YToCheck => I_YToCheck,
I_Y => I_Y,
I_Ready => I_Ready,
O_Valid => O_Valid,
O_IsVisible => O_IsVisible,
O_Offset => O_Offset
);
StimulusProc : process
variable i : integer := 0;
begin
-- Init
i := 0;
I_CE <= '1';
I_Valid <= '0';
I_Ready <= '1';
I_Y <= (others => '0');
I_YToCheck <= (others => '0');
wait for K_CLKPeriod * 5;
for i in TestValues'range loop
-- Warte auf Ready
wait until rising_edge(I_CLK);
while O_Ready /= '1' loop
wait until rising_edge(I_CLK);
end loop;
-- Werte setzen
I_Y <= std_logic_vector(to_unsigned(TestValues(i).SpriteY, G_YWidth));
I_YToCheck <= std_logic_vector(to_unsigned(TestValues(i).YToCheck, G_YWidth));
I_Valid <= '1';
wait until rising_edge(I_CLK);
I_Valid <= '0';
-- Warte auf O_Valid
while O_Valid /= '1' loop
wait until rising_edge(I_CLK);
end loop;
-- Ergebnis prüfen
if O_IsVisible /= TestValues(i).ExpectedVisible then
assert false
report "Fehler bei Test " & integer'image(i) &
": SpriteY=" & integer'image(TestValues(i).SpriteY) &
" YToCheck=" & integer'image(TestValues(i).YToCheck) &
" Erwartet Sichtbarkeit=" & std_logic'image(TestValues(i).ExpectedVisible) &
" Tatsaechlich=" & std_logic'image(O_IsVisible)
severity error;
elsif O_IsVisible = '1' then
-- Nur prüfen, wenn sichtbar
if to_integer(unsigned(O_Offset)) /= TestValues(i).ExpectedOffset then
assert false
report "Fehler bei Test " & integer'image(i) &
": Falscher Offset. Erwartet=" & integer'image(TestValues(i).ExpectedOffset) &
" Tatsaechlich=" & integer'image(to_integer(unsigned(O_Offset)))
severity error;
else
report "Test " & integer'image(i) & " erfolgreich." severity note;
end if;
else
-- Unsichtbarer Fall, Sichtbarkeit korrekt => Erfolg
report "Test " & integer'image(i) & " erfolgreich." severity note;
end if;
wait for K_CLKPeriod * 2;
end loop;
report "Alle Tests abgeschlossen." severity note;
TestDone <= true;
wait;
end process;
end;