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;