From 2497f386feef0dca2099fa609d3c1e78db8c5206 Mon Sep 17 00:00:00 2001 From: Manfred Date: Fri, 17 Dec 2010 10:34:45 +0100 Subject: [PATCH] uart: rxd drin --- cpu/sim/testcore1.do | 2 + cpu/src/extension_uart.vhd | 2 +- cpu/src/extension_uart_b.vhd | 17 ++++ cpu/src/extension_uart_pkg.vhd | 24 ++++- cpu/src/rs232_rx.vhd | 40 +++++++++ cpu/src/rs232_rx_arc.vhd | 155 +++++++++++++++++++++++++++++++++ 6 files changed, 238 insertions(+), 2 deletions(-) create mode 100755 cpu/src/rs232_rx.vhd create mode 100755 cpu/src/rs232_rx_arc.vhd diff --git a/cpu/sim/testcore1.do b/cpu/sim/testcore1.do index 4df36d1..a4baa8d 100644 --- a/cpu/sim/testcore1.do +++ b/cpu/sim/testcore1.do @@ -40,6 +40,8 @@ vcom -work work ../src/extension_b.vhd vcom -work work ../src/extension_uart_pkg.vhd vcom -work work ../src/rs232_tx.vhd vcom -work work ../src/rs232_tx_arc.vhd +vcom -work work ../src/rs232_rx.vhd +vcom -work work ../src/rs232_rx_arc.vhd vcom -work work ../src/extension_uart.vhd vcom -work work ../src/extension_uart_b.vhd diff --git a/cpu/src/extension_uart.vhd b/cpu/src/extension_uart.vhd index 368f218..e928ad0 100644 --- a/cpu/src/extension_uart.vhd +++ b/cpu/src/extension_uart.vhd @@ -21,7 +21,7 @@ entity extension_uart is ext_reg : in extmod_rec; data_out : out gp_register_t; -- Input - + bus_rx : in std_logic; -- Ouput bus_tx : out std_logic ); diff --git a/cpu/src/extension_uart_b.vhd b/cpu/src/extension_uart_b.vhd index bf29728..7dc2892 100644 --- a/cpu/src/extension_uart_b.vhd +++ b/cpu/src/extension_uart_b.vhd @@ -38,6 +38,23 @@ port map( w1_st_co(0) ); +rs232_rx_inst : rs232_rx +generic map( + RESET_VALUE + ) +port map( + --System inputs + clk, + reset, + + --Bus + bus_rx, + + --From/to sendlogic + w1_st_co(17), + w4_uart_receive(byte_t'range) + +); diff --git a/cpu/src/extension_uart_pkg.vhd b/cpu/src/extension_uart_pkg.vhd index c9892bd..80df4b2 100644 --- a/cpu/src/extension_uart_pkg.vhd +++ b/cpu/src/extension_uart_pkg.vhd @@ -38,7 +38,7 @@ constant CLK_PER_BAUD : integer := 16330000; ext_reg : in extmod_rec; data_out : out gp_register_t; -- Input - + bus_rx : in std_logic; -- Ouput bus_tx : out std_logic ); @@ -67,4 +67,26 @@ component rs232_tx is ); end component rs232_tx; +component rs232_rx is + generic ( + -- active reset value + RESET_VALUE : std_logic + ); + + port( + --System inputs + sys_clk : in std_logic; + sys_res_n : in std_logic; + + --Bus + bus_rx : in std_logic; + + --To sendlogic + new_rx_data : out std_logic; + rx_data : out uart_data + ); +end component rs232_rx; + + + end package extension_uart_pkg; diff --git a/cpu/src/rs232_rx.vhd b/cpu/src/rs232_rx.vhd new file mode 100755 index 0000000..d363ac2 --- /dev/null +++ b/cpu/src/rs232_rx.vhd @@ -0,0 +1,40 @@ +--------------------------------------------------------------------------------- +-- Filename : rs232_rx.vhd +-- ========== +-- +-- Beschreibung : Empfang von Daten ueber die RS232 Schnittstelle +-- ============== +-- +-- Autoren : Martin Perner, Schwarz Manfred +-- ========= +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.std_logic_unsigned.all; +use IEEE.std_logic_arith.all; + +use work.common_pkg.all; +use work.core_pkg.all; +use work.extension_uart_pkg.all; + +entity rs232_rx is + generic ( + -- active reset value + RESET_VALUE : std_logic + ); + + port( + --System inputs + sys_clk : in std_logic; + sys_res_n : in std_logic; + + --Bus + bus_rx : in std_logic; + + --To sendlogic + new_rx_data : out std_logic; + rx_data : out uart_data + ); + +end rs232_rx; diff --git a/cpu/src/rs232_rx_arc.vhd b/cpu/src/rs232_rx_arc.vhd new file mode 100755 index 0000000..6cc9430 --- /dev/null +++ b/cpu/src/rs232_rx_arc.vhd @@ -0,0 +1,155 @@ +--------------------------------------------------------------------------------- +-- Filename : rs232_rx_arc.vhd +-- ========== +-- +-- Beschreibung : Empfang von Daten ueber die RS232 Schnittstelle +-- ============== +-- +-- Autoren : Martin Perner, Schwarz Manfred +-- ========= +---------------------------------------------------------------------------------- + +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.core_pkg.all; +use work.extension_uart_pkg.all; + +architecture beh of rs232_rx is + -- definierern der intern verwendeten Signale + type STATE_TYPE is (IDLE, READ_START, READ_BIT, READ_STOP, POST_STOP); + signal state, state_next : STATE_TYPE; + signal bus_rx_last, bus_rx_int, new_rx_data_nxt : std_logic := '0'; + signal cnt, cnt_next : integer := 0; + signal baud_cnt, baud_cnt_next : integer := 0; + signal rx_data_int, rx_data_nxt, rx_data_res_int, rx_data_res_nxt : uart_data; + +begin + -- syncronisierungs Prozess + rs232_rx_syn : process(sys_clk, sys_res_n) + begin + if (sys_res_n = RESET_VALUE) then + -- reset Zustand + state <= IDLE; + cnt <= 0; + rx_data_res_int <= x"00"; + + elsif rising_edge(sys_clk) then + -- sync Zustand, uebernehmen der next-Signale + state <= state_next; + cnt <= cnt_next; + baud_cnt <= baud_cnt_next; + bus_rx_int <= bus_rx_last; + rx_data_int <= rx_data_nxt; + rx_data_res_int <= rx_data_res_nxt; + new_rx_data <= new_rx_data_nxt; + + end if; + end process; + + -- setzen des Ausgangsignals, Rxt-Daten + rx_data <= rx_data_res_int; + + -- Zustandsmaschienen Prozess + rs232_states : process(sys_clk,state,cnt, bus_rx, bus_rx_last, baud_cnt,bus_rx_int) + begin + state_next <= state; -- mal schauen ob des so geht + bus_rx_last <= bus_rx; -- mal schauen ob des so geht + case state is + when IDLE => + -- nach einem Wechsel der rxt-Leitung von 1 auf 0 wird der einlese Vorgang + -- getriggert mithilfe eines Zustandsuebergangs von IDLE auf READ_START + if (bus_rx_last = '0' and bus_rx_int = '1') then + state_next <= READ_START; + end if; + when READ_START => + -- im READ_START Zustand wird eine halbe Bitzeit gewartet. Liegt auf der rxt-Leitung + -- immer noch die 0 an so wird mit deim Lesebvorgang mit einem Zustandswechsel von + -- READ_START nach READ_BIT vorgefahren, wenn eine 1 anliegt wird abgebrochen und + -- wieder nach IDLE gewechselt + if (bus_rx = '0' and baud_cnt = CLK_PER_BAUD/2) then + state_next <= READ_BIT; + elsif (bus_rx = '1' and baud_cnt = CLK_PER_BAUD/2) then + state_next <= IDLE; + end if; + when READ_BIT => + -- hier werden mit Hilfe eines Countersignals 8 Datenbits im Abstand der eingestellten + -- Bitzeit eingelesen und gespeichert. + -- Nach beendigung wird in den Zustand READ_STOP gewechselt. + if (cnt = 7 and baud_cnt = CLK_PER_BAUD) then + state_next <= READ_STOP; + else + state_next <= READ_BIT; + end if; + when READ_STOP => + -- hier wird nur noch auf das Stopbit abgewartet und gelesen um den + -- Lesevorgang koerrekt zu beenden + if baud_cnt = CLK_PER_BAUD and bus_rx = '1' then + state_next <= POST_STOP; + elsif baud_cnt = CLK_PER_BAUD and bus_rx = '0' then + state_next <= IDLE; + end if; + when POST_STOP => + -- hier wird nur noch eine halbe Bitzeit gewartet + if baud_cnt = CLK_PER_BAUD/2 then + state_next <= IDLE; + end if; + end case; + end process; + + -- Ausgabe Logik + rs232_tx_baud : process(state, cnt, bus_rx, baud_cnt, rx_data_int, rx_data_res_int) + begin + -- Signale halten um Latches zu vermeiden + cnt_next <= cnt; + new_rx_data_nxt <= '0'; + baud_cnt_next <= baud_cnt; + rx_data_nxt <= rx_data_int; + rx_data_res_nxt <= rx_data_res_int; + -- Statewechesel wie obenbeschrieben + case state is + when IDLE => + baud_cnt_next <= 0; + when READ_START => + -- baut_cnt zyklenweise erhoehen bis es einer halben Bitzeit entspricht + -- anschliessend zuruecksetzten + baud_cnt_next <= baud_cnt + 1; + if baud_cnt = CLK_PER_BAUD/2 then + baud_cnt_next <= 0; + rx_data_nxt <= x"00"; + end if; + when READ_BIT => + -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht + -- anschliessend zuruecksetzen + -- Zustand der rxt-Leitung im rx_data_nxt abspeichern + baud_cnt_next <= baud_cnt + 1; + if baud_cnt = CLK_PER_BAUD then + baud_cnt_next <= 0; + cnt_next <= cnt+1; + rx_data_nxt(cnt) <= bus_rx; + end if; + when READ_STOP => + -- baut_cnt zyklenweise erhoehen bis es einer Bitzeit entspricht + -- anschliessend zuruecksetzen + -- Counter reseten + -- Signal fuer neue rx-Daten setzen um die send_logic zu aktivieren + cnt_next <= 0; + baud_cnt_next <= baud_cnt + 1; + if baud_cnt = CLK_PER_BAUD then + baud_cnt_next <= 0; + end if; + when POST_STOP => + --halbe bitzeit wartenr auf counter warten + baud_cnt_next <= baud_cnt + 1; + if baud_cnt = CLK_PER_BAUD/2 then + new_rx_data_nxt <= '1'; + rx_data_res_nxt <= rx_data_int; + baud_cnt_next <= 0; + end if; + end case; + end process; + +end architecture beh; + -- 2.25.1