1 -- `Deep Thought', a softcore CPU implemented on a FPGA
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>
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.
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.
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/>.
23 use IEEE.std_logic_1164.all;
24 use IEEE.numeric_std.all;
26 use work.common_pkg.all;
27 use work.core_pkg.all;
30 use work.extension_pkg.all;
31 use work.extension_uart_pkg.all;
33 architecture behav of extension_uart is
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);
40 signal uart_int_nxt : std_logic;
41 signal uart_data_read_nxt : std_logic;
46 rs232_tx_inst : rs232_tx
60 w3_uart_send(byte_t'range),
66 rs232_rx_inst : rs232_rx
88 syn : process (clk, reset)
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');
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;
111 -------------------------- LESEN UND SCHREIBEN ANFANG ------------------------------------------------------------
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)
116 variable tmp_data : gp_register_t;
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;
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);
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);
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);
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);
140 case ext_reg.addr(1 downto 0) is
142 w1_st_co_nxt <= tmp_data;
144 w2_uart_config_nxt <= tmp_data;
146 w1_st_co_nxt(0) <= '1'; -- busy flag set
147 w3_uart_send_nxt <= tmp_data;
149 --w4_uart_receive_nxt <= tmp_data; sollte nur gelesen werden
154 if tx_rdy = '1' and tx_rdy_int = '0' then
155 w1_st_co_nxt(0) <= '0'; -- busy flag reset
158 if new_bus_rx = '1' then
159 w4_uart_receive_nxt(7 downto 0) <= rx_data;
160 w1_st_co_nxt(1) <= '1';
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';
170 gread : process (clk,ext_reg,w1_st_co,w2_uart_config,w3_uart_send,w4_uart_receive)
172 variable tmp_data : gp_register_t;
176 uart_data_read_nxt <= '0';
178 if ext_reg.sel = '1' and ext_reg.wr_en = '0' then
179 case ext_reg.addr(1 downto 0) is
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);
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);
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);
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);
194 data_out <= tmp_data;
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);
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);
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);
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);
209 data_out <= tmp_data;
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);
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);
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);
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);
224 data_out <= tmp_data;
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);
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);
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);
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);
240 data_out <= tmp_data;
244 data_out <= (others=>'0');
249 -------------------------- LESEN UND SCHREIBEN ENDE ---------------------------------------------------------------
251 -------------------------- INTERNE VERARBEITUNG ANFANG ------------------------------------------------------------
253 dataprocess : process (ext_reg,tx_rdy,w2_uart_config)
258 new_tx_data_nxt <= '0';
259 bd_rate <= w2_uart_config(15 downto 0);
261 if ext_reg.sel = '1' and ext_reg.wr_en = '1' then
262 case ext_reg.addr(1 downto 0) is
268 new_tx_data_nxt <= '1';
275 end process dataprocess;
279 -------------------------- INTERNE VERARBEITUNG ENDE --------------------------------------------------------------