OpenCores
URL https://opencores.org/ocsvn/cortexi/cortexi/trunk

Subversion Repositories cortexi

[/] [cortexi/] [trunk/] [uart.vhd] - Blame information for rev 13

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 9 riedelx
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
 
6
-- uart baudrate
7
-- baudrate register = 1  =>  clk / 8
8
-- baudrate register = 2  =>  clk / 12
9
-- baudrate register = N  =>  clk / ((N + 1) * 4)
10
 
11
entity uart is
12
    Port ( clk     : in  std_logic;
13
           rst     : in  std_logic;
14
           datain  : in  std_logic_vector(7 downto 0);
15
           dataout : out std_logic_vector(7 downto 0);
16
           addr    : in  std_logic_vector(2 downto 0);
17
           cs      : in  std_logic;
18
           wr      : in  std_logic;
19
           serIn   : in  std_logic;
20
           serOut  : out std_logic);
21
end uart;
22
 
23
architecture Behavioral of uart is
24
 
25
  type UARTregisters is array (0 to 7) of std_logic_vector(7 downto 0);
26
  signal registers : UARTregisters;
27
  signal txBaud    : std_logic_vector(15 downto 0);
28
  signal rxBaud    : std_logic_vector(15 downto 0);
29
  signal txFSM     : std_logic_vector(3 downto 0);
30
  signal rxFSM     : std_logic_vector(3 downto 0);
31
  signal txTick    : std_logic_vector(2 downto 0);
32
  signal rxTick    : std_logic_vector(2 downto 0);
33
  signal txBit     : std_logic_vector(2 downto 0);
34
  signal rxBit     : std_logic_vector(2 downto 0);
35
  signal sendRequest : std_logic;
36
  signal serInput  : std_logic;
37
 
38
begin
39
 
40
  process(clk, rst)
41
  begin
42
    if falling_edge(clk) then
43
      if rst = '0' then
44
        for i in 0 to 7 loop
45
          registers(i) <= x"00";
46
        end loop;
47
        txBaud      <= x"0000";
48
        rxBaud      <= x"0000";
49
        dataout     <= x"00";
50
        sendRequest <= '0';
51
        txFSM  <= "0000";
52
        rxFSM  <= "0000";
53
        txTick <= "000";
54
        rxTick <= "000";
55
        txBit  <= "000";
56
        rxBit  <= "000";
57
        serOut <= '1';
58
        serInput <= '1';
59
      else
60
        serInput <= serIn;
61
-------- access to UART registers -----------------------
62
        if cs = '0' then   -- uart selected
63
          if wr = '0' then -- write access
64
            registers(conv_integer(addr)) <= datain;
65
            if addr = "000" then
66
              sendRequest <= '1';
67
            end if;
68
          else
69
            if addr = "001" then
70
              registers(4)(1) <= '0'; -- data ready
71
              registers(4)(2) <= '0'; -- frame error
72
            end if;
73
            dataout <= registers(conv_integer(addr));
74
          end if;
75
        end if;
76
-------- baudrate ---------------------------------------
77
        txBaud <= txBaud + 1;
78
        if txBaud = (registers(2) & registers(3)) then
79
          txBaud <= x"0000";
80
        end if;
81
        rxBaud <= rxBaud + 1;
82
        if rxBaud = (registers(2) & registers(3)) then
83
          rxBaud <= x"0000";
84
        end if;
85
-------- transmitter ------------------------------------
86
        case txFSM is
87
          when "0000" => --##### tx idle #####
88
            if sendRequest = '1' then
89
              registers(4)(0) <= '1'; -- tx busy
90
              sendRequest <= '0';
91
              txFSM  <= "0001";
92
              txBaud <= x"0000";
93
              txTick <= "000";
94
              txBit  <= "000";
95
              serOut <= '0';  -- start bit
96
            end if;
97
          when "0001" => --##### send start bit #####
98
            if txBaud = x"0000" then
99
              txTick <= txTick + 1;
100
              if txTick = "011" then
101
                txTick <= "000";
102
                txFSM  <= "0010";
103
                serOut <= registers(0)(conv_integer(txBit));
104
                txBit  <= txBit + 1;
105
              end if;
106
            end if;
107
          when "0010" => --##### send data bits #####
108
            if txBaud = x"0000" then
109
              txTick <= txTick + 1;
110
              if txTick = "011" then
111
                txTick <= "000";
112
                serOut <= registers(0)(conv_integer(txBit));
113
                txBit  <= txBit + 1;
114
                if txBit = "111" then
115
                  txFSM <= "0011";
116
                end if;
117
              end if;
118
            end if;
119
          when "0011" => --##### send stop bit #####
120
            if txBaud = x"0000" then
121
              txTick <= txTick + 1;
122
              if txTick = "011" then
123
                txTick <= "000";
124
                serOut <= '1';
125
                txFSM  <= "0100";
126
              end if;
127
            end if;
128
          when "0100" => --##### finishing stop bit #####
129
            if txBaud = x"0000" then
130
              txTick <= txTick + 1;
131
              if txTick = "011" then
132
                txFSM <= "0000";
133
                registers(4)(0) <= '0'; -- tx ready
134
              end if;
135
            end if;
136
          when others =>
137
            txFSM <= "0000";
138
        end case; -- txFSM
139
-------- receiver ------------------------------------
140
        case rxFSM is
141
          when "0000" => --##### awaiting start bit #####
142
            if serInput = '0' then
143
              rxBaud <= x"0000";
144
              rxTick <= "000";
145
              rxFSM  <= "0001";
146
            end if;
147
          when "0001" => --##### cnt to middle start bit #####
148
            if rxBaud = x"0000" then
149
              rxTick <= rxTick + 1;
150
              if rxTick = "001" then
151
                if serInput = '1' then -- false start bit
152
                  rxFSM <= "0000";
153
                else
154
                  rxTick <= "000";
155
                  rxBit  <= "000";
156
                  rxFSM  <= "0010";
157
                end if;
158
              end if;
159
            end if;
160
          when "0010" => --##### receive bits ######
161
            if rxBaud = x"0000" then
162
              rxTick <= rxTick + 1;
163
              if rxTick = "011" then
164
                rxTick <= "000";
165
                registers(1)(conv_integer(rxBit)) <= serInput;
166
                rxBit <= rxBit + 1;
167
                if rxBit = "111" then -- last bit
168
                  rxFSM <= "0011";
169
                end if;
170
              end if;
171
            end if;
172
          when "0011" => --##### receive stop bit #####
173
            if rxBaud = x"0000" then
174
              rxTick <= rxTick + 1;
175
              if rxTick = "011" then
176
                if serInput = '0' then
177
                  registers(4)(2) <= '1'; -- frame error
178
                else
179
                  registers(4)(1) <= '1'; -- data ready
180
                end if;
181
                rxFSM <= "0000";
182
              end if;
183
            end if;
184
          when others =>
185
            rxFSM <= "0000";
186
        end case; -- rxFSM
187
      end if; -- rst = '0'
188
    end if; -- rising_edge(clk)
189
  end process;
190
 
191
end Behavioral;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.