aboutsummaryrefslogtreecommitdiffstats
path: root/icestick/uart/hdl/uart_rx.vhd
blob: 5f488cc1e438ef1c02f2fb59a1bb58110853510d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
library ieee;
  use ieee.std_logic_1164.all;

entity uart_rx is
  generic (
    C_BITS           : integer := 8;
    C_CYCLES_PER_BIT : integer := 104
  );
  port (
    isl_clk    : in std_logic;
    isl_data_n : in std_logic;
    oslv_data  : out std_logic_vector(C_BITS-1 downto 0);
    osl_valid  : out std_logic
  );
end entity uart_rx;

architecture rtl of uart_rx is
  signal int_cycle_cnt : integer range 0 to C_CYCLES_PER_BIT-1 := 0;
  signal int_bit_cnt : integer range 0 to C_BITS+1 := 0;

  signal slv_data : std_logic_vector(C_BITS-1 downto 0) := (others => '0');
  signal sl_valid : std_logic := '0';

  type t_state is (IDLE, INIT, RECEIVE);
  signal state : t_state;

begin
  process(isl_clk)
  begin
    if rising_edge(isl_clk) then
      case state is
        when IDLE =>
          sl_valid <= '0';
          if isl_data_n = '0' then
            -- wait for the start bit
            state <= INIT;
          end if;
        
        when INIT =>
          int_cycle_cnt <= C_CYCLES_PER_BIT / 2;
          int_bit_cnt <= 0;
          state <= RECEIVE;

        when RECEIVE =>
          if int_bit_cnt < C_BITS+1 then
            if int_cycle_cnt < C_CYCLES_PER_BIT-1 then
              int_cycle_cnt <= int_cycle_cnt+1;
            else
              -- receive data bits
              int_cycle_cnt <= 0;
              int_bit_cnt <= int_bit_cnt+1;
              slv_data <= not isl_data_n & slv_data(slv_data'LEFT downto 1); -- low active
            end if;
          elsif isl_data_n = '1' then
            -- wait for the stop bit
            sl_valid <= '1';
            state <= IDLE;
          end if;

      end case;
    end if;
  end process;

  oslv_data <= slv_data;
  osl_valid <= sl_valid;
end architecture rtl;