history: simple implementierung + testbench
authorBernhard Urban <lewurm@gmail.com>
Sun, 16 May 2010 15:53:16 +0000 (17:53 +0200)
committerBernhard Urban <lewurm@gmail.com>
Sun, 16 May 2010 15:53:16 +0000 (17:53 +0200)
auf ins tilab \o/

src/beh_history_tb.do [new file with mode: 0644]
src/beh_history_tb.vhd [new file with mode: 0644]
src/gen_pkg.vhd
src/history.vhd
src/sp_ram.vhd

diff --git a/src/beh_history_tb.do b/src/beh_history_tb.do
new file mode 100644 (file)
index 0000000..2f52a4c
--- /dev/null
@@ -0,0 +1,14 @@
+#alias fuer simulation neustarten
+alias rr "restart -f"
+
+#signale hinzufuegen
+add wave inst/*
+
+#rauszoomen
+wave zoomout 500.0
+
+#simulation starten und 100ms lang laufen lassen (wird durch assert abgebrochen)
+run -all
+
+#ganz nach links scrollen
+wave seetime 0
diff --git a/src/beh_history_tb.vhd b/src/beh_history_tb.vhd
new file mode 100644 (file)
index 0000000..7eb3029
--- /dev/null
@@ -0,0 +1,125 @@
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.numeric_std.all;
+use work.gen_pkg.all;
+
+entity beh_history_tb is
+end entity beh_history_tb;
+
+architecture sim of beh_history_tb is
+       -- system
+       signal sys_clk, sys_res_n : std_logic;
+       -- history/display
+       signal d_new_eingabe, d_new_result : std_logic;
+       signal d_zeile : hzeile;
+       signal d_spalte : hspalte;
+       signal d_get, d_done : std_logic;
+       signal d_char : hbyte;
+       -- history/scanner
+       signal s_char : hbyte;
+       signal s_take, s_done, s_backspace : std_logic;
+
+       -- tmp: history<>scanner
+       signal do_it, finished : std_logic;
+
+       signal stop : boolean := false;
+begin
+       -- history
+       inst : entity work.history(beh)
+       port map (
+               sys_clk => sys_clk,
+               sys_res_n => sys_res_n,
+               -- scanner
+               s_char => s_char,
+               s_take => s_take,
+               s_done => s_done,
+               s_backspace => s_backspace,
+               -- display
+               d_new_eingabe => d_new_eingabe,
+               d_new_result => d_new_result,
+               d_zeile => d_zeile,
+               d_spalte => d_spalte,
+               d_get => d_get,
+               d_done => d_done,
+               d_char => d_char,
+               -- TODO: tmp only!
+               do_it => do_it,
+               finished => finished
+       );
+
+       process
+       begin
+               sys_clk <= '0';
+               wait for 15 ns;
+               sys_clk <= '1';
+               wait for 15 ns;
+               if stop = true then
+                       wait;
+               end if;
+       end process;
+
+       process
+               variable input : hstring := "12345678                                                               ";
+               variable ctmp : character;
+
+               variable checkall : boolean := true;
+               variable i : integer := 1;
+               variable j : integer;
+       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);
+               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;
+                               end if;
+                               d_get <= '0';
+                               icwait(sys_clk, 2);
+                               j := j + 1;
+                       end loop;
+                       i := i + 1;
+               end loop;
+
+               do_it <= '1';
+               wait on finished;
+               icwait(sys_clk, 2);
+               do_it <= '0';
+
+
+               if checkall then
+                       report "alle testfaelle der History waren erfolgreich!";
+               else
+                       report "einige testfaelle schlugen fehl";
+               end if;
+               icwait(sys_clk, 10);
+               stop <= true;
+               wait;
+       end process;
+end architecture sim;
index a897b0a7b504d2fc780d84c06b5659a408612fcd..1fd0404bb2b1a07c64b083f73499b1cddb1eb068 100644 (file)
@@ -19,9 +19,9 @@ package gen_pkg is
        subtype cinteger is integer;
 
        -- vorerst: 2 * 71
-       -- constant H_RAM_SIZE : integer := 142;
+       constant H_RAM_SIZE : integer := 142;
        -- danach: 50 * 71 * 2 = 7100
-       constant H_RAM_SIZE : integer := 7100;
+       -- constant H_RAM_SIZE : integer := 7100;
        constant H_RAM_WIDTH : integer := log2c(H_RAM_SIZE);
        subtype hspalte is std_logic_vector(6 downto 0);
        subtype hzeile is std_logic_vector(4 downto 0);
index fc0abbe65df10f9664c630e691b493e3e77db1e9..2f3c2dd0334bd8986e53fa2464c846b673d77859 100644 (file)
@@ -32,9 +32,11 @@ entity history is
 end entity history;
 
 architecture beh of history is
-       type HISTORY_STATE is (SIDLE);
+       type HISTORY_STATE is (SIDLE, S_S_INIT, S_S_WRITE, S_S_BS, S_S_DONE, S_S_FIN,
+               S_D_INIT, S_D_WAIT, S_D_WRITE);
        signal state_int, state_next : HISTORY_STATE;
        signal s_done_int, s_done_next : std_logic;
+       signal s_cnt_int, s_cnt_next : hspalte;
        signal d_new_eingabe_int, d_new_eingabe_next : std_logic;
        signal d_new_result_int, d_new_result_next : std_logic;
        signal d_done_int, d_done_next : std_logic;
@@ -43,9 +45,9 @@ architecture beh of history is
        signal finished_int, finished_next : std_logic;
 
        -- ram
-       signal address, address_next, address_int : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
-       signal data_out, data_in, data_in_next, data_in_int : hbyte;
-       signal wr, wr_next, wr_int : std_logic;
+       signal address_next, address_int : std_logic_vector(H_RAM_WIDTH - 1 downto 0);
+       signal data_out, data_in_next, data_in_int : hbyte;
+       signal wr_next, wr_int : std_logic;
 begin
        s_done <= s_done_int;
        d_new_eingabe <= d_new_eingabe_int;
@@ -55,10 +57,6 @@ begin
 
        finished <= finished_int;
 
-       address <= address_int;
-       data_in <= data_in_int;
-       wr <= wr_int;
-
        process(sys_clk, sys_res_n)
        begin
                if sys_res_n = '0' then
@@ -66,6 +64,7 @@ begin
                        state_int <= SIDLE;
                        -- out
                        s_done_int <= '0';
+                       s_cnt_int <= (0 => '1', others => '0');
                        d_new_result_int <= '0';
                        d_new_eingabe_int <= '0';
                        d_done_int <= '0';
@@ -73,7 +72,7 @@ begin
 
                        finished_int <= '0';
 
-                       address_int <= (others => '0');
+                       address_int <= (0 => '1', others => '0');
                        data_in_int <= x"00";
                        wr_int <= '0';
                elsif rising_edge(sys_clk) then
@@ -81,6 +80,7 @@ begin
                        state_int <= state_next;
                        -- out
                        s_done_int <= s_done_next;
+                       s_cnt_int <= s_cnt_next;
                        d_new_result_int <= d_new_result_next;
                        d_new_eingabe_int <= d_new_eingabe_next;
                        d_done_int <= d_done_next;
@@ -95,22 +95,93 @@ begin
        end process;
 
        -- next state
-       process(state_int)
+       process(state_int, d_get, do_it, s_take, s_backspace)
        begin
                state_next <= state_int;
 
                case state_int is
                        when SIDLE =>
-                               null;
+                               -- S_S_FIN: tmp..
+                               if d_get = '1' then
+                                       state_next <= S_D_INIT;
+                               elsif do_it = '1' then
+                                       state_next <= S_S_FIN;
+                               elsif s_take = '1' then
+                                       state_next <= S_S_INIT;
+                               end if;
+                       when S_S_INIT =>
+                               if s_backspace = '1' then
+                                       state_next <= S_S_BS;
+                               else
+                                       state_next <= S_S_WRITE;
+                               end if;
+                       when S_S_WRITE | S_S_BS =>
+                               state_next <= S_S_DONE;
+                       when S_S_FIN =>
+                               if do_it = '0' then
+                                       state_next <= SIDLE;
+                               end if;
+                       when S_S_DONE =>
+                               if s_take = '0' then
+                                       state_next <= SIDLE;
+                               end if;
+
+                       when S_D_INIT =>
+                               state_next <= S_D_WAIT;
+                       when S_D_WAIT =>
+                               state_next <= S_D_WRITE;
+                       when S_D_WRITE =>
+                               if d_get = '0' then
+                                       state_next <= SIDLE;
+                               end if;
                end case;
        end process;
 
        -- out
-       process(state_int)
+       process(state_int, s_cnt_int, d_spalte, data_out, s_char, address_int,
+               data_in_int)
        begin
+               s_done_next <= '0';
+               s_cnt_next <= s_cnt_int;
+               d_new_result_next <= '0';
+               d_new_eingabe_next <= '0';
+               d_done_next <= '0';
+               d_char_next <= (others => '0');
+               finished_next <= '0';
+               wr_next <= '0';
+               address_next <= address_int;
+               data_in_next <= data_in_int;
+
                case state_int is
                        when SIDLE =>
                                null;
+                       when S_S_INIT =>
+                               null;
+                       when S_S_WRITE =>
+                               wr_next <= '1';
+                               address_next <= '0' & s_cnt_int;
+                               data_in_next <= s_char;
+                               s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1);
+                       when S_S_BS =>
+                               wr_next <= '1';
+                               address_next <= '0' & std_logic_vector(unsigned(s_cnt_int) - 1);
+                               data_in_next <= (others => '0');
+                               s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) - 1);
+                       when S_S_FIN =>
+                               finished_next <= '1';
+                               s_cnt_next <= (0 => '1', others => '0');
+                               d_new_result_next <= '1';
+                       when S_S_DONE =>
+                               s_done_next <= '1';
+                               d_new_eingabe_next <= '1';
+
+                       when S_D_INIT =>
+                               address_next <= '0' & d_spalte;
+                       when S_D_WAIT =>
+                               null;
+                       when S_D_WRITE =>
+                               d_char_next <= data_out;
+                               d_done_next <= '1';
                end case;
        end process;
 
@@ -120,10 +191,9 @@ begin
        )
        port map (
                sys_clk => sys_clk,
-               sys_res_n => sys_res_n,
-               address => address,
+               address => address_int,
                data_out => data_out,
-               wr => wr,
-               data_in => data_in
+               wr => wr_int,
+               data_in => data_in_int
        );
 end architecture beh;
index a2a2371aaf901c9d7debab4fef0020766d7db8bd..4d39020db802fbca901b720e72ba6143a3bb38f2 100644 (file)
@@ -10,7 +10,6 @@ entity sp_ram is
        );
        port (
                sys_clk : in std_logic;
-               sys_res_n : in std_logic;
                address : in std_logic_vector(ADDR_WIDTH - 1 downto 0);
                data_out : out hbyte;
                wr : in std_logic;
@@ -20,14 +19,12 @@ end entity sp_ram;
 
 architecture beh of sp_ram is
        subtype RAM_ENTRY_TYPE is hbyte;
-       type RAM_TYPE is array (0 to (2 ** ADDR_WIDTH) - 1) of RAM_ENTRY_TYPE;
+       type RAM_TYPE is array (1 to (2 ** ADDR_WIDTH)) of RAM_ENTRY_TYPE;
        signal ram : RAM_TYPE := (others => x"00");
 begin
-       process(sys_clk, sys_res_n)
+       process(sys_clk)
        begin
-               if sys_res_n = '0' then
-                       ram <= (others => x"00");
-               elsif rising_edge(sys_clk) then
+               if rising_edge(sys_clk) then
                        data_out <= ram(to_integer(unsigned(address)));
                        if wr = '1' then
                                ram(to_integer(unsigned(address))) <= data_in;