From 3c7195008725d62225052f655609abc96027528b Mon Sep 17 00:00:00 2001 From: Vladimir Burian Date: Fri, 28 Jan 2011 17:13:40 +0100 Subject: [PATCH] First prototype of receiver shift register. --- rx.vhd | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++++ tb/Makefile | 3 +- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 rx.vhd diff --git a/rx.vhd b/rx.vhd new file mode 100644 index 0000000..5a7bde6 --- /dev/null +++ b/rx.vhd @@ -0,0 +1,95 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +-------------------------------------------------------------------------------- +-- Input shift register +-- +-- It is used to receive a serial asynchronous frame. In the steady state, the +-- signal 'ready' is set, the 'data' output vector and signals 'bad_start_bit' +-- and 'bad_stop_bit' contains valid values of the last received frame. +-- +-- Receiving is done by the following procedure: +-- - wait until 'ready' = 1 +-- - set 'en' and raise 'clk' positive edge (1st bit is sampled) +-- - 'ready' goes to 0 +-- - continue generating clock signal until 'ready' = 1 again +-- - frame is received +-- +-- All operations, 'rx' sampling, etc. (except for reset) are synchronous to +-- 'clk' rising egdes. +-- +-- Invalid start bit is signalized at the begining of the frame, so the +-- receiving can be immediately stopped by receiver reset. +-------------------------------------------------------------------------------- + +entity receiver is + port ( + clk : in std_logic; + reset : in std_logic; + en : in std_logic; + rx : in std_logic; + ready : out std_logic; + bad_start_bit : out std_logic; + bad_stop_bit : out std_logic; + data : out std_logic_vector (7 downto 0)); +end entity receiver; + +-------------------------------------------------------------------------------- + +architecture behavioral of receiver is + + signal rx_shift_reg : std_logic_vector (9 downto 0); + signal rx_flag : std_logic_vector (9 downto 0); + signal rx_ready : std_logic; + signal rx_running : std_logic; + +-------------------------------------------------------------------------------- + +begin + + process (clk, reset) is + begin + if reset = '1' then + rx_ready <= '1'; + rx_running <= '0'; + + bad_stop_bit <= '0'; + bad_start_bit <= '0'; + + elsif clk'event and clk = '1' then + -- Start receiving a new frame + if rx_ready = '1' and en = '1' then + rx_shift_reg <= rx & rx_shift_reg (9 downto 1); + rx_flag <= "0100000000"; + rx_ready <= '0'; + rx_running <= '1'; + + bad_start_bit <= rx; + bad_stop_bit <= '0'; + + -- Receiving of the 1st data bit and all its consequents + elsif rx_running = '1' then + rx_shift_reg <= rx & rx_shift_reg (9 downto 1); + rx_flag <= '0' & rx_flag (9 downto 1); + + -- End of the frame is comming + if rx_flag (0) = '1' then + rx_ready <= '1'; + rx_running <= '0'; + + bad_stop_bit <= not rx; + end if; + end if; + + end if; + end process; + +-------------------------------------------------------------------------------- + + data <= rx_shift_reg (8 downto 1); + ready <= rx_ready; + +end architecture behavioral; + diff --git a/tb/Makefile b/tb/Makefile index 351eb42..88f78a0 100644 --- a/tb/Makefile +++ b/tb/Makefile @@ -3,7 +3,8 @@ VHDL_ENTITIES = uart.o \ tx.o \ fifo.o \ baud_gen.o \ - tx_control.o + tx_control.o \ + rx.o STOP_TIME = 50us -- 2.39.2