-- `Deep Thought', a softcore CPU implemented on a FPGA -- -- Copyright (C) 2010 Markus Hofstaetter -- Copyright (C) 2010 Martin Perner -- Copyright (C) 2010 Stefan Rebernig -- Copyright (C) 2010 Manfred Schwarz -- Copyright (C) 2010 Bernhard Urban -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.extension_uart_pkg.all; use work.common_pkg.all; use work.core_pkg.all; architecture beh of rs232_tx is -- definierern der intern verwendeten Signale type STATE_TYPE is (IDLE,SEND); signal state, state_next : STATE_TYPE; signal bus_tx_int, bus_tx_nxt : std_logic := '1'; signal baud_cnt,baud_cnt_next : integer := 0; signal cnt, cnt_next : natural range 0 to 11 := 0; signal idle_sig, idle_sig_next : std_logic := '0'; begin -- syncronisierungs Prozess rs232_tx_syn : process(sys_clk, sys_res_n) begin if (sys_res_n = RESET_VALUE) then -- reset cnt <= 0; baud_cnt <= 0; state <= IDLE; idle_sig <= '0'; bus_tx_int <= '1'; baud_cnt <= 0; elsif rising_edge(sys_clk) then -- sync Zustand, uebernehmen der next-Signale baud_cnt <= baud_cnt_next; cnt <= cnt_next; state <= state_next; idle_sig <= idle_sig_next; bus_tx_int <= bus_tx_nxt; end if; end process; bus_tx <= bus_tx_int; -- Zustandsmaschienen Prozess rs232_tx_state : process(state, new_tx_data, idle_sig) begin state_next <= state; case state is when IDLE => -- wenn neue Sendedaten anliegen wird in den Zustand SEND gewechselt if new_tx_data = '1' then state_next <= SEND; end if; when SEND => -- wenn das Byte inklusive Start- und Stopbit versendet wurde, geht -- der Prozess wieder in den IDLE Zustand. if idle_sig = '1' then state_next <= IDLE; end if; end case; end process; -- Ausgabe Logik rs232_tx_baud : process(sys_clk, sys_res_n, state, baud_cnt, cnt, tx_data, bus_tx_int,stop_bit, bd_rate) begin -- Solang idle_sig auf 0 ist wird im SEND Zustand verblieben idle_sig_next <= '0'; bus_tx_nxt <= bus_tx_int; cnt_next <= cnt; -- Counter erhoehen um die Zeit einer Bitdauer abzuwarten baud_cnt_next <= baud_cnt + 1; case state is when IDLE => -- tx-Signale im idle Zustand halten tx_rdy <= '1'; cnt_next <= 0; -- TODO: wtf, typproblem baud_cnt_next <= to_integer(IEEE.numeric_std.unsigned(bd_rate)); --baud_cnt_next <= CLK_PER_BAUD; when SEND => -- Signalisiert dass gerade ein Byte versendet wird tx_rdy <= '0'; if baud_cnt = bd_rate then -- wenn die Bitdauer erreicht ist, Counter reseten baud_cnt_next <= 0; -- Counter um die einzelen Bits zu versenden cnt_next <= cnt + 1; case cnt is when 0 => -- counter = 0 => Startbit versenden bus_tx_nxt <= '0'; when 9 => -- counter = 9 => Stopbit versenden bus_tx_nxt <= '1'; when 10 => bus_tx_nxt <= '1'; -- stop_bit 1 heit 2 stop bits if stop_bit = '0' then cnt_next <= 0; -- Signalisieren dass der Sendevorgang beendet ist idle_sig_next <= '1'; end if; when 11 => bus_tx_nxt <= '1'; cnt_next <= 0; -- Signalisieren dass der Sendevorgang beendet ist idle_sig_next <= '1'; when others => -- counter von 1 bis 8 => Datenbits versenden bus_tx_nxt <= tx_data(cnt-1); end case; end if; end case; end process; end architecture beh;