scanner: argh... es kommen ja scancodes rein und keine asciicodes!
authorBernhard Urban <lewurm@gmail.com>
Sun, 16 May 2010 18:15:39 +0000 (20:15 +0200)
committerBernhard Urban <lewurm@gmail.com>
Sun, 16 May 2010 18:48:05 +0000 (20:48 +0200)
src/beh_scanner_tb.vhd
src/gen_pkg.vhd
src/parser.vhd
src/scanner.test
src/scanner.vhd

index 71007f1d56aafd21de78bc429d64404295c1a854..e904d76024c941a461b090932b5742f68b5403ab 100644 (file)
@@ -22,8 +22,7 @@ architecture sim of beh_scanner_tb is
        signal stop : boolean := false;
 begin
        inst : entity work.scanner(beh)
-       port map
-       (
+       port map (
                sys_clk => sys_clk,
                sys_res_n => sys_res_n,
                -- ps/2
@@ -51,27 +50,48 @@ begin
        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); last : std_logic_vector(7 downto 0)) return boolean is
                                variable y : boolean;
                begin
                        case x is
                                -- nur gueltig wenn davor ein numpad-mod byte gekommen ist
-                               -- 0 - 4
-                               when x"30" | x"31" | x"32" | x"33" | x"34" => y := last = x"e0";
-                               -- 5 - 9
-                               when x"35" | x"36" | x"37" | x"38" | x"39" => y := last = x"e0";
-                               -- *, +, -, /
-                               when x"2a" | x"2b" | x"2d" | x"2f" => y := last = x"e0";
+                               when SC_KP_DIV => y := last = x"e0";
 
                                -- immer gueltig
-                               when x"20" => y := true; -- ' '
-                               when x"1c" => y := true; -- enter
-                               when x"0e" => y := true; -- backspace
-
-                               -- alle anderen zeichen sind immer ungueltig
+                               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_SPACE |
+                                       SC_BKSP | SC_ENTER =>
+                                               y := true;
                                when others => y := false;
                        end case;
-                       -- assert(false) report "x: " & integer'image(to_integer(unsigned(x))) & ", last: " & integer'image(to_integer(unsigned(last))) & ", result: " & boolean'image(y);
                        return y;
                end function;
 
@@ -152,12 +172,18 @@ begin
                                icwait(sys_clk, 1);
                                j := j + 1;
 
+                               if j = 73 then
+                                       run_tc := false;
+                                       assert(false) report "wtf @ schleife";
+                                       next mainl;
+                               end if;
+
                                new_data <= '1';
                                case input(j) is
-                                       when '$' => data <= x"1c"; -- $ (enter)
-                                       when '!' => data <= x"0e"; -- ! (backspace)
+                                       when nul => data <= ascii2sc(x"1c"); -- $ (enter)
+                                       when '!' => data <= ascii2sc(x"0e"); -- ! (backspace)
                                        when '.' => data <= x"e0"; -- . (modifier fuer Numpad)
-                                       when others => data <= std_logic_vector(to_unsigned(character'pos(input(j)),8));
+                                       when others => data <= ascii2sc(std_logic_vector(to_unsigned(character'pos(input(j)),8)));
                                end case;
                                icwait(sys_clk, 1);
                                new_data <= '0';
index 1fd0404bb2b1a07c64b083f73499b1cddb1eb068..3b7f87e67f2c7d4cbfa2b95605804f70cc299047 100644 (file)
@@ -26,11 +26,33 @@ package gen_pkg is
        subtype hspalte is std_logic_vector(6 downto 0);
        subtype hzeile is std_logic_vector(4 downto 0);
        subtype hbyte is std_logic_vector(7 downto 0);
-       subtype hstring is string(1 to 71);
+       subtype hstring is string(1 to 72);
        subtype hstr_int is integer range 0 to 72;
 
        function find_msb(a : csigned) return divinteger;
        procedure icwait(signal clk_i : IN std_logic; cycles: natural);
+
+       -- http://www.marjorie.de/ps2/scancode-set2.htm
+       constant SC_KP_0 : std_logic_vector(7 downto 0) := x"70";
+       constant SC_KP_1 : std_logic_vector(7 downto 0) := x"69";
+       constant SC_KP_2 : std_logic_vector(7 downto 0) := x"72";
+       constant SC_KP_3 : std_logic_vector(7 downto 0) := x"7a";
+       constant SC_KP_4 : std_logic_vector(7 downto 0) := x"6b";
+       constant SC_KP_5 : std_logic_vector(7 downto 0) := x"73";
+       constant SC_KP_6 : std_logic_vector(7 downto 0) := x"74";
+       constant SC_KP_7 : std_logic_vector(7 downto 0) := x"6c";
+       constant SC_KP_8 : std_logic_vector(7 downto 0) := x"75";
+       constant SC_KP_9 : std_logic_vector(7 downto 0) := x"7d";
+
+       constant SC_KP_PLUS : std_logic_vector(7 downto 0) := x"79";
+       constant SC_KP_MINUS : std_logic_vector(7 downto 0) := x"7b";
+       constant SC_KP_MUL : std_logic_vector(7 downto 0) := x"7c";
+       constant SC_KP_DIV : std_logic_vector(7 downto 0) := x"4a"; -- inkl. 0xe0!
+
+       constant SC_ENTER : std_logic_vector(7 downto 0) := x"5a";
+       constant SC_KP_ENTER : std_logic_vector(7 downto 0) := x"5a"; -- inkl. 0xe0!
+       constant SC_BKSP : std_logic_vector(7 downto 0) := x"66";
+       constant SC_SPACE : std_logic_vector(7 downto 0) := x"29";
 end package gen_pkg;
 
 package body gen_pkg is
index ec03fedc4e407f4c4ef9a98e68562b9422d501ed..54aebe61eb3ecd39ef22e467042ab617b0f998db 100644 (file)
@@ -349,9 +349,9 @@ begin
 
                type errstrings is array (natural range 1 to 3) of hstring;
                constant error_str : errstrings := (
-                       1 => "                                                   Division durch Null" & nul,
-                       2 => "                                                                Syntax" & nul,
-                       3 => "                                                  Over- bzw. Underflow" & nul
+                       1 => "                                                    Division durch Null" & nul,
+                       2 => "                                                                 Syntax" & nul,
+                       3 => "                                                   Over- bzw. Underflow" & nul
                );
        begin
                -- internal
index 8a5035ae1ddc385a26ec4081169eb3479de919f3..10433283783c83c9341dc6ffa7714a7ce550753d 100644 (file)
@@ -1,29 +1,28 @@
 # readme: folgende spezialzeichen werden zum testen verwendet
-# $ ... Enter
 # ! ... Backspace
 # . ... 0xe0 (modifier fuer Numpad)
 #
 # testfall 1:
-asdf.2.1.3$
+asdf213
 213
 # t2:
-.2.1.4.+.5$
+214+5
 214+5
 # t3:
-.2 .* .2.4.5.6$
+2 * 2456
 2 * 2456
 # t4:
-.2 ./         .2.4.+         $
+2 ./         24+         
 2 /         24+         
 # t5:
-.2.3.4.5 !!.1$
+2345 !!1
 2341
 # t6:
-.+.-.*./$
++-*./
 +-*/
 # t7:
-.2.3.4!!$
+234!!
 2
-# t8: (beachte dass der . vor den operatoren fehlt)
-.2+-*/!! !! !!!!!.1$
+# t8:
+2+-*./!! !! !!!!!1
 1
index 8506b1bd5882320c6ed1f693a15ab046a1b3c42b..9e1f0bde5b9e8e28fc8e657d587980fa3d0dd2a9 100644 (file)
@@ -58,20 +58,6 @@ begin
 
        -- next state
        process(state_int, new_data, data, finished, s_done)
-               function valid_char (x : std_logic_vector(7 downto 0)) return boolean is
-                       variable y : boolean;
-               begin
-                       case x is
-                               -- 0 - 4
-                               when x"30" | x"31" | x"32" | x"33" | x"34" => y := true;
-                               -- 5 - 9
-                               when x"35" | x"36" | x"37" | x"38" | x"39" => y := true;
-                               -- *, +, -, /
-                               when x"2a" | x"2b" | x"2d" | x"2f" => y := true;
-                               when others => y := false;
-                       end case;
-                       return y;
-               end function;
        begin
                state_next <= state_int;
 
@@ -83,14 +69,20 @@ begin
                        when SREAD =>
                                case data is
                                        when x"e0" => state_next <= SMOD;
-                                       when x"0e" => state_next <= SDEL;
-                                       when x"1c" => state_next <= SENTER;
-                                       when x"20" => state_next <= STAKE;
+                                       when SC_BKSP => state_next <= SDEL;
+                                       when SC_ENTER => state_next <= SENTER;
+                                       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_SPACE =>
+                                                       state_next <= STAKE;
                                        when others => state_next <= SIDLE;
                                end case;
                        when SMOD =>
                                if new_data = '1' then
-                                       if valid_char(data) then
+                                       if data = SC_KP_ENTER then
+                                               state_next <= SENTER;
+                                       elsif data = SC_KP_DIV then
                                                state_next <= STAKE;
                                        else
                                                state_next <= SIDLE;
@@ -109,6 +101,29 @@ begin
 
        -- out
        process(state_int, data)
+               function sc2ascii (x : hbyte) return hbyte is
+                       variable y : hbyte;
+               begin
+                       case x is
+                               when SC_KP_0 => y := x"30";
+                               when SC_KP_1 => y := x"31";
+                               when SC_KP_2 => y := x"32";
+                               when SC_KP_3 => y := x"33";
+                               when SC_KP_4 => y := x"34";
+                               when SC_KP_5 => y := x"35";
+                               when SC_KP_6 => y := x"36";
+                               when SC_KP_7 => y := x"37";
+                               when SC_KP_8 => y := x"38";
+                               when SC_KP_9 => y := x"39";
+                               when SC_KP_PLUS => y := x"2b";
+                               when SC_KP_MINUS => y := x"2d";
+                               when SC_KP_MUL => y := x"2a";
+                               when SC_KP_DIV => y := x"2f";
+                               when SC_SPACE => y := x"20";
+                               when others => y := x"41";
+                       end case;
+                       return y;
+               end function;
        begin
                s_char_next <= (others => '0');
                s_take_next <= '0';
@@ -124,7 +139,7 @@ begin
                                null;
                        when STAKE =>
                                s_take_next <= '1';
-                               s_char_next <= hbyte(data);
+                               s_char_next <= sc2ascii(hbyte(data));
                        when SDEL =>
                                s_take_next <= '1';
                                s_backspace_next <= '1';