From 5f4ec84aff1e4c4d26eb7707a2e9d899ed519bb9 Mon Sep 17 00:00:00 2001 From: Bernhard Urban Date: Thu, 20 May 2010 16:03:13 +0200 Subject: [PATCH] history/display: backspace logic --- spec/speck.tex | 1 + src/beh_display_tb.vhd | 3 ++- src/beh_history_tb.do | 10 ++++++++ src/beh_history_tb.vhd | 18 +++++++-------- src/calc.vhd | 4 +++- src/calc_s3e.vhd | 4 +++- src/display.vhd | 52 ++++++++++++++++++++++++++++++++++++------ src/gen_pkg.vhd | 4 +--- src/history.test | 4 ++++ src/history.vhd | 44 +++++++++++++++++++++++++++-------- 10 files changed, 112 insertions(+), 32 deletions(-) diff --git a/spec/speck.tex b/spec/speck.tex index 07878be..8a08c8f 100644 --- a/spec/speck.tex +++ b/spec/speck.tex @@ -623,6 +623,7 @@ behandelt??) \item Scanner: fehler in der state-maschine: ein extriger uebergang von \emph{read} auf \emph{\"ubernehmen} ist n\"otig um leerzeichen \"ubernehmen zu k\"oennen. +\item History $\Rightarrow$ Display: ein zus\"atzliches Signal \emph{d\_new\_bs}. \end{itemize} \end{document} diff --git a/src/beh_display_tb.vhd b/src/beh_display_tb.vhd index b3be1e1..5b6e6a1 100644 --- a/src/beh_display_tb.vhd +++ b/src/beh_display_tb.vhd @@ -17,7 +17,7 @@ architecture sim of beh_display_tb is 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/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; @@ -36,6 +36,7 @@ begin -- 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, diff --git a/src/beh_history_tb.do b/src/beh_history_tb.do index 6f93833..0eb6002 100644 --- a/src/beh_history_tb.do +++ b/src/beh_history_tb.do @@ -4,6 +4,16 @@ alias rr "restart -f" #signale hinzufuegen add wave * +delete wave d_spalte +add wave inst/d_spalte +add wave inst/s_cnt_int + +add wave inst/state_int +add wave inst/was_bs_int + +add wave inst_disp/state_int +add wave inst_disp/istate_int + #rauszoomen wave zoomout 500.0 diff --git a/src/beh_history_tb.vhd b/src/beh_history_tb.vhd index c1e9a7d..bf1eb89 100644 --- a/src/beh_history_tb.vhd +++ b/src/beh_history_tb.vhd @@ -13,7 +13,7 @@ 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_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; @@ -47,6 +47,7 @@ begin -- 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, @@ -65,6 +66,7 @@ begin -- 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, @@ -109,9 +111,9 @@ begin process begin free <= '0'; - icwait(sys_clk, 2); + wait for 15 ns; free <= '1'; - icwait(sys_clk, 2); + wait for 30 ns; if stop = true then wait; end if; @@ -144,7 +146,7 @@ begin return y; end function; - function valid_char (x : std_logic_vector(7 downto 0); last : std_logic_vector(7 downto 0)) return boolean is + function valid_char (x : std_logic_vector(7 downto 0)) return boolean is variable y : boolean; begin case x is @@ -169,7 +171,6 @@ begin variable run_tc, run_inner : boolean := true; variable i, j, y : natural; - variable last : std_logic_vector(7 downto 0); begin -- init & reset sys_res_n <= '0'; @@ -178,7 +179,7 @@ begin s_done <= '0'; finished <= '0'; - icwait(sys_clk, 5); + icwait(sys_clk, 20); sys_res_n <= '1'; i := 1; @@ -209,8 +210,7 @@ begin j := 0; mainl : while run_tc loop - last := data; - icwait(sys_clk, 1); + icwait(sys_clk, 10); j := j + 1; if j = 73 then @@ -237,7 +237,7 @@ begin -- ack'en skippen, falls es ein "spezielles" zeichen ist (steht -- in abhaengigkeit zum vorherigen zeichen) - if(not valid_char(data, last)) then + if(not valid_char(data)) then next mainl; end if; diff --git a/src/calc.vhd b/src/calc.vhd index cda8ee2..6f54a29 100644 --- a/src/calc.vhd +++ b/src/calc.vhd @@ -37,7 +37,7 @@ architecture top of calc is 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/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; @@ -86,6 +86,7 @@ begin -- 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, @@ -110,6 +111,7 @@ begin -- 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, diff --git a/src/calc_s3e.vhd b/src/calc_s3e.vhd index 6ff9ea2..bc1cc09 100644 --- a/src/calc_s3e.vhd +++ b/src/calc_s3e.vhd @@ -40,7 +40,7 @@ architecture top of calc is 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/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; @@ -92,6 +92,7 @@ begin -- 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, @@ -116,6 +117,7 @@ begin -- 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, diff --git a/src/display.vhd b/src/display.vhd index ed8cac9..8b0a9cc 100644 --- a/src/display.vhd +++ b/src/display.vhd @@ -13,6 +13,7 @@ entity display is -- History d_new_eingabe : in std_logic; d_new_result : in std_logic; + d_new_bs : in std_logic; d_zeile : out hzeile; d_spalte : out hspalte; d_get : out std_logic; @@ -26,8 +27,9 @@ entity display is end entity display; architecture beh of display is - type DISPLAY_STATE is (SIDLE, S_NEW_RESULT, S_NEW_INPUT, S_COUNTUP, S_GETCH, - S_CR1, S_NL1, S_PUTCH1, S_PUTCH2, S_WAIT, S_NOP1); + type DISPLAY_STATE is (SIDLE, S_NEW_BS, S_BACK, S_BLANK, S_NEW_RESULT, + S_NEW_INPUT, S_COUNTUP, S_GETCH, S_CR1, S_NL1, S_PUTCH1, S_PUTCH2, + S_WAIT, S_NOP1); signal state_int, state_next : DISPLAY_STATE; signal d_zeile_int, d_zeile_next : hzeile; signal d_spalte_int, d_spalte_next : hspalte; @@ -68,8 +70,8 @@ begin end process; -- next state - process(state_int, d_new_result, d_new_eingabe, d_done, free, d_spalte_int, - d_char, istate_int) + process(state_int, d_new_result, d_new_eingabe, d_new_bs, d_done, free, + d_spalte_int, d_char, istate_int) begin state_next <= state_int; istate_next <= istate_int; @@ -77,16 +79,36 @@ begin case state_int is when SIDLE => istate_next <= b"111"; -- default: immer wieder ins SIDLE; - if d_new_eingabe = '1' then + if d_new_bs = '1' then + state_next <= S_NEW_BS; + elsif d_new_eingabe = '1' then state_next <= S_NEW_INPUT; end if; if d_new_result = '1' then state_next <= S_NEW_RESULT; end if; + when S_NEW_RESULT => state_next <= S_CR1; when S_NEW_INPUT => state_next <= S_COUNTUP; + + when S_NEW_BS => + state_next <= S_BACK; + when S_BACK => + if free = '0' then + state_next <= S_WAIT; + case istate_int is + when b"111" => istate_next <= b"001"; -- => danach S_BLANK und wieder hierher + when others => istate_next <= b"111"; -- => danach SIDLE + end case; + end if; + when S_BLANK => + if free = '0' then + state_next <= S_WAIT; + istate_next <= b"010"; -- => danach S_BACK + end if; + when S_CR1 => if free = '0' then state_next <= S_WAIT; @@ -97,6 +119,7 @@ begin state_next <= S_WAIT; istate_next <= b"111"; -- => wieder nach SIDLE end if; + when S_COUNTUP => state_next <= S_GETCH; when S_GETCH => @@ -117,6 +140,8 @@ begin if free = '1' then case istate_int is when b"000" => state_next <= S_NL1; + when b"001" => state_next <= S_BLANK; + when b"010" => state_next <= S_BACK; when others => state_next <= SIDLE; end case; end if; @@ -136,20 +161,33 @@ begin case state_int is when SIDLE => null; - when S_NEW_INPUT => - null; when S_NEW_RESULT => d_spalte_next <= (others => '0'); case d_zeile_int is when "11111" => d_zeile_next <= "00000"; when others => d_zeile_next <= std_logic_vector(unsigned(d_zeile_int) + 1); end case; + when S_NEW_INPUT => + null; + + when S_NEW_BS => + -- underflow check schon im history modul + d_spalte_next <= std_logic_vector(unsigned(d_spalte_int) - 1); + when S_BACK => + -- einen schritt zurueck + command_next <= COMMAND_SET_CURSOR_COLUMN; + command_data_next <= x"ffffff" & '0' & std_logic_vector(unsigned(d_spalte_int)); + when S_BLANK => + command_next <= COMMAND_SET_CHAR; + command_data_next <= x"ffffff" & x"20"; -- white space + when S_CR1 => command_next <= COMMAND_SET_CHAR; command_data_next <= x"ffffff" & x"0d"; -- carrige return when S_NL1 => command_next <= COMMAND_SET_CHAR; command_data_next <= x"ffffff" & x"0a"; -- newline + when S_COUNTUP => d_get_next <= '1'; d_spalte_next <= std_logic_vector(unsigned(d_spalte_int) + 1); diff --git a/src/gen_pkg.vhd b/src/gen_pkg.vhd index 0236b72..b4ed94d 100644 --- a/src/gen_pkg.vhd +++ b/src/gen_pkg.vhd @@ -18,10 +18,8 @@ package gen_pkg is -- integer ist 32bit (31bit + sign) subtype cinteger is integer; - -- vorerst: 1 * 71 + -- TODO: 50 * 71 * 2 = 7100 constant H_RAM_SIZE : integer := 71; - -- danach: 50 * 71 * 2 = 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); diff --git a/src/history.test b/src/history.test index 37ecd83..92f4e1f 100644 --- a/src/history.test +++ b/src/history.test @@ -5,3 +5,7 @@ asdf213 # testfall 2: 12 + 4 +# testfall 3: +123!!5 +# testfall 4: +123!!!!5 diff --git a/src/history.vhd b/src/history.vhd index 08b0359..b1a1b01 100644 --- a/src/history.vhd +++ b/src/history.vhd @@ -17,6 +17,7 @@ entity history is -- Display d_new_eingabe : out std_logic; d_new_result : out std_logic; + d_new_bs : out std_logic; d_zeile : in hzeile; d_spalte : in hspalte; d_get : in std_logic; @@ -35,10 +36,12 @@ architecture beh of history is 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_WRITE); signal state_int, state_next : HISTORY_STATE; + signal was_bs_int, was_bs_next : std_logic; 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_new_bs_int, d_new_bs_next: std_logic; signal d_done_int, d_done_next : std_logic; signal d_char_int, d_char_next : hbyte; @@ -52,6 +55,7 @@ begin s_done <= s_done_int; d_new_eingabe <= d_new_eingabe_int; d_new_result <= d_new_result_int; + d_new_bs <= d_new_bs_int; d_done <= d_done_int; d_char <= d_char_int; @@ -62,11 +66,13 @@ begin if sys_res_n = '0' then -- internal state_int <= SIDLE; + was_bs_int <= '0'; -- out s_done_int <= '0'; s_cnt_int <= (0 => '1', others => '0'); d_new_result_int <= '0'; d_new_eingabe_int <= '0'; + d_new_bs_int <= '0'; d_done_int <= '0'; d_char_int <= (others => '0'); @@ -78,11 +84,13 @@ begin elsif rising_edge(sys_clk) then -- internal state_int <= state_next; + was_bs_int <= was_bs_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_new_bs_int <= d_new_bs_next; d_done_int <= d_done_next; d_char_int <= d_char_next; @@ -95,9 +103,10 @@ begin end process; -- next state - process(state_int, d_get, do_it, s_take, s_backspace) + process(state_int, d_get, do_it, s_take, s_backspace, was_bs_int) begin state_next <= state_int; + was_bs_next <= was_bs_int; case state_int is when SIDLE => @@ -115,8 +124,11 @@ begin else state_next <= S_S_WRITE; end if; - when S_S_WRITE | S_S_BS => + when S_S_WRITE => + state_next <= S_S_DONE; + when S_S_BS => state_next <= S_S_DONE; + was_bs_next <= '1'; when S_S_FIN => if do_it = '0' then state_next <= SIDLE; @@ -124,6 +136,7 @@ begin when S_S_DONE => if s_take = '0' then state_next <= SIDLE; + was_bs_next <= '0'; end if; when S_D_INIT => @@ -137,12 +150,15 @@ begin -- out process(state_int, s_cnt_int, d_spalte, data_out, s_char, address_int, - data_in_int, d_new_result_int, d_new_eingabe_int) + data_in_int, d_new_result_int, d_new_eingabe_int, d_new_bs_int, + was_bs_int) + variable addr_tmp : std_logic_vector(H_RAM_WIDTH - 1 downto 0); begin s_done_next <= '0'; s_cnt_next <= s_cnt_int; d_new_result_next <= d_new_result_int; d_new_eingabe_next <= d_new_eingabe_int; + d_new_bs_next <= '0'; d_done_next <= '0'; d_char_next <= (others => '0'); finished_next <= '0'; @@ -151,30 +167,38 @@ begin data_in_next <= data_in_int; case state_int is - when S_S_INIT => - null; when SIDLE => -- TODO: tmp fix d_new_result_next <= '0'; + when S_S_INIT => + null; when S_S_WRITE => wr_next <= '1'; address_next <= s_cnt_int; data_in_next <= s_char; s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) + 1); when S_S_BS => + -- ab 1 darf nicht mehr dekrementiert werden + if unsigned(s_cnt_int) /= 1 then + addr_tmp := std_logic_vector(unsigned(s_cnt_int) - 1); + d_new_bs_next <= '1'; + else + addr_tmp := s_cnt_int; + end if; + s_cnt_next <= addr_tmp; + wr_next <= '1'; - address_next <= std_logic_vector(unsigned(s_cnt_int) - 1); + address_next <= addr_tmp; data_in_next <= (others => '0'); - if unsigned(s_cnt_int) /= 0 then - s_cnt_next <= std_logic_vector(unsigned(s_cnt_int) - 1); - end if; 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'; + if was_bs_int = '0' then + d_new_eingabe_next <= '1'; + end if; when S_D_INIT => address_next <= d_spalte; -- 2.25.1