@@ 0,0 1,275 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use work.testing_functions.all;
+use work.data_link_pkg.all;
+
+entity link_controller_tb is
+end entity link_controller_tb;
+
+architecture a1 of link_controller_tb is
+ type test_vector is record
+ di_char : character_vector;
+ ci_resync : std_logic;
+ ci_lane_alignment_error : std_logic;
+ ci_lane_alignment_aligned : std_logic;
+ ci_lane_alignment_ready : std_logic;
+
+ ci_frame_alignment_error : std_logic;
+ ci_frame_alignment_aligned : std_logic;
+
+ expected_synced : std_logic;
+ expected_state : link_state;
+ expected_uncorrectable_error : std_logic;
+ expected_error : std_logic;
+ expected_config_index : integer;
+ end record test_vector;
+
+ type config_array is array (natural range<>) of link_config;
+ constant config_vectors : config_array :=
+ (
+ (
+ DID => 170,
+ ADJCNT => 7,
+ BID => 14,
+ ADJDIR => '1',
+ PHADJ => '1',
+ LID => 10,
+ SCR => '1',
+ L => 31,
+ F => 205,
+ K => 32,
+ M => 52,
+ CS => 2,
+ N => 4,
+ SUBCLASSV => 1,
+ Nn => 30,
+ JESDV => 0,
+ S => 1,
+ HD => '0',
+ CF => 0,
+ RES1 => "11111111",
+ RES2 => "00000000",
+ X => "010010000",
+ CHKSUM => 48
+ ),
+ (
+ DID => 170,
+ ADJCNT => 7,
+ BID => 14,
+ ADJDIR => '1',
+ PHADJ => '1',
+ LID => 10,
+ SCR => '1',
+ L => 31,
+ F => 205,
+ K => 32,
+ M => 52,
+ CS => 2,
+ N => 4,
+ SUBCLASSV => 1,
+ Nn => 30,
+ JESDV => 0,
+ S => 1,
+ HD => '0',
+ CF => 0,
+ RES1 => "11111111",
+ RES2 => "11111111",
+ X => "010010000",
+ CHKSUM => 48
+ )
+ );
+
+ type test_vector_array is array (natural range<>) of test_vector;
+ constant test_vectors : test_vector_array :=
+ (
+ --kout der noter char resync ler lal lre fer fal expsyn expstexpuner exper expconf
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '1', CGS, '0', '0', -1),
+ (('1', '0', '0', "00011100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1), --R
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('1', '0', '0', "01111100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1), --A
+ (('1', '0', '0', "00011100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1), --R
+ (('0', '0', '0', "10011100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "10101010"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "01111110"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "01101010"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "11011110"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "11001100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "01011111"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00110011"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "10000011"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00111101"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "11111111"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('0', '0', '0', "00110000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1),
+ (('1', '0', '0', "01111100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', -1), --A
+ (('1', '0', '0', "00011100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0), --R
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('1', '0', '0', "01111100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0), --A
+ (('1', '0', '0', "00011100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0), --R
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0),
+ (('1', '0', '0', "01111100"), '0', '0', '0', '0', '0', '0', '1', ILS, '0', '0', 0), --A
+ (('0', '0', '0', "01010101"), '0', '0', '0', '0', '0', '0', '1', DATA, '0', '0', 0),
+ (('0', '0', '0', "01010101"), '0', '0', '0', '0', '0', '0', '1', DATA, '0', '0', 0),
+ (('0', '0', '0', "01010101"), '0', '0', '0', '0', '0', '0', '1', DATA, '0', '0', 0),
+ (('0', '0', '0', "01010101"), '0', '0', '0', '0', '0', '0', '1', DATA, '0', '0', 0),
+ (('0', '0', '0', "01010101"), '0', '0', '0', '0', '0', '0', '1', DATA, '0', '0', 0),
+ (('0', '0', '1', "01010101"), '0', '0', '0', '0', '0', '0', '1', DATA, '0', '1', 0),
+ (('0', '0', '0', "01010101"), '0', '1', '0', '0', '0', '0', '1', DATA, '0', '1', 0),
+ (('0', '0', '0', "01010101"), '0', '1', '0', '0', '1', '0', '1', DATA, '0', '1', 0),
+ (('0', '0', '0', "01010101"), '0', '0', '0', '0', '1', '0', '1', DATA, '0', '1', 0),
+ (('0', '0', '0', "01010101"), '1', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "01010101"), '1', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "01010101"), '1', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '0', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '1', CGS, '0', '0', -1),
+ (('1', '0', '0', "10111100"), '0', '0', '0', '0', '0', '0', '1', CGS, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '1', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1),
+ (('0', '0', '0', "00000000"), '0', '0', '0', '0', '0', '0', '0', INIT, '0', '0', -1)
+ );
+
+ constant clk_period : time := 1 ns;
+
+ constant F : integer range 0 to 256 := 17;
+ constant K : integer range 0 to 32 := 1;
+
+ signal clk : std_logic := '0';
+ signal reset : std_logic := '0';
+
+ signal di_char : character_vector;
+ signal do_config : link_config;
+
+ signal ci_resync : std_logic := '0';
+ signal ci_lane_alignment_error : std_logic := '0';
+ signal ci_lane_alignment_aligned : std_logic := '0';
+ signal ci_lane_alignment_ready : std_logic := '0';
+ signal ci_frame_alignment_error : std_logic := '0';
+ signal ci_frame_alignment_aligned : std_logic := '0';
+
+
+ signal co_finished : std_logic;
+ signal co_state : link_state;
+ signal co_synced : std_logic;
+ signal co_error : std_logic;
+ signal co_uncorrectable_error : std_logic;
+
+ signal test_data_index : integer := 0;
+
+begin -- architecture a1
+ uut : entity work.link_controller
+ port map (
+ ci_char_clk => clk,
+ ci_reset => reset,
+ ci_F => F,
+ ci_K => K,
+ ci_resync => ci_resync,
+ ci_lane_alignment_aligned => ci_lane_alignment_aligned,
+ ci_lane_alignment_error => ci_lane_alignment_error,
+ ci_lane_alignment_ready => ci_lane_alignment_ready,
+ ci_frame_alignment_aligned => ci_frame_alignment_aligned,
+ ci_frame_alignment_error => ci_frame_alignment_error,
+ di_char => di_char,
+ do_config => do_config,
+ co_synced => co_synced,
+ co_state => co_state,
+ co_uncorrectable_error => co_uncorrectable_error,
+ co_error => co_error
+ );
+
+ clk <= not clk after clk_period/2;
+ reset <= '1' after clk_period*2;
+
+ test: process is
+ variable test_vec : test_vector;
+ variable prev_test_vec : test_vector;
+ begin -- process test
+ wait for clk_period*2;
+
+ for i in test_vectors'range loop
+ test_data_index <= i;
+ test_vec := test_vectors(i);
+ di_char <= test_vec.di_char;
+ ci_resync <= test_vec.ci_resync;
+ ci_lane_alignment_aligned <= test_vec.ci_lane_alignment_aligned;
+ ci_lane_alignment_error <= test_vec.ci_lane_alignment_error;
+ ci_lane_alignment_ready <= test_vec.ci_lane_alignment_ready;
+ ci_frame_alignment_aligned <= test_vec.ci_frame_alignment_aligned;
+ ci_frame_alignment_error <= test_vec.ci_frame_alignment_error;
+
+ if i > 0 then
+ prev_test_vec := test_vectors(i - 1);
+
+ if prev_test_vec.expected_config_index > -1 then
+ assert do_config = config_vectors(prev_test_vec.expected_config_index) report "The config does not match. Index: " & integer'image(i-1) severity error;
+ end if;
+
+ assert co_state = prev_test_vec.expected_state report "The state does not match. Index: " & integer'image(i-1) severity error;
+ assert co_synced = prev_test_vec.expected_synced report "The synced does not match. Index: " & integer'image(i-1) severity error;
+ assert co_error = prev_test_vec.expected_error report "The error does not match. Index: " & integer'image(i-1) severity error;
+ assert co_uncorrectable_error = prev_test_vec.expected_uncorrectable_error report "The uncorrectable error does not match. Index: " & integer'image(i-1) severity error;
+ end if;
+
+ wait for clk_period;
+ end loop; -- i
+ wait for 100 ms;
+ end process test;
+end architecture a1;