history/display: nach d_new_result = '1' werden die naechsten 70 bytes vom display
[hwmod.git] / src / display.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5 use work.textmode_vga_component_pkg.all;
6 use work.textmode_vga_pkg.all;
7 use work.textmode_vga_platform_dependent_pkg.all;
8
9 entity display is
10         port (
11                 sys_clk : in std_logic;
12                 sys_res_n : in std_logic;
13                 -- History
14                 d_new_eingabe : in std_logic;
15                 d_new_result : in std_logic;
16                 d_new_bs : in std_logic;
17                 d_zeile : out hzeile;
18                 d_spalte : out hspalte;
19                 d_get : out std_logic;
20                 d_done : in std_logic;
21                 d_char : in hbyte;
22                 -- VGA
23                 command : out std_logic_vector(7 downto 0);
24                 command_data : out std_logic_vector(31 downto 0);
25                 free : in std_logic
26         );
27 end entity display;
28
29 architecture beh of display is
30         type DISPLAY_STATE is (SIDLE, S_NEW_BS, S_BACK, S_BLANK, S_NEW_RESULT,
31                 S_ZEILEUP, S_NEW_INPUT, S_COUNTUP, S_GETCH, S_CR1, S_NL1, S_PUTCH1,
32                 S_PUTCH2, S_WAIT, S_NOP1, S_READ_RESULT);
33         signal state_int, state_next : DISPLAY_STATE;
34         signal d_zeile_int, d_zeile_next : hzeile;
35         signal d_spalte_int, d_spalte_next : hspalte;
36         signal d_get_int, d_get_next : std_logic;
37         signal command_int, command_next : std_logic_vector(7 downto 0);
38         signal command_data_int, command_data_next : std_logic_vector(31 downto 0);
39         signal istate_next, istate_int : signed(2 downto 0);
40 begin
41         d_zeile <= d_zeile_int;
42         d_spalte <= d_spalte_int;
43         d_get <= d_get_int;
44         command <= command_int;
45         command_data <= command_data_int;
46
47         process(sys_clk, sys_res_n)
48         begin
49                 if sys_res_n = '0' then
50                         -- internal
51                         state_int <= SIDLE;
52                         istate_int <= (others => '0');
53                         -- out
54                         d_zeile_int <= (others => '0');
55                         d_spalte_int <= (others => '0');
56                         d_get_int <= '0';
57                         command_int <= COMMAND_NOP;
58                         command_data_int <= (others => '0');
59                 elsif rising_edge(sys_clk) then
60                         -- internal
61                         state_int <= state_next;
62                         istate_int <= istate_next;
63                         -- out
64                         d_zeile_int <= d_zeile_next;
65                         d_spalte_int <= d_spalte_next;
66                         d_get_int <= d_get_next;
67                         command_int <= command_next;
68                         command_data_int <= command_data_next;
69                 end if;
70         end process;
71
72         -- next state
73         process(state_int, d_new_result, d_new_eingabe, d_new_bs, d_done, free,
74                 d_spalte_int, d_char, istate_int)
75         begin
76                 state_next <= state_int;
77                 istate_next <= istate_int;
78
79                 case state_int is
80                         when SIDLE =>
81                                 istate_next <= b"111"; -- default: immer wieder ins SIDLE;
82                                 if d_new_bs = '1' then
83                                         state_next <= S_NEW_BS;
84                                 elsif d_new_eingabe = '1' then
85                                         state_next <= S_NEW_INPUT;
86                                 end if;
87                                 if d_new_result = '1' then
88                                         state_next <= S_NEW_RESULT;
89                                 end if;
90
91                         when S_NEW_RESULT =>
92                                 state_next <= S_ZEILEUP;
93                         when S_NEW_INPUT =>
94                                 state_next <= S_COUNTUP;
95
96                         when S_NEW_BS =>
97                                 state_next <= S_BACK;
98                         when S_BACK =>
99                                 if free = '0' then
100                                         state_next <= S_WAIT;
101                                         case istate_int is
102                                                 when b"111" => istate_next <= b"001"; -- => danach S_BLANK und wieder hierher
103                                                 when others => istate_next <= b"111"; -- => danach SIDLE
104                                         end case;
105                                 end if;
106                         when S_BLANK =>
107                                 if free = '0' then
108                                         state_next <= S_WAIT;
109                                         istate_next <= b"010"; -- => danach S_BACK
110                                 end if;
111
112                         when S_ZEILEUP =>
113                                 case istate_int is
114                                         when b"011" =>
115                                                 state_next <= S_WAIT;
116                                                 istate_next <= b"111";
117                                         when others => state_next <= S_CR1;
118                                 end case;
119
120                         when S_CR1 =>
121                                 if free = '0' then
122                                         state_next <= S_WAIT;
123                                         case istate_int is
124                                                 when b"110" => istate_next <= b"101"; -- => danach S_NL1 und SIDLe
125                                                 when others => istate_next <= b"000"; -- => danach S_NL1 und S_COUNTUP
126                                         end case;
127                                 end if;
128                         when S_NL1 =>
129                                 if free = '0' then
130                                         state_next <= S_WAIT;
131                                         case istate_int is
132                                                 when b"101" => istate_next <= b"011"; -- => danach S_ZEILEUP
133                                                 when others => istate_next <= b"100"; -- => danach S_READ_RESULT
134                                         end case;
135                                 end if;
136                         when S_READ_RESULT =>
137                                 if unsigned(d_spalte_int) /= 70 then
138                                         state_next <= S_COUNTUP;
139                                         istate_next <= b"100"; -- => wieder nach S_READ_RESULT
140                                 else
141                                         state_next <= S_WAIT;
142                                         istate_next <= b"110"; -- => danach S_CR1 und d_spalte_next clearen und d_zeile_next inkrementieren
143                                 end if;
144
145                         when S_COUNTUP =>
146                                 state_next <= S_GETCH;
147                         when S_GETCH =>
148                                 if free = '1' and d_done = '1' and d_new_result = '0' and d_new_eingabe = '0' then
149                                         state_next <= S_PUTCH1;
150                                 end if;
151                         when S_PUTCH1 =>
152                                 state_next <= S_PUTCH2;
153                         when S_PUTCH2 =>
154                                 if free = '0' or (free = '1' and d_char = x"00") then
155                                         state_next <= S_WAIT;
156                                 end if;
157                         when S_WAIT =>
158                                 if free = '1' and d_done = '0' then
159                                         state_next <= S_NOP1;
160                                 end if;
161                         when S_NOP1 =>
162                                 if free = '1' then
163                                         case istate_int is
164                                                 when b"000" => state_next <= S_NL1;
165                                                 when b"001" => state_next <= S_BLANK;
166                                                 when b"010" => state_next <= S_BACK;
167                                                 when b"011" => state_next <= S_ZEILEUP;
168                                                 when b"100" => state_next <= S_READ_RESULT;
169                                                 when b"110" => state_next <= S_CR1;
170                                                 when b"101" => state_next <= S_NL1;
171                                                 when others => state_next <= SIDLE;
172                                         end case;
173                                 end if;
174                 end case;
175         end process;
176
177         -- out
178         process(state_int, d_zeile_int, d_spalte_int, d_get_int, command_int,
179                 command_data_int, d_char, istate_int)
180         begin
181                 d_zeile_next <= d_zeile_int;
182                 d_spalte_next <= d_spalte_int;
183                 d_get_next <= '0';
184                 command_next <= command_int;
185                 command_data_next <= command_data_int;
186
187                 case state_int is
188                         when SIDLE =>
189                                 null;
190                         when S_NEW_RESULT =>
191                         when S_NEW_INPUT =>
192                                 null;
193
194                         when S_NEW_BS =>
195                                 -- underflow check schon im history modul
196                                 d_spalte_next <= std_logic_vector(unsigned(d_spalte_int) - 1);
197                         when S_BACK =>
198                                 -- einen schritt zurueck
199                                 command_next <= COMMAND_SET_CURSOR_COLUMN;
200                                 command_data_next <= x"ffffff" & '0' & std_logic_vector(unsigned(d_spalte_int));
201                         when S_BLANK =>
202                                 command_next <= COMMAND_SET_CHAR;
203                                 command_data_next <= x"ffffff" & x"20"; -- white space
204
205                         when S_ZEILEUP =>
206                                 d_spalte_next <= (others => '0');
207                                 case d_zeile_int is
208                                         when "1111111" => d_zeile_next <= (others => '0');
209                                         when others => d_zeile_next <= std_logic_vector(unsigned(d_zeile_int) + 1);
210                                 end case;
211
212                         when S_CR1 =>
213                                 command_next <= COMMAND_SET_CHAR;
214                                 command_data_next <= x"ffffff" & x"0d"; -- carrige return
215                         when S_NL1 =>
216                                 command_next <= COMMAND_SET_CHAR;
217                                 command_data_next <= x"ffffff" & x"0a"; -- newline
218                         when S_READ_RESULT => null;
219
220                         when S_COUNTUP =>
221                                 d_get_next <= '1';
222                                 d_spalte_next <= std_logic_vector(unsigned(d_spalte_int) + 1);
223                         when S_GETCH =>
224                                 d_get_next <= '1';
225                         when S_PUTCH1 =>
226                                 if d_char /= x"00" then
227                                         command_next <= COMMAND_SET_CHAR;
228                                         command_data_next <= x"ffffff" & std_logic_vector(d_char);
229                                 end if;
230                         when S_PUTCH2 => null;
231                         when S_WAIT | S_NOP1 =>
232                                 command_next <= COMMAND_NOP;
233                                 command_data_next <= x"00000000";
234                 end case;
235         end process;
236 end architecture beh;