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

Subversion Repositories rio

[/] [rio/] [trunk/] [rtl/] [vhdl/] [Uart.vhd] - Blame information for rev 49

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

Line No. Rev Author Line
1 20 magro732
-------------------------------------------------------------------------------
2
-- 
3
-- RapidIO IP Library Core
4
-- 
5
-- This file is part of the RapidIO IP library project
6
-- http://www.opencores.org/cores/rio/
7
-- 
8
-- Description
9
-- Generic UART with FIFO interface.
10
--
11
-- To Do:
12
-- -
13
-- 
14
-- Author(s): 
15
-- - Magnus Rosenius, magro732@opencores.org 
16
-- 
17
-------------------------------------------------------------------------------
18
-- 
19
-- Copyright (C) 2013 Authors and OPENCORES.ORG 
20
-- 
21
-- This source file may be used and distributed without 
22
-- restriction provided that this copyright statement is not 
23
-- removed from the file and that any derivative work contains 
24
-- the original copyright notice and the associated disclaimer. 
25
-- 
26
-- This source file is free software; you can redistribute it 
27
-- and/or modify it under the terms of the GNU Lesser General 
28
-- Public License as published by the Free Software Foundation; 
29
-- either version 2.1 of the License, or (at your option) any 
30
-- later version. 
31
-- 
32
-- This source is distributed in the hope that it will be 
33
-- useful, but WITHOUT ANY WARRANTY; without even the implied 
34
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
35
-- PURPOSE. See the GNU Lesser General Public License for more 
36
-- details. 
37
-- 
38
-- You should have received a copy of the GNU Lesser General 
39
-- Public License along with this source; if not, download it 
40
-- from http://www.opencores.org/lgpl.shtml 
41
-- 
42
-------------------------------------------------------------------------------
43
 
44
-------------------------------------------------------------------------------
45
-- Uart implementation.
46
-------------------------------------------------------------------------------
47
 
48
library ieee;
49
use ieee.std_logic_1164.all;
50
use ieee.numeric_std.all;
51
 
52
 
53
-------------------------------------------------------------------------------
54
-- Entity for Uart.
55
-------------------------------------------------------------------------------
56
entity Uart is
57
  generic(
58
    DIVISOR_WIDTH : natural;
59
    DATA_WIDTH : natural);
60
  port(
61
    clk : in std_logic;
62
    areset_n : in std_logic;
63
 
64
    divisor_i : in std_logic_vector(DIVISOR_WIDTH-1 downto 0);
65
 
66
    serial_i : in std_logic;
67
    serial_o : out std_logic;
68
 
69
    empty_o : out std_logic;
70
    read_i : in std_logic;
71
    data_o : out std_logic_vector(DATA_WIDTH-1 downto 0);
72
 
73
    full_o : out std_logic;
74
    write_i : in std_logic;
75
    data_i : in std_logic_vector(DATA_WIDTH-1 downto 0));
76
end entity;
77
 
78
 
79
-------------------------------------------------------------------------------
80
-- Architecture for Uart.
81
-------------------------------------------------------------------------------
82
architecture UartImpl of Uart is
83
  signal bitDuration : unsigned(DIVISOR_WIDTH-1 downto 0);
84
  signal bitSample : unsigned(DIVISOR_WIDTH-1 downto 0);
85
 
86
  type StateTypeRx is (STATE_INIT, STATE_IDLE,
87
                       STATE_START, STATE_DATA, STATE_STOP);
88
  signal rxState : StateTypeRx;
89
  signal rxShifter : std_logic_vector(DATA_WIDTH-1 downto 0);
90
  signal rxCounter : unsigned(DIVISOR_WIDTH-1 downto 0);
91
  signal rxBitCounter : natural range 0 to DATA_WIDTH-1;
92
  signal rxComplete : std_logic;
93
  signal rxData : std_logic_vector(DATA_WIDTH-1 downto 0);
94
 
95
  type StateTypeRxFifo is (STATE_EMPTY, STATE_WAITREAD);
96
  signal rxFifoState : StateTypeRxFifo;
97
 
98
  type StateTypeTx is (STATE_IDLE, STATE_SEND);
99
  signal txState : StateTypeTx;
100
  signal txShifter : std_logic_vector(DATA_WIDTH downto 0);
101
  signal txCounter : unsigned(DIVISOR_WIDTH-1 downto 0);
102
  signal txBitCounter : natural range 0 to DATA_WIDTH+1;
103
 
104
begin
105
 
106
  -- Setup the tick values when a bit is complete and when to sample it.
107
  bitDuration <= unsigned(divisor_i);
108
  bitSample <= '0' & unsigned(divisor_i(DIVISOR_WIDTH-1 downto 1));
109
 
110
  -----------------------------------------------------------------------------
111
  -- UART receiving process.
112
  -----------------------------------------------------------------------------
113
  Receiver: process(clk, areset_n)
114
  begin
115
    if (areset_n = '0') then
116
      rxState <= STATE_INIT;
117
      rxShifter <= (others => '0');
118
      rxBitCounter <= 0;
119
      rxCounter <= (others => '0');
120
 
121
      rxComplete <= '0';
122
      rxData <= (others => '0');
123
    elsif (clk'event and (clk = '1')) then
124
      rxComplete <= '0';
125
 
126
      case rxState is
127
 
128
        when STATE_INIT =>
129
          ---------------------------------------------------------------------
130
          -- Wait for the line to become idle.
131
          ---------------------------------------------------------------------
132
          if (serial_i = '1') then
133
            rxState <= STATE_IDLE;
134
          end if;
135
 
136
        when STATE_IDLE =>
137
          ---------------------------------------------------------------------
138
          -- Wait for a long enough start pulse.
139
          ---------------------------------------------------------------------
140
          if (serial_i = '0') then
141
            -- The serial input is zero, indicating a start bit.
142
 
143
            -- Check how long it has been zero.
144
            if (rxCounter = bitSample) then
145
              -- It has been zero long enough.
146
              -- Proceed to read the full start bit before starting to sample
147
              -- the data.
148
              rxState <= STATE_START;
149
            else
150
              -- Stay in this state until it has lasted long enough.
151
            end if;
152
 
153
            -- Update to next sampling interval.
154
            rxCounter <= rxCounter + 1;
155
          else
156
            -- The serial input is not zero.
157
            -- Restart the sampling interval.
158
            rxCounter <= (others => '0');
159
          end if;
160
 
161
        when STATE_START =>
162
          ---------------------------------------------------------------------
163
          -- Wait for the startbit to end.
164
          ---------------------------------------------------------------------
165
          if (rxCounter = bitDuration) then
166
            rxCounter <= (others => '0');
167
            rxState <= STATE_DATA;
168
          else
169
            rxCounter <= rxCounter + 1;
170
          end if;
171
 
172
        when STATE_DATA =>
173
          ---------------------------------------------------------------------
174
          -- Sample data bits where it's appropriate.
175
          ---------------------------------------------------------------------
176
          if (rxCounter = bitDuration) then
177
            -- End of bit.
178
            -- Check if all the data bits has been read.
179
            if (rxBitCounter = (DATA_WIDTH-1)) then
180
              -- All data bits read.
181
              -- Read the stop bit.
182
              rxState <= STATE_STOP;
183
              rxBitCounter <= 0;
184
            else
185
              -- Continue to read more data bits.
186
              rxBitCounter <= rxBitCounter + 1;
187
            end if;
188
 
189
            -- Restart sampling interval.
190
            rxCounter <= (others => '0');
191
          elsif (rxCounter = bitSample) then
192
            -- Sample the bit and continue to sample until the bit ends.
193
            rxShifter <= serial_i & rxShifter((DATA_WIDTH-1) downto 1);
194
            rxCounter <= rxCounter + 1;
195
          else
196
            -- Wait for the middle or the end of the data to be reached.
197
            rxCounter <= rxCounter + 1;
198
          end if;
199
 
200
        when STATE_STOP =>
201
          ---------------------------------------------------------------------
202
          -- Sample stop bit where it's appropriate.
203
          ---------------------------------------------------------------------
204
          if (rxCounter = bitSample) then
205
            -- Sample the stop bit.
206
 
207
            -- Check if the stop bit is valid.
208
            if (serial_i = '1') then
209
              -- The stop bit is ok.
210
              -- Forward the read data.
211
              rxComplete <= '1';
212
              rxData <= rxShifter;
213
            else
214
              -- The stop bit is not ok.
215
              -- Do not forward the data character.
216
            end if;
217
 
218
            -- Reset sampling counter and go back to the init state.
219
            rxState <= STATE_INIT;
220
            rxCounter <= (others => '0');
221
          else
222
            -- Wait for the middle or the end of the data to be reached.
223
            rxCounter <= rxCounter + 1;
224
          end if;
225
 
226
        when others =>
227
          ---------------------------------------------------------------------
228
          -- Undefined state.
229
          ---------------------------------------------------------------------
230
          rxState <= STATE_IDLE;
231
          rxCounter <= (others => '0');
232
 
233
      end case;
234
    end if;
235
  end process;
236
 
237
  -----------------------------------------------------------------------------
238
  -- UART receiver fifo.
239
  -----------------------------------------------------------------------------
240
  ReceiverFifo: process(clk, areset_n)
241
  begin
242
    if (areset_n = '0') then
243
      empty_o <= '1';
244
      data_o <= (others => '0');
245
      rxFifoState <= STATE_EMPTY;
246
    elsif (clk'event and (clk = '1')) then
247
      case rxFifoState is
248
 
249
        when STATE_EMPTY =>
250
          -- Wait for data to be forwarded from the UART receiver.
251
          if (rxComplete = '1') then
252
            -- Indicate there is data to read from.
253
            empty_o <= '0';
254
            data_o <= rxData;
255
            rxFifoState <= STATE_WAITREAD;
256
          else
257
            -- Wait for data to be received.
258
          end if;
259
 
260
        when STATE_WAITREAD =>
261
          -- Wait for the data to be read from the output port.
262
          if (read_i = '1') then
263
            -- The data has been read.
264
            empty_o <= '1';
265
            rxFifoState <= STATE_EMPTY;
266
          end if;
267
          -- Check if new data has been forwarded from the UART.
268
          if (rxComplete = '1') then
269
            -- New data has been forwarded without the output port being read.
270
            -- Overrun. Data has been lost.
271
            -- REMARK: Indicate this???
272
          end if;
273
 
274
        when others =>
275
          -- Undefined state.
276
          rxFifoState <= STATE_EMPTY;
277
      end case;
278
    end if;
279
  end process;
280
 
281
  -----------------------------------------------------------------------------
282
  -- UART transmitter process.
283
  -----------------------------------------------------------------------------
284
  Transmitter: process(clk, areset_n)
285
  begin
286
    if (areset_n = '0') then
287
      txState <= STATE_IDLE;
288
      txShifter <= (others => '0');
289
      txBitCounter <= 0;
290
      txCounter <= (others => '0');
291
 
292
      full_o <= '0';
293
      serial_o <= '1';
294
    elsif (clk'event and (clk = '1')) then
295
      case txState is
296
 
297
        when STATE_IDLE =>
298
          ---------------------------------------------------------------------
299
          -- Wait for new data to be input on the input port.
300
          ---------------------------------------------------------------------
301
          if (write_i = '1') then
302
            -- New data present.
303
            full_o <= '1';
304
            txShifter <= "1" & data_i;
305
            txCounter <= (others => '0');
306
            txBitCounter <= 0;
307
            txState <= STATE_SEND;
308
            serial_o <= '0';
309
          end if;
310
 
311
        when STATE_SEND =>
312
          ---------------------------------------------------------------------
313
          -- Wait for the bit to be completly transmitted.
314
          ---------------------------------------------------------------------
315
          if (txCounter = bitDuration) then
316
            -- The bit has been sent.
317
 
318
            -- Check if the full character has been sent.
319
            if (txBitCounter = (DATA_WIDTH+1)) then
320
              -- Character has been sent.
321
              full_o <= '0';
322
              txState <= STATE_IDLE;
323
            else
324
              -- Character has not been sent yet.
325
              -- Send the next bit.
326
              serial_o <= txShifter(0);
327
              txShifter <= "0" & txShifter(DATA_WIDTH downto 1);
328
              txBitCounter <= txBitCounter + 1;
329
            end if;
330
 
331
            -- Update to the next bit.
332
            txCounter <= (others => '0');
333
          else
334
            -- Wait for the end of the bit.
335
            txCounter <= txCounter + 1;
336
          end if;
337
 
338
        when others =>
339
          ---------------------------------------------------------------------
340
          -- Undefined state.
341
          ---------------------------------------------------------------------
342
          txState <= STATE_IDLE;
343
 
344
      end case;
345
    end if;
346
  end process;
347
 
348
end architecture;
349
 

powered by: WebSVN 2.1.0

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