AMBPEX5_v20_SX50T_CORE
adm/main/cl_test_check.vhd
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