use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gen_pkg.all;
+use work.textmode_vga_component_pkg.all;
+use work.textmode_vga_pkg.all;
+use work.textmode_vga_platform_dependent_pkg.all;
entity beh_history_tb is
end entity beh_history_tb;
-- system
signal sys_clk, sys_res_n : std_logic;
-- history/display
- signal d_new_eingabe, d_new_result : std_logic;
+ signal d_new_eingabe, d_new_result, d_new_bs : std_logic;
signal d_zeile : hzeile;
signal d_spalte : hspalte;
signal d_get, d_done : std_logic;
-- history/scanner
signal s_char : hbyte;
signal s_take, s_done, s_backspace : std_logic;
-
- -- tmp: history<>scanner
+ -- ps/2
+ signal new_data : std_logic;
+ signal data : std_logic_vector(7 downto 0);
+ -- vga/display
+ signal free : std_logic;
+ signal command : std_logic_vector(COMMAND_SIZE - 1 downto 0);
+ signal command_data : std_logic_vector(3 * COLOR_SIZE + CHAR_SIZE -1 downto 0);
+ -- history/parser
+ signal p_rget : std_logic;
+ signal p_rdone : std_logic;
+ signal p_read : hbyte;
+ signal p_wtake : std_logic;
+ signal p_wdone : std_logic;
+ signal p_write : hbyte;
+ signal p_finished : std_logic;
+ -- parser/scanner
signal do_it, finished : std_logic;
signal stop : boolean := false;
-- display
d_new_eingabe => d_new_eingabe,
d_new_result => d_new_result,
+ d_new_bs => d_new_bs,
+ d_zeile => d_zeile,
+ d_spalte => d_spalte,
+ d_get => d_get,
+ d_done => d_done,
+ d_char => d_char,
+ -- parser
+ p_rget => p_rget,
+ p_rdone => p_rdone,
+ p_read => p_read,
+ p_wtake => p_wtake,
+ p_wdone => p_wdone,
+ p_write => p_write,
+ p_finished => p_finished
+ );
+
+ -- display
+ inst_disp : entity work.display(beh)
+ port map (
+ sys_clk => sys_clk,
+ sys_res_n => sys_res_n,
+ -- history
+ d_new_eingabe => d_new_eingabe,
+ d_new_result => d_new_result,
+ d_new_bs => d_new_bs,
d_zeile => d_zeile,
d_spalte => d_spalte,
d_get => d_get,
d_done => d_done,
d_char => d_char,
- -- TODO: tmp only!
+ -- vga
+ command => command,
+ command_data => command_data,
+ free => free
+ );
+
+ -- parser
+ inst_parser : entity work.parser(beh)
+ port map (
+ sys_clk => sys_clk,
+ sys_res_n => sys_res_n,
+ -- history
+ p_rget => p_rget,
+ p_rdone => p_rdone,
+ p_read => p_read,
+ p_wtake => p_wtake,
+ p_wdone => p_wdone,
+ p_write => p_write,
+ p_finished => p_finished,
+ -- scanner
+ do_it => do_it,
+ finished => finished
+ );
+
+ -- scanner
+ inst_scan : entity work.scanner(beh)
+ port map (
+ sys_clk => sys_clk,
+ sys_res_n => sys_res_n,
+ -- ps/2
+ new_data => new_data,
+ data => data,
+ -- history
+ s_char => s_char,
+ s_take => s_take,
+ s_done => s_done,
+ s_backspace => s_backspace,
+ -- Parser
do_it => do_it,
finished => finished
);
+
process
begin
sys_clk <= '0';
end process;
process
- variable input : hstring := "12345678 ";
- variable ctmp : character;
+ begin
+ free <= '0';
+ wait for 15 ns;
+ free <= '1';
+ wait for 30 ns;
+ if stop = true then
+ wait;
+ end if;
+ end process;
+
+ process
+ function ascii2sc (x : hbyte) return hbyte is
+ variable y : hbyte;
+ begin
+ case x is
+ when x"30" => y := SC_KP_0;
+ when x"31" => y := SC_KP_1;
+ when x"32" => y := SC_KP_2;
+ when x"33" => y := SC_KP_3;
+ when x"34" => y := SC_KP_4;
+ when x"35" => y := SC_KP_5;
+ when x"36" => y := SC_KP_6;
+ when x"37" => y := SC_KP_7;
+ when x"38" => y := SC_KP_8;
+ when x"39" => y := SC_KP_9;
+ when x"2b" => y := SC_KP_PLUS;
+ when x"2d" => y := SC_KP_MINUS;
+ when x"2a" => y := SC_KP_MUL;
+ when x"2f" => y := SC_KP_DIV;
+ when x"20" => y := SC_SPACE;
+ when x"1c" => y := SC_ENTER;
+ when x"0e" => y := SC_BKSP;
+ when others => y := x"41";
+ end case;
+ return y;
+ end function;
+
+ function valid_char (x : std_logic_vector(7 downto 0)) return boolean is
+ variable y : boolean;
+ begin
+ case x is
+ when SC_KP_0 | SC_KP_1 | SC_KP_2 | SC_KP_3 |
+ SC_KP_4 | SC_KP_5 | SC_KP_6 | SC_KP_7 |
+ SC_KP_8 | SC_KP_9 | SC_KP_PLUS |
+ SC_KP_MINUS | SC_KP_MUL |
+ SC_KP_DIV | SC_SPACE |
+ SC_BKSP | SC_ENTER =>
+ y := true;
+ when others => y := false;
+ end case;
+ return y;
+ end function;
- variable checkall : boolean := true;
- variable i : integer := 1;
- variable j : integer;
+ -- textio stuff
+ use std.textio.all;
+ file f : text open read_mode is "../../src/history.test";
+ variable l : line;
+
+ variable input : string(1 to 100);
+
+ variable run_tc, run_inner : boolean := true;
+ variable i, j, y : natural;
begin
-- init & reset
sys_res_n <= '0';
- s_char <= x"00";
- s_take <= '0';
- s_backspace <= '0';
- d_zeile <= (others => '0');
- d_spalte <= (others => '0');
- d_get <= '0';
- do_it <= '0';
-
- icwait(sys_clk, 5);
+ new_data <= '0';
+ data <= (others => '0');
+
+ icwait(sys_clk, 20);
sys_res_n <= '1';
- while i <= 10 loop
- s_take <= '1';
- ctmp := input(i);
- s_char <= hbyte(to_unsigned(character'pos(ctmp),8));
- wait on s_done;
- s_take <= '0';
- wait on d_new_eingabe;
- icwait(sys_clk, 2);
- j := 1;
- while j <= i loop
- d_spalte <= std_logic_vector(to_unsigned(j,7));
- d_zeile <= (others => '0');
- d_get <= '1';
- wait on d_done;
- icwait(sys_clk, 1);
- if d_char /= hbyte(to_unsigned(character'pos(input(j)),8)) then
- assert(false) report "passt nicht? d_char: "
- & character'val(to_integer(unsigned(d_char))) & ", solte sein: "
- & input(j);
- checkall := false;
+ i := 1;
+ f_loop : while not endfile(f) loop
+ data <= (others => '0');
+
+ f1_loop : while not endfile(f) loop
+ readline (f, l);
+ input := (others => nul);
+ if (l'length <= 100) then
+ input(1 to l'length) := l.all;
+ if (input(1) = '#') then
+ next f1_loop;
+ else
+ exit f1_loop;
+ end if;
+ else
+ report "fehler in history.test: eingabe zu lange in testfall " & natural'image(i);
+ next f_loop;
end if;
- d_get <= '0';
- icwait(sys_clk, 2);
- j := j + 1;
- end loop;
+ end loop f1_loop;
+
+ report "testcase(" & natural'image(i) & ").input: " & input;
i := i + 1;
- end loop;
- do_it <= '1';
- wait on finished;
- icwait(sys_clk, 2);
- do_it <= '0';
+ icwait(sys_clk, 5);
+ run_tc := true;
+ j := 0;
+ mainl : while run_tc loop
+ icwait(sys_clk, 10);
+ j := j + 1;
- if checkall then
- report "alle testfaelle der History waren erfolgreich!";
- else
- report "einige testfaelle schlugen fehl";
- end if;
- icwait(sys_clk, 10);
+ if j = 101 then
+ run_tc := false;
+ assert(false) report "wtf @ schleife";
+ next mainl;
+ end if;
+
+ -- jedes mal release
+ new_data <= '1';
+ data <= x"f0";
+ icwait(sys_clk, 1);
+ new_data <= '0';
+ icwait(sys_clk, 1);
+ new_data <= '1';
+
+ case input(j) is
+ when nul => data <= ascii2sc(x"1c"); -- $ (enter)
+ when '!' => data <= ascii2sc(x"0e"); -- ! (backspace)
+ when others => data <= ascii2sc(std_logic_vector(to_unsigned(character'pos(input(j)),8)));
+ end case;
+ icwait(sys_clk, 1);
+ new_data <= '0';
+
+ -- ack'en skippen, falls es ein "spezielles" zeichen ist (steht
+ -- in abhaengigkeit zum vorherigen zeichen)
+ if(not valid_char(data)) then
+ next mainl;
+ end if;
+
+ -- wuenschswert waere das hier:
+ -- > wait on s_backspace, s_take, do_it;
+ -- geht aber leider nicht, weil sich die signale vllt schon
+ -- geaendert haben
+ run_inner := true;
+ main_inner : while run_inner loop
+ icwait(sys_clk, 1);
+
+ run_inner := false;
+ if s_backspace = '1' or s_take = '1' then
+ icwait(sys_clk, 1);
+ s_done <= '1';
+ wait on s_take; -- = '0'
+ icwait(sys_clk, 1);
+ s_done <= '0';
+ elsif do_it = '1' then
+ -- dauert normalweiser noch laenger (parser braucht
+ -- relativ lange)
+ icwait(sys_clk, 7);
+ finished <= '1';
+ wait on do_it; -- = '0'
+ icwait(sys_clk, 1);
+ finished <= '0';
+ icwait(sys_clk, 850);
+
+ run_tc := false;
+ else
+ -- assert(false) report "history_tb: kann passieren. wenn tb haengt, dann hier auskommentieren";
+ run_inner := true;
+ end if;
+ end loop;
+ end loop;
+ report "==================";
+ end loop f_loop;
+
+ icwait(sys_clk, 850);
stop <= true;
wait;
end process;