Add testbench and configuration files for SpriteChannel and YHitCheck modules
Not functional yet
This commit is contained in:
221
test/OPDecoder_tb.vhd
Normal file
221
test/OPDecoder_tb.vhd
Normal file
@@ -0,0 +1,221 @@
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use work.OPCodes.all;
|
||||
use std.env.stop;
|
||||
|
||||
entity OPDecoder_tb is
|
||||
end entity OPDecoder_tb;
|
||||
|
||||
architecture bench of OPDecoder_tb is
|
||||
-- Clock period
|
||||
constant K_CLKPeriod : time := 10 ns;
|
||||
-- Generics
|
||||
constant G_OPCodeData_Width : integer := 10;
|
||||
constant G_ROM_DataWidth : integer := 16;
|
||||
constant G_Index_Width : integer := 6;
|
||||
constant G_Offset_Width : integer := 4;
|
||||
constant G_LineData_Width : integer := 16;
|
||||
constant G_X_Width : integer := 10;
|
||||
constant G_Y_Width : integer := 10;
|
||||
constant G_Sprite_Height : integer := 16;
|
||||
constant G_PipelineStages : integer := 2;
|
||||
|
||||
-- Ports
|
||||
signal I_CLK : std_logic;
|
||||
signal I_CE : std_logic;
|
||||
signal I_RST : std_logic;
|
||||
signal I_OP_Valid : std_logic := '0';
|
||||
signal O_OP_Ready : std_logic := '0';
|
||||
signal I_OP_Code : std_logic_vector(3 downto 0) := (others => '0');
|
||||
signal I_OP_Data : std_logic_vector(G_OPCodeData_Width - 1 downto 0) := (others => '0');
|
||||
signal O_Register_Index_WE : std_logic := '0';
|
||||
signal O_Register_Index : std_logic_vector(G_Index_Width - 1 downto 0) := (others => '0');
|
||||
signal O_Register_Offset_WE : std_logic := '0';
|
||||
signal O_Register_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0');
|
||||
signal O_Register_X_We : std_logic := '0';
|
||||
signal O_Register_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
||||
signal O_Register_Y_WE : std_logic := '0';
|
||||
signal O_Register_Y : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
||||
signal O_Register_CachedLineData_WE : std_logic := '0';
|
||||
signal O_Register_CachedLineData : std_logic_vector(G_LineData_Width - 1 downto 0) := (others => '0');
|
||||
signal O_Register_CacheValid_WE : std_logic := '0';
|
||||
signal O_Register_CacheValid : std_logic := '0';
|
||||
signal I_YHitCheck_Ready : std_logic := '0';
|
||||
signal O_YHitCheck_Valid : std_logic := '0';
|
||||
signal O_YHitCheck_YToCheck : std_logic_vector(G_Y_Width - 1 downto 0) := (others => '0');
|
||||
signal O_YHitCheck_Ready : std_logic := '0';
|
||||
signal I_YHitCheck_Valid : std_logic := '0';
|
||||
signal I_YHitCheck_IsVisible : std_logic := '0';
|
||||
signal I_YHitCheck_Offset : std_logic_vector(G_Offset_Width - 1 downto 0) := (others => '0');
|
||||
signal O_Rom_Valid : std_logic := '0';
|
||||
signal I_Rom_Ready : std_logic := '0';
|
||||
signal I_Rom_Valid : std_logic := '0';
|
||||
signal O_Rom_Ready : std_logic := '0';
|
||||
signal I_Rom_Data : std_logic_vector(G_ROM_DataWidth - 1 downto 0) := (others => '0');
|
||||
signal O_CalcPipeline_Valid : std_logic := '0';
|
||||
signal I_CalcPipeline_Ready : std_logic := '0';
|
||||
signal O_CalcPipeline_X : std_logic_vector(G_X_Width - 1 downto 0) := (others => '0');
|
||||
|
||||
signal R1, R2 : std_logic := '0';
|
||||
|
||||
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;
|
||||
|
||||
i_OPDecoder : entity work.OPDecoder
|
||||
generic map(
|
||||
G_OPCodeData_Width => G_OPCodeData_Width,
|
||||
G_ROM_DataWidth => G_ROM_DataWidth,
|
||||
G_Index_Width => G_Index_Width,
|
||||
G_Offset_Width => G_Offset_Width,
|
||||
G_LineData_Width => G_LineData_Width,
|
||||
G_X_Width => G_X_Width,
|
||||
G_Y_Width => G_Y_Width
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
I_RST => I_RST,
|
||||
I_OP_Valid => I_OP_Valid,
|
||||
O_OP_Ready => O_OP_Ready,
|
||||
I_OP_Code => I_OP_Code,
|
||||
I_OP_Data => I_OP_Data,
|
||||
O_Register_Index_WE => O_Register_Index_WE,
|
||||
O_Register_Index => O_Register_Index,
|
||||
O_Register_Offset_WE => O_Register_Offset_WE,
|
||||
O_Register_Offset => O_Register_Offset,
|
||||
O_Register_X_We => O_Register_X_We,
|
||||
O_Register_X => O_Register_X,
|
||||
O_Register_Y_WE => O_Register_Y_WE,
|
||||
O_Register_Y => O_Register_Y,
|
||||
O_Register_CachedLineData_WE => O_Register_CachedLineData_WE,
|
||||
O_Register_CachedLineData => O_Register_CachedLineData,
|
||||
O_Register_CacheValid_WE => O_Register_CacheValid_WE,
|
||||
O_Register_CacheValid => O_Register_CacheValid,
|
||||
I_YHitCheck_Ready => I_YHitCheck_Ready,
|
||||
O_YHitCheck_Valid => O_YHitCheck_Valid,
|
||||
O_YHitCheck_YToCheck => O_YHitCheck_YToCheck,
|
||||
O_YHitCheck_Ready => O_YHitCheck_Ready,
|
||||
I_YHitCheck_Valid => I_YHitCheck_Valid,
|
||||
I_YHitCheck_IsVisible => I_YHitCheck_IsVisible,
|
||||
I_YHitCheck_Offset => I_YHitCheck_Offset,
|
||||
O_Rom_Valid => O_Rom_Valid,
|
||||
I_Rom_Ready => I_Rom_Ready,
|
||||
I_Rom_Valid => I_Rom_Valid,
|
||||
O_Rom_Ready => O_Rom_Ready,
|
||||
I_Rom_Data => I_Rom_Data,
|
||||
O_HSpritePipeline_Valid => O_CalcPipeline_Valid,
|
||||
I_HSpritePipeline_Ready => I_CalcPipeline_Ready,
|
||||
O_HSpritePipeline_X_Request => O_CalcPipeline_X
|
||||
);
|
||||
|
||||
I_CalcPipeline_Ready <= O_CalcPipeline_Valid;
|
||||
|
||||
i_YHitCheck : entity work.VerticalSpritePipeline
|
||||
generic map(
|
||||
G_Y_Width => G_Y_Width,
|
||||
G_Sprite_Height => G_Sprite_Height,
|
||||
G_Offset_Width => G_Offset_Width,
|
||||
G_PipelineStages => G_PipelineStages
|
||||
)
|
||||
port map(
|
||||
I_CLK => I_CLK,
|
||||
I_CE => I_CE,
|
||||
O_Ready => I_YHitCheck_Ready,
|
||||
I_Valid => O_YHitCheck_Valid,
|
||||
I_YToCheck => O_YHitCheck_YToCheck,
|
||||
I_Y => "0000000000",
|
||||
I_Ready => O_YHitCheck_Ready,
|
||||
O_Valid => I_YHitCheck_Valid,
|
||||
O_IsVisible => I_YHitCheck_IsVisible,
|
||||
O_Offset => I_YHitCheck_Offset
|
||||
);
|
||||
|
||||
StimulusProc : process
|
||||
type T_OpTest is record
|
||||
Code : std_logic_vector(3 downto 0);
|
||||
Data : std_logic_vector(G_OPCodeData_Width - 1 downto 0);
|
||||
Name : string(1 to 20);
|
||||
end record;
|
||||
|
||||
type T_OpTestArray is array (natural range <>) of T_OpTest;
|
||||
|
||||
constant TestCases : T_OpTestArray := (
|
||||
0 => (K_OP_NOP, (others => '0'), "NOP "),
|
||||
1 => (K_OP_SET_ID, std_logic_vector(to_unsigned(2, G_OPCodeData_Width)), "SET_ID "),
|
||||
2 => (K_OP_SET_X, std_logic_vector(to_unsigned(3, G_OPCodeData_Width)), "SET_X "),
|
||||
3 => (K_OP_SET_Y, std_logic_vector(to_unsigned(4, G_OPCodeData_Width)), "SET_Y "),
|
||||
4 => (K_OP_CLEAR_ALL, (others => '1'), "CLEAR_ALL "),
|
||||
6 => (K_OP_REQ_ROW_DATA, std_logic_vector(to_unsigned(5, G_OPCodeData_Width)), "REQ_ROW_DATA "),
|
||||
5 => (K_OP_NEWLINE, std_logic_vector(to_unsigned(1, G_Y_Width)), "NEWLINE ")
|
||||
);
|
||||
|
||||
variable i : integer;
|
||||
begin
|
||||
-- Init
|
||||
I_RST <= '1';
|
||||
I_CE <= '1';
|
||||
wait for K_CLKPeriod * 2;
|
||||
I_RST <= '0';
|
||||
wait for K_CLKPeriod * 2;
|
||||
|
||||
for i in TestCases'range loop
|
||||
-- Warte auf Ready
|
||||
wait until rising_edge(I_CLK);
|
||||
while O_OP_Ready /= '1' loop
|
||||
wait until rising_edge(I_CLK);
|
||||
end loop;
|
||||
|
||||
I_OP_Code <= TestCases(i).Code;
|
||||
I_OP_Data <= TestCases(i).Data;
|
||||
I_OP_Valid <= '1';
|
||||
|
||||
wait until rising_edge(I_CLK);
|
||||
I_OP_Valid <= '0';
|
||||
|
||||
-- Einfach ein bisschen warten, bis Modul durch ist
|
||||
-- wait for K_CLKPeriod * 5;
|
||||
|
||||
report "Opcode-Test: " & TestCases(i).Name & " abgeschlossen." severity note;
|
||||
end loop;
|
||||
|
||||
report "Alle OPCodes getestet." severity note;
|
||||
TestDone <= true;
|
||||
wait;
|
||||
end process;
|
||||
|
||||
-- ROM Simulation: immer gültig, gibt X"FFFF" zurück
|
||||
RomProcess : process (I_CLK)
|
||||
begin
|
||||
if rising_edge(I_CLK) then
|
||||
if I_CE = '1' then
|
||||
-- Standard: nichts tun
|
||||
I_Rom_Valid <= '0';
|
||||
I_Rom_Data <= (others => '0');
|
||||
|
||||
-- Prüfen, ob Decoder Daten anfordert
|
||||
if O_Rom_Valid = '1' then
|
||||
I_Rom_Valid <= '1';
|
||||
I_Rom_Data <= (others => '1'); -- z.B. X"FFFF"
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- ROM ist immer bereit
|
||||
I_Rom_Ready <= '1';
|
||||
end architecture;
|
Reference in New Issue
Block a user