From 3e8a43d9f939026ba7fbd109043772fad8bb6787 Mon Sep 17 00:00:00 2001 From: Alexander Oh Date: Wed, 19 May 2010 20:52:10 +0200 Subject: [PATCH] initial uart_rx --- src/Makefile | 2 +- src/beh_uart_rx.do | 56 ++++++++++++++++ src/beh_uart_rx.vhd | 57 ++++++++++++++++ src/uart_rx.vhd | 157 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 271 insertions(+), 1 deletion(-) create mode 100644 src/beh_uart_rx.do create mode 100644 src/beh_uart_rx.vhd create mode 100644 src/uart_rx.vhd diff --git a/src/Makefile b/src/Makefile index 461f4a8..10f5e59 100644 --- a/src/Makefile +++ b/src/Makefile @@ -24,7 +24,7 @@ WORK := work # o source files der module # o reihenfolge ist wichtig # o keine testbechnes hier angeben -SRCFILES := alu parser scanner display sp_ram history uart_tx +SRCFILES := alu parser scanner display sp_ram history uart_tx uart_rx # o files der packages # o keine testbechnes hier angeben diff --git a/src/beh_uart_rx.do b/src/beh_uart_rx.do new file mode 100644 index 0000000..4f70701 --- /dev/null +++ b/src/beh_uart_rx.do @@ -0,0 +1,56 @@ +#alias fuer simulation neustarten +alias rr "restart -f" + +#signale hinzufuegen +add wave inst/* + +delete wave /beh_parser_tb/inst/op1_int +delete wave /beh_parser_tb/inst/op1 +delete wave /beh_parser_tb/inst/op1_next +add wave -radix decimal inst/op1_int + +delete wave /beh_parser_tb/inst/op2_int +delete wave /beh_parser_tb/inst/op2 +delete wave /beh_parser_tb/inst/op2_next +add wave -radix decimal inst/op2_int + +delete wave /beh_parser_tb/inst/op3 +add wave -radix decimal inst/op3 +delete wave /beh_parser_tb/inst/opM +add wave -radix decimal inst/opM + +delete wave /beh_parser_tb/inst/z_int +delete wave /beh_parser_tb/inst/z_next +add wave -radix decimal inst/z_int +add wave -radix decimal inst/z_next + +delete wave /beh_parser_tb/inst/strich_int +delete wave /beh_parser_tb/inst/strich_next +add wave -radix decimal inst/strich_int +add wave -radix decimal inst/strich_next + +delete wave /beh_parser_tb/inst/punkt_int +delete wave /beh_parser_tb/inst/punkt_next +add wave -radix decimal inst/punkt_int +add wave -radix decimal inst/punkt_next + +delete wave /beh_parser_tb/inst/wtmp_int +delete wave /beh_parser_tb/inst/wtmp_next +add wave -radix decimal inst/wtmp_int +add wave -radix decimal inst/wtmp_next + +delete wave /beh_parser_tb/inst/p_write_int +delete wave /beh_parser_tb/inst/p_write_next +delete wave /beh_parser_tb/inst/p_write +add wave -hex inst/p_write_int +add wave -hex inst/p_write_next + + +#rauszoomen +wave zoomout 500.0 + +#simulation starten und 100ms lang laufen lassen (wird durch assert abgebrochen) +run -all + +#ganz nach links scrollen +wave seetime 0 diff --git a/src/beh_uart_rx.vhd b/src/beh_uart_rx.vhd new file mode 100644 index 0000000..c3394ce --- /dev/null +++ b/src/beh_uart_rx.vhd @@ -0,0 +1,57 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +use work.gen_pkg.all; + +entity beh_uart_rx_tb is +end entity beh_uart_rx_tb; + +architecture sim of beh_uart_rx_tb is + + constant clk_period : time := 2ns; + signal clock : std_logic; + signal reset : std_logic; + signal done : std_logic; + signal newsig : std_logic; + signal data : std_logic_vector(7 downto 0); + signal serial_out : std_logic; +begin + inst : entity work.uart_tx(beh) + port map ( + sys_clk => clock, + sys_res => reset, + txd => serial_out, + tx_data => data, + tx_new => newsig, + tx_done => done + ); + + stimuli : process + begin + newsig <= '0'; + wait for 10ns; + --send 'Hallo Welt' + data <= X"42"; --'B' + newsig <= '1'; + wait for 1000ns; + + assert false report "Test finished" severity failure; + end process stimuli; + + res_gen : process + begin + reset <= '0'; + wait for 20ns; + reset <= '1'; + wait for 1000ns; + end process res_gen; + + clock_gen : process + begin + clock <= '0'; + wait for clk_period/2; + clock <= '1'; + wait for clk_period/2; + end process clock_gen; + +end sim; diff --git a/src/uart_rx.vhd b/src/uart_rx.vhd new file mode 100644 index 0000000..90dcedc --- /dev/null +++ b/src/uart_rx.vhd @@ -0,0 +1,157 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.numeric_std.all; +--use work.gen_pkg.all; + +--package int_types is +-- type STATE_UART_RX is (IDLE, BUSY, DONE); +--end package int_types; + +entity uart_rx is +port( + sys_clk : in std_logic; + sys_res : in std_logic; + txd : in std_logic; -- warning: this is asynchronous input! + tx_data : out std_logic_vector(7 downto 0); -- map this to a larger register with containing input + tx_new : out std_logic; +); +end entity uart_rx; + +architecture beh of uart_rx is + constant timer_max : integer := 35; + + signal timer, timer_next : integer range 0 to 65535; + signal counter, counter_next : integer range 0 to 15; + signal state, state_next : STATE_UART_RX; + signal tx_data_pref : std_logic_vector(7 downto 0); -- FIXME: this isnt named next so that the interface isn't called tx_data_next ... + +begin +--FIXME: + process(sys_clk, sys_res_n) + begin + if sys_res_n = ‘0‘ then + -- Set reset state + state <= IDLE; + tx_data_prev <= X"0"; + elsif rising_edge(sys_clk) then + -- Store next state + state <= state_next; + tx_data_prev <= tx_data; + end if; + end process; + + process(state, txd, counter) + begin + state_next <= state; + case state is + when IDLE => + if (txd = 0) then + state_next <= BUSY; + else + state_next <= IDLE; + end if; + when BUSY => + if (counter = 9) then --FIXME: is this true? + state_next <= DONE; + else + state_next <= BUSY; + end if; + when DONE => + state_next <= IDLE; + end case; + end process; + + process(state) + begin + -- Set default values + -- for the outputs + tx_new <= ‘0‘; + + -- Calculate the outputs + -- based on the current + -- state + case state is + when IDLE => + tx_new <= ‘0‘; + when BUSY => + tx_new <= ‘0‘; + case (counter) + tx_data(counter-2) <= txd; + end case; + when DONE => + tx_new <= '1'; + end case; + end process; +-- END FIXME: do fill this out CORRECTLY + + process (sys_clk, sys_res) + begin + if sys_res = '0' then + counter <= 0; + timer <= 0; + elsif rising_edge(sys_clk) then + counter <= counter_next; + timer <= timer_next; + end if; + end process; + + process(timer) + begin + if (timer = timer_max) then + timer_next <= 0; + else + timer_next <= timer + 1; + end if; + end process; + + process (timer, counter, tx_new) + begin + if (tx_new = '1') then + if (timer = timer_max) then + if (counter > 10) then + counter_next <= 0; + else + counter_next <= counter + 1; + end if; + else + counter_next <= counter; + end if; + else + counter_next <= 0; + end if; + end process; + + process (counter, txd) + begin + tx_data <= tx_data_prev; + -- TODO: we probably want oversampling and averaging + failure! + -- FIXME: this is per se not synthesisable + case (counter) is + when 0 => --start bit + assert (txd = '0'); + when 1 => + tx_data(0) <= txd; + when 2 => + tx_data(1) <= txd; + when 3 => + tx_data(2) <= txd; + when 4 => + tx_data(3) <= txd; + when 5 => + tx_data(4) <= txd; + when 6 => + tx_data(5) <= txd; + when 7 => + tx_data(6) <= txd; + when 8 => + tx_data(7) <= txd; + when 9 => -- stop bit + assert (txd = '1'); + when others => -- idle + assert (txd = '1'); + end case; + end process; + + tx_done <= '0'; + +end architecture beh; -- 2.25.1