copyleft: gplv3 added and set repo to public
[calu.git] / cpu / src / rs232_tx_arc.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.extension_uart_pkg.all;
27
28 use work.common_pkg.all;
29 use work.core_pkg.all;
30
31 architecture beh of rs232_tx is
32         -- definierern der intern verwendeten Signale
33         type STATE_TYPE is (IDLE,SEND);
34         signal state, state_next : STATE_TYPE;
35         signal bus_tx_int, bus_tx_nxt : std_logic := '1';
36         signal baud_cnt,baud_cnt_next : integer := 0;
37         signal cnt, cnt_next : natural range 0 to 11 := 0;
38         signal idle_sig, idle_sig_next : std_logic := '0';
39         
40 begin
41         -- syncronisierungs Prozess
42         rs232_tx_syn : process(sys_clk, sys_res_n)
43         begin
44                 if (sys_res_n = RESET_VALUE) then
45                         -- reset
46                         cnt <= 0;
47                         baud_cnt <= 0;
48                         state <= IDLE;
49                         idle_sig <= '0';
50                         bus_tx_int <= '1';
51                         baud_cnt <= 0;
52                 elsif rising_edge(sys_clk) then
53                         -- sync Zustand, uebernehmen der next-Signale
54                         baud_cnt <= baud_cnt_next;
55                         cnt <= cnt_next;
56                         state <= state_next;
57                         idle_sig <= idle_sig_next;
58                         bus_tx_int <= bus_tx_nxt;
59                 end if;
60         end process;
61
62         bus_tx <= bus_tx_int;
63
64         -- Zustandsmaschienen Prozess
65         rs232_tx_state : process(state, new_tx_data, idle_sig)
66         begin
67                 state_next <= state;
68                 case state is
69                         when IDLE =>
70                                 -- wenn neue Sendedaten anliegen wird in den Zustand SEND gewechselt
71                                 if new_tx_data = '1' then
72                                         state_next <= SEND;
73                                 end if;
74                         when SEND =>
75                                 -- wenn das Byte inklusive Start- und Stopbit versendet wurde, geht 
76                                 -- der Prozess wieder in den IDLE Zustand.
77                                 if idle_sig = '1' then
78                                         state_next <= IDLE;
79                                 end if;
80                         end case;
81         end process;
82
83         -- Ausgabe Logik
84         rs232_tx_baud : process(sys_clk, sys_res_n, state, baud_cnt, cnt, tx_data, bus_tx_int,stop_bit, bd_rate)
85         begin 
86                 -- Solang idle_sig auf 0 ist wird im SEND Zustand verblieben
87                 idle_sig_next <= '0';
88                 bus_tx_nxt <= bus_tx_int;
89                 cnt_next <= cnt;
90                 -- Counter erhoehen um die Zeit einer Bitdauer abzuwarten
91                 baud_cnt_next <= baud_cnt + 1;
92
93                 case state is
94                         when IDLE =>
95                                 -- tx-Signale im idle Zustand halten
96                                 tx_rdy <= '1';
97                                 cnt_next <= 0;
98                                 -- TODO: wtf, typproblem
99                                 baud_cnt_next <= to_integer(IEEE.numeric_std.unsigned(bd_rate));
100                                 --baud_cnt_next <= CLK_PER_BAUD;
101                         when SEND =>
102                                 -- Signalisiert dass gerade ein Byte versendet wird 
103                                 tx_rdy <= '0';
104                                 if baud_cnt = bd_rate then 
105                                         -- wenn die Bitdauer erreicht ist, Counter reseten
106                                         baud_cnt_next <= 0;
107                                         -- Counter um die einzelen Bits zu versenden
108                                         cnt_next <= cnt + 1;
109                                         case cnt is
110                                                 when 0 =>
111                                                         -- counter = 0 => Startbit versenden
112                                                         bus_tx_nxt <= '0';
113                                                 when 9 =>
114                                                         -- counter = 9 => Stopbit versenden
115                                                         bus_tx_nxt <= '1';
116                                                 when 10 =>
117                                                         bus_tx_nxt <= '1';
118                                                         -- stop_bit 1 heit 2 stop bits
119                                                         if stop_bit = '0' then 
120                                                                 cnt_next <= 0;
121                                                                 -- Signalisieren dass der Sendevorgang beendet ist
122                                                                 idle_sig_next <= '1';
123                                                         end if;
124                                                 when 11 => 
125                                                         bus_tx_nxt <= '1';
126                                                         cnt_next <= 0;
127                                                         -- Signalisieren dass der Sendevorgang beendet ist
128                                                         idle_sig_next <= '1';
129                                                 when others =>
130                                                         -- counter von 1 bis 8 => Datenbits versenden
131                                                         bus_tx_nxt <= tx_data(cnt-1);
132                                         end case;
133                                 end if;
134                 end case;
135         end process;
136
137 end architecture beh;