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

Subversion Repositories rs232_syscon

[/] [rs232_syscon/] [trunk/] [VHDL/] [uart_sqclk_pack.vhd] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 jclaytons
--------------------------------------------------------------------------
2
-- Package of UART components
3
--
4
-- This UART uses a squarewave input for the BAUDRATE clock.  In other
5
-- words, the BAUD rate is exactly the same as the frequency of the
6
-- incoming clock.  This is in contrast to other UARTs which need a
7
-- Baud rate clock which is some multiple of the actual Baud rate
8
-- desired.  Because of the 1x nature of the Baud clock, the receiver
9
-- needs at least one Baud Clock interval in which to measure the
10
-- Baud clock versus the system clock, before it can start working.
11
-- Also, the system clock must be somewhat higher than the Baud clock
12
-- in order for the receiver to work.
13
--
14
-- This package contains the UART, plus individual async_tx and async_rx
15
-- modules, which are the transmit and receive sections of the UART.
16
--
17
--
18
 
19
library IEEE;
20
use IEEE.STD_LOGIC_1164.ALL;
21
use IEEE.NUMERIC_STD.ALL;
22
 
23
package uart_sqclk_pack is
24
 
25
  component uart_sqclk
26
    port (
27
 
28
      sys_rst_n     : in std_logic;
29
      sys_clk       : in std_logic;
30
      sys_clk_en    : in std_logic;
31
 
32
      -- rate and parity
33
      parity_i      : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
34
      rate_clk_i    : in std_logic;
35
 
36
      -- serial I/O
37
      tx_stream     : out std_logic;
38
      rx_stream     : in std_logic;
39
 
40
      --control and status
41
      tx_wr_i       : in  std_logic;        -- Starts Transmit
42
      tx_dat_i      : in  unsigned(7 downto 0);
43
      tx_done_o     : out std_logic;
44
      rx_restart_i  : in  std_logic;        -- High clears error flags, clears rx_done_o
45
      rx_dat_o      : out unsigned(7 downto 0);
46
      rx_wr_o       : out std_logic;        -- High pulse means store rx_dat_o.
47
      rx_done_o     : out std_logic;        -- Remains high after receive, until clk edge with rx_restart_i=1
48
      frame_err_o   : out std_logic;        -- High = error.  Reset when rx_restart_i asserted.
49
      parity_err_o  : out std_logic         -- High = error.  Reset when rx_restart_i asserted.
50
    );
51
  end component;
52
 
53
  component async_tx_sqclk
54
    port (
55
 
56
      sys_rst_n    : in std_logic;
57
      sys_clk      : in std_logic;
58
      sys_clk_en   : in std_logic;
59
 
60
      -- rate and parity
61
      tx_parity_i  : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
62
      tx_clk_i     : in std_logic;
63
 
64
      -- serial output
65
      tx_stream    : out std_logic;
66
 
67
      -- control and status
68
      tx_wr_i      : in  std_logic;        -- Starts Transmit
69
      tx_dat_i     : in  unsigned(7 downto 0);
70
      tx_done_o    : out std_logic
71
    );
72
  end component;
73
 
74
 
75
  component async_rx_sqclk
76
    port (
77
 
78
      sys_rst_n    : in std_logic;
79
      sys_clk      : in std_logic;
80
      sys_clk_en   : in std_logic;
81
 
82
      -- rate and parity
83
      rx_parity_i  : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
84
      rx_clk_i     : in std_logic;
85
 
86
      -- serial input
87
      rx_stream    : in std_logic;
88
 
89
      -- control and status
90
      rx_restart_i : in  std_logic;        -- High clears error flags, clears rx_done_o
91
      rx_dat_o     : out unsigned(7 downto 0);
92
      rx_wr_o      : out std_logic;        -- High pulse means store rx_dat_o.
93
      rx_done_o    : out std_logic;        -- Remains high after receive, until rx_restart_i
94
      frame_err_o  : out std_logic;        -- High = error.  Reset when rx_restart_i asserted.
95
      parity_err_o : out std_logic         -- High = error.  Reset when rx_restart_i asserted.
96
    );
97
  end component;
98
 
99
end uart_sqclk_pack;
100
 
101
package body uart_sqclk_pack is
102
end uart_sqclk_pack;
103
 
104
 
105
--------------------------------------------------------------------
106
-- UART.  Variable Speed, RX Buffer, but no TX buffer
107
-- High Speed Asynchronous Receiver & Transmitter
108
-- 
109
-- Description:
110
--   This block receives and transmits asynchronous serial bytes.  The Baudrate
111
-- and parity are selectable through inputs, but the number of bits per character
112
-- is fixed at eight.
113
--
114
-- NOTES:
115
-- Transmit starts when tx_wr_i is detected high at a rising clock edge.
116
-- Once the transmit operation is completed, tx_done_o latches high.
117
--
118
-- The receive input is passed through two layers of synchronizing flip-flops
119
-- to help mitigate metastability issues, since this signal can come from
120
-- outside of the sys_clk clock domain.  All other logic connecting to inputs
121
-- of this function are assumed to be within the same clock domain.
122
--
123
-- The receiver looks for a new start bit immediately following the rx_wr_o
124
-- pulse, but rx_done_o is delayed until the expected end of the received
125
-- character.  If a new start bit is detected just prior to the expected end
126
-- of the received character, then rx_done_o is not asserted.
127
--
128
-- Receive begins when the falling edge of the start bit is detected.
129
-- Then after 10 or 11 bit times have passed (depending on the parity setting)
130
-- the rx_wr_o signal will pulse high for one clock period, indicating rx_dat_o
131
-- contains valid receive data.  The rx_wr_o pulse is only issued if there is
132
-- no parity error, and the stop bit is actually detected high at the sampling
133
-- time.
134
-- The rx_dat_o outputs will hold the received data until the next rx_wr_o pulse.
135
-- The rx_dat_o output provides the received data, even in the presence of a
136
-- parity or stop-bit error.
137
-- Error flags are valid during rx_wr_o, but they remain latched, until
138
-- rx_restart_i.
139
--
140
-- The Baud rate is equal to the frequency of the rate_clk_i input.
141
-- It should be, as nearly as possible, a square wave of the desired
142
-- communications rate.
143
--
144
library IEEE;
145
use IEEE.STD_LOGIC_1164.ALL;
146
use IEEE.NUMERIC_STD.ALL;
147
 
148
entity uart_sqclk is
149
    port (
150
 
151
      sys_rst_n     : in std_logic;
152
      sys_clk       : in std_logic;
153
      sys_clk_en    : in std_logic;
154
 
155
      -- rate and parity
156
      parity_i      : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
157
      rate_clk_i    : in std_logic;
158
 
159
      -- serial I/O
160
      tx_stream     : out std_logic;
161
      rx_stream     : in std_logic;
162
 
163
      --control and status
164
      tx_wr_i       : in  std_logic;        -- Starts Transmit
165
      tx_dat_i      : in  unsigned(7 downto 0);
166
      tx_done_o     : out std_logic;
167
      rx_restart_i  : in  std_logic;        -- High clears error flags, clears rx_done_o
168
      rx_dat_o      : out unsigned(7 downto 0);
169
      rx_wr_o       : out std_logic;        -- High pulse means store rx_dat_o.
170
      rx_done_o     : out std_logic;        -- Remains high after receive, until clk edge with rx_restart_i=1
171
      frame_err_o   : out std_logic;        -- High = error.  Reset when rx_restart_i asserted.
172
      parity_err_o  : out std_logic         -- High = error.  Reset when rx_restart_i asserted.
173
    );
174
end uart_sqclk;
175
 
176
library work;
177
use work.uart_sqclk_pack.all;
178
 
179
architecture beh of uart_sqclk is
180
 
181
-- Components
182
 
183
begin
184
 
185
  tx1: async_tx_sqclk
186
    port map (
187
       sys_rst_n     => sys_rst_n,
188
       sys_clk       => sys_clk,
189
       sys_clk_en    => sys_clk_en,
190
 
191
       -- rate and parity
192
       tx_parity_i   => parity_i, -- 0=none, 1=even, 2 or 3=odd
193
       tx_clk_i      => rate_clk_i,
194
 
195
       -- serial output
196
       tx_stream     => tx_stream,
197
 
198
       -- control and status
199
       tx_wr_i       => tx_wr_i,       -- Starts Transmit
200
       tx_dat_i      => tx_dat_i,
201
       tx_done_o     => tx_done_o
202
    );
203
 
204
  rx1: async_rx_sqclk
205
    port map (
206
       sys_rst_n     => sys_rst_n,
207
       sys_clk       => sys_clk,
208
       sys_clk_en    => sys_clk_en,
209
 
210
       -- rate and parity
211
       rx_parity_i   => parity_i, -- 0=none, 1=even, 2 or 3=odd
212
       rx_clk_i      => rate_clk_i,
213
 
214
       -- serial input
215
       rx_stream     => rx_stream,
216
 
217
       -- control and status
218
       rx_restart_i  => rx_restart_i,  -- High clears error flags, clears rx_done_o
219
       rx_dat_o      => rx_dat_o,
220
       rx_wr_o       => rx_wr_o,       -- High pulse means store rx_dat_o.
221
       rx_done_o     => rx_done_o,     -- Remains high after receive, until rx_restart_i
222
       frame_err_o   => frame_err_o,   -- High = error.  Reset when rx_restart_i asserted.
223
       parity_err_o  => parity_err_o   -- High = error.  Reset when rx_restart_i asserted.
224
    );
225
 
226
end beh;
227
 
228
 
229
-------------------------------------------------------------------------------
230
-- Asynchronous Receiver With Output Buffer
231
------------------------------------------------------------------------------- 
232
--
233
-- Author: John Clayton
234
-- Date  : Aug  05, 2013 Added this change log header, which was missing.
235
--                       Added first_edge signal to avoid erroneous initial
236
--                       baud interval measurement (John Clayton & Philip 
237
--                       Kasavan)
238
--         Jan.  2, 2014 Added output buffer, changed idle_prep to include
239
--                       the actual transition to IDLE state.  Added
240
--                       POST_RECV state, so that the rx_done_o signal will
241
--                       reflect the true end of the received character.
242
--                       This helps in applications where a received
243
--                       asynchronous input is "echoed back" directly,
244
--                       as the rx_wr_o signal can be used to switch the
245
--                       signal at the correct time.
246
--         Feb.  6, 2014 Added requirement for half_baud to be non-zero
247
--                       before leaving IDLE state.  This prevents leaving
248
--                       IDLE due to falling edges prior to the first Baud
249
--                       interval measurement.
250
--
251
-- Description
252
-------------------------------------------------------------------------------
253
-- Squarewave tx_clk_i input determines rate.
254
-- (tx_clk_i does not really need to be a squarewave.  Only the rising edges
255
--  are measured and used.)
256
-- 
257
-- Description:
258
--   This block receives asynchronous serial bytes.  The Baudrate and parity
259
-- are determined by inputs, but the number of bits per character is
260
-- fixed at eight.
261
--
262
-- NOTES:
263
-- The receive input and baudrate clock are passed through two layers of
264
-- synchronizing flip-flops to mitigate metastability, since those signals can
265
-- originate outside of the sys_clk clock domain.  All other logic connecting to 
266
-- input of this function are assumed to be within the same clock domain.
267
--
268
-- The receiver looks for a new start bit immediately following the rx_wr_o
269
-- pulse, but rx_done_o is delayed until the expected end of the received
270
-- character.  If a new start bit is detected just prior to the expected end
271
-- of the received character, then rx_done_o is not asserted.
272
--
273
-- Receive begins when the falling edge of the start bit is detected.
274
-- Then after 10 or 11 bit times have passed (depending on the parity setting)
275
-- the rx_wr_o signal will pulse high for one clock period, indicating rx_dat_o
276
-- contains valid receive data.  The rx_wr_o pulse is only issued if there is
277
-- no parity error, and the stop bit is actually detected high at the sampling
278
-- time.
279
-- The rx_dat_o outputs will hold the received data until the next rx_wr_o pulse.
280
-- The rx_dat_o output provides the received data, even in the presence of a
281
-- parity or stop-bit error.
282
-- Error flags are valid during rx_wr_o, but they remain latched, until
283
-- rx_restart_i.
284
--
285
-- Although the receiver immediately restarts itself to receive the next
286
-- character, the rx_restart_i input can clear the error indicators.  The rx_restart_i
287
-- input is like a synchronous reset in this respect since it will cause a receive
288
-- operation to abort.
289
--
290
 
291
library IEEE;
292
use IEEE.STD_LOGIC_1164.ALL;
293
use IEEE.NUMERIC_STD.ALL;
294
 
295
entity async_rx_sqclk is
296
    port (
297
 
298
      sys_rst_n    : in std_logic;
299
      sys_clk      : in std_logic;
300
      sys_clk_en   : in std_logic;
301
 
302
      -- rate and parity
303
      rx_parity_i  : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
304
      rx_clk_i     : in std_logic;
305
 
306
      -- serial input
307
      rx_stream    : in std_logic;
308
 
309
      -- control and status
310
      rx_restart_i : in  std_logic;        -- High clears error flags, synchronously resets receiver
311
      rx_dat_o     : out unsigned(7 downto 0);
312
      rx_wr_o      : out std_logic;        -- High pulse means store rx_dat_o.
313
      rx_done_o    : out std_logic;        -- Indicates receiver is idle
314
      frame_err_o  : out std_logic;        -- High = error.  Reset when rx_restart_i asserted.
315
      parity_err_o : out std_logic         -- High = error.  Reset when rx_restart_i asserted.
316
    );
317
end async_rx_sqclk;
318
 
319
architecture beh of async_rx_sqclk is
320
 
321
 
322
-- RX signals
323
  -- rx_clk_i synchronizing flip-flops and rising edge detector
324
signal rx_clk_r1       : std_logic;
325
signal rx_clk_r2       : std_logic;
326
  -- RX input synchronizing flip flops
327
signal rx_stream_r1    : std_logic;
328
signal rx_stream_r2    : std_logic;
329
  -- RX signals
330
    -- RX State Machine
331
type RX_STATE_TYPE is (IDLE, CHECK_START_1, CHECK_START_2, RECV_DATA, POST_RECV);
332
signal rx_state        : RX_STATE_TYPE;
333
signal start_bit_start : std_logic;             -- Signals falling edge of rx_stream_i
334
signal rx_sr           : unsigned(8 downto 0);  -- Shift register
335
signal rx_bcnt         : unsigned(3 downto 0);  -- Number of bits left, counts down
336
signal rx_bcnt_start   : unsigned(3 downto 0);  -- Total number of bits
337
signal rx_parity_good  : std_logic;
338
  -- Timers have been sized to hold baud interval for speeds as slow as 9600 bps at 100MHz sys_clk
339
signal rx_timer        : unsigned(13 downto 0); -- Elapsed sys_clks from last bit time start
340
signal half_baud       : unsigned(13 downto 0); -- One half of full_baud
341
signal full_baud       : unsigned(13 downto 0); -- Baud interval, as measured from rx_clk_i
342
signal baud_timer      : unsigned(13 downto 0); -- Used to measure baud interval
343
signal bit_sampled     : std_logic;             -- High indicates bit is already sampled, don't allow resampling.
344
 
345
signal first_edge      : std_logic;
346
 
347
begin
348
 
349
  -- Synchronizing flip flops to avoid metastability issues...
350
  rx_stream_syncproc: Process(sys_rst_n,sys_clk)
351
  BEGIN
352
    if (sys_rst_n = '0') then
353
      rx_stream_r1 <= '1';
354
      rx_stream_r2 <= '1';
355
    elsif (sys_clk'event AND sys_clk='1') then
356
      if (sys_clk_en='1') then
357
        rx_stream_r2 <= rx_stream_r1;
358
        rx_stream_r1 <= rx_stream;
359
      end if;
360
    end if;
361
  END PROCESS rx_stream_syncproc;
362
--  start_bit_start <= rx_stream_r2 and not rx_stream_r1;
363
  -- This signal has been rewritten carefully to avoid "artifacts" which occur
364
  -- during simulation, when rx_stream_r1 is 'X', in a manner reminiscent of
365
  -- metastability.
366
  start_bit_start <= '1' when rx_stream_r2='1' and rx_stream_r1/='1' else '0';
367
 
368
  -- Synchronizing flip flops to avoid metastability issues...
369
  rx_clk_syncproc: Process(sys_rst_n,sys_clk)
370
  BEGIN
371
    if (sys_rst_n = '0') then
372
      rx_clk_r1 <= '0';
373
      rx_clk_r2 <= '0';
374
    elsif (sys_clk'event AND sys_clk='1') then
375
      if (sys_clk_en='1') then
376
        rx_clk_r2 <= rx_clk_r1;
377
        rx_clk_r1 <= rx_clk_i;
378
      end if;
379
    end if;
380
  END PROCESS rx_clk_syncproc;
381
 
382
  -- This is the baud interval measuring process.
383
  -- Measurements are only made between rising edges
384
  baud_measure_proc: Process(sys_rst_n,sys_clk)
385
  BEGIN
386
    if (sys_rst_n = '0') then
387
      full_baud  <= (others=>'0');
388
      baud_timer <= (others=>'0');
389
      first_edge <= '0';
390
    elsif (sys_clk'event AND sys_clk='1') then
391
      if (sys_clk_en='1') then
392
        if(first_edge = '1')then
393
          if (rx_clk_r1='1' and rx_clk_r2='0') then
394
            full_baud  <= baud_timer;
395
            baud_timer <= (others=>'0');
396
          else
397
            baud_timer <= baud_timer+1;
398
          end if;
399
        elsif(rx_clk_r1='1' and rx_clk_r2='0') then
400
          first_edge <= '1';
401
        end if;
402
      end if;
403
    end if;
404
  END PROCESS baud_measure_proc;
405
 
406
 
407
  -- This process handles the incoming bits
408
  uart_rx_bits: Process(sys_rst_n,sys_clk)
409
 
410
  procedure idle_prep is
411
  begin
412
    rx_done_o   <= '1';
413
    bit_sampled <= '0';
414
    rx_bcnt     <= (others=>'0');
415
    rx_timer    <= (others=>'0');
416
    rx_state    <= IDLE;
417
  end idle_prep;
418
 
419
  begin
420
    if (sys_rst_n = '0') then
421
      idle_prep;
422
      rx_sr        <= (others=>'0');
423
      frame_err_o  <= '0';
424
      parity_err_o <= '0';
425
      rx_wr_o      <= '0';
426
      rx_dat_o     <= (others=>'0');
427
    elsif (sys_clk'event AND sys_clk='1') then
428
      if (sys_clk_en='1') then
429
        -- Default values
430
        rx_wr_o      <= '0';           -- Default to no data write
431
        -- Handle incrementing the sample timer
432
        rx_timer<=rx_timer+1;
433
        -- State transitions
434
        case rx_state is
435
 
436
          when IDLE         =>
437
            rx_done_o   <= '1';           -- Indicate receive is done.
438
            bit_sampled <= '0';           -- Indicate bit is not yet sampled.
439
            if (rx_restart_i='1') then
440
              idle_prep;
441
              frame_err_o  <= '0';        -- At rx_restart, also clear error flags
442
              parity_err_o <= '0';
443
            elsif (half_baud/=0 and start_bit_start='1') then
444
              rx_timer  <= (others=>'0'); -- Reset timer back to zero
445
              rx_bcnt   <= rx_bcnt_start; -- Initialize bit counter
446
              rx_done_o <= '0';
447
              rx_state  <= CHECK_START_1;
448
            end if;
449
 
450
          when CHECK_START_1 =>
451
            if (rx_restart_i='1') then    -- Restart has very high priority
452
              idle_prep;
453
            elsif (rx_stream_r2='1') then -- High during this time is an error
454
              frame_err_o <= '1';
455
              idle_prep;
456
            elsif (rx_timer>=half_baud) then -- Must use >= since threshold may change downward
457
              rx_state  <= CHECK_START_2;
458
            end if;
459
 
460
          when CHECK_START_2 =>            -- During second half of start bit, don't verify low level
461
            if (rx_restart_i='1') then     -- Restart has very high priority
462
              idle_prep;
463
            elsif (rx_timer>=full_baud or rx_stream_r2='1') then -- Wait for end of start bit
464
              rx_timer <= (others=>'0'); -- Reset timer back to zero
465
              rx_state <= RECV_DATA;
466
            end if;
467
 
468
          when RECV_DATA     =>
469
            if (rx_restart_i='1') then     -- Restart has very high priority
470
              idle_prep;
471
            elsif (rx_timer>=full_baud) then -- Must use >= since threshold may change downward
472
              rx_timer <= (others=>'0'); -- Reset timer back to zero
473
              bit_sampled <= '0';
474
            elsif (rx_timer>=half_baud and bit_sampled='0') then -- Must use >= since threshold may change downward
475
              bit_sampled <= '1';
476
              if (rx_bcnt="0000") then
477
                rx_state <= POST_RECV;
478
                rx_dat_o <= rx_sr(7 downto 0);
479
                if (rx_parity_good='1' and rx_stream_r2='1') then
480
                  rx_wr_o <= '1';            -- If all is correct, create a one clock long pulse to store rx_dat_o.
481
                else
482
                  if (rx_stream_r2='0') then
483
                    frame_err_o <= '1';        -- Record error if there is a bad stop bit
484
                  end if;
485
                  if (rx_parity_good='0') then
486
                    parity_err_o <= '1';       -- Record error if there is bad parity
487
                  end if;
488
                end if;
489
              else -- Process a new bit
490
                rx_sr(7 downto 0) <= rx_sr(8 downto 1);
491
                if (rx_parity_i = "00") then
492
                  rx_sr(7) <= rx_stream_r2;  -- Store the new incoming bit
493
                else
494
                  rx_sr(8) <= rx_stream_r2;
495
                end if;
496
                rx_bcnt <= rx_bcnt-1;
497
              end if;
498
            end if;
499
 
500
          when POST_RECV => -- Wait out latter half of stop bit, checking for start bits...
501
            if (rx_restart_i='1') then
502
              bit_sampled  <= '0';
503
              frame_err_o  <= '0'; -- At rx_restart, also clear error flags
504
              parity_err_o <= '0';
505
              idle_prep;
506
            elsif (start_bit_start='1') then
507
              bit_sampled <= '0';
508
              rx_timer  <= (others=>'0'); -- Reset timer back to zero
509
              rx_bcnt   <= rx_bcnt_start; -- Initialize bit counter
510
              rx_done_o <= '0';
511
              rx_state  <= CHECK_START_1;
512
            elsif (rx_timer>=full_baud) then -- Wait for end of start bit
513
              bit_sampled <= '0'; -- Indicate bit is not yet sampled.
514
              idle_prep; -- Asserts rx_done_o to indicate completion
515
            end if;
516
 
517
          when others => null;
518
 
519
        end case;
520
      end if;
521
    end if;
522
  end process uart_rx_bits;
523
 
524
  -------------------------
525
  -- Assign number of bits to shift in.
526
  rx_bcnt_start <= "1000" when (rx_parity_i="00") else "1001";
527
 
528
  -------------------------
529
  -- Assign half baud period
530
  half_baud <= ('0' & full_baud(13 downto 1));
531
 
532
  -------------------------
533
  -- Parity check process
534
  rx_parity_check: process(rx_sr, rx_parity_i)
535
  begin
536
    if (rx_parity_i="00") then       -- No parity...
537
      rx_parity_good <= '1'; -- (always good.)
538
    elsif (rx_parity_i="01") then    -- Even parity...
539
      rx_parity_good <= not (rx_sr(0) XOR rx_sr(1) XOR rx_sr(2) XOR rx_sr(3) XOR rx_sr(4)
540
                                      XOR rx_sr(5) XOR rx_sr(6) XOR rx_sr(7) XOR rx_sr(8));
541
    else                     -- Odd parity...
542
      rx_parity_good <=     (rx_sr(0) XOR rx_sr(1) XOR rx_sr(2) XOR rx_sr(3) XOR rx_sr(4)
543
                                      XOR rx_sr(5) XOR rx_sr(6) XOR rx_sr(7) XOR rx_sr(8));
544
    end if;
545
  end process;
546
 
547
end beh;
548
 
549
 
550
-------------------------------------------------------------------------------
551
-- Asynchronous Transmitter With No Buffering
552
------------------------------------------------------------------------------- 
553
--
554
-- Author: John Clayton
555
-- Date  : Aug  08, 2013 Added this change log header, which was missing.
556
--                       Changed tx_done_o signal so that it pulses after
557
--                       the stop bit is finished.  How could this have
558
--                       remained so woefully incorrect for so long?!
559
--         Jan  02, 2014 Fixed a latent bug in the logic for asserting
560
--                       tx_done_o.  Prior to this fix, it was possible
561
--                       for a write that was coincident with do_txbit to
562
--                       be ignored!  Once again, how could this have
563
--                       remained so woefully incorrect all this time?!
564
--         Jan  07, 2014 Rewrote the startup logic to allow for cases
565
--                       when tx_wr_i='1' and tx_bcnt="0000" and do_txbit='1'
566
--                       Also rewrote the tx_done_o signal so that it is
567
--                       asserted earlier - when "tx_almost_done" is high.
568
--                       This is all calculated to allow the transmitter
569
--                       to send characters back-to-back using its own
570
--                       tx_done_o signal as a tx_wr_i signal.  This is
571
--                       actually getting pretty neat.  The unit sends out
572
--                       asynchronous characters, but insists on doing it
573
--                       in synchronism with the tx_clk_i input... so it
574
--                       isn't really very asynchronous in that sense!
575
--
576
-- Description
577
-------------------------------------------------------------------------------
578
-- Squarewave tx_clk_i input determines rate.
579
-- (tx_clk_i need not be a squarewave for this module, since only the rising
580
--  edge is used.  In the accompanying receiver, however, both edges are used.)
581
-- 
582
-- Description:
583
--   This block transmits asynchronous serial bytes.  The Baudrate and parity
584
-- are determined by inputs, but the number of bits per character is
585
-- fixed at eight.
586
--
587
-- NOTES:
588
-- Transmit starts when the transmitter is idle and tx_wr_i is detected high
589
-- at a rising sys_clk edge.
590
--
591
-- Once the transmit operation is completed, done_o latches high.
592
--
593
-- Since the baud clock might be asynchronous to the sys_clk, there are
594
-- syncronizing flip-flops on it inside this module.
595
 
596
library IEEE;
597
use IEEE.STD_LOGIC_1164.ALL;
598
use IEEE.NUMERIC_STD.ALL;
599
 
600
entity async_tx_sqclk is
601
    port (
602
 
603
      sys_rst_n    : in std_logic;
604
      sys_clk      : in std_logic;
605
      sys_clk_en   : in std_logic;
606
 
607
      -- rate and parity
608
      tx_parity_i  : in unsigned(1 downto 0); -- 0=none, 1=even, 2 or 3=odd
609
      tx_clk_i     : in std_logic;
610
 
611
      -- serial output
612
      tx_stream    : out std_logic;
613
 
614
      -- control and status
615
      tx_wr_i      : in  std_logic;        -- Starts Transmit
616
      tx_dat_i     : in  unsigned(7 downto 0);
617
      tx_done_o    : out std_logic
618
    );
619
end async_tx_sqclk;
620
 
621
architecture beh of async_tx_sqclk is
622
 
623
-- TX signals
624
  -- TX clock synchronizing flip-flops and rising edge detection
625
signal tx_clk_r1 : std_logic;
626
signal tx_clk_r2 : std_logic;
627
  -- TX clock enable, shift register and bit count
628
signal do_txbit       : std_logic;
629
signal tx_sr          : unsigned(9 downto 0);
630
signal tx_bcnt        : unsigned(3 downto 0); -- Number of bits
631
signal tx_almost_done : std_logic;
632
signal tx_done        : std_logic;
633
 
634
begin
635
 
636
  -- This process detects the rising edge of tx_clk_i
637
  tx_clk_edge_proc: Process(sys_rst_n,sys_clk)
638
  BEGIN
639
    if (sys_rst_n = '0') then
640
      tx_clk_r1 <= '0';
641
      tx_clk_r2 <= '0';
642
    elsif (sys_clk'event AND sys_clk='1') then
643
      if (sys_clk_en='1') then
644
        tx_clk_r1 <= tx_clk_i;
645
        tx_clk_r2 <= tx_clk_r1;
646
      end if;
647
    end if;
648
  END PROCESS tx_clk_edge_proc;
649
  do_txbit <= (tx_clk_r1 and not tx_clk_r2); -- rising edge detect
650
 
651
  -- This process loads the shift register, then counts as the bits transmit out.
652
  byte_tx: Process(sys_rst_n,sys_clk)
653
  BEGIN
654
    if (sys_rst_n = '0') then
655
      tx_sr     <= (others=>'0');
656
      tx_bcnt   <= (others=>'0');
657
      tx_stream <= '1';
658
      tx_done   <= '1';
659
    elsif (sys_clk'event and sys_clk='1') then
660
      if (sys_clk_en='1') then
661
        -- Start a new transmission when ready
662
        -- Case 1 is starting while do_txbit is high
663
        if tx_bcnt="0000" and do_txbit='1' and tx_wr_i='1' then
664
          tx_stream <= '0';                             -- Provide start bit
665
          tx_sr(7 downto 0) <= tx_dat_i;                -- Load the TX data
666
          tx_sr(8) <= '1';                              -- Default the parity bit to one
667
          if(tx_parity_i = "00") then                   --If no parity...
668
            tx_bcnt  <= "1001";                         -- send start, 8 data bits, and stop
669
          elsif (tx_parity_i = "01") then               --If even parity...
670
            tx_bcnt  <= "1010";                         -- send start, 8 data bits, parity, and stop
671
            tx_sr(8) <= tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
672
                        tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7);
673
          else                                          --If odd parity...
674
            tx_bcnt  <= "1011";                         --send start, 8 data bits, parity, and stop
675
            tx_sr(8) <= NOT (tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
676
                             tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7));
677
          end if;
678
          tx_done <= '0';
679
        -- Case 2 is starting while do_txbit is low
680
        elsif tx_done='1' and tx_wr_i='1' then -- Only allow loads when transmitter is idle
681
          tx_sr(0) <= '0';                              -- Load start bit
682
          tx_sr(8 downto 1) <= tx_dat_i;                -- Load the TX data
683
          tx_sr(9) <= '1';                              -- Default the parity bit to one
684
          if(tx_parity_i = "00") then                   --If no parity...
685
            tx_bcnt  <= "1010";                         -- send start, 8 data bits, and stop
686
          elsif (tx_parity_i = "01") then               --If even parity...
687
            tx_bcnt  <= "1011";                         -- send start, 8 data bits, parity, and stop
688
            tx_sr(9) <= tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
689
                        tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7);
690
          else                                          --If odd parity...
691
            tx_bcnt  <= "1011";                         --send start, 8 data bits, parity, and stop
692
            tx_sr(9) <= NOT (tx_dat_i(0) XOR tx_dat_i(1) XOR tx_dat_i(2) XOR tx_dat_i(3) XOR
693
                             tx_dat_i(4) XOR tx_dat_i(5) XOR tx_dat_i(6) XOR tx_dat_i(7));
694
          end if;
695
          tx_done <= '0';
696
        -- Process through the remaining data
697
        elsif(tx_bcnt>"0000" and do_txbit='1') then     -- Still have bits to send?
698
          tx_bcnt <= tx_bcnt-1;
699
          tx_sr(8 downto 0) <= tx_sr(9 downto 1);       -- Right shift the data (send LSB first)
700
          tx_sr(9) <= '1';
701
          tx_stream <= tx_sr(0);
702
        end if;
703
        -- Assert tx_done when truly finished.
704
        if tx_almost_done='1' and tx_wr_i='0' then
705
          tx_done <= '1';
706
        end if;
707
      end if; -- sys_clk_en
708
    end if; -- sys_clk'event...
709
  END PROCESS byte_tx;
710
 
711
  tx_almost_done <= '1' when (tx_done='0' and tx_bcnt="0000" and do_txbit='1') else '0';
712
  tx_done_o <= '1' when tx_done='1' or tx_almost_done='1' else '0';
713
 
714
end beh;
715
 
716
 

powered by: WebSVN 2.1.0

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