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

Subversion Repositories bitserial

[/] [bitserial/] [trunk/] [uart.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 howe.r.j.8
-- FILE:      uart.vhd
2
-- BRIEF:     UART TX/RX module
3
-- LICENSE:   MIT
4
-- COPYRIGHT: Richard James Howe (2019, 2020)
5
--
6
-- The UART (Universal Asynchronous Receiver/Transmitter) is one of the simplest
7
-- serial communication methods available. It is often used for debugging, for
8
-- issuing commands to embedded devices and sometimes even for uploading firmware
9
-- to devices. The data format and speed are configurable but there is no method
10
-- for automatically configuring a UART, both sides must have agreed on the
11
-- settings before hand. Configurable options include; baud, use of an
12
-- even of odd parity bit, number of data bits and number of stop bits.
13
--
14
-- The clock is not transmitted as part of the signal (which is why baud
15
-- must be agreed upon before hand), a single packet starts with a 'start bit',
16
-- where the line goes low. The receiver must synchronize to this start bit (it
17
-- resets the clock that generates pulse at the sample rate and baud when it
18
-- encounters a start bit).
19
--
20
-- A transmission with 8 data bits, 1 parity bit and 1 stop bit looks like
21
-- this:
22
-- ____   ______________________________   ________________
23
--     \_/|0|1|2|3|4|5|6|7|P|S|         \_/
24
--     Start   Data     Parity Stop    |--- More data --->
25
--
26
-- Start bits are always low, stop bits high. The most common format is
27
-- 8 data bits, no parity bit, and 1 stop bit at either 9600 or 115200 baud.
28
--
29
-- For the receiver a clock that is a multiple of the baud is used so the
30
-- bits can be sampled with a higher frequency than the bit rate.
31
--
32
-- Some notes:
33
-- * We can transmit from an 8-bit UART to a less than 8-bit UART fine, so
34
-- long as parity is not used, as
35
-- * Certain UARTs have the ability to transmit a BREAK signal by holding
36
-- the line low for a period greater than the packet length. We can transmit
37
-- that by lowering the baud rate and transmitting all zeroes. Receiving a
38
-- break (correctly) would require changing the receiver.
39
--
40
--
41
-- See:
42
-- * <https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter>
43
--
44
-- NOTE: We could replace this entire package with an entirely software driven
45
-- solution. The only hardware we would need two timers driven at the sample
46
-- rate (one for RX, one for TX) and a deglitched RX signal. An interrupt
47
-- would be generated on the timers expiry.
48
--
49
library ieee, work;
50
use ieee.std_logic_1164.all;
51
use ieee.numeric_std.all;
52
 
53
package uart_pkg is
54
        constant uart_8N1: std_ulogic_vector(7 downto 0) := "10000100";
55
 
56
        type uart_generics is record
57
                clock_frequency:    positive; -- clock frequency of module clock
58
                delay:              time;     -- gate delay for simulation purposes
59
                asynchronous_reset: boolean;  -- use asynchronous reset if true
60
        end record;
61
 
62
        component uart_tx is
63
                generic (
64
                        g:       uart_generics;
65
                        N:       positive;
66
                        format:  std_ulogic_vector(7 downto 0) := uart_8N1;
67
                        use_cfg: boolean);
68
                port (
69
                        clk:    in std_ulogic;
70
                        rst:    in std_ulogic;
71
                        cr:    out std_ulogic;
72
                        baud:   in std_ulogic; -- Pulse at baud
73
                        tx:    out std_ulogic;
74
                        ok:    out std_ulogic;
75
                        ctr:    in std_ulogic_vector(format'range);
76
                        ctr_we: in std_ulogic;
77
                        we:     in std_ulogic; -- di write enable
78
                        di:     in std_ulogic_vector(N - 1 downto 0));
79
        end component;
80
 
81
        component uart_rx is
82
                generic (
83
                        g:       uart_generics;
84
                        N:       positive;
85
                        D:       positive;
86
                        format:  std_ulogic_vector(7 downto 0) := uart_8N1;
87
                        use_cfg: boolean);
88
                port (
89
                        clk:     in std_ulogic;
90
                        rst:     in std_ulogic;
91
                        cr:     out std_ulogic;
92
                        baud:    in std_ulogic;
93
                        sample:  in std_ulogic;
94
                        failed: out std_ulogic_vector(1 downto 0);
95
                        ctr:     in std_ulogic_vector(7 downto 0);
96
                        ctr_we:  in std_ulogic;
97
                        rx:      in std_ulogic;
98
                        we:     out std_ulogic;
99
                        do:     out std_ulogic_vector(N - 1 downto 0));
100
        end component;
101
 
102
        component uart_fifo is
103
                generic (
104
                        g:           uart_generics;
105
                        data_width:  positive;
106
                        fifo_depth:  positive;
107
                        read_first:  boolean := true);
108
                port (
109
                        clk:   in  std_ulogic;
110
                        rst:   in  std_ulogic;
111
                        di:    in  std_ulogic_vector(data_width - 1 downto 0);
112
                        we:    in  std_ulogic;
113
                        re:    in  std_ulogic;
114
                        do:    out std_ulogic_vector(data_width - 1 downto 0);
115
 
116
                        -- optional
117
                        full:  out std_ulogic := '0';
118
                        empty: out std_ulogic := '1');
119
        end component;
120
 
121
        component uart_baud is -- Generates a pulse at the sample rate and baud
122
                generic (
123
                        g:    uart_generics;
124
                        init: integer;
125
                        N:    positive := 16;
126
                        D:    positive := 3);
127
                port (
128
                        clk:      in std_ulogic;
129
                        rst:      in std_ulogic;
130
                        we:       in std_ulogic;
131
                        cnt:      in std_ulogic_vector(N - 1 downto 0);
132
                        cr:       in std_ulogic := '0';
133
                        sample:  out std_ulogic;
134
                        baud:    out std_ulogic);
135
        end component;
136
 
137
        component uart_top is
138
                generic (
139
                        clock_frequency:    positive; -- clock frequency of module clock
140
                        delay:              time;     -- gate delay for simulation purposes
141
                        asynchronous_reset: boolean;  -- use asynchronous reset if true
142
                        baud:               positive := 115200;
143
                        format:             std_ulogic_vector(7 downto 0) := uart_8N1;
144
                        fifo_depth:         natural := 0;
145
                        use_cfg:            boolean := false;
146
                        use_tx:             boolean := true;
147
                        use_rx:             boolean := true
148
                        ); -- Use FIFO to buffer results?
149
                port (
150
                        clk:    in std_ulogic;
151
                        rst:    in std_ulogic;
152
 
153
                        tx:            out std_ulogic;
154
                        tx_fifo_full:  out std_ulogic;
155
                        tx_fifo_empty: out std_ulogic;
156
                        tx_fifo_we:     in std_ulogic;
157
                        tx_fifo_data:   in std_ulogic_vector(7 downto 0);
158
 
159
                        rx:             in std_ulogic;
160
                        rx_fifo_full:  out std_ulogic;
161
                        rx_fifo_empty: out std_ulogic;
162
                        rx_fifo_re:     in std_ulogic;
163
                        rx_fifo_data:  out std_ulogic_vector(7 downto 0);
164
 
165
                        reg:             in std_ulogic_vector(15 downto 0);
166
                        clock_reg_tx_we: in std_ulogic;
167
                        clock_reg_rx_we: in std_ulogic;
168
                        control_reg_we:  in std_ulogic);
169
        end component;
170
 
171
        component uart_tb is
172
                generic(g: uart_generics);
173
        end component;
174
 
175
        function parity(slv:std_ulogic_vector; even: boolean) return std_ulogic;
176
        function parity(slv:std_ulogic_vector; even: std_ulogic) return std_ulogic;
177
        constant ctr_use_parity:  integer := 0;
178
        constant ctr_even_parity: integer := 1;
179
        function ctr_stop_bits(ctr: std_ulogic_vector(7 downto 0)) return integer;
180
        function ctr_data_bits(ctr: std_ulogic_vector(7 downto 0)) return integer;
181
end package;
182
 
183
package body uart_pkg is
184
        function parity(slv: std_ulogic_vector; even: boolean) return std_ulogic is
185
                variable z: std_ulogic := '0';
186
        begin
187
                if not even then
188
                        z := '1';
189
                end if;
190
                for i in slv'range loop
191
                        z := z xor slv(i);
192
                end loop;
193
                return z;
194
        end;
195
 
196
        function parity(slv:std_ulogic_vector; even: std_ulogic) return std_ulogic is
197
                variable z: boolean := false;
198
        begin
199
                if even = '1' then
200
                        z := true;
201
                end if;
202
                return parity(slv, z);
203
        end;
204
 
205
        function ctr_stop_bits(ctr: std_ulogic_vector(7 downto 0)) return integer is
206
                variable ii: std_ulogic_vector(1 downto 0);
207
        begin
208
                ii := ctr(3 downto 2);
209
                return to_integer(unsigned(ii));
210
        end function;
211
 
212
        function ctr_data_bits(ctr: std_ulogic_vector(7 downto 0)) return integer is
213
                variable ii: std_ulogic_vector(3 downto 0);
214
        begin
215
                ii := ctr(7 downto 4);
216
                return to_integer(unsigned(ii));
217
        end function;
218
end;
219
 
220
library ieee, work;
221
use ieee.std_logic_1164.all;
222
use ieee.numeric_std.all;
223
use work.uart_pkg.all;
224
 
225
entity uart_top is
226
        generic (
227
                clock_frequency:    positive; -- clock frequency of module clock
228
                delay:              time;     -- gate delay for simulation purposes
229
                asynchronous_reset: boolean;  -- use asynchronous reset if true
230
                baud:               positive := 115200;
231
                format:             std_ulogic_vector(7 downto 0) := uart_8N1;
232
                fifo_depth:         natural := 0; -- FIFO depth, 0,1 = no FIFO
233
                use_cfg:            boolean := false; -- allow run time configuration of baud rate and format?
234
                use_tx:             boolean := true;  -- instantiate TX functionality?
235
                use_rx:             boolean := true   -- instantiate RX functionality?
236
        );
237
        port (
238
                clk:    in std_ulogic;
239
                rst:    in std_ulogic;
240
 
241
                tx:            out std_ulogic;
242
                tx_fifo_full:  out std_ulogic;
243
                tx_fifo_empty: out std_ulogic;
244
                tx_fifo_we:     in std_ulogic;
245
                tx_fifo_data:   in std_ulogic_vector(7 downto 0);
246
 
247
                rx:             in std_ulogic;
248
                rx_fifo_full:  out std_ulogic;
249
                rx_fifo_empty: out std_ulogic;
250
                rx_fifo_re:     in std_ulogic;
251
                rx_fifo_data:  out std_ulogic_vector(7 downto 0);
252
 
253
                reg:             in std_ulogic_vector(15 downto 0);
254
                clock_reg_tx_we: in std_ulogic;
255
                clock_reg_rx_we: in std_ulogic;
256
                control_reg_we:  in std_ulogic);
257
end entity;
258
 
259
architecture structural of uart_top is
260
        constant g: uart_generics := (
261
                clock_frequency => clock_frequency,
262
                delay => delay,
263
                asynchronous_reset => asynchronous_reset
264
        );
265
        constant tx_init: integer  := g.clock_frequency / (baud * 16); -- 54 = 115200 @ 100 MHz
266
        constant rx_init: positive := tx_init - 1; -- 50 = 115200 @ 100 MHz + Fudge Factor
267
        constant N: positive := 8;
268
 
269
        signal rx_ok, rx_nd, rx_push, rx_re: std_ulogic := '0';
270
        signal rx_pushed: std_ulogic_vector(rx_fifo_data'range) := (others => '0');
271
        signal tx_pop, tx_ok: std_ulogic := '0';
272
        signal tx_popped: std_ulogic_vector(tx_fifo_data'range) := (others => '0');
273
        signal tx_fifo_empty_b, rx_fifo_full_b: std_ulogic := '0';
274
 
275
        signal tx_sample, tx_baud, tx_cr: std_ulogic := '0';
276
        signal rx_sample, rx_baud, rx_cr, rx_we: std_ulogic := '0';
277
        signal rx_fail: std_ulogic_vector(1 downto 0) := (others => '0');
278
        signal rx_ok_buf: std_ulogic := '0';
279
        signal do, do_c, do_n: std_ulogic_vector(rx_fifo_data'range) := (others => '0');
280
        signal fail_c, fail_n: std_ulogic_vector(1 downto 0) := (others => '0');
281
        signal nd_c, nd_n: std_ulogic := '0'; -- new data
282
 
283
begin
284
        rx_ok_buf <= not (fail_c(0) or fail_c(1)) after g.delay;
285
        rx_ok <= rx_ok_buf;
286
        rx_pushed <= do after g.delay;
287
        rx_nd <= nd_c and rx_ok_buf after g.delay; -- no new data if there are errors
288
        rx_re <= rx_push;
289
 
290
        process (clk, rst)
291
        begin
292
                if use_rx then
293
                        if rst = '1' and g.asynchronous_reset then
294
                                do_c   <= (others => '0') after g.delay;
295
                                fail_c <= (others => '0') after g.delay;
296
                                nd_c   <= '0' after g.delay;
297
                        elsif rising_edge(clk) then
298
                                if rst = '1' and not g.asynchronous_reset then
299
                                        do_c   <= (others => '0') after g.delay;
300
                                        fail_c <= (others => '0') after g.delay;
301
                                        nd_c   <= '0' after g.delay;
302
                                else
303
                                        do_c <= do_n     after g.delay;
304
                                        nd_c <= nd_n     after g.delay;
305
                                        fail_c <= fail_n after g.delay;
306
                                end if;
307
                        end if;
308
                end if;
309
        end process;
310
 
311
        process (do_c, do, nd_c, rx_we, rx_re, fail_c, rx_fail)
312
        begin
313
                if use_tx then
314
                        do_n   <= do_c   after g.delay;
315
                        nd_n   <= nd_c   after g.delay;
316
                        fail_n <= fail_c after g.delay;
317
                        if rx_we = '1' then
318
                                nd_n   <= '1'     after g.delay;
319
                                do_n   <= do      after g.delay;
320
                                fail_n <= rx_fail after g.delay;
321
                        elsif rx_re = '1' then
322
                                nd_n   <= '0' after g.delay;
323
                        end if;
324
                end if;
325
        end process;
326
 
327
        ugen0: if fifo_depth <= 1 generate
328
                        tx_pop        <= tx_fifo_we;
329
                        tx_popped     <= tx_fifo_data;
330
                        tx_fifo_full  <= not tx_ok;
331
                        tx_fifo_empty <= tx_ok;
332
 
333
                        rx_push       <= rx_fifo_re;
334
                        rx_fifo_data  <= rx_pushed;
335
                        rx_fifo_full  <= rx_nd;
336
                        rx_fifo_empty <= not rx_nd;
337
        end generate;
338
 
339
        ugen1: if fifo_depth > 1 generate
340
                tx_fifo_empty <=               tx_fifo_empty_b;
341
                tx_pop        <= tx_ok and not tx_fifo_empty_b;
342
 
343
                ugen1_fifo_tx: if use_tx generate
344
                        uart_fifo_tx_0: work.uart_pkg.uart_fifo
345
                                generic map(g => g,
346
                                           data_width => tx_fifo_data'length,
347
                                           fifo_depth => fifo_depth)
348
                                port map (clk  => clk, rst => rst,
349
                                          di   => tx_fifo_data,
350
                                          we   => tx_fifo_we,
351
                                          re   => tx_pop,
352
                                          do   => tx_popped,
353
                                          full => tx_fifo_full,
354
                                          empty => tx_fifo_empty_b);
355
                end generate;
356
 
357
                rx_fifo_full <=                         rx_fifo_full_b;
358
                rx_push      <= rx_nd and rx_ok and not rx_fifo_full_b;
359
                ugen1_fifo_rx: if use_rx generate
360
                        uart_fifo_rx_0: work.uart_pkg.uart_fifo
361
                                generic map(g => g,
362
                                           data_width => rx_fifo_data'length,
363
                                           fifo_depth => fifo_depth,
364
                                           read_first => false)
365
                                port map (clk  => clk, rst => rst,
366
                                          di   => rx_pushed,
367
                                          we   => rx_push,
368
                                          re   => rx_fifo_re,
369
                                          do   => rx_fifo_data,
370
                                          full => rx_fifo_full_b, empty => rx_fifo_empty);
371
                end generate;
372
        end generate;
373
 
374
        uart_tx_gen: if use_tx generate
375
                baud_tx: work.uart_pkg.uart_baud
376
                        generic map(g => g, init => tx_init, N => reg'length, D => 3)
377
                        port map(
378
                                clk    => clk,
379
                                rst    => rst,
380
                                we     => clock_reg_tx_we,
381
                                cnt    => reg,  -- 0x32/50 is 1152000 @ 100MHz clk
382
                                cr     => tx_cr,
383
                                sample => tx_sample,
384
                                baud   => tx_baud);
385
 
386
                tx_0: work.uart_pkg.uart_tx
387
                        generic map(g => g, N => N, format => format, use_cfg => use_cfg)
388
                        port map(
389
                                clk     => clk,
390
                                rst     => rst,
391
 
392
                                cr      => tx_cr,
393
                                baud    => tx_baud,
394
                                ok      => tx_ok,
395
                                we      => tx_pop,
396
                                ctr     => reg(reg'high downto reg'high - 7),
397
                                ctr_we  => control_reg_we,
398
                                di      => tx_popped,
399
                                tx      => tx);
400
        end generate;
401
 
402
        uart_rx_gen: if use_rx generate
403
                baud_rx: work.uart_pkg.uart_baud
404
                        generic map(g => g, init => rx_init, N => reg'length, D => 3)
405
                        port map(
406
                                clk    => clk,
407
                                rst    => rst,
408
                                we     => clock_reg_rx_we,
409
                                cnt    => reg,
410
                                cr     => rx_cr,
411
                                sample => rx_sample,
412
                                baud   => rx_baud);
413
 
414
                rx_0: work.uart_pkg.uart_rx
415
                        generic map(g => g, N => N, D => 3, format => format, use_cfg => use_cfg)
416
                        port map(
417
                                clk     => clk,
418
                                rst     => rst,
419
 
420
                                baud    => rx_baud,
421
                                sample  => rx_sample,
422
                                cr      => rx_cr,
423
                                failed  => rx_fail,
424
                                ctr     => reg(reg'low + 7 downto reg'low),
425
                                ctr_we  => control_reg_we,
426
                                we      => rx_we,
427
                                do      => do,
428
                                rx      => rx);
429
        end generate;
430
end architecture;
431
 
432
library ieee, work;
433
use ieee.std_logic_1164.all;
434
use ieee.numeric_std.all;
435
use work.uart_pkg.all;
436
 
437
entity uart_fifo is
438
        generic (g: uart_generics;
439
                data_width: positive;
440
                fifo_depth: positive;
441
                read_first: boolean := true);
442
        port (
443
                clk:   in  std_ulogic;
444
                rst:   in  std_ulogic;
445
                di:    in  std_ulogic_vector(data_width - 1 downto 0);
446
                we:    in  std_ulogic;
447
                re:    in  std_ulogic;
448
                do:    out std_ulogic_vector(data_width - 1 downto 0);
449
 
450
                -- optional
451
                full:  out std_ulogic := '0';
452
                empty: out std_ulogic := '1');
453
end uart_fifo;
454
 
455
architecture behavior of uart_fifo is
456
        type fifo_data_t is array (0 to fifo_depth - 1) of std_ulogic_vector(di'range);
457
        signal data: fifo_data_t := (others => (others => '0'));
458
        function rindex_init return integer is
459
        begin
460
                if read_first then
461
                        return 0;
462
                end if;
463
                return fifo_depth - 1;
464
        end function;
465
 
466
        signal count:  integer range 0 to fifo_depth := 0;
467
        signal windex: integer range 0 to fifo_depth - 1 := 0;
468
        signal rindex: integer range 0 to fifo_depth - 1 := rindex_init;
469
 
470
        signal is_full:  std_ulogic := '0';
471
        signal is_empty: std_ulogic := '1';
472
begin
473
        do       <= data(rindex) after g.delay;
474
        full     <= is_full after g.delay;  -- buffer these bad boys
475
        empty    <= is_empty after g.delay;
476
        is_full  <= '1' when count = fifo_depth else '0' after g.delay;
477
        is_empty <= '1' when count = 0          else '0' after g.delay;
478
 
479
        process (rst, clk) is
480
        begin
481
                if rst = '1' and g.asynchronous_reset then
482
                        windex <= 0 after g.delay;
483
                        count  <= 0 after g.delay;
484
                        rindex <= rindex_init after g.delay;
485
                elsif rising_edge(clk) then
486
                        if rst = '1' and not g.asynchronous_reset then
487
                                windex <= 0 after g.delay;
488
                                count  <= 0 after g.delay;
489
                                rindex <= rindex_init after g.delay;
490
                        else
491
                                if we = '1' and re = '0' then
492
                                        if is_full = '0' then
493
                                                count <= count + 1 after g.delay;
494
                                        end if;
495
                                elsif we = '0' and re = '1' then
496
                                        if is_empty = '0' then
497
                                                count <= count - 1 after g.delay;
498
                                        end if;
499
                                end if;
500
 
501
                                if re = '1' and is_empty = '0' then
502
                                        if rindex = (fifo_depth - 1) then
503
                                                rindex <= 0 after g.delay;
504
                                        else
505
                                                rindex <= rindex + 1 after g.delay;
506
                                        end if;
507
                                end if;
508
 
509
                                if we = '1' and is_full = '0' then
510
                                        if windex = (fifo_depth - 1) then
511
                                                windex <= 0 after g.delay;
512
                                        else
513
                                                windex <= windex + 1 after g.delay;
514
                                        end if;
515
                                        data(windex) <= di after g.delay;
516
                                end if;
517
                        end if;
518
                end if;
519
        end process;
520
end behavior;
521
 
522
-- This module generates a sample pulse and a baud pulse. The sample rate
523
-- can be controlled by setting 'cnt'. This sample rate is then divided by
524
-- 2^(D+1) to get the baud.
525
library ieee, work;
526
use ieee.std_logic_1164.all;
527
use ieee.numeric_std.all;
528
use work.uart_pkg.all;
529
 
530
entity uart_baud is
531
        generic (g: uart_generics; init: integer; N: positive := 16; D: positive := 3);
532
        port (
533
                clk:     in std_ulogic;
534
                rst:     in std_ulogic;
535
 
536
                we:      in std_ulogic;
537
                cnt:     in std_ulogic_vector(N - 1 downto 0);
538
                cr:      in std_ulogic := '0';
539
 
540
                sample: out std_ulogic;  -- sample pulse
541
                baud:   out std_ulogic); -- baud (sample rate / 2^(D+1))
542
end entity;
543
 
544
architecture behaviour of uart_baud is
545
        constant cmp_init: std_ulogic_vector := std_ulogic_vector(to_unsigned(init, cnt'length));
546
        signal cmp_c, cmp_n: std_ulogic_vector(cnt'range)  :=  cmp_init;
547
        signal cnt_c, cnt_n: std_ulogic_vector(cnt'range)  := (others => '0');
548
        signal div_c, div_n: std_ulogic_vector(D downto 0) := (others => '0');
549
        signal pul_c, pul_n: std_ulogic := '0';
550
        signal pulse: std_ulogic := '0';
551
begin
552
        pulse  <= (not cr) and pul_n and (pul_c xor pul_n) after g.delay; -- rising edge detector
553
        baud   <= (not cr) and div_n(div_n'high) and (div_c(div_c'high) xor div_n(div_n'high)) after g.delay;
554
        sample <= pulse;
555
 
556
        process (clk, rst)
557
        begin
558
                if rst = '1' and g.asynchronous_reset then
559
                        cmp_c <= cmp_init after g.delay;
560
                        cnt_c <= (others => '0') after g.delay;
561
                        div_c <= (others => '0') after g.delay;
562
                        pul_c <= '0' after g.delay;
563
                elsif rising_edge(clk) then
564
                        if rst = '1' and not g.asynchronous_reset then
565
                                cmp_c <= cmp_init after g.delay;
566
                                cnt_c <= (others => '0') after g.delay;
567
                                div_c <= (others => '0') after g.delay;
568
                                pul_c <= '0' after g.delay;
569
                        else
570
                                cmp_c <= cmp_n after g.delay;
571
                                cnt_c <= cnt_n after g.delay;
572
                                div_c <= div_n after g.delay;
573
                                pul_c <= pul_n after g.delay;
574
                        end if;
575
                end if;
576
        end process;
577
 
578
        process (pulse, div_c, cr, we)
579
        begin
580
                div_n <= div_c after g.delay;
581
                if cr = '1' or we = '1' then
582
                        div_n <= (others => '0') after g.delay;
583
                        div_n(div_n'high) <= '1' after g.delay;
584
                elsif pulse = '1' then
585
                        div_n <= std_ulogic_vector(unsigned(div_c) + 1) after g.delay;
586
                end if;
587
        end process;
588
 
589
        process (cmp_c, cnt_c, we, cnt, cr)
590
        begin
591
                cmp_n <= cmp_c after g.delay;
592
                cnt_n <= cnt_c after g.delay;
593
 
594
                if we = '1' then
595
                        cmp_n <= cnt after g.delay;
596
                        cnt_n <= (others => '0') after g.delay;
597
                        pul_n <= '0' after g.delay;
598
                elsif cr = '1' then
599
                        cnt_n <= (others => '0') after g.delay;
600
                        pul_n <= '0' after g.delay;
601
                elsif cnt_c = cmp_c then
602
                        cnt_n <= (others => '0') after g.delay;
603
                        pul_n <= '1' after g.delay;
604
                else
605
                        cnt_n <= std_ulogic_vector(unsigned(cnt_c) + 1) after g.delay;
606
                        pul_n <= '0' after g.delay;
607
                end if;
608
        end process;
609
end architecture;
610
 
611
library ieee, work;
612
use ieee.std_logic_1164.all;
613
use work.uart_pkg.all;
614
 
615
entity uart_rx is
616
        generic (
617
                g:       uart_generics;
618
                N:       positive;
619
                D:       positive;
620
                format:  std_ulogic_vector(7 downto 0) := uart_8N1;
621
                use_cfg: boolean);
622
        port (
623
                clk:     in std_ulogic;
624
                rst:     in std_ulogic;
625
                cr:     out std_ulogic; -- reset sample/baud clock when start bit detected
626
                baud:    in std_ulogic;
627
                sample:  in std_ulogic; -- pulses at baud and sample rate
628
                failed: out std_ulogic_vector(1 downto 0);
629
                ctr:     in std_ulogic_vector(7 downto 0);
630
                ctr_we:  in std_ulogic;
631
                rx:      in std_ulogic; -- physical RX signal
632
                we:     out std_ulogic; -- write 'do' to output register
633
                do:     out std_ulogic_vector(N - 1 downto 0));
634
end entity;
635
 
636
architecture behaviour of uart_rx is
637
        type state is (reset, idle, start, data, parity, stop, done);
638
        signal state_c, state_n: state;
639
        signal ctr_c, ctr_n: std_ulogic_vector(ctr'range);
640
        signal rx_c, rx_n: std_ulogic_vector(do'range);
641
        signal sr_c, sr_n: std_ulogic_vector(D - 1 downto 0);
642
        signal rx_sync: std_ulogic;
643
        signal count_c, count_n: integer range 0 to N - 1;
644
        signal majority: std_ulogic;
645
        signal fail_c, fail_n: std_ulogic_vector(1 downto 0);
646
begin
647
        do     <= rx_c after g.delay;
648
        failed <= fail_c after g.delay;
649
 
650
        assert D < 4 severity failure;
651
 
652
        majority_1: if D = 1 generate
653
                majority <= sr_c(0) after g.delay;
654
        end generate;
655
 
656
        majority_2: if D = 2 generate
657
                majority <= sr_c(0) and sr_c(1) after g.delay; -- even wins is 'sr_c(0) or sr_c(1)'
658
        end generate;
659
 
660
        majority_3: if D = 3 generate
661
                majority <= (sr_c(0) and sr_c(1)) or (sr_c(1) and sr_c(2)) or (sr_c(0) and sr_c(2)) after g.delay;
662
        end generate;
663
 
664
        process (clk, rst)
665
                procedure reset is
666
                begin
667
                        rx_c     <= (others => '0') after g.delay;
668
                        sr_c     <= (others => '0') after g.delay;
669
                        fail_c   <= (others => '0') after g.delay;
670
                        state_c  <= reset after g.delay;
671
                        count_c  <= 0 after g.delay;
672
                        rx_sync  <= '0' after g.delay;
673
                        if use_cfg then ctr_c  <= (others => '0') after g.delay; end if;
674
                end procedure;
675
        begin
676
                if rst = '1' and g.asynchronous_reset then
677
                        reset;
678
                elsif rising_edge(clk) then
679
                        if rst = '1' and not g.asynchronous_reset then
680
                                reset;
681
                        else
682
                                rx_c     <= rx_n after g.delay;
683
                                sr_c     <= sr_n after g.delay;
684
                                state_c  <= state_n after g.delay;
685
                                count_c  <= count_n after g.delay;
686
                                fail_c   <= fail_n after g.delay;
687
                                rx_sync  <= rx after g.delay;
688
                                if use_cfg then ctr_c <= ctr_n after g.delay; end if;
689
                        end if;
690
                end if;
691
                if not use_cfg then ctr_c <= format after g.delay; end if;
692
        end process;
693
 
694
        process (rx_c, sr_c, ctr_c, ctr_we, ctr, state_c, rx_sync, baud, sample, count_c, fail_c, majority)
695
        begin
696
                fail_n  <= fail_c  after g.delay;
697
                rx_n    <= rx_c    after g.delay;
698
                sr_n    <= sr_c    after g.delay;
699
                state_n <= state_c after g.delay;
700
                we      <= '0'     after g.delay;
701
                cr      <= '0'     after g.delay;
702
                count_n <= count_c after g.delay;
703
                if use_cfg then ctr_n <= ctr_c   after g.delay; end if;
704
 
705
                if sample = '1' then
706
                        sr_n <= sr_c(sr_c'high - 1 downto sr_c'low) & rx_sync after g.delay;
707
                end if;
708
 
709
                case state_c is
710
                when reset =>
711
                        rx_n     <= (others => '0') after g.delay;
712
                        sr_n     <= (others => '0') after g.delay;
713
                        fail_n   <= (others => '0') after g.delay;
714
                        if use_cfg then
715
                                ctr_n    <= format after g.delay; -- 8 bits, 1 stop bit, parity off
716
                        end if;
717
                        state_n  <= idle after g.delay;
718
                when idle =>
719
                        count_n <= 0 after g.delay;
720
                        if rx_sync = '0' then -- and majority = '1' then
721
                                state_n <= start after g.delay;
722
                                cr      <= '1' after g.delay;
723
                                sr_n    <= (others => '0') after g.delay;
724
                                fail_n  <= (others => '0') after g.delay;
725
                        end if;
726
                when start =>
727
                        if baud = '1' then
728
                                if majority /= '0' then
729
                                        state_n   <= done after g.delay; -- frame error
730
                                        fail_n(0) <= '1' after g.delay;
731
                                else
732
                                        state_n <= data after g.delay;
733
                                end if;
734
                                sr_n <= (others => '0') after g.delay;
735
                        end if;
736
                when data =>
737
                        rx_n(count_c) <= majority after g.delay;
738
                        if baud = '1' then
739
                                if count_c = (ctr_data_bits(ctr_c) - 1) then
740
                                        count_n <= 0 after g.delay;
741
                                        if ctr_c(ctr_use_parity) = '1' then
742
                                                state_n <= parity after g.delay;
743
                                        else
744
                                                state_n <= stop after g.delay;
745
                                        end if;
746
                                else
747
                                        count_n <= count_c + 1 after g.delay;
748
                                end if;
749
                                sr_n <= (others => '0') after g.delay;
750
                        end if;
751
                when parity =>
752
                        if baud = '1' then
753
                                if (ctr_c(ctr_use_parity) = '1') and (majority /= parity(rx_c, ctr_c(ctr_even_parity))) then
754
                                        fail_n(1) <= '1' after g.delay; -- parity error, still process stop bits
755
                                end if;
756
                                state_n <= stop after g.delay;
757
                                sr_n <= (others => '0') after g.delay;
758
                        end if;
759
                when stop =>
760
                        if baud = '1' then
761
                                if majority /= '1' then
762
                                        state_n   <= done after g.delay; -- frame error
763
                                        fail_n(0) <= '1' after g.delay;
764
                                elsif count_c = ctr_stop_bits(ctr_c) then
765
                                        state_n <= done after g.delay;
766
                                else
767
                                        count_n <= count_c + 1 after g.delay;
768
                                end if;
769
                        end if;
770
                when done => -- The consuming module needs to store rx_c/fail_c immediately
771
                        we      <= '1' after g.delay;
772
                        state_n <= idle after g.delay;
773
                end case;
774
 
775
                if ctr_we = '1' then
776
                        if not (state_c = idle or state_c = done or state_c = reset) then
777
                                rx_n      <= (others => '0') after g.delay;
778
                                state_n   <= idle after g.delay;
779
                                we        <= '1' after g.delay;
780
                                fail_n(0) <= '1' after g.delay; -- frame error!
781
                        end if;
782
                        ctr_n <= ctr after g.delay;
783
                end if;
784
        end process;
785
end architecture;
786
 
787
library ieee, work;
788
use ieee.std_logic_1164.all;
789
use work.uart_pkg.all;
790
 
791
entity uart_tx is
792
        generic (
793
                g:       uart_generics;
794
                N:       positive;
795
                format:  std_ulogic_vector(7 downto 0) := uart_8N1;
796
                use_cfg: boolean);
797
        port (
798
                clk:    in std_ulogic;
799
                rst:    in std_ulogic;
800
                cr:    out std_ulogic;
801
                baud:   in std_ulogic; -- Pulse at baud
802
                tx:    out std_ulogic;
803
                ok:    out std_ulogic;
804
                ctr:    in std_ulogic_vector(format'range);
805
                ctr_we: in std_ulogic;
806
                we:     in std_ulogic; -- di write enable
807
                di:     in std_ulogic_vector(N - 1 downto 0));
808
end entity;
809
 
810
architecture behaviour of uart_tx is
811
        type state is (reset, idle, start, data, parity, stop);
812
        signal state_c, state_n: state;
813
        signal di_c, di_n: std_ulogic_vector(di'range);
814
        signal ctr_c, ctr_n: std_ulogic_vector(ctr'range);
815
        signal busy: std_ulogic;
816
        signal parity_c, parity_n: std_ulogic;
817
        signal count_c, count_n: integer range 0 to 15;
818
begin
819
        busy <= '0' when state_c = idle else '1' after g.delay;
820
        ok <= not busy after g.delay;
821
 
822
        process (clk, rst)
823
                procedure reset is
824
                begin
825
                        di_c     <= (others => '0') after g.delay;
826
                        state_c  <= reset after g.delay;
827
                        parity_c <= '0' after g.delay;
828
                        count_c  <= 0 after g.delay;
829
                        if use_cfg then ctr_c <= (others => '0') after g.delay; end if;
830
                end procedure;
831
        begin
832
                if rst = '1' and g.asynchronous_reset then
833
                        reset;
834
                elsif rising_edge(clk) then
835
                        if rst = '1' and not g.asynchronous_reset then
836
                                reset;
837
                        else
838
                                di_c     <= di_n     after g.delay;
839
                                state_c  <= state_n  after g.delay;
840
                                parity_c <= parity_n after g.delay;
841
                                count_c  <= count_n  after g.delay;
842
                                if use_cfg then ctr_c <= ctr_n after g.delay; end if;
843
                        end if;
844
                end if;
845
                if not use_cfg then ctr_c <= format after g.delay; end if;
846
        end process;
847
 
848
        process (di_c, di, ctr_c, ctr_we, ctr, state_c, we, baud, parity_c, count_c)
849
        begin
850
                count_n <= count_c after g.delay;
851
                state_n <= state_c after g.delay;
852
                di_n    <= di_c after g.delay;
853
                if use_cfg then ctr_n <= ctr_c after g.delay; end if;
854
                tx <= '1' after g.delay;
855
                cr <= '0';
856
 
857
                if ctr_c(ctr_use_parity) = '1' then
858
                        parity_n <= parity(di_c, ctr_c(ctr_even_parity)) after g.delay;
859
                else
860
                        parity_n <= '0' after g.delay;
861
                end if;
862
 
863
                case state_c is
864
                when reset  =>
865
                        state_n  <= idle after g.delay;
866
                        ctr_n    <= format after g.delay; -- 8 bits, 1 stop bit, parity off
867
                        count_n  <= 0 after g.delay;
868
                        parity_n <= '0' after g.delay;
869
                        di_n     <= (others => '0') after g.delay;
870
                when idle   =>
871
                        count_n  <= 0 after g.delay;
872
                        if use_cfg and ctr_we = '1' then -- NB. We can either lose data, or control writes
873
                                ctr_n <= ctr after g.delay;
874
                        elsif we = '1' then
875
                                di_n    <= di after g.delay;
876
                                cr      <= '1';
877
                                state_n <= start after g.delay;
878
                        end if;
879
                when start  =>
880
                        tx <= '0' after g.delay;
881
                        if baud = '1' then
882
                                state_n <= data after g.delay;
883
                        end if;
884
                when data   =>
885
                        tx <= di_c(count_c) after g.delay;
886
                        if baud = '1' then
887
                                if count_c = (ctr_data_bits(ctr_c) - 1) then
888
                                        count_n <= 0 after g.delay;
889
                                        if ctr_c(ctr_use_parity) = '1' then
890
                                                state_n <= parity after g.delay;
891
                                        else
892
                                                state_n <= stop after g.delay;
893
                                        end if;
894
                                else
895
                                        count_n <= count_c + 1 after g.delay;
896
                                end if;
897
                        end if;
898
                when parity =>
899
                        tx <= parity_c after g.delay;
900
                        if baud = '1' then
901
                                state_n <= stop after g.delay;
902
                        end if;
903
                when stop   =>
904
                        tx <= '1' after g.delay;
905
                        if baud = '1' then
906
                                if count_c = ctr_stop_bits(ctr_c) then
907
                                        count_n <= 0 after g.delay;
908
                                        state_n <= idle after g.delay;
909
                                else
910
                                        count_n <= count_c + 1 after g.delay;
911
                                end if;
912
                        end if;
913
                end case;
914
        end process;
915
end architecture;
916
 
917
library ieee, work;
918
use ieee.std_logic_1164.all;
919
use ieee.numeric_std.all;
920
use work.uart_pkg.all;
921
 
922
entity uart_tb is
923
        generic(g: uart_generics);
924
end entity;
925
 
926
architecture testing of uart_tb is
927
        constant clock_period: time     := 1000 ms / g.clock_frequency;
928
        constant fifo_depth: natural    := 8;
929
        signal rst, clk:     std_ulogic := '1';
930
        signal stop:         boolean    := false;
931
        signal loopback:     boolean    := true;
932
        signal tx, rx:       std_ulogic;
933
        signal di, do:       std_ulogic_vector(7 downto 0);
934
        signal reg:          std_ulogic_vector(15 downto 0);
935
        signal clock_reg_tx_we: std_ulogic;
936
        signal clock_reg_rx_we: std_ulogic;
937
        signal control_reg_we:  std_ulogic;
938
 
939
        signal tx_fifo_full:  std_ulogic;
940
        signal tx_fifo_empty: std_ulogic;
941
        signal tx_fifo_we:    std_ulogic := '0';
942
        signal rx_fifo_full:  std_ulogic;
943
        signal rx_fifo_empty: std_ulogic;
944
        signal rx_fifo_re:    std_ulogic := '0';
945
begin
946
        -- duration: process begin wait for 20000 us; stop <= true; wait; end process;
947
        clk_process: process
948
        begin
949
                rst <= '1';
950
                wait for clock_period * 5;
951
                rst <= '0';
952
                while not stop loop
953
                        clk <= '1';
954
                        wait for clock_period / 2;
955
                        clk <= '0';
956
                        wait for clock_period / 2;
957
                end loop;
958
                wait;
959
        end process;
960
 
961
        stimulus: process
962
                procedure write(data: std_ulogic_vector(di'range)) is
963
                begin
964
                        wait for clock_period * 1;
965
                        while tx_fifo_full = '1' loop
966
                                wait for clock_period;
967
                        end loop;
968
                        di <= data;
969
                        tx_fifo_we <= '1';
970
                        wait for clock_period;
971
                        tx_fifo_we <= '0';
972
                end procedure;
973
        begin
974
                di <= x"00";
975
                wait until rst = '0';
976
                wait for clock_period;
977
                reg             <=  x"8080";
978
                control_reg_we  <=  '1';
979
                wait for clock_period;
980
                control_reg_we  <=  '0';
981
                reg             <=  x"0036";
982
                clock_reg_tx_we <=  '1';
983
                wait for clock_period;
984
                clock_reg_tx_we <=  '0';
985
                clock_reg_rx_we <=  '1';
986
                reg             <=  x"0035";
987
                wait for clock_period;
988
                clock_reg_rx_we <=  '0';
989
                wait for clock_period;
990
 
991
                write(x"AA");
992
                write(x"BB");
993
                write(x"CC");
994
                write(x"DD");
995
                write(x"EE");
996
                write(x"FF");
997
                wait for clock_period;
998
                while tx_fifo_empty = '0' loop
999
                        wait for clock_period;
1000
                end loop;
1001
                loopback <= false;
1002
                wait for clock_period * 50000;
1003
                stop <= true;
1004
                wait;
1005
        end process;
1006
 
1007
        ack: process
1008
        begin
1009
                while not stop loop
1010
                        if rx_fifo_empty = '0' then
1011
                                rx_fifo_re <= '1';
1012
                        else
1013
                                rx_fifo_re <= '0';
1014
                        end if;
1015
                        wait for clock_period;
1016
                end loop;
1017
                wait;
1018
        end process;
1019
        rx <= tx when loopback else '0'; -- loop back test
1020
        uut: work.uart_pkg.uart_top
1021
                generic map (
1022
                clock_frequency    => g.clock_frequency,
1023
                delay              => g.delay,
1024
                asynchronous_reset => g.asynchronous_reset,
1025
                baud               => 115200,
1026
                format             => uart_8N1,
1027
                fifo_depth         => fifo_depth)
1028
                port map (
1029
                        clk => clk,
1030
                        rst => rst,
1031
 
1032
                        tx             =>  tx,
1033
                        tx_fifo_full   =>  tx_fifo_full,
1034
                        tx_fifo_empty  =>  tx_fifo_empty,
1035
                        tx_fifo_we     =>  tx_fifo_we,
1036
                        tx_fifo_data   =>  di,
1037
 
1038
                        rx             =>  rx,
1039
                        rx_fifo_full   =>  rx_fifo_full,
1040
                        rx_fifo_empty  =>  rx_fifo_empty,
1041
                        rx_fifo_re     =>  rx_fifo_re,
1042
                        rx_fifo_data   =>  do,
1043
 
1044
                        reg             => reg,
1045
                        clock_reg_tx_we => clock_reg_tx_we,
1046
                        clock_reg_rx_we => clock_reg_rx_we,
1047
                        control_reg_we  => control_reg_we);
1048
 
1049
end architecture;
1050
 

powered by: WebSVN 2.1.0

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