410bc4fbb05aa0674f9e0eab1aa024bfa3da3b4d
[hwmod.git] / src / pc_communication.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.numeric_std.all;
4 use work.gen_pkg.all;
5
6 entity pc_communication is
7         port (
8                 sys_clk : in std_logic;
9                 sys_res_n : in std_logic;
10
11                 --button
12                 btn_a : in std_logic;
13
14                 --uart_tx
15                 tx_data : out std_logic_vector(7 downto 0);
16                 tx_new : out std_logic;
17                 tx_done : in std_logic;
18
19                 --uart_rx
20                 rx_data : in std_logic_vector(7 downto 0);
21                 rx_new : in std_logic;
22
23                 -- History
24                 pc_zeile : out hzeile;
25                 pc_spalte : out hspalte;
26                 pc_get :  out std_logic;
27                 pc_done : in std_logic;
28                 pc_char : in hbyte
29         );
30 end entity pc_communication;
31
32 architecture beh of pc_communication is
33         signal spalte, spalte_next : integer range 1 to HSPALTE_MAX + 2;
34         signal zeile , zeile_next : integer range 0 to HZEILE_MAX + 1;
35         signal get, get_next : std_logic;
36         signal new_i, new_i_next : std_logic;
37         signal tx_done_i, tx_done_i_next : std_logic;
38         signal tx_data_i, tx_data_i_next : std_logic_vector (7 downto 0);
39
40         type STATE_PC is (IDLE, FETCH, FORWARD, WAIT_UART, UART_DONE, CR, CR_WAIT,
41                 NL, NL_WAIT, PRINT_NO1, PRINT_NO1_WAIT, PRINT_NO2, PRINT_NO2_WAIT,
42                 PRINT_NO3, PRINT_NO3_WAIT, PRINT_NO4, PRINT_NO4_WAIT, PRINT_NO5,
43                 PRINT_NO5_WAIT, PRINT_NO6, PRINT_NO0_WAIT);
44         signal state, state_next : STATE_PC ;
45 begin
46         pc_zeile <= hzeile(std_logic_vector(to_unsigned(zeile,7)));
47         pc_spalte <= hspalte(std_logic_vector(to_unsigned(spalte,7)));
48         pc_get <= get;
49         tx_new <= new_i;
50         tx_done_i_next <= tx_done;
51         tx_data <= tx_data_i;
52
53         sync: process (sys_clk, sys_res_n)
54         begin
55                 if sys_res_n = '0' then
56                         state <= IDLE;
57                         spalte <= 1;
58                         zeile <= 0;
59                         get <= '0';
60                         new_i <= '0';
61                         tx_data_i <= x"00";
62                         tx_done_i <= '0';
63                 elsif rising_edge(sys_clk) then
64                         spalte <= spalte_next;
65                         zeile <= zeile_next;
66                         state <= state_next;
67                         get <= get_next;
68                         new_i <= new_i_next;
69                         tx_done_i <= tx_done_i_next;
70                         tx_data_i <= tx_data_i_next;
71                 end if;
72         end process sync;
73
74         process (state, zeile, spalte, tx_data_i, tx_done_i, pc_char, rx_new, btn_a,
75                         pc_done)
76                 variable tmp : std_logic_vector(6 downto 0);
77         begin
78                 get_next <= '0';
79                 new_i_next <= '0';
80                 spalte_next <= spalte;
81                 zeile_next <= zeile;
82                 tx_data_i_next <= tx_data_i;
83
84                 state_next <= state;
85                 case state is
86                         when IDLE =>
87 --                              if (rx_new = '1' and rx_data = x"0a") or btn_a = '0' then
88                                 if (rx_new = '1') or btn_a = '0' then
89                                         state_next <= PRINT_NO0_WAIT;
90                                 end if;
91
92                         when PRINT_NO0_WAIT =>
93                                 if tx_done_i = '0' then
94                                         state_next <= PRINT_NO1;
95                                 end if;
96                         when PRINT_NO1 =>
97                                 tx_data_i_next <= x"28"; -- '('
98                                 new_i_next <= '1';
99                                 if tx_done_i = '1' then
100                                         state_next <= PRINT_NO1_WAIT;
101                                 end if;
102                         when PRINT_NO1_WAIT =>
103                                 if tx_done_i = '0' then
104                                         state_next <= PRINT_NO2;
105                                 end if;
106                         when PRINT_NO2 =>
107                                 tx_data_i_next <= zeile2char(std_logic_vector(to_unsigned(zeile,7)), 1);
108                                 new_i_next <= '1';
109                                 if tx_done_i = '1' then
110                                         state_next <= PRINT_NO2_WAIT;
111                                 end if;
112                         when PRINT_NO2_WAIT =>
113                                 if tx_done_i = '0' then
114                                         state_next <= PRINT_NO3;
115                                 end if;
116                         when PRINT_NO3 =>
117                                 tx_data_i_next <= zeile2char(std_logic_vector(to_unsigned(zeile,7)), 2);
118                                 new_i_next <= '1';
119                                 if tx_done_i = '1' then
120                                         state_next <= PRINT_NO3_WAIT;
121                                 end if;
122                         when PRINT_NO3_WAIT =>
123                                 if tx_done_i = '0' then
124                                         state_next <= PRINT_NO4;
125                                 end if;
126                         when PRINT_NO4 =>
127                                 tx_data_i_next <= x"29"; -- ')'
128                                 new_i_next <= '1';
129                                 if tx_done_i = '1' then
130                                         state_next <= PRINT_NO4_WAIT;
131                                 end if;
132                         when PRINT_NO4_WAIT =>
133                                 if tx_done_i = '0' then
134                                         state_next <= PRINT_NO5;
135                                 end if;
136                         when PRINT_NO5 =>
137                                 tx_data_i_next <= x"24"; -- '$'
138                                 new_i_next <= '1';
139                                 if tx_done_i = '1' then
140                                         state_next <= PRINT_NO5_WAIT;
141                                 end if;
142                         when PRINT_NO5_WAIT =>
143                                 if tx_done_i = '0' then
144                                         state_next <= PRINT_NO6;
145                                 end if;
146                         when PRINT_NO6 =>
147                                 tx_data_i_next <= x"20"; -- ' '
148                                 new_i_next <= '1';
149                                 if tx_done_i = '1' then
150                                         state_next <= FETCH;
151                                 end if;
152
153                         when FETCH =>
154                                 get_next <= '1';
155                                 if pc_done = '1' and tx_done_i = '0' then
156                                         state_next <= FORWARD;
157                                         if pc_char = x"00" then
158                                                 state_next <= UART_DONE;
159                                         end if;
160                                 end if;
161                         when FORWARD =>
162                                 tx_data_i_next <= pc_char;
163                                 new_i_next <= '1';
164                                 -- halte pc_get weiterhin high sodass pc_char garantiert gleich bleibt
165                                 get_next <= '1';
166                                 state_next <= WAIT_UART;
167                         when WAIT_UART =>
168                                 new_i_next <= '1';
169                                 get_next <= '1';
170                                 if tx_done_i = '1' then
171                                         state_next <= UART_DONE;
172                                 end if;
173                         when UART_DONE =>
174                                 state_next <= FETCH;
175                                 spalte_next <= spalte + 1;
176                                 if spalte = HSPALTE_MAX + 1 then
177                                         state_next <= NL;
178                                         spalte_next <= 1;
179                                         zeile_next <= zeile + 1;
180                                 end if;
181                         when NL =>
182                                 tx_data_i_next <= x"0a";
183                                 new_i_next <= '1';
184                                 if tx_done_i = '1' then
185                                         state_next <= NL_WAIT;
186                                 end if;
187                         when NL_WAIT =>
188                                 state_next <= CR;
189                         when CR =>
190                                 tx_data_i_next <= x"0d";
191                                 new_i_next <= '1';
192                                 if tx_done_i = '1' then
193                                         state_next <= CR_WAIT;
194                                 end if;
195                         when CR_WAIT =>
196                                 tmp := std_logic_vector(to_unsigned(zeile,7));
197                                 if tmp(0) = '0' then
198                                         -- es handelt sich um eingabe
199                                         -- => print zeilennummer
200                                         state_next <= PRINT_NO0_WAIT;
201                                 else
202                                         state_next <= FETCH;
203                                 end if;
204                                 if zeile = HZEILE_MAX then
205                                         state_next <= IDLE;
206                                         zeile_next <= 0;
207                                         spalte_next <= 1;
208                                 end if;
209                 end case;
210         end process;
211 end architecture beh;