copyleft: gplv3 added and set repo to public
[calu.git] / cpu / src / extension_uart_b.vhd
1 --   `Deep Thought', a softcore CPU implemented on a FPGA
2 --
3 --  Copyright (C) 2010 Markus Hofstaetter <markus.manrow@gmx.at>
4 --  Copyright (C) 2010 Martin Perner <e0725782@student.tuwien.ac.at>
5 --  Copyright (C) 2010 Stefan Rebernig <stefan.rebernig@gmail.com>
6 --  Copyright (C) 2010 Manfred Schwarz <e0725898@student.tuwien.ac.at>
7 --  Copyright (C) 2010 Bernhard Urban <lewurm@gmail.com>
8 --
9 --  This program is free software: you can redistribute it and/or modify
10 --  it under the terms of the GNU General Public License as published by
11 --  the Free Software Foundation, either version 3 of the License, or
12 --  (at your option) any later version.
13 --
14 --  This program is distributed in the hope that it will be useful,
15 --  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 --  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 --  GNU General Public License for more details.
18 --
19 --  You should have received a copy of the GNU General Public License
20 --  along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
22 library IEEE;
23 use IEEE.std_logic_1164.all;
24 use IEEE.numeric_std.all;
25
26 use work.common_pkg.all;
27 use work.core_pkg.all;
28
29 use work.mem_pkg.all;
30 use work.extension_pkg.all;
31 use work.extension_uart_pkg.all;
32
33 architecture behav of extension_uart is
34
35 signal w1_st_co, w1_st_co_nxt, w2_uart_config, w2_uart_config_nxt, w3_uart_send, w3_uart_send_nxt, w4_uart_receive, w4_uart_receive_nxt : gp_register_t;
36 signal new_bus_rx,new_wb_data,  new_wb_data_nxt, new_tx_data, new_tx_data_nxt, tx_rdy, tx_rdy_int : std_logic;
37 signal  bd_rate : baud_rate_l;
38 signal rx_data : std_logic_vector(7 downto 0);
39
40 signal uart_int_nxt : std_logic;
41 signal uart_data_read_nxt : std_logic;
42
43 begin
44
45
46 rs232_tx_inst : rs232_tx
47 generic map(
48                 RESET_VALUE
49                 )
50 port map(
51         --System inputs
52         clk,
53         reset,
54
55         --Bus
56         bus_tx,
57
58         --From/to sendlogic
59         new_tx_data,
60         w3_uart_send(byte_t'range),
61         tx_rdy,
62         bd_rate,
63         w1_st_co(16)
64 );
65
66 rs232_rx_inst : rs232_rx
67 generic map(
68                 RESET_VALUE,
69                 2
70                 )
71 port map(
72         --System inputs
73         clk,
74         reset,
75
76         --Bus
77         bus_rx,
78
79         --From/to sendlogic
80         new_bus_rx,
81         rx_data,
82         bd_rate
83 );
84
85
86
87
88 syn : process (clk, reset)
89 begin
90    if (reset = RESET_VALUE) then
91                         w1_st_co <= (others=>'0');
92                         w2_uart_config(31 downto 16) <= (others=>'0');
93                         w2_uart_config(15 downto 0) <= std_logic_vector(to_unsigned(CLK_PER_BAUD, 16));
94                         w3_uart_send <= (others=>'0');
95                         w4_uart_receive <= (others=>'0');
96                         tx_rdy_int <= '0';
97                         new_tx_data <= '0';
98                         uart_int <= '0';
99
100         elsif rising_edge(clk) then            
101                         w1_st_co <= w1_st_co_nxt;
102                         w2_uart_config <= w2_uart_config_nxt;
103                         w3_uart_send <= w3_uart_send_nxt;
104                         w4_uart_receive <= w4_uart_receive_nxt;
105                         new_tx_data <= new_tx_data_nxt;
106                         tx_rdy_int <= tx_rdy;
107                         uart_int <= uart_int_nxt;
108    end if;
109 end process syn;
110
111 -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------
112
113 gwriten : process
114         (ext_reg,tx_rdy,w1_st_co,w2_uart_config,w3_uart_send,w4_uart_receive,tx_rdy_int, rx_data, new_bus_rx, uart_data_read_nxt)
115
116 variable tmp_data  : gp_register_t;
117
118 begin
119                 uart_int_nxt <= '0';
120                 w1_st_co_nxt <= w1_st_co;
121                 w2_uart_config_nxt <= w2_uart_config;
122                 w3_uart_send_nxt <= w3_uart_send;
123                 w4_uart_receive_nxt <= w4_uart_receive;
124
125         if ext_reg.sel = '1' and ext_reg.wr_en = '1' then
126                 tmp_data := (others =>'0');                     
127                 if ext_reg.byte_en(0) = '1' then
128                         tmp_data(byte_t'range) :=ext_reg.data(byte_t'range);
129                 end if;
130                 if ext_reg.byte_en(1) = '1' then
131                         tmp_data((2*byte_t'length-1) downto byte_t'length) := ext_reg.data((2*byte_t'length-1) downto byte_t'length);
132                 end if;
133                 if ext_reg.byte_en(2) = '1' then
134                         tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := ext_reg.data((3*byte_t'length-1) downto 2*byte_t'length);
135                 end if;
136                 if ext_reg.byte_en(3) = '1' then
137                         tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := ext_reg.data((4*byte_t'length-1) downto 3*byte_t'length);
138                 end if;
139
140                 case ext_reg.addr(1 downto 0) is
141                 when "00" => 
142                         w1_st_co_nxt <= tmp_data;
143                 when "01" =>
144                         w2_uart_config_nxt <= tmp_data;
145                 when "10" =>
146                         w1_st_co_nxt(0) <= '1'; -- busy flag set
147                         w3_uart_send_nxt <= tmp_data;
148                 when "11" =>
149                         --w4_uart_receive_nxt <= tmp_data; sollte nur gelesen werden
150                 when others => null;
151                 end case;
152         end if;
153
154         if  tx_rdy = '1' and tx_rdy_int = '0' then
155                 w1_st_co_nxt(0) <= '0'; -- busy flag reset      
156         end if;
157
158         if new_bus_rx = '1' then
159                 w4_uart_receive_nxt(7 downto 0) <= rx_data;
160                 w1_st_co_nxt(1) <= '1';
161                 uart_int_nxt <= '1';
162         end if;
163         
164         if (uart_data_read_nxt = '1' and w1_st_co(1) = '1' and ext_reg.sel = '1') then
165                 w1_st_co_nxt(1) <= '0';
166         end if;
167         
168 end process gwriten;
169
170 gread : process (clk,ext_reg,w1_st_co,w2_uart_config,w3_uart_send,w4_uart_receive)
171
172 variable tmp_data  : gp_register_t;
173
174 begin
175
176         uart_data_read_nxt <= '0';
177
178         if ext_reg.sel = '1' and ext_reg.wr_en = '0' then
179                 case ext_reg.addr(1 downto 0) is
180                 when "00" => 
181                         tmp_data := (others =>'0');                     
182                         if ext_reg.byte_en(0) = '1' then
183                                 tmp_data(byte_t'range) := w1_st_co(byte_t'range);
184                         end if;
185                         if ext_reg.byte_en(1) = '1' then
186                                 tmp_data((2*byte_t'length-1) downto byte_t'length) := w1_st_co((2*byte_t'length-1) downto byte_t'length);
187                         end if;
188                         if ext_reg.byte_en(2) = '1' then
189                                 tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w1_st_co((3*byte_t'length-1) downto 2*byte_t'length);
190                         end if;
191                         if ext_reg.byte_en(3) = '1' then
192                                 tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w1_st_co((4*byte_t'length-1) downto 3*byte_t'length);
193                         end if;
194                         data_out <= tmp_data;
195                 when "01" =>
196                         tmp_data := (others =>'0');                     
197                         if ext_reg.byte_en(0) = '1' then
198                                 tmp_data(byte_t'range) := w2_uart_config(byte_t'range);
199                         end if;
200                         if ext_reg.byte_en(1) = '1' then
201                                 tmp_data((2*byte_t'length-1) downto byte_t'length) := w2_uart_config((2*byte_t'length-1) downto byte_t'length);
202                         end if;
203                         if ext_reg.byte_en(2) = '1' then
204                                 tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w2_uart_config((3*byte_t'length-1) downto 2*byte_t'length);
205                         end if;
206                         if ext_reg.byte_en(3) = '1' then
207                                 tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w2_uart_config((4*byte_t'length-1) downto 3*byte_t'length);
208                         end if;
209                         data_out <= tmp_data;
210                 when "10" =>
211                         tmp_data := (others =>'0');                     
212                         if ext_reg.byte_en(0) = '1' then
213                                 tmp_data(byte_t'range) := w3_uart_send(byte_t'range);
214                         end if;
215                         if ext_reg.byte_en(1) = '1' then
216                                 tmp_data((2*byte_t'length-1) downto byte_t'length) := w3_uart_send((2*byte_t'length-1) downto byte_t'length);
217                         end if;
218                         if ext_reg.byte_en(2) = '1' then
219                                 tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w3_uart_send((3*byte_t'length-1) downto 2*byte_t'length);
220                         end if;
221                         if ext_reg.byte_en(3) = '1' then
222                                 tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w3_uart_send((4*byte_t'length-1) downto 3*byte_t'length);
223                         end if;
224                         data_out <= tmp_data;
225                 when "11" =>
226                         tmp_data := (others =>'0');     
227                         uart_data_read_nxt <= '1';
228                         if ext_reg.byte_en(0) = '1' then
229                                 tmp_data(byte_t'range) := w4_uart_receive(byte_t'range);
230                         end if;
231                         if ext_reg.byte_en(1) = '1' then
232                                 tmp_data((2*byte_t'length-1) downto byte_t'length) := w4_uart_receive((2*byte_t'length-1) downto byte_t'length);
233                         end if;
234                         if ext_reg.byte_en(2) = '1' then
235                                 tmp_data((3*byte_t'length-1) downto 2*byte_t'length) := w4_uart_receive((3*byte_t'length-1) downto 2*byte_t'length);
236                         end if;
237                         if ext_reg.byte_en(3) = '1' then
238                                 tmp_data((4*byte_t'length-1) downto 3*byte_t'length) := w4_uart_receive((4*byte_t'length-1) downto 3*byte_t'length);
239                         end if;
240                         data_out <= tmp_data;
241                 when others => null;
242                 end case;
243         else
244                 data_out  <= (others=>'0');             
245         end if;
246 end process gread;
247
248
249 -------------------------- LESEN UND SCHREIBEN ENDE ---------------------------------------------------------------
250
251 -------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------
252
253 dataprocess : process (ext_reg,tx_rdy,w2_uart_config)
254
255
256 begin
257
258         new_tx_data_nxt <= '0';
259         bd_rate <= w2_uart_config(15 downto 0);
260
261         if ext_reg.sel = '1' and ext_reg.wr_en = '1' then
262                 case ext_reg.addr(1 downto 0) is
263                 when "00" => 
264
265                 when "01" =>
266
267                 when "10" =>
268                         new_tx_data_nxt <= '1';
269                 when "11" =>
270                 
271                 when others => null;
272                 end case;
273         end if;
274
275 end process dataprocess;
276
277
278
279 -------------------------- INTERNE VERARBEITUNG ENDE --------------------------------------------------------------
280
281 end behav;
282