URL
https://opencores.org/ocsvn/pcie_ds_dma/pcie_ds_dma/trunk
Subversion Repositories pcie_ds_dma
[/] [pcie_ds_dma/] [trunk/] [core/] [adm/] [main/] [cl_test_check.vhd] - Rev 20
Go to most recent revision | Compare with Previous | Blame | View Log
------------------------------------------------------------------------------- -- -- Title : cl_test_check -- Author : Dmitry Smekhov -- Company : Instrumental Systems -- E-mail : dsmv@insys.ru -- -- Version : 1.0 -- ------------------------------------------------------------------------------- -- -- Description : Узел проверки входного потока -- -- Тестовая последовательность представляет собой набор блоков. -- Размер блока задаётся кратным страницы размером 4 килобайта -- (512 слов по 64 бита) -- Первое 64-х разрядное слово в блоке содержит сигнатуру и порядковый номер. -- 31..0 - сигнатура 0xA5A50123 -- 63..32 - порядковый номер блока -- -- Содержимое блока зависит от его порядкового номера в последовательности. -- -- Содержимое блока: -- 0 - Бегущая единица по 64-м разрядам -- 1 - Бегущий ноль по 64-м разрядам -- 2 - Бегущая единица с инверсией по 64-м разрядам --- Чётные номера слов - бегущая единица по 64-м разрядам -- Нечётные номера - инверсия предыдущего слова -- 3 - Бегущая единица в блоке -- Номер слова сравнивается с номером блока (сравниваются восемь младший разрядов) -- При совпадении - в слово записывается бегущая 1. -- Остальные слова - значение ноль. -- 4 - Бегущий ноль с инверсией по 64-м разрядам -- Чётные номера - бегущий ноль по 64-м разрядам -- Нечётные номера - инверсия предыдущего слова -- 5 - Бегущий ноль а в блоке -- Номер слова сравнивается с номером блока (сравниваются восемь младший разрядов) -- При совпадении - в слово записывается бегущий 0. -- Остальные слова - значение 0xFFFFFFFFFFFFFFFF. -- 6,7 - Счётчик по 64-м разрядам -- Чётные номера - значение счётчика -- Нечётные номера - инверсия предыдущего слова -- 8,9 - Псевдослучайная последовательность -- Формируется М-последовательность по 64 разрядам. -- Начальное значение - 1 -- Слово формируется сдвигом на один разряд вправо. -- В младший разряд слова записывается значение x[63] xor x[62] -- -- -- Для режима счётчика и псевдослучайной последовательности начальное значение -- формируется при инициализации тестовой последовательности. -- Для остальных режимов - при инициализации проверки блока -- -- -- Регистр test_check_ctrl -- -- 0 - 1 сброс узла -- 5 - 1 старт приёма данных -- 7 - 1 фиксированный тип блока -- 11..8 - номер блока при test_check_ctrl[7]=1 -- ------------------------------------------------------------------------------- -- -- Version 1.0 -- ------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; package cl_test_check_pkg is component cl_test_check is port( ---- Global ---- reset : in std_logic; -- 0 - сброс clk : in std_logic; -- тактовая частота ---- DIO_OUT ---- do_clk : in std_logic; -- тактовая частота чтения из FIFO do_data : in std_logic_vector( 63 downto 0 ); do_data_en : in std_logic; -- 1 - передача данных из dio_out ---- Управление ---- test_check_ctrl : in std_logic_vector( 15 downto 0 ); test_check_size : in std_logic_vector( 15 downto 0 ); -- размер в блоках по 512x64 (4096 байт) test_check_bl_rd : out std_logic_vector( 31 downto 0 ); test_check_bl_ok : out std_logic_vector( 31 downto 0 ); test_check_bl_err : out std_logic_vector( 31 downto 0 ); test_check_error : out std_logic_vector( 31 downto 0 ); test_check_err_adr : in std_logic_vector( 15 downto 0 ); test_check_err_data: out std_logic_vector( 15 downto 0 ) ); end component; end package; library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; library unisim; use unisim.vcomponents.all; library work; use work.adm2_pkg.all; entity cl_test_check is port( ---- Global ---- reset : in std_logic; -- 0 - сброс clk : in std_logic; -- тактовая частота ---- DIO_OUT ---- do_clk : in std_logic; -- тактовая частота чтения из FIFO do_data : in std_logic_vector( 63 downto 0 ); do_data_en : in std_logic; -- 1 - передача данных из dio_out ---- Управление ---- test_check_ctrl : in std_logic_vector( 15 downto 0 ); test_check_size : in std_logic_vector( 15 downto 0 ); -- размер в блоках по 512x64 (4096 байт) test_check_bl_rd : out std_logic_vector( 31 downto 0 ); test_check_bl_ok : out std_logic_vector( 31 downto 0 ); test_check_bl_err : out std_logic_vector( 31 downto 0 ); test_check_error : out std_logic_vector( 31 downto 0 ); test_check_err_adr : in std_logic_vector( 15 downto 0 ); test_check_err_data: out std_logic_vector( 15 downto 0 ) ); end cl_test_check; architecture cl_test_check of cl_test_check is signal block_rd : std_logic_vector( 31 downto 0 ); signal block_ok : std_logic_vector( 31 downto 0 ); signal block_err : std_logic_vector( 31 downto 0 ); signal total_err : std_logic_vector( 31 downto 0 ); signal data_expect : std_logic_vector( 63 downto 0 ); signal cnt1 : std_logic_vector( 24 downto 0 ); signal cnt1_z : std_logic; signal cnt1_eq : std_logic; signal rst : std_logic; signal data_en : std_logic; -- 1 - приём слова данных signal data_en_z : std_logic; signal do_data_z : std_logic_vector( 63 downto 0 ); signal data_ex0 : std_logic_vector( 63 downto 0 ); signal data_ex1 : std_logic_vector( 63 downto 0 ); signal data_ex2 : std_logic_vector( 63 downto 0 ); signal data_ex3 : std_logic_vector( 63 downto 0 ); signal data_ex4 : std_logic_vector( 63 downto 0 ); signal data_ex5 : std_logic_vector( 63 downto 0 ); signal block_mode : std_logic_vector( 3 downto 0 ); signal word_error : std_logic; signal flag_error : std_logic; -- 1 - признак ошибки при приёма блока signal flag_error_clr : std_logic; -- 1 - сброс flag_error signal data_error : std_logic_vector( 191 downto 0 ); signal data_error_wr : std_logic; signal data_error_wr1 : std_logic; signal data_error_ovr : std_logic; signal data_error_out : std_logic_vector( 191 downto 0 ); signal err_data : std_logic_vector( 15 downto 0 ); signal block_ok_en : std_logic; begin pr_cnt1: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' or (cnt1_eq='1' and data_en='1') ) then cnt1( 24 downto 0 ) <= (others=>'0') after 1 ns; elsif( data_en='1' ) then cnt1 <= cnt1 + 1 after 1 ns; end if; end if; end process; pr_cnt1_z: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then cnt1_z <= '1' after 1 ns; cnt1_eq <= '0' after 1 ns; elsif( data_en='1' ) then if( cnt1_eq='1' ) then cnt1_z <= '1' after 1 ns; else cnt1_z <= '0' after 1 ns; end if; if( cnt1( 24 downto 9 )=test_check_size-1 and cnt1( 8 downto 0 )="111111110" ) then cnt1_eq <= '1' after 1 ns; else cnt1_eq <= '0' after 1 ns; end if; end if; end if; end process; data_en <= do_data_en; rst <= reset and not test_check_ctrl(0); pr_block_mode: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then block_mode <= "0000" after 1 ns; elsif( test_check_ctrl(7)='1' ) then block_mode <= test_check_ctrl( 11 downto 8 ) after 1 ns; elsif( data_en='1' and cnt1_eq='1' ) then if( block_mode="1001" ) then block_mode <= "0000" after 1 ns; else block_mode <= block_mode + 1 after 1 ns; end if; end if; end if; end process; pr_block_rd: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then block_rd <= (others=>'0') after 1 ns; elsif( data_en='1' and cnt1_eq='1' ) then block_rd <= block_rd + 1 after 1 ns; end if; end if; end process; pr_data_expect: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then data_ex4 <= (others=>'0') after 1 ns; data_ex5 <= (0=>'1', others=>'0') after 1 ns; data_ex0 <= x"0000000000000001" after 1 ns; elsif( data_en='1' ) then if( cnt1_z='1' ) then data_expect( 31 downto 0 ) <= x"A5A50123" after 1 ns; data_expect( 63 downto 32 ) <= block_rd after 1 ns; case( block_mode( 3 downto 0 ) ) is when "0000" => -- Бегущая 1 по 64-м разрядам data_ex0 <= x"0000000000000001" after 1 ns; when "0001" => -- Бегущий 0 по 64-м разрядам data_ex0 <= not x"0000000000000001" after 1 ns; when "0010" => -- Бегущая 1 с инверсией по 64-м разрядам data_ex1 <= x"0000000000000001" after 1 ns; when "0011" => -- Бегущий 0 с инверсией по 64-м разрядам data_ex1 <= not x"0000000000000001" after 1 ns; when "0100" => -- Бегущая 1 в блоке 0 data_ex2 <= x"0000000000000001" after 1 ns; data_ex3 <= (others=>'0'); when "0101" => -- Бегущий 0 в блоке 1 data_ex2 <= not x"0000000000000001" after 1 ns; data_ex3 <= (others=>'1') after 1 ns; when others=> null; end case; else case( block_mode( 3 downto 0 ) )is when "0000" | "0001" => data_expect <= data_ex0 after 1 ns; data_ex0( 63 downto 1 ) <= data_ex0( 62 downto 0 ) after 1 ns; data_ex0( 0 ) <= data_ex0( 63 ) after 1 ns; when "0010" | "0011" => -- Бегущий 0 с инверсией по 32-м разрядам -- when "0011" => -- Бегущий 0 с инверсией по 64-м разрядам if( cnt1(0)='0' ) then data_expect <= data_ex1 after 1 ns; else data_expect <= not data_ex1 after 1 ns; data_ex1( 63 downto 1 ) <= data_ex1( 62 downto 0 ) after 1 ns; data_ex1( 0 ) <= data_ex1( 63 ) after 1 ns; end if; when "0100" | "0101" => -- Бегущий 0 в блоке 1 -- when "0111" => -- Бегущий 1 в блоке 0 if( cnt1( 7 downto 0 )=block_rd( 7 downto 0 ) )then data_expect <= data_ex2 after 1 ns; data_ex2( 63 downto 1 ) <= data_ex2( 62 downto 0 ) after 1 ns; data_ex2( 0 ) <= data_ex2( 63 ) after 1 ns; else data_expect <= data_ex3 after 1 ns; end if; when "0110" | "0111" => -- Счётчик if( cnt1(0)='0' ) then data_expect <= data_ex4 after 1 ns; else data_expect <= not data_ex4 after 1 ns; -- data_ex4 <= data_ex4 + x"0000000000000001"; data_ex4(31 downto 0) <= data_ex4(31 downto 0) + 1; if (data_ex4(31 downto 0)=x"FFFFFFFF") then data_ex4(63 downto 32) <= data_ex4(63 downto 32) + 1; end if; end if; when "1000" | "1001" => -- Псевдослучайная последовательность data_expect <= data_ex5 after 1 ns; data_ex5( 63 downto 1 ) <= data_ex5( 62 downto 0 ) after 1 ns; --data_ex5( 0 ) <= data_ex5( 63 ) xor data_ex5(62) after 1 ns; data_ex5( 0 ) <= data_ex5( 63 ) xor data_ex5(62) xor data_ex5(60) xor data_ex5(59) after 1 ns; when others=> null; end case; end if; end if; end if; end process; do_data_z <= do_data after 1 ns when rising_edge( do_clk ); data_en_z <= data_en after 1 ns when rising_edge( do_clk ); word_error <= '1' when do_data_z /= data_expect else '0'; pr_total_err: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then total_err <= (others=>'0') after 1 ns; elsif( data_en_z='1' and word_error='1' and total_err/=x"FFFFFFFF" ) then total_err <= total_err + 1 after 1 ns; end if; end if; end process; pr_flag_error_clr: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then flag_error_clr <= '0' after 1 ns; elsif( cnt1_z='1' and data_en='1' ) then flag_error_clr <= '1' after 1 ns; else flag_error_clr <= '0' after 1 ns; end if; end if; end process; pr_flag_error: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then flag_error <= '0' after 1 ns; elsif( data_en_z='1' and word_error='1' ) then flag_error <= '1' after 1 ns; elsif( flag_error_clr='1' ) then flag_error <= '0' after 1 ns; end if; end if; end process; data_error_wr <= data_en_z and word_error; data_error( 63 downto 0 ) <= do_data_z; data_error( 127 downto 64 ) <= data_expect; data_error( 152 downto 128 ) <= cnt1 after 1 ns when rising_edge( do_clk ); data_error( 159 downto 153 ) <= (others=>'0'); data_error( 191 downto 160 ) <= block_rd after 1 ns when rising_edge( do_clk ); pr_data_error_ovr: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then data_error_ovr <= '0' after 1 ns; elsif( data_error_wr='1' and total_err( 3 downto 0 )="1111" ) then data_error_ovr <= '1' after 1 ns; end if; end if; end process; data_error_wr1 <= data_error_wr and not data_error_ovr; pr_block_ok: process( do_clk ) begin if( rising_edge( do_clk ) ) then if( rst='0' ) then block_ok <= (others=>'0') after 1 ns; block_err <= (others=>'0' ) after 1 ns; elsif( block_ok_en='1' ) then if( flag_error_clr='1' and flag_error='0' ) then block_ok <= block_ok + 1 after 1 ns; end if; if( flag_error_clr='1' and flag_error='1' ) then block_err <= block_err + 1 after 1 ns; end if; end if; end if; end process; pr_block_ok_en: process( clk ) begin if( rising_edge( clk ) ) then if( rst='0' ) then block_ok_en <= '0' after 1 ns; elsif( cnt1_eq='1' ) then block_ok_en <= '1' after 1 ns; end if; end if; end process; gen_data_error: for ii in 0 to 191 generate ram0: ram16x1d port map( we => data_error_wr1, d => data_error( ii ), wclk => do_clk, a0 => total_err( 0 ), a1 => total_err( 1 ), a2 => total_err( 2 ), a3 => total_err( 3 ), --spo => data_out( 0 ), dpra0 => test_check_err_adr( 4 ), dpra1 => test_check_err_adr( 5 ), dpra2 => test_check_err_adr( 6 ), dpra3 => test_check_err_adr( 7 ), dpo => data_error_out( ii ) ); end generate; err_data <= data_error_out( 15 downto 0 ) when test_check_err_adr( 3 downto 0 )="0000" else data_error_out( 31 downto 16 ) when test_check_err_adr( 3 downto 0 )="0001" else data_error_out( 47 downto 32 ) when test_check_err_adr( 3 downto 0 )="0010" else data_error_out( 63 downto 48 ) when test_check_err_adr( 3 downto 0 )="0011" else data_error_out( 79 downto 64 ) when test_check_err_adr( 3 downto 0 )="0100" else data_error_out( 95 downto 80 ) when test_check_err_adr( 3 downto 0 )="0101" else data_error_out( 111 downto 96 ) when test_check_err_adr( 3 downto 0 )="0110" else data_error_out( 127 downto 112 ) when test_check_err_adr( 3 downto 0 )="0111" else data_error_out( 143 downto 128 ) when test_check_err_adr( 3 downto 0 )="1000" else data_error_out( 159 downto 144 ) when test_check_err_adr( 3 downto 0 )="1001" else data_error_out( 175 downto 160 ) when test_check_err_adr( 3 downto 0 )="1010" else data_error_out( 191 downto 176 ) when test_check_err_adr( 3 downto 0 )="1011" else (others=>'-'); test_check_err_data <= err_data after 1 ns when rising_edge( clk ); test_check_bl_rd <= block_rd; test_check_bl_ok <= block_ok; test_check_bl_err <= block_err; test_check_error <= total_err; end cl_test_check;
Go to most recent revision | Compare with Previous | Blame | View Log