-- $Id$ 

-- Copyright (C) 2009 FAUmachine Team <info@faumachine.org>.
-- This program is free software. You can redistribute it and/or modify it
-- under the terms of the GNU General Public License, either version 2 of
-- the License, or (at your option) any later version. See COPYING.

-- test if procedure calls from concurrent processes work as expected.

package t is 
	procedure foo(constant send : in string; constant timeout : IN time);
end package t;

package body t is
	procedure foo(constant send : in string; constant timeout : IN time) 
	is
		type escapes is (NOT_ESCAPED, ESC_DIGIT_1, ESC_DIGIT_2);
		VARIABLE esc : escapes := NOT_ESCAPED;
		VARIABLE digit1 : character;
	begin
	FOR i IN send'range LOOP
		case esc is
		when NOT_ESCAPED =>
			case send(i) is
			when '\' =>
				esc := ESC_DIGIT_1;

			--when 'c' =>
			--	assert false report "c" severity note;
			--	WAIT FOR timeout;
			--when 'l' =>
			--	assert false report "l" severity note;
			--	WAIT FOR timeout;
			--when 'p' =>
			--	assert false report "p" severity note;
			--	WAIT FOR timeout;
			--when '1' =>
			--	assert false report "1" severity note;
			--	WAIT FOR timeout;
			--when '2' =>
			--	assert false report "2" severity note;
			--	WAIT FOR timeout;
			when others =>
				--assert false report send severity note;
				--case i is 
				--	when 1 => 
				--		assert false report "i=1"
				--		severity note;
				--	when 2 => 
				--		assert false report "i=2"
				--		severity note;
				--	when 3 => 
				--		assert false report "i=3"
				--		severity note;
				--	when 4 => 
				--		assert false report "i=4"
				--		severity note;
				--	when others =>
				--		assert false report "i>4"
				--		severity note;
				--end case;

				assert false report "unknown character"
					severity failure;
			end case;

		when ESC_DIGIT_1 =>
			digit1 := send(i);
			esc := ESC_DIGIT_2;
			--assert false report "=> esc 2" severity note;

		when ESC_DIGIT_2 =>
			case digit1 is
			when '0' =>
				case send(i) is
				when '8' =>	-- backspace
					assert false report "<backspace>" 
						severity note;
					WAIT FOR timeout;

				when 'd' =>	-- carriage return
					assert false report "<cr>" 
						severity note;
					WAIT FOR timeout;

				when others => 
					assert false report
						"unknown escape"
						severity failure;
				end case;

			when others =>
				assert false report 
					"unknown escape sequence"
					severity failure;
			end case;
			esc := NOT_ESCAPED;
			--assert false report "=> not escaped" severity note;

		end case;
	END LOOP;

	-- sanity check
	case esc is
	when NOT_ESCAPED => 
		null;
	when others =>
		assert false report send severity note;
		assert false report "broken escape sequence" severity
			failure;
	end case;

	end;
end t;

entity test_bench is
end entity test_bench;

use t.all;
architecture test_bench_impl of test_bench is
begin
	p : process
	begin
		wait for 10 ms;
		-- type sequence "\08\08\08\08\08\08"
		foo("\08", 100 ms);
		wait;
	end process;

	q : process
	begin
		wait for 10 ms;

		-- type sequence "\08\08\08\08\08\08"
		foo("\08\08\08", 100 ms);
		wait for 1 sec;
		assert false report "simulation finished" severity note;
		wait;
	end process;

end test_bench_impl;
