library ieee;
use ieee.std_logic_1164.all;
use work.testing_functions.all;
entity char_alignment_tb is
end entity char_alignment_tb;
architecture a1 of char_alignment_tb is
type data_array is array (0 to 200) of std_logic_vector(9 downto 0);
type test_vector is record -- A vector for testing
data_count : integer; -- The count of 10b encoded data
data : data_array;
synced_after : integer; -- The amount of clock cycles to turn synced to 1 after
expected_data : data_array;
expected_aligned_after : integer; -- The amount of clock cycles after the aligned should be 1
expected_alignment_index : integer; -- The correct alignment index to be set after aligned_after clock cyles
end record test_vector;
type test_vector_array is array (natural range <>) of test_vector;
constant test_vectors : test_vector_array := (
(
data_count => 10,
synced_after => 4,
expected_aligned_after => 4,
expected_alignment_index => 0,
data => (0 => "0011111010", 1 => "0000000000", 2 => "1111111111", 3 => "0101010101", 4 => "1111100000", 5 => "0000011111", others => "0000000000"),
expected_data => (0 => "0011111010", 1 => "0000000000", 2 => "1111111111", 3 => "0101010101", 4 => "1111100000", 5 => "0000011111", others => "0000000000")
),
(
data_count => 10,
synced_after => 4,
expected_aligned_after => 4,
expected_alignment_index => 1,
data => (0 => "0111110100", 1 => "0000010100", 2 => "1010101011", 3 => "0101010101", 4 => "1111000000", 5 => "0000111110", 6 => "0000000000", others => "0000000000"),
expected_data => (0 => "0011111010", 1 => "0000001010", 2 => "0101010101", 3 => "1010101010", 4 => "1111100000", 5 => "0000011111", others => "0000000000")
)
);
constant clk_period : time := 1 ns; -- The clock period
signal clk : std_logic := '0'; -- The clock
signal reset : std_logic := '0'; -- The reset
signal ci_synced : std_logic := '0'; -- Whether synced
signal di_10b : std_logic_vector(9 downto 0) := (others => '0'); -- The 10b data input
signal do_10b : std_logic_vector(9 downto 0);
signal co_aligned : std_logic;
signal test_data_index : integer := 0;
signal cycle_num : integer := 0;
begin -- architecture a1
uut : entity work.char_alignment
port map (
ci_link_clk => clk,
ci_reset => reset,
di_chars => di_10b,
do_chars => do_10b,
ci_synced => ci_synced,
co_aligned => co_aligned);
clk_gen: process is
begin -- process clk_gen
wait for clk_period/2;
clk <= not clk;
end process clk_gen;
reset_gen: process is
begin -- process reset_gen
wait for clk_period*2;
reset <= '1';
end process reset_gen;
test: process is
variable test_vec : test_vector;
begin -- process test
wait for clk_period*3;
for i in test_vectors'range loop
test_vec := test_vectors(i);
test_data_index <= i;
for cycle in 0 to test_vectors(i).data_count loop
cycle_num <= cycle;
di_10b <= test_vec.data(cycle);
if cycle >= test_vec.synced_after then
ci_synced <= '1';
else
ci_synced <= '0';
end if;
if cycle = test_vec.expected_aligned_after then
assert (co_aligned = '1') report "Not aligned after " & integer'image(test_vec.expected_aligned_after) & ", index: " & integer'image(i) severity error;
end if;
if cycle >= test_vec.synced_after then
assert (do_10b = test_vec.expected_data(cycle - 2)) report "The data does not match, data index: " & integer'image(i) & ", expected: " & vec2str(test_vec.expected_data(cycle - 2)) & ", got: " & vec2str(do_10b) severity error;
end if;
wait for clk_period;
end loop; -- cycle
end loop; -- i
end process test;
end architecture a1;