]> rtime.felk.cvut.cz Git - fpga/uart.git/blobdiff - rx.vhd
First prototype of receiver shift register.
[fpga/uart.git] / rx.vhd
diff --git a/rx.vhd b/rx.vhd
new file mode 100644 (file)
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;
+