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

Subversion Repositories jart

[/] [jart/] [branches/] [ver0branch/] [uart_serial.vhdl] - Blame information for rev 75

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

Line No. Rev Author Line
1 10 jguarin200
-- Author : Julian Andres Guarin Reyes.
2
-- Project : JART, Just Another Ray Tracer.
3
-- email : jguarin2002 at gmail.com, j.guarin at javeriana.edu.co
4
 
5
-- This code was entirely written by Julian Andres Guarin Reyes.
6
-- The following code is licensed under GNU Public License
7
-- http://www.gnu.org/licenses/gpl-3.0.txt.
8
 
9
 -- This file is part of JART (Just Another Ray Tracer).
10
 
11
    -- JART (Just Another Ray Tracer) is free software: you can redistribute it and/or modify
12
    -- it under the terms of the GNU General Public License as published by
13
    -- the Free Software Foundation, either version 3 of the License, or
14
    -- (at your option) any later version.
15
 
16
    -- JART (Just Another Ray Tracer) is distributed in the hope that it will be useful,
17
    -- but WITHOUT ANY WARRANTY; without even the implied warranty of
18
    -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
    -- GNU General Public License for more details.
20
 
21
    -- You should have received a copy of the GNU General Public License
22
    -- along with JART (Just Another Ray Tracer).  If not, see <http://www.gnu.org/licenses/>.
23
 
24
 
25 9 jguarin200
library ieee;
26
use ieee.std_logic_1164.all;
27
use ieee.std_logic_unsigned.all;
28
use ieee.numeric_std.all;
29
 
30
entity uart is
31
        port(
32
 
33
                rst                     : in  std_logic;                      -- reset control signal
34
                clk                     : in  std_logic;                      -- 100 MHz on PLL
35
 
36
                -- Reception channel
37
                Rx                      : in  std_logic;                      -- Linea de entrada RS232
38
                RxDataOut       : out std_logic_vector(7 downto 0);   -- Buffer de salida
39
                RxRdy           : out std_logic;                      -- Bandera para indicar que el dato esta listo 
40
 
41
 
42
                -- Transmition channel
43
                Tx                      : out std_logic;                      -- Linea de salida RS232
44
                TxDataIn        : in  std_logic_vector(7 downto 0);   -- Buffer de entrada 
45
                TxLoad          : in  std_logic;                      -- Señal de carga
46
                TxBusy      : out std_logic                      -- Bandera de Canal ocupado
47
        );
48
 
49
end entity;
50
 
51
 
52
architecture rtl of uart is
53
 
54
        -------------------------------------------------------------------------------
55
        -- Ticks 
56
        -------------------------------------------------------------------------------
57 10 jguarin200
        constant TBIT                   : integer := 434/4;     --   15 1 bit Divide By four in order to obtain 460800 bps at 50 MHZ, by 2 for 230400, by 1 for 115200 bps
58
        constant THALF_BIT              : integer := 217/4;     --  7 1/2 bit Divide By four in order to obtain 460800 bps at 50 MHZ, by 2 for 230400, by 1 for 115200 bps
59 9 jguarin200
        -------------------------------------------------------------------------------
60
        -- Maquinas de Estado
61
        -------------------------------------------------------------------------------
62
        type tTxStateMachine is (WAITING_LOAD_TX,SET_STARTBIT_TX,SET_NBIT_TX,FINISH_TX);
63
        type tRxStateMachine is (WAIT_START_BIT,HOLD_STARTBIT_RX,WAIT_FOR_NEW_BIT_RX,SAMPLE_BIT_RX,SAMPLE_STOPBIT_RX);--,RX_OVF,DEBUGGING_RX);
64
        signal sTxState      : tTxStateMachine;
65
        signal sRxState      : tRxStateMachine;
66
        -------------------------------------------------------------------------------
67
        -- Baud Rate Signals : Bit 16th bit16, Bit half bit2, Entire Bit bit1.
68
        -------------------------------------------------------------------------------
69
        signal bit2   : std_logic;                      -- 1/2 BAUDIO
70
        signal bit1   : std_logic;                      -- 1 BAUDIO
71
        -------------------------------------------------------------------------------
72
        -- Registros de Transmision
73
        -------------------------------------------------------------------------------
74
        signal sTxDataInReg     : std_logic_vector(7 downto 0);  -- Registro de precarga de salida
75
        signal sShiftTxData     : std_logic_vector(9 downto 0);  -- Registro de corrimiento de salida
76
 
77
        -------------------------------------------------------------------------------
78
        -- Registros de Recepcion
79
        -------------------------------------------------------------------------------
80
        signal sShiftRxData     : std_logic_vector(7 downto 0);  -- Registro de corrimiento de llegada.
81
        signal sSyncRxCounter   : std_logic;                    -- Señal de sincronizacion para el contador de medio bit.
82
        signal sEnableTxCounter : std_logic;                                    -- Señal de sincronizacion para conteo de un bit entero en la transmision.                                              
83
        signal sRx0, sRx1               : std_logic;                                    -- Señal Rx Registrada
84
 
85
begin
86
 
87
        ------------------------------------------------------------------------------
88
        --             Countador Principal de Transmision                        --- 
89
        -------------------------------------------------------------------------------
90
        txCntr:
91
        process(rst,clk)
92
                variable counter : integer range 0 to 1023;
93
        begin
94
                if rst = '0' then
95
 
96
                        bit1 <= '0';
97
                        counter := 0;
98
 
99
                elsif rising_edge(clk) then
100
 
101
                        bit1 <= '0';
102
                        if sEnableTxCounter ='0' then
103
                                counter := 0;
104
                        elsif counter = TBIT then
105
                                bit1 <= '1';
106
                                counter := 0;
107
                        else
108
                                counter := counter + 1;
109
                        end if;
110
 
111
                end if;
112
        end process;
113
 
114
 
115
 
116
        ------------------------------------------------------------------------------
117
        -- Countador Principal de Transmision  (115200 bps : 1/2 Baudio con 8 Ticks => 1 Tick / 54 ns)
118
        -- Adicionalmente este contador usa la señal sSyncRxCounter, para resetearlo.
119
        -------------------------------------------------------------------------------
120
        rxCntr:
121
        process(rst, clk)
122
                variable counter : integer range 0 to 1023;
123
        begin
124
 
125
                if rst = '0' then
126
                        bit2 <= '0';
127
                        counter := 0;
128
                elsif rising_edge(clk) then
129
                        bit2 <= '0';
130
                        if sSyncRxCounter = '1' then
131
                                counter:=0;
132
 
133
                        elsif counter = THALF_BIT then
134
                                -- Reset el contador y marcar medio bit.
135
                                bit2 <= '1';
136
                                counter := 0;
137
                        else
138
                                counter := counter + 1;
139
                        end if;
140
                end if;
141
 
142
        end process;
143
 
144
 
145
        -------------------------------------------------------------------------------
146
        -- Maquina de estado de transmision
147
        -------------------------------------------------------------------------------
148
        txFSM:
149
        process(rst, clk)
150
                variable counter : integer range 0 to 15;
151
        begin
152
                if rst = '0' then
153
 
154
                        -- Seleccionar estado de espera.
155
                        sTxState                <= WAITING_LOAD_TX;
156
 
157
                        -- Registro de corrimiento en 1. De esa manera se pone automaticamente la linea de transmision en 1.
158
                        sShiftTxData    <= (others => '1');
159
 
160
                        -- Deshabilitar el contador de transmision (canal libre).
161
                        sEnableTxCounter <= '0';
162
 
163
                elsif rising_edge(clk) then
164
 
165
                        case sTxState is
166
 
167
                                when WAITING_LOAD_TX =>
168
 
169
                                        if TxLoad = '1' then
170
 
171
                                                -- Cargar Dato
172
                                                sTxDataInReg <= TxDataIn;
173
 
174
                                                -- Siguiente estado : Cargar bit 
175
                                                sTxState  <= SET_STARTBIT_TX;
176
 
177
                                                -- Habilitar el contador de Tx  (canal ocupado)
178
                                                sEnableTxCounter <= '1';
179
 
180
                                        end if;
181
 
182
                                when SET_STARTBIT_TX =>
183
 
184
                                        if bit1 = '1' then -- Esperar a que transcurra el tiempo de un bit.
185
 
186
                                                -- 0 avo bit
187
                                                counter := 1;
188
 
189
                                                -- Colocar el startbit
190
                                                sShiftTxData(9 downto 0) <= '1' & sTxDataInReg(7 downto 0) & '0'; -- Enviar START BIT 
191
 
192
                                                -- Pasar a esperar tbit para colocar el siguiente bit de datos en la linea tx
193
                                                sTxState <= SET_NBIT_TX; -- Cargar siguiente dato 
194
 
195
                                        end if;
196
 
197
                                when SET_NBIT_TX =>
198
 
199
                                        if bit1 = '1' then -- Paso un bit
200
 
201
                                                -- Contar el numero de datos enviados
202
                                                counter := counter + 1; -- Calcular el numero de datos - 1 enviados
203
 
204
                                                -- Correr el registro de y transmitir el ultimo bit.
205
                                                sShiftTxData(9 downto 0) <= '1' & sShiftTxData(9 downto 1);
206
 
207
                                                if counter = 10 then -- 10 bits enviados parar.
208
 
209
                                                        -- Ir al estado de finalizacion de la transmision
210
                                                        sTxState <= FINISH_TX;
211
 
212
 
213
 
214
                                                end if;
215
 
216
                                        end if;
217
 
218
                                when FINISH_TX => -- stop bit
219
 
220
                                        if bit1 = '1' then
221
 
222
                                                -- Estado Ocioso 
223
                                                sTxState <= WAITING_LOAD_TX;
224
 
225
                                                -- Deshabilitar el contador de transmision y declarar el canal de transmision libre.
226
                                                sEnableTxCounter <= '0';
227
 
228
                                        end if;
229
 
230
                                when others =>
231
 
232
                                        -- Si no se sabe el estado entonces ir a finish para liberar el canal.
233
                                        sTxState <= FINISH_TX;
234
 
235
                        end case;
236
 
237
                end if;
238
 
239
        end process;
240
 
241
        -- Declarar el canal como ocupado o desocupado si el contador de transmision está encendido o apagado respectivamente
242
        TxBusy <= sEnableTxCounter;
243
        Tx <= sShiftTxData(0);
244
 
245
 
246
  -------------------------------------------------------------------------------
247
  -- Reception process
248
  -------------------------------------------------------------------------------
249
        rxFSM: process(rst, clk)
250
                variable counter : integer range 0 to 127;
251
        begin
252
                if rst = '0' then
253
 
254
                        RxDataOut <= (others => '1');
255
                        RxRdy <= '0';
256
                        sShiftRxData <= (others => '1');
257
                        sRxState <= WAIT_START_BIT;
258
                        sRx0<='1';
259
                        sRx1<='1';
260
 
261
                elsif rising_edge(clk) then
262
 
263
 
264
 
265
                        RxRdy <= '0';
266
                        sSyncRxCounter <='0';
267
 
268
                        -- Doble FF para la sincronizaciòn de Rx. Esto no funciona muy bien con PLL.
269
                        -- Preguntar a Alejandra.
270
                        sRx0 <= Rx;
271
                        sRx1 <= sRx0;
272
 
273
                        case sRxState is
274
 
275
                                when WAIT_START_BIT =>  -- Wait start bit
276
 
277
                                        if (sRx1 and not(sRx0))='1' then -- Si hay un Flanco de bajada
278
 
279
                                                -- Siguiente estado : esperar que pase el bit de start
280
                                                sRxState <= HOLD_STARTBIT_RX;
281
 
282
                                                -- Sincronizacion contador
283
                                                sSyncRxCounter <='1';
284
 
285
 
286
                                                -- Vamos en el primer bit.
287
                                                counter := 0;
288
 
289
                                        end if;
290
 
291
 
292
 
293
                                when HOLD_STARTBIT_RX =>
294
 
295
                                        if bit2 = '1' then -- Nos encontramos en la mitad del baudio del start bit. Ahora lo muestreamos sin cargarlo ;)                  
296
 
297
                                                sRxState <= WAIT_FOR_NEW_BIT_RX; -- Siguiente estado es detectar nuevo bit.
298
 
299
                                        end if;
300
 
301
 
302
                                when WAIT_FOR_NEW_BIT_RX =>
303
 
304
                                        if bit2 = '1' then -- En este momento nos encontramos en el comienzo de un bit.
305
 
306
                                                if counter = 8 then -- Si hemos leido el OCTAVO bit entonces el que sigue es el NOVENO bit  (STOP BIT)
307
 
308
                                                        sRxState <= SAMPLE_STOPBIT_RX; -- Ir al estado de lectura del stop bit.                                 
309
 
310
                                                else
311
 
312
                                                        sRxState <= SAMPLE_BIT_RX;-- Ir al estado de carga de un bit de datos.
313
 
314
                                                end if;
315
 
316
                                        end if;
317
 
318
 
319
                                when SAMPLE_BIT_RX =>
320
 
321
                                        if bit2 = '1' then -- Nos encontramos en la mitad de un baudio. Muestrear el bit correspondiente.
322
 
323
                                                --Contar el numero de bits leidos.
324
                                                counter := counter + 1;
325
 
326
                                                --Cargar el bit que se encuentra en la linea RX (después del flip flop para evitar metaestabilidad)
327
                                                sShiftRxData(7 downto 0) <= sRx0 & sShiftRxData(7 downto 1);
328
 
329
                                                -- Siguiente estado : Detectar nuevo baudio.
330
                                                sRxState <= WAIT_FOR_NEW_BIT_RX;
331
 
332
                                        end if;
333
 
334
 
335
 
336
                                when SAMPLE_STOPBIT_RX =>
337
 
338
                                        if bit2 = '1' then -- Estamos en la mitad del stop bit.
339
 
340
                                                -- Cargar el dato del shift register al buffer de salida.
341
                                                RxDataOut <= sShiftRxData;
342
 
343
                                                -- Siguiente estado: Ocioso, esperando por un start bit.
344
                                                sRxState <= WAIT_START_BIT;
345
 
346
                                                -- Avisar que está listo el dato.
347
                                                RxRdy <='1';
348
 
349
                                        end if;
350
 
351
 
352
                                when others =>
353
 
354
                                        sRxState <= WAIT_START_BIT;
355
 
356
                        end case;
357
 
358
                end if;
359
 
360
        end process;
361
 
362
end rtl;
363
 

powered by: WebSVN 2.1.0

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