AMBPEX5_v20_SX50T_CORE
|
00001 ------------------------------------------------------------------------------- 00002 -- 00003 -- Title : cl_test_check 00004 -- Author : Dmitry Smekhov 00005 -- Company : Instrumental Systems 00006 -- E-mail : dsmv@insys.ru 00007 -- 00008 -- Version : 1.0 00009 -- 00010 ------------------------------------------------------------------------------- 00011 -- 00012 -- Description : Узел проверки входного потока 00013 -- 00014 -- Тестовая последовательность представляет собой набор блоков. 00015 -- Размер блока задаётся кратным страницы размером 4 килобайта 00016 -- (512 слов по 64 бита) 00017 -- Первое 64-х разрядное слово в блоке содержит сигнатуру и порядковый номер. 00018 -- 31..0 - сигнатура 0xA5A50123 00019 -- 63..32 - порядковый номер блока 00020 -- 00021 -- Содержимое блока зависит от его порядкового номера в последовательности. 00022 -- 00023 -- Содержимое блока: 00024 -- 0 - Бегущая единица по 64-м разрядам 00025 -- 1 - Бегущий ноль по 64-м разрядам 00026 -- 2 - Бегущая единица с инверсией по 64-м разрядам 00027 --- Чётные номера слов - бегущая единица по 64-м разрядам 00028 -- Нечётные номера - инверсия предыдущего слова 00029 -- 3 - Бегущая единица в блоке 00030 -- Номер слова сравнивается с номером блока (сравниваются восемь младший разрядов) 00031 -- При совпадении - в слово записывается бегущая 1. 00032 -- Остальные слова - значение ноль. 00033 -- 4 - Бегущий ноль с инверсией по 64-м разрядам 00034 -- Чётные номера - бегущий ноль по 64-м разрядам 00035 -- Нечётные номера - инверсия предыдущего слова 00036 -- 5 - Бегущий ноль а в блоке 00037 -- Номер слова сравнивается с номером блока (сравниваются восемь младший разрядов) 00038 -- При совпадении - в слово записывается бегущий 0. 00039 -- Остальные слова - значение 0xFFFFFFFFFFFFFFFF. 00040 -- 6,7 - Счётчик по 64-м разрядам 00041 -- Чётные номера - значение счётчика 00042 -- Нечётные номера - инверсия предыдущего слова 00043 -- 8,9 - Псевдослучайная последовательность 00044 -- Формируется М-последовательность по 64 разрядам. 00045 -- Начальное значение - 1 00046 -- Слово формируется сдвигом на один разряд вправо. 00047 -- В младший разряд слова записывается значение x[63] xor x[62] 00048 -- 00049 -- 00050 -- Для режима счётчика и псевдослучайной последовательности начальное значение 00051 -- формируется при инициализации тестовой последовательности. 00052 -- Для остальных режимов - при инициализации проверки блока 00053 -- 00054 -- 00055 -- Регистр test_check_ctrl 00056 -- 00057 -- 0 - 1 сброс узла 00058 -- 5 - 1 старт приёма данных 00059 -- 7 - 1 фиксированный тип блока 00060 -- 11..8 - номер блока при test_check_ctrl[7]=1 00061 -- 00062 00063 ------------------------------------------------------------------------------- 00064 -- 00065 -- Version 1.0 00066 -- 00067 ------------------------------------------------------------------------------- 00068 00069 00070 00071 00072 library ieee; 00073 use ieee.std_logic_1164.all; 00074 00075 package cl_test_check_pkg is 00076 00077 component cl_test_check is 00078 port( 00079 00080 ---- Global ---- 00081 reset : in std_logic; -- 0 - сброс 00082 clk : in std_logic; -- тактовая частота 00083 00084 ---- DIO_OUT ---- 00085 do_clk : in std_logic; -- тактовая частота чтения из FIFO 00086 do_data : in std_logic_vector( 63 downto 0 ); 00087 do_data_en : in std_logic; -- 1 - передача данных из dio_out 00088 00089 00090 ---- Управление ---- 00091 test_check_ctrl : in std_logic_vector( 15 downto 0 ); 00092 test_check_size : in std_logic_vector( 15 downto 0 ); -- размер в блоках по 512x64 (4096 байт) 00093 test_check_bl_rd : out std_logic_vector( 31 downto 0 ); 00094 test_check_bl_ok : out std_logic_vector( 31 downto 0 ); 00095 test_check_bl_err : out std_logic_vector( 31 downto 0 ); 00096 test_check_error : out std_logic_vector( 31 downto 0 ); 00097 test_check_err_adr : in std_logic_vector( 15 downto 0 ); 00098 test_check_err_data: out std_logic_vector( 15 downto 0 ) 00099 00100 ); 00101 end component; 00102 00103 end package; 00104 00105 00106 library ieee; 00107 use ieee.std_logic_1164.all; 00108 use ieee.std_logic_arith.all; 00109 use ieee.std_logic_unsigned.all; 00110 00111 library unisim; 00112 use unisim.vcomponents.all; 00113 00114 library work; 00115 use work.adm2_pkg.all; 00116 00117 entity cl_test_check is 00118 port( 00119 00120 ---- Global ---- 00121 reset : in std_logic; -- 0 - сброс 00122 clk : in std_logic; -- тактовая частота 00123 00124 ---- DIO_OUT ---- 00125 do_clk : in std_logic; -- тактовая частота чтения из FIFO 00126 do_data : in std_logic_vector( 63 downto 0 ); 00127 do_data_en : in std_logic; -- 1 - передача данных из dio_out 00128 00129 00130 ---- Управление ---- 00131 test_check_ctrl : in std_logic_vector( 15 downto 0 ); 00132 test_check_size : in std_logic_vector( 15 downto 0 ); -- размер в блоках по 512x64 (4096 байт) 00133 test_check_bl_rd : out std_logic_vector( 31 downto 0 ); 00134 test_check_bl_ok : out std_logic_vector( 31 downto 0 ); 00135 test_check_bl_err : out std_logic_vector( 31 downto 0 ); 00136 test_check_error : out std_logic_vector( 31 downto 0 ); 00137 test_check_err_adr : in std_logic_vector( 15 downto 0 ); 00138 test_check_err_data: out std_logic_vector( 15 downto 0 ) 00139 00140 ); 00141 end cl_test_check; 00142 00143 00144 architecture cl_test_check of cl_test_check is 00145 00146 signal block_rd : std_logic_vector( 31 downto 0 ); 00147 signal block_ok : std_logic_vector( 31 downto 0 ); 00148 signal block_err : std_logic_vector( 31 downto 0 ); 00149 signal total_err : std_logic_vector( 31 downto 0 ); 00150 00151 signal data_expect : std_logic_vector( 63 downto 0 ); 00152 00153 signal cnt1 : std_logic_vector( 24 downto 0 ); 00154 signal cnt1_z : std_logic; 00155 signal cnt1_eq : std_logic; 00156 00157 signal rst : std_logic; 00158 signal data_en : std_logic; -- 1 - приём слова данных 00159 signal data_en_z : std_logic; 00160 signal do_data_z : std_logic_vector( 63 downto 0 ); 00161 00162 signal data_ex0 : std_logic_vector( 63 downto 0 ); 00163 signal data_ex1 : std_logic_vector( 63 downto 0 ); 00164 signal data_ex2 : std_logic_vector( 63 downto 0 ); 00165 signal data_ex3 : std_logic_vector( 63 downto 0 ); 00166 signal data_ex4 : std_logic_vector( 63 downto 0 ); 00167 signal data_ex5 : std_logic_vector( 63 downto 0 ); 00168 00169 00170 signal block_mode : std_logic_vector( 3 downto 0 ); 00171 signal word_error : std_logic; 00172 signal flag_error : std_logic; -- 1 - признак ошибки при приёма блока 00173 signal flag_error_clr : std_logic; -- 1 - сброс flag_error 00174 00175 signal data_error : std_logic_vector( 191 downto 0 ); 00176 signal data_error_wr : std_logic; 00177 signal data_error_wr1 : std_logic; 00178 signal data_error_ovr : std_logic; 00179 signal data_error_out : std_logic_vector( 191 downto 0 ); 00180 signal err_data : std_logic_vector( 15 downto 0 ); 00181 00182 signal block_ok_en : std_logic; 00183 00184 begin 00185 00186 pr_cnt1: process( do_clk ) begin 00187 if( rising_edge( do_clk ) ) then 00188 if( rst='0' or (cnt1_eq='1' and data_en='1') ) then 00189 cnt1( 24 downto 0 ) <= (others=>'0') after 1 ns; 00190 elsif( data_en='1' ) then 00191 cnt1 <= cnt1 + 1 after 1 ns; 00192 end if; 00193 end if; 00194 end process; 00195 00196 pr_cnt1_z: process( do_clk ) begin 00197 if( rising_edge( do_clk ) ) then 00198 00199 if( rst='0' ) then 00200 cnt1_z <= '1' after 1 ns; 00201 cnt1_eq <= '0' after 1 ns; 00202 elsif( data_en='1' ) then 00203 00204 if( cnt1_eq='1' ) then 00205 cnt1_z <= '1' after 1 ns; 00206 else 00207 cnt1_z <= '0' after 1 ns; 00208 end if; 00209 00210 if( cnt1( 24 downto 9 )=test_check_size-1 and cnt1( 8 downto 0 )="111111110" ) then 00211 cnt1_eq <= '1' after 1 ns; 00212 else 00213 cnt1_eq <= '0' after 1 ns; 00214 end if; 00215 end if; 00216 00217 end if; 00218 end process; 00219 00220 00221 00222 data_en <= do_data_en; 00223 00224 rst <= reset and not test_check_ctrl(0); 00225 00226 pr_block_mode: process( do_clk ) begin 00227 if( rising_edge( do_clk ) ) then 00228 if( rst='0' ) then 00229 block_mode <= "0000" after 1 ns; 00230 elsif( test_check_ctrl(7)='1' ) then 00231 block_mode <= test_check_ctrl( 11 downto 8 ) after 1 ns; 00232 elsif( data_en='1' and cnt1_eq='1' ) then 00233 if( block_mode="1001" ) then 00234 block_mode <= "0000" after 1 ns; 00235 else 00236 block_mode <= block_mode + 1 after 1 ns; 00237 end if; 00238 end if; 00239 end if; 00240 end process; 00241 00242 pr_block_rd: process( do_clk ) begin 00243 if( rising_edge( do_clk ) ) then 00244 if( rst='0' ) then 00245 block_rd <= (others=>'0') after 1 ns; 00246 elsif( data_en='1' and cnt1_eq='1' ) then 00247 block_rd <= block_rd + 1 after 1 ns; 00248 end if; 00249 end if; 00250 end process; 00251 00252 00253 pr_data_expect: process( do_clk ) begin 00254 if( rising_edge( do_clk ) ) then 00255 if( rst='0' ) then 00256 data_ex4 <= (others=>'0') after 1 ns; 00257 data_ex5 <= (0=>'1', others=>'0') after 1 ns; 00258 data_ex0 <= x"0000000000000001" after 1 ns; 00259 elsif( data_en='1' ) then 00260 if( cnt1_z='1' ) then 00261 data_expect( 31 downto 0 ) <= x"A5A50123" after 1 ns; 00262 data_expect( 63 downto 32 ) <= block_rd after 1 ns; 00263 case( block_mode( 3 downto 0 ) ) is 00264 when "0000" => -- Бегущая 1 по 64-м разрядам 00265 data_ex0 <= x"0000000000000001" after 1 ns; 00266 when "0001" => -- Бегущий 0 по 64-м разрядам 00267 data_ex0 <= not x"0000000000000001" after 1 ns; 00268 when "0010" => -- Бегущая 1 с инверсией по 64-м разрядам 00269 data_ex1 <= x"0000000000000001" after 1 ns; 00270 when "0011" => -- Бегущий 0 с инверсией по 64-м разрядам 00271 data_ex1 <= not x"0000000000000001" after 1 ns; 00272 when "0100" => -- Бегущая 1 в блоке 0 00273 data_ex2 <= x"0000000000000001" after 1 ns; 00274 data_ex3 <= (others=>'0'); 00275 when "0101" => -- Бегущий 0 в блоке 1 00276 data_ex2 <= not x"0000000000000001" after 1 ns; 00277 data_ex3 <= (others=>'1') after 1 ns; 00278 00279 when others=> null; 00280 end case; 00281 else 00282 case( block_mode( 3 downto 0 ) )is 00283 when "0000" | "0001" => 00284 data_expect <= data_ex0 after 1 ns; 00285 data_ex0( 63 downto 1 ) <= data_ex0( 62 downto 0 ) after 1 ns; 00286 data_ex0( 0 ) <= data_ex0( 63 ) after 1 ns; 00287 00288 when "0010" | "0011" => -- Бегущий 0 с инверсией по 32-м разрядам 00289 -- when "0011" => -- Бегущий 0 с инверсией по 64-м разрядам 00290 if( cnt1(0)='0' ) then 00291 data_expect <= data_ex1 after 1 ns; 00292 else 00293 data_expect <= not data_ex1 after 1 ns; 00294 data_ex1( 63 downto 1 ) <= data_ex1( 62 downto 0 ) after 1 ns; 00295 data_ex1( 0 ) <= data_ex1( 63 ) after 1 ns; 00296 end if; 00297 when "0100" | "0101" => -- Бегущий 0 в блоке 1 00298 -- when "0111" => -- Бегущий 1 в блоке 0 00299 if( cnt1( 7 downto 0 )=block_rd( 7 downto 0 ) )then 00300 data_expect <= data_ex2 after 1 ns; 00301 data_ex2( 63 downto 1 ) <= data_ex2( 62 downto 0 ) after 1 ns; 00302 data_ex2( 0 ) <= data_ex2( 63 ) after 1 ns; 00303 else 00304 data_expect <= data_ex3 after 1 ns; 00305 end if; 00306 00307 when "0110" | "0111" => -- Счётчик 00308 if( cnt1(0)='0' ) then 00309 data_expect <= data_ex4 after 1 ns; 00310 else 00311 data_expect <= not data_ex4 after 1 ns; 00312 -- data_ex4 <= data_ex4 + x"0000000000000001"; 00313 data_ex4(31 downto 0) <= data_ex4(31 downto 0) + 1; 00314 if (data_ex4(31 downto 0)=x"FFFFFFFF") then 00315 data_ex4(63 downto 32) <= data_ex4(63 downto 32) + 1; 00316 end if; 00317 end if; 00318 00319 when "1000" | "1001" => -- Псевдослучайная последовательность 00320 data_expect <= data_ex5 after 1 ns; 00321 data_ex5( 63 downto 1 ) <= data_ex5( 62 downto 0 ) after 1 ns; 00322 --data_ex5( 0 ) <= data_ex5( 63 ) xor data_ex5(62) after 1 ns; 00323 data_ex5( 0 ) <= data_ex5( 63 ) xor data_ex5(62) xor data_ex5(60) xor data_ex5(59) after 1 ns; 00324 when others=> null; 00325 end case; 00326 end if; 00327 end if; 00328 end if; 00329 end process; 00330 00331 00332 00333 do_data_z <= do_data after 1 ns when rising_edge( do_clk ); 00334 data_en_z <= data_en after 1 ns when rising_edge( do_clk ); 00335 00336 word_error <= '1' when do_data_z /= data_expect else '0'; 00337 00338 pr_total_err: process( do_clk ) begin 00339 if( rising_edge( do_clk ) ) then 00340 if( rst='0' ) then 00341 total_err <= (others=>'0') after 1 ns; 00342 elsif( data_en_z='1' and word_error='1' and total_err/=x"FFFFFFFF" ) then 00343 total_err <= total_err + 1 after 1 ns; 00344 end if; 00345 end if; 00346 end process; 00347 00348 pr_flag_error_clr: process( do_clk ) begin 00349 if( rising_edge( do_clk ) ) then 00350 if( rst='0' ) then 00351 flag_error_clr <= '0' after 1 ns; 00352 elsif( cnt1_z='1' and data_en='1' ) then 00353 flag_error_clr <= '1' after 1 ns; 00354 else 00355 flag_error_clr <= '0' after 1 ns; 00356 end if; 00357 end if; 00358 end process; 00359 00360 00361 pr_flag_error: process( do_clk ) begin 00362 if( rising_edge( do_clk ) ) then 00363 if( rst='0' ) then 00364 flag_error <= '0' after 1 ns; 00365 elsif( data_en_z='1' and word_error='1' ) then 00366 flag_error <= '1' after 1 ns; 00367 elsif( flag_error_clr='1' ) then 00368 flag_error <= '0' after 1 ns; 00369 end if; 00370 end if; 00371 end process; 00372 00373 00374 data_error_wr <= data_en_z and word_error; 00375 00376 data_error( 63 downto 0 ) <= do_data_z; 00377 data_error( 127 downto 64 ) <= data_expect; 00378 data_error( 152 downto 128 ) <= cnt1 after 1 ns when rising_edge( do_clk ); 00379 data_error( 159 downto 153 ) <= (others=>'0'); 00380 data_error( 191 downto 160 ) <= block_rd after 1 ns when rising_edge( do_clk ); 00381 00382 pr_data_error_ovr: process( do_clk ) begin 00383 if( rising_edge( do_clk ) ) then 00384 if( rst='0' ) then 00385 data_error_ovr <= '0' after 1 ns; 00386 elsif( data_error_wr='1' and total_err( 3 downto 0 )="1111" ) then 00387 data_error_ovr <= '1' after 1 ns; 00388 end if; 00389 end if; 00390 end process; 00391 00392 data_error_wr1 <= data_error_wr and not data_error_ovr; 00393 00394 pr_block_ok: process( do_clk ) begin 00395 if( rising_edge( do_clk ) ) then 00396 if( rst='0' ) then 00397 block_ok <= (others=>'0') after 1 ns; 00398 block_err <= (others=>'0' ) after 1 ns; 00399 elsif( block_ok_en='1' ) then 00400 if( flag_error_clr='1' and flag_error='0' ) then 00401 block_ok <= block_ok + 1 after 1 ns; 00402 end if; 00403 if( flag_error_clr='1' and flag_error='1' ) then 00404 block_err <= block_err + 1 after 1 ns; 00405 end if; 00406 end if; 00407 end if; 00408 end process; 00409 00410 pr_block_ok_en: process( clk ) begin 00411 if( rising_edge( clk ) ) then 00412 if( rst='0' ) then 00413 block_ok_en <= '0' after 1 ns; 00414 elsif( cnt1_eq='1' ) then 00415 block_ok_en <= '1' after 1 ns; 00416 end if; 00417 end if; 00418 end process; 00419 00420 00421 gen_data_error: for ii in 0 to 191 generate 00422 00423 ram0: ram16x1d 00424 port map( 00425 we => data_error_wr1, 00426 d => data_error( ii ), 00427 wclk => do_clk, 00428 a0 => total_err( 0 ), 00429 a1 => total_err( 1 ), 00430 a2 => total_err( 2 ), 00431 a3 => total_err( 3 ), 00432 --spo => data_out( 0 ), 00433 dpra0 => test_check_err_adr( 4 ), 00434 dpra1 => test_check_err_adr ( 5 ), 00435 dpra2 => test_check_err_adr( 6 ), 00436 dpra3 => test_check_err_adr( 7 ), 00437 dpo => data_error_out( ii ) 00438 ); 00439 00440 end generate; 00441 00442 err_data <= data_error_out( 15 downto 0 ) when test_check_err_adr( 3 downto 0 )="0000" else 00443 data_error_out( 31 downto 16 ) when test_check_err_adr( 3 downto 0 )="0001" else 00444 data_error_out( 47 downto 32 ) when test_check_err_adr( 3 downto 0 )="0010" else 00445 data_error_out( 63 downto 48 ) when test_check_err_adr( 3 downto 0 )="0011" else 00446 data_error_out( 79 downto 64 ) when test_check_err_adr( 3 downto 0 )="0100" else 00447 data_error_out( 95 downto 80 ) when test_check_err_adr( 3 downto 0 )="0101" else 00448 data_error_out( 111 downto 96 ) when test_check_err_adr( 3 downto 0 )="0110" else 00449 data_error_out( 127 downto 112 ) when test_check_err_adr( 3 downto 0 )="0111" else 00450 data_error_out( 143 downto 128 ) when test_check_err_adr( 3 downto 0 )="1000" else 00451 data_error_out( 159 downto 144 ) when test_check_err_adr( 3 downto 0 )="1001" else 00452 data_error_out( 175 downto 160 ) when test_check_err_adr( 3 downto 0 )="1010" else 00453 data_error_out( 191 downto 176 ) when test_check_err_adr( 3 downto 0 )="1011" else 00454 (others=>'-'); 00455 00456 00457 test_check_err_data <= err_data after 1 ns when rising_edge( clk ); 00458 00459 00460 test_check_bl_rd <= block_rd; 00461 test_check_bl_ok <= block_ok; 00462 test_check_bl_err <= block_err; 00463 test_check_error <= total_err; 00464 00465 00466 end cl_test_check; 00467 00468