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

Subversion Repositories light52

[/] [light52/] [trunk/] [vhdl/] [light52_uart.vhdl] - Blame information for rev 8

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

Line No. Rev Author Line
1 2 ja_rd
--------------------------------------------------------------------------------
2
-- light52_uart.vhdl -- Basic, hardwired RS232 UART.
3
--------------------------------------------------------------------------------
4
--
5
-- Most operational parameters are hardcoded: 8 bit words, no parity, 1 stop 
6
-- bit. The only parameter that can be configured in run time is the baud rate,
7
-- and only if generic HARDWIRED is set to false.
8
--
9
-- The UART is independent of any external timers and has its own baud rate 
10
-- counter (if enabled with generic HARDWIRED). 
11
-- 9-bit modes from the original MCS51 UART are not yet supported.
12
-- The UART supports polled mode with TxRdy and RxRdy flags in SCON and will 
13
-- eventually support parity bits. 
14
--
15
-- The receiver logic is a simplified copy of the original 8051 UART as 
16
-- described in Intel manuals. The bit period is split in 16 sampling periods, 
17
-- and 3 samples are taken at the center of each bit period. The bit value is 
18
-- decided by majority. The receiver logic has some error recovery capability 
19
-- that should make this core reliable enough for actual application use -- yet, 
20
-- the core does not have a formal test bench.
21
--
22
-- See usage notes below.
23
--------------------------------------------------------------------------------
24
-- Copyright (C) 2012 Jose A. Ruiz
25
--                                                              
26
-- This source file may be used and distributed without         
27
-- restriction provided that this copyright statement is not    
28
-- removed from the file and that any derivative work contains  
29
-- the original copyright notice and the associated disclaimer. 
30
--                                                              
31
-- This source file is free software; you can redistribute it   
32
-- and/or modify it under the terms of the GNU Lesser General   
33
-- Public License as published by the Free Software Foundation; 
34
-- either version 2.1 of the License, or (at your option) any   
35
-- later version.                                               
36
--                                                              
37
-- This source is distributed in the hope that it will be       
38
-- useful, but WITHOUT ANY WARRANTY; without even the implied   
39
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
40
-- PURPOSE.  See the GNU Lesser General Public License for more 
41
-- details.                                                     
42
--                                                              
43
-- You should have received a copy of the GNU Lesser General    
44
-- Public License along with this source; if not, download it   
45
-- from http://www.opencores.org/lgpl.shtml
46
--------------------------------------------------------------------------------
47
 
48
library ieee;
49
use ieee.std_logic_1164.all;
50
use ieee.numeric_std.all;
51
 
52
--------------------------------------------------------------------------------
53
-- UART programmer model
54
--------------------------------------------------------------------------------
55
--
56
-- The UART has a number of configuration registers addressable with input 
57
-- signal addr_i:
58
--
59
-- [00] => SCON: Status/control register (r/w).
60
-- [01] => SBUF: Data buffer, both transmission and reception.
61
-- [10] => SBPL: Bit period register, low byte -- OPTIONAL.
62
-- [11] => SBPH: Bit period register, high byte -- OPTIONAL.
63
--
64
-- Note that the SFR address mapping is determined externally.
65
-- Note too that SCON flags are not compatible to the original 51 except for 
66
-- the TI and RI flags.
67
--
68
-- Data buffers:
69
----------------
70
--
71
-- SBUF works as in the original 8051. Writing to it triggers a transmission, 
72
-- and the same address [00b] is used for both the rx and the tx buffer. 
73
--
74
-- Writing to the data buffer when flag TxRdy is high will trigger a 
75
-- transmission and clear flag TxRdy.
76
-- Writing to the data buffer when flag TxRdy is clear will have no effect.
77
-- 
78
-- Reading the data register when flag RxRdy is high will return the last 
79
-- received data byte, and will clear flag RxRdy but NOT RxIrq. 
80
-- Reading the register when flag RxRdy is clear will return indeterminate data,
81
-- which in practice will usually be the last byte received.
82
--
83
-- Interrupts:
84
--------------
85
--
86
-- The core has two interrupt sources tied to a single external irq line. The
87
-- sources are these:
88
-- 
89
-- -# Receiver interrupt: Raised when the stop bit is sampled and determined 
90
--    to be valid (about the middle of the bit period).
91
--    If the stop bit is not valid (not high) then the interrupt is not 
92
--    triggered. If a start bit is determined to be spurious (i.e. the falling
93
--    edge is detected but the bit value when sampled is not 0) then the
94
--    interrupt is not triggered -- because reception is aborted.
95
--    This interrupt sets flag RxIrw in the status register.
96
-- -# Transmitter interrupt: Raised at the end of the transmission of the stop
97
--    bit.
98
--    This interrupt sets flag TxIrq in the status register 1 clock cycle after
99
--    the interrupt is raised.
100
-- 
101
-- The core does not have any interrupt enable mask. If any interrupt source 
102
-- triggers, the output irq_o is asserted for one cycle. This is all the extent 
103
-- of the interrupt processing done by this module -- enough to be connected
104
-- to the light52 interrupt module but not for general use outside this project.
105
-- 
106
-- Error detection:
107
-------------------
108
--
109
-- The core is capable of detecting and recovering from these error conditions:
110
-- 
111
-- -# When a start bit is determined to be spurious (i.e. the falling edge is 
112
--    detected but the bit value when sampled is not 0) then the core returns to
113
--    its idle state (waiting for a new start bit).
114
-- -# If a stop bit is determined to be invalid (not 1 when sampled), the 
115
--    reception interrupt is not triggered and the received byte is discarded.
116
-- -# When the 3 samples taken from the center of a bit period are not equal, 
117
--    the bit value is decided by majority.
118
-- 
119
-- In none of the 3 cases does the core raise any error flag. It would be very 
120
-- easy to include those flags in the core, but it would take a lot more time 
121
-- to test them minimally and that's why they haven't been included.
122
--
123
-- Status register flags:
124
-------------------------
125
--
126
--      7       6       5       4       3       2       1       0
127
--  +-------+-------+-------+-------+-------+-------+-------+-------+
128
--  |   0   |   0   | RxRdy | TxRdy |   0   |   0   | RxIrq | TxIrq |
129
--  +-------+-------+-------+-------+-------+-------+-------+-------+
130
--      h       h       r       r       h       h      W1C     W1C    
131
--
132
--  Bits marked 'h' are hardwired and can't be modified. 
133
--  Bits marked 'r' are read only; they are set and clear by the core.
134
--  Bits marked W1C ('Write 1 Clear') are set by the core when an interrupt 
135
--  has been triggered and must be cleared by the software by writing a '1'.
136
--
137
-- -# Status bit TxRdy is high when there isn't any transmission in progress. 
138
--    It is cleared when data is written to the transmission buffer and is 
139
--    raised at the same time the transmission interrupt is triggered.
140
-- -# Status bit RxRdy is raised at the same time the receive interrupt is
141
--    triggered and is cleared when the data register is read.
142
-- -# Status bit TxIrq is raised when the transmission interrupt is triggered 
143
--    and is cleared when a 1 is written to it.
144
-- -# Status bit RxIrq is raised when the reception interrupt is triggered 
145
--    and is cleared when a 1 is written to it.
146
--
147
-- When writing to the status/control registers, only flags TxIrq and RxIrq are
148
-- affected, and only when writing a '1' as explained above. All other flags 
149
-- are read-only.
150
--
151
-- Baud rate configuration:
152
---------------------------
153
--
154
-- The baud rate is determined by the value of 14-bit register 'bit_period_reg'.
155
-- This register holds the length of the bit period in clock cycles and its
156
-- value may be hardcoded or configured at run time.
157
--
158
-- When generic HARDWIRED is true, bit_period_reg is hardwired with a value 
159
-- computed from the value of generic BAUD_RATE. The bit period computation 
160
-- needs to know the master clock rate, which should be given in generic 
161
-- CLOCK_RATE.
162
-- Writes to the baud registers when HARDWIRED is true will be ignored.
163
--
164
-- When generic HARDWIRED is false, generics BAUD_RATE and CLOCK_RATE determine 
165
-- the reset value of bit_period_reg, but the register can be changed at run 
166
-- time by writing at addresses [10b] and [11b], which access the low and high 
167
-- bytes of the register, respectively.
168
-- Reading from those register addresses returns the value of the status 
169
-- register (a LUT saving measure) so the registers are effectively write-only.
170
--
171
--------------------------------------------------------------------------------
172
-- Core interface signals:
173
--
174
-- clk_i:     Clock input, active rising edge.
175
-- reset_i:   Synchronous reset.
176
-- txd_o:     TxD UART output.
177
-- rxd_i:     RxD UART input -- synchronization logic included.
178
-- irq_o:     Interrupt output, asserted for 1 cycle when triggered.
179
-- data_i:    Data bus, input.
180
-- data_o:    Data bus, output.
181
-- addr_i:    Register selection address (see above).
182
-- wr_i:      Write enable input.
183
-- rd_i:      Read enable input.
184
-- ce_i:      Chip enable, must be active at the same time as wr_i or rd_i.
185
-- 
186
--
187
-- A detailed explanation of the interface timing will not be given. The core 
188
-- reads and writes like a synchronous memory. There's usage examples in other 
189
-- project files.
190
--------------------------------------------------------------------------------
191
 
192
entity light52_uart is
193
  generic (
194
    HARDWIRED     : boolean := true;  -- Baud rate hardwired to constant value 
195
    BAUD_RATE     : natural := 19200; -- Default (or hardwired) baud rate 
196
    CLOCK_FREQ    : natural := 50E6); -- Clock rate
197
    port (
198
        rxd_i     : in std_logic;
199
        txd_o     : out std_logic;
200
 
201
        irq_o     : out std_logic;
202
 
203
        data_i    : in std_logic_vector(7 downto 0);
204
        data_o    : out std_logic_vector(7 downto 0);
205
 
206
        addr_i    : in std_logic_vector(1 downto 0);
207
        wr_i      : in std_logic;
208
        rd_i      : in std_logic;
209
        ce_i      : in std_logic;
210
 
211
        clk_i     : in std_logic;
212
        reset_i   : in std_logic
213
    );
214
end light52_uart;
215
 
216
architecture hardwired of light52_uart is
217
 
218
-- Bit period expressed in master clock cycles
219
constant DEFAULT_BIT_PERIOD : integer := (CLOCK_FREQ / BAUD_RATE);
220
 
221
 
222
--##############################################################################
223
 
224
-- Common signals
225
 
226
signal reset :            std_logic;
227
signal clk :              std_logic;
228
 
229
 
230
signal bit_period_reg :   unsigned(13 downto 0);
231
signal sampling_period :  unsigned(9 downto 0);
232
 
233
 
234
-- Interrupt & status register signals
235
 
236
signal tx_irq_flag :      std_logic;
237
signal rx_irq_flag :      std_logic;
238
signal load_stat_reg :    std_logic;
239
signal load_tx_reg :      std_logic;
240
 
241
-- Receiver signals
242
signal rxd_q :            std_logic;
243
signal tick_ctr :         unsigned(3 downto 0);
244
signal state :            unsigned(3 downto 0);
245
signal next_state :       unsigned(3 downto 0);
246
signal start_bit_detected : std_logic;
247
signal reset_tick_ctr :   std_logic;
248
signal stop_bit_sampled : std_logic;
249
signal load_rx_buffer :   std_logic;
250
signal stop_error :       std_logic;
251
signal samples :          std_logic_vector(2 downto 0);
252
signal sampled_bit :      std_logic;
253
signal do_shift :         std_logic;
254
signal rx_buffer :        std_logic_vector(7 downto 0);
255
signal rx_shift_reg :     std_logic_vector(9 downto 0);
256
signal tick_ctr_enable :  std_logic;
257
signal tick_baud_ctr :    unsigned(10 downto 0);
258
 
259
signal rx_rdy_flag :      std_logic;
260
signal rx_irq :           std_logic;
261
signal set_rx_rdy_flag :  std_logic;
262
signal rxd :              std_logic;
263
 
264
signal read_rx :          std_logic;
265
signal status :           std_logic_vector(7 downto 0);
266
 
267
-- Transmitter signals 
268
 
269
signal tx_counter :       unsigned(13 downto 0);
270
signal tx_data :          std_logic_vector(10 downto 0);
271
signal tx_ctr_bit :       unsigned(3 downto 0);
272
signal tx_busy :          std_logic;
273
signal tx_irq :           std_logic;
274
 
275
 
276
 
277
begin
278
 
279
-- Do a minimal sanity check on the value of the generics.
280
-- This will only catch some of the many ways the configuration can go wrong,
281
-- the rest will get caught while debugging...
282
assert (BAUD_RATE*16) < CLOCK_FREQ
283
report "UART default baud rate is too high."
284
severity failure;
285
 
286
 
287
-- Rename the most commonly used inputs to get rid of the i/o suffix
288
clk <= clk_i;
289
reset <= reset_i;
290
rxd <= rxd_i;
291
 
292
 
293
-- Serial port status byte -- only 2 status flags -- SEE process interrupt_flags
294
-- below if you change these!
295
status <=
296
    "00" & rx_rdy_flag & (not tx_busy) &    -- State flags
297
    "00" & rx_irq_flag & tx_irq_flag;       -- Interrupt flags
298
 
299
-- Read register multiplexor
300
with addr_i select data_o <=
301
    rx_buffer   when "01",
302
    status      when others;
303
 
304
 
305
load_tx_reg <= '1' when wr_i = '1' and ce_i = '1' and addr_i = "01" else '0';
306
load_stat_reg <= '1' when wr_i = '1' and ce_i = '1' and addr_i = "00" else '0';
307
read_rx <= '1' when rd_i = '1' and ce_i = '1' else '0';
308
 
309
rx_irq <= set_rx_rdy_flag;
310
 
311
irq_o <= rx_irq or tx_irq;
312
 
313
interrupt_flags:
314
process(clk)
315
begin
316
  if clk'event and clk='1' then
317
    if reset = '1' then
318
      rx_irq_flag <= '0';
319
      tx_irq_flag <= '0';
320
    else
321
      if set_rx_rdy_flag='1' then
322
        rx_irq_flag <= '1';
323
      elsif load_stat_reg='1' and data_i(1)='1' then
324
        rx_irq_flag <= '0';
325
      end if;
326
      if tx_irq='1' then
327
        tx_irq_flag <= '1';
328
      elsif load_stat_reg='1' and data_i(0)='1' then
329
        tx_irq_flag <= '0';
330
      end if;
331
    end if;
332
  end if;
333
end process interrupt_flags;
334
 
335
 
336
baud_rate_registers:
337
process(clk)
338
begin
339
  if clk'event and clk='1' then
340
    if reset = '1' then
341
      bit_period_reg <= to_unsigned(DEFAULT_BIT_PERIOD,14);
342
    else
343
      if wr_i = '1' and ce_i = '1' then
344
        if addr_i = "10" then
345
          bit_period_reg(7 downto 0) <= unsigned(data_i);
346
        elsif addr_i = "11" then
347
          bit_period_reg(13 downto 8) <= unsigned(data_i(5 downto 0));
348
        end if;
349
      end if;
350
    end if;
351
  end if;
352
end process baud_rate_registers;
353
 
354
sampling_period <= bit_period_reg(13 downto 4);
355
 
356
 
357
-- Receiver --------------------------------------------------------------------
358
 
359
baud_counter:
360
process(clk)
361
begin
362
  if clk'event and clk='1' then
363
    if reset='1' then
364
      tick_baud_ctr <= (others => '0');
365
    else
366
      if tick_baud_ctr=sampling_period then
367
        tick_baud_ctr <= (others => '0');
368
      else
369
        tick_baud_ctr <= tick_baud_ctr + 1;
370
      end if;
371
    end if;
372
  end if;
373
end process baud_counter;
374
 
375
tick_ctr_enable<= '1' when tick_baud_ctr=sampling_period else '0';
376
 
377
-- Register RxD at the bit sampling rate -- 16 times the baud rate. 
378
rxd_input_register:
379
process(clk)
380
begin
381
  if clk'event and clk='1' then
382
    if reset='1' then
383
      rxd_q <= '0';
384
    else
385
      if tick_ctr_enable='1' then
386
        rxd_q <= rxd;
387
      end if;
388
    end if;
389
  end if;
390
end process rxd_input_register;
391
 
392
-- We detect the start bit when...
393
start_bit_detected <= '1' when
394
      state="0000" and        -- ...we're waiting for the start bit...
395
      rxd_q='1' and rxd='0'   -- ...and we see RxD going 1-to-0
396
      else '0';
397
 
398
-- As soon as we detect the start bit we synchronize the bit sampler to 
399
-- the start bit's falling edge.
400
reset_tick_ctr <= '1' when start_bit_detected='1' else '0';
401
 
402
-- We have seen the end of the stop bit when...
403
stop_bit_sampled <= '1' when
404
      state="1010" and        -- ...we're in the stop bit period...
405
      tick_ctr="1011"         -- ...and we get the 11th sample in the bit period
406
      else '0';
407
 
408
-- Load the RX buffer with the shift register when...
409
load_rx_buffer <= '1' when
410
      stop_bit_sampled='1' and  -- ...we've just seen the end of the stop bit...
411
      sampled_bit='1'           -- ...and its value is correct (1)
412
      else '0';
413
 
414
-- Conversely, we detect a stop bit error when...   
415
stop_error <= '1' when
416
      stop_bit_sampled='1' and  -- ...we've just seen the end of the stop bit...
417
      sampled_bit='0'           -- ...and its value is incorrect (0)
418
      else '0';
419
 
420
-- tick_ctr is a counter 16 times faster than the baud rate that is aligned to 
421
-- the falling edge of the start bit, so that when tick_ctr=0 we're close to 
422
-- the start of a bit period.      
423
bit_sample_counter:
424
process(clk)
425
begin
426
  if clk'event and clk='1' then
427
    if reset='1' then
428
      tick_ctr <= "0000";
429
    else
430
      if tick_ctr_enable='1' then
431
        -- Restart counter when it reaches 15 OR when the falling edge
432
        -- of the start bit is detected; this is how we synchronize to the 
433
        -- start bit.
434
        if tick_ctr="1111" or reset_tick_ctr='1' then
435
          tick_ctr <= "0000";
436
        else
437
          tick_ctr <= tick_ctr + 1;
438
        end if;
439
      end if;
440
    end if;
441
  end if;
442
end process bit_sample_counter;
443
 
444
-- Main RX state machine: 
445
-- 0      -> waiting for start bit
446
-- 1      -> sampling start bit
447
-- 2..9   -> sampling data bit 0 to 7
448
-- 10     -> sampling stop bit
449
next_state <=
450
  -- Start sampling the start bit when we detect the falling edge
451
  "0001" when state="0000" and start_bit_detected='1' else
452
  -- Return to idle state if the start bit is not a clean 0
453
  "0000" when state="0001" and tick_ctr="1010" and sampled_bit='1' else
454
  -- Return to idle state at the end of the stop bit period
455
  "0000" when state="1010" and tick_ctr="1111" else
456
  -- Otherwise, proceed to next bit period at the end of each period
457
  state + 1 when tick_ctr="1111" and do_shift='1' else
458
  state;
459
 
460
rx_state_machine_register:
461
process(clk)
462
begin
463
  if clk'event and clk='1' then
464
    if reset='1' then
465
      state <= "0000";
466
    else
467
      if tick_ctr_enable='1' then
468
        state <= next_state;
469
      end if;
470
    end if;
471
  end if;
472
end process rx_state_machine_register;
473
 
474
-- Collect 3 RxD samples from the 3 central sampling periods of the bit period.
475
rx_sampler:
476
process(clk)
477
begin
478
  if clk'event and clk='1' then
479
    if reset='1' then
480
      samples <= "000";
481
    else
482
      if tick_ctr_enable='1' then
483
        if tick_ctr="0111" then
484
          samples(0) <= rxd;
485
        end if;
486
        if tick_ctr="1000" then
487
          samples(1) <= rxd;
488
        end if;
489
        if tick_ctr="1001" then
490
          samples(2) <= rxd;
491
        end if;
492
      end if;
493
    end if;
494
  end if;
495
end process rx_sampler;
496
 
497
-- Decide the value of the RxD bit by majority
498
with samples select
499
  sampled_bit <=  '0' when "000",
500
                  '0' when "001",
501
                  '0' when "010",
502
                  '1' when "011",
503
                  '0' when "100",
504
                  '1' when "101",
505
                  '1' when "110",
506
                  '1' when others;
507
 
508
rx_buffer_register:
509
process(clk)
510
begin
511
  if clk'event and clk='1' then
512
    if reset='1' then
513
      rx_buffer <= "00000000";
514
      set_rx_rdy_flag <= '0';
515
    else
516
      if tick_ctr_enable='1' and load_rx_buffer='1' and rx_rdy_flag='0' then
517
        rx_buffer <= rx_shift_reg(8 downto 1);
518
        set_rx_rdy_flag <= '1';
519
      else
520
        set_rx_rdy_flag <= '0';
521
      end if;
522
    end if;
523
  end if;
524
end process rx_buffer_register;
525
 
526
rx_flag:
527
process(clk)
528
begin
529
  if clk'event and clk='1' then
530
    if reset='1' then
531
      rx_rdy_flag <= '0';
532
    else
533
      if set_rx_rdy_flag='1' then
534
        rx_rdy_flag <= '1';
535
      else
536
        if read_rx = '1' then
537
          rx_rdy_flag <= '0';
538
        end if;
539
      end if;
540
    end if;
541
  end if;
542
end process rx_flag;
543
 
544
-- RX shifter control: shift in any state other than idle state (0)
545
do_shift <= state(0) or state(1) or state(2) or state(3);
546
 
547
rx_shift_register:
548
process(clk)
549
begin
550
  if clk'event and clk='1' then
551
    if reset='1' then
552
      rx_shift_reg <= "1111111111";
553
    else
554
      if tick_ctr_enable='1' then
555
        if tick_ctr="1010" and do_shift='1' then
556
          rx_shift_reg(9) <= sampled_bit;
557
          rx_shift_reg(8 downto 0) <= rx_shift_reg(9 downto 1);
558
        end if;
559
      end if;
560
    end if;
561
  end if;
562
end process rx_shift_register;
563
 
564
 
565
-- Transmitter -----------------------------------------------------------------
566
 
567
 
568
main_tx_process:
569
process(clk)
570
begin
571
if clk'event and clk='1' then
572
 
573
  if reset='1' then
574
    tx_data <= "10111111111";
575
    tx_busy <= '0';
576
    tx_irq <= '0';
577
    tx_ctr_bit <= "0000";
578
    tx_counter <= (others => '0');
579
  elsif load_tx_reg='1' and tx_busy='0' then
580
    tx_data <= "1"&data_i&"01";
581
    tx_busy <= '1';
582
  else
583
    if tx_busy='1' then
584
      if tx_counter = bit_period_reg then
585
        tx_counter <= (others => '0');
586
        tx_data(9 downto 0) <= tx_data(10 downto 1);
587
        tx_data(10) <= '1';
588
        if tx_ctr_bit = "1010" then
589
           tx_busy <= '0';
590
           tx_irq <= '1';
591
           tx_ctr_bit <= "0000";
592
        else
593
           tx_ctr_bit <= tx_ctr_bit + 1;
594
        end if;
595
      else
596
        tx_counter <= tx_counter + 1;
597
      end if;
598
    else
599
      tx_irq <= '0';
600
    end if;
601
  end if;
602
end if;
603
end process main_tx_process;
604
 
605
txd_o <= tx_data(0);
606
 
607
end hardwired;

powered by: WebSVN 2.1.0

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