aboutsummaryrefslogtreecommitdiffstats
path: root/doc/using/UART_srcs/rx/UART_RX_8N1.vhd
blob: a7fe757a5c4fa9eec0849f393637123764445510 (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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
-- UART_RX_8N1.vhd
----------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;


entity UART_8N1_RX is

  generic (clk_freq : integer;
           baudrate : integer);
  port(
    clk           : in  std_logic;
    reset         : in  std_logic;
    --8bit interface
    rdata         : out std_logic_vector(7 downto 0);
    rd            : in  std_logic;
    rd_en         : out std_logic;
    --physical wire RX
    rx            : in  std_logic
    );
end UART_8N1_RX;


architecture Behavioral of UART_8N1_RX is

  type   state_type is (idle, start, data0, data1, data2, data3, data4,
   data5, data6, data7, stop);
  signal state : state_type;

  signal puffer : std_logic_vector (7 downto 0);

--FIFO
  type RAM is array (0 to 63) of std_logic_vector (7 downto 0);

  signal fifo : RAM ;

  signal nextwrite    : unsigned(5 downto 0);
  signal nextread     : unsigned(5 downto 0);

  constant tick       : integer := clk_freq/baudrate;
  signal tick_counter : integer range 0 to (tick+1);
 

begin
  
  rdata  <= fifo(to_integer(nextread));
  
  process (clk)
  begin
    if rising_edge(clk) then
      if rd = '1'  then
        nextread <= nextread+1;
      end if;
      if reset = '1' then 
        nextread <= (others => '0');
      end if;			  
    end if;
  end process;

 rd_en<= '0' when  nextread=nextwrite else '1';
 

  process(clk)
  begin
    
    if (clk'event and clk = '1') then
      tick_counter <= tick_counter + 1;

      case state is
        
        when idle =>
          tick_counter <= 0;
          if (rx = '0') then  --check start condtion
            state <= start;
          else
            state <= idle;
          end if;
            
        when start =>
          if (tick_counter = tick/2) then  --capture in the middle
            tick_counter <= 0;
            state        <= data0;
          end if;
          
        when data0 =>
          if (tick_counter = tick) then
            puffer (0)   <= rx;
            tick_counter <= 0;
            state        <= data1;
          end if;
        when data1 =>
          if (tick_counter = tick) then
            puffer (1)   <= rx;
            tick_counter <= 0;
            state        <= data2;
          end if;
        when data2 =>
          if (tick_counter = tick) then
            puffer (2)   <= rx;
            tick_counter <= 0;
            state        <= data3;
          end if;
        when data3 =>
          if (tick_counter = tick) then
            puffer(3)    <= rx;
            tick_counter <= 0;
            state        <= data4;
          end if;
        when data4 =>
          if (tick_counter = tick) then
            puffer (4)   <= rx;
            tick_counter <= 0;
            state        <= data5;
          end if;
        when data5 =>
          if (tick_counter = tick) then
            puffer (5)   <= rx;
            tick_counter <= 0;
            state        <= data6;
          end if;
        when data6 =>
          if (tick_counter = tick) then
            puffer (6)   <= rx;
            tick_counter <= 0;
            state        <= data7;
          end if;
        when data7 =>
          if (tick_counter = tick) then
            puffer (7)   <= rx;
            tick_counter <= 0;
            state        <= stop;
          end if;
        when stop =>
          if (tick_counter = tick) then
            fifo(to_integer(nextwrite)) <= puffer;
            nextwrite                   <= nextwrite+1;
            tick_counter <= 0;
            state        <= idle;
          end if;
      end case;
      if reset='1' then
        state <=idle;
        nextwrite <= (others => '0');
      end if;
    end if;

  end process;
end Behavioral;