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

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [VHDL/] [acia6850.vhd] - Blame information for rev 209

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

Line No. Rev Author Line
1 138 davidgb
--===========================================================================--
2
--                                                                           --
3
--                  Synthesizable 6850 compatible ACIA                       --
4
--                                                                           --
5
--===========================================================================--
6 100 davidgb
--
7
--  File name      : acia6850.vhd
8 138 davidgb
--
9 100 davidgb
--  Entity name    : acia6850
10
--
11 138 davidgb
--  Purpose        : Implements a RS232 6850 compatible 
12 100 davidgb
--                   Asynchronous Communications Interface Adapter (ACIA)
13
--                  
14
--  Dependencies   : ieee.std_logic_1164
15 138 davidgb
--                   ieee.numeric_std
16 118 dilbert57
--                   ieee.std_logic_unsigned
17 138 davidgb
--
18
--  Author         : John E. Kent
19
--
20
--  Email          : dilbert57@opencores.org      
21
--
22
--  Web            : http://opencores.org/project,system09
23
--
24 100 davidgb
--  Origins        : miniUART written by Ovidiu Lupas olupas@opencores.org
25 138 davidgb
--
26
--  Registers      :
27
--
28
--  IO address + 0 Read - Status Register
29
--
30 100 davidgb
--     Bit[7] - Interrupt Request Flag
31
--     Bit[6] - Receive Parity Error (parity bit does not match)
32
--     Bit[5] - Receive Overrun Error (new character received before last read)
33
--     Bit[4] - Receive Framing Error (bad stop bit)
34
--     Bit[3] - Clear To Send level
35
--     Bit[2] - Data Carrier Detect (lost modem carrier)
36
--     Bit[1] - Transmit Buffer Empty (ready to accept next transmit character)
37
--     Bit[0] - Receive Data Ready (character received)
38
-- 
39
--  IO address + 0 Write - Control Register
40 138 davidgb
--
41 100 davidgb
--     Bit[7]     - Rx Interupt Enable
42
--          0     - disabled
43
--          1     - enabled
44 138 davidgb
--     Bits[6..5] - Transmit Control
45 100 davidgb
--        0 0     - TX interrupt disabled, RTS asserted
46 138 davidgb
--        0 1     - TX interrupt enabled,  RTS asserted
47
--        1 0     - TX interrupt disabled, RTS cleared
48
--        1 1     - TX interrupt disabled, RTS asserted, Send Break
49 100 davidgb
--     Bits[4..2] - Word Control
50 197 davidgb
--      0 0 0     - 7 data, 2 stop, even parity 
51
--      0 0 1     - 7 data, 2 stop, odd  parity
52
--      0 1 0     - 7 data, 1 stop, even parity
53
--      0 1 1     - 7 data, 1 stop, odd  parity
54
--      1 0 0     - 8 data, 2 stop, no   parity
55
--      1 0 1     - 8 data, 1 stop, no   parity
56
--      1 1 0     - 8 data, 1 stop, even parity
57
--      1 1 1     - 8 data, 1 stop, odd  parity
58 100 davidgb
--     Bits[1..0] - Baud Control
59
--        0 0     - Baud Clk divide by 1
60
--        0 1     - Baud Clk divide by 16
61
--        1 0     - Baud Clk divide by 64
62
--        1 1     - Reset
63 138 davidgb
--
64
--  IO address + 1 Read - Receive Data Register
65
--
66
--     Read when Receive Data Ready bit set
67
--     Read resets Receive Data Ready bit 
68
--
69
--  IO address + 1 Write - Transmit Data Register
70
--
71
--     Write when Transmit Buffer Empty bit set
72
--     Write resets Transmit Buffer Empty Bit
73
--
74
--
75 197 davidgb
--  Copyright (C) 2002 - 2012 John Kent
76 138 davidgb
--
77
--  This program is free software: you can redistribute it and/or modify
78
--  it under the terms of the GNU General Public License as published by
79
--  the Free Software Foundation, either version 3 of the License, or
80
--  (at your option) any later version.
81
--
82
--  This program is distributed in the hope that it will be useful,
83
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
84
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
85
--  GNU General Public License for more details.
86
--
87
--  You should have received a copy of the GNU General Public License
88
--  along with this program.  If not, see <http://www.gnu.org/licenses/>.
89
--
90
--===========================================================================--
91 100 davidgb
--                                                                           --
92 138 davidgb
--                              Revision  History                            --
93 100 davidgb
--                                                                           --
94 138 davidgb
--===========================================================================--
95
--
96 100 davidgb
-- Version Author        Date         Changes
97
--
98
-- 0.1     Ovidiu Lupas  2000-01-15   New model
99
-- 1.0     Ovidiu Lupas  2000-01      Synthesis optimizations
100 138 davidgb
-- 2.0     Ovidiu Lupas  2000-04      Bugs removed - the RSBusCtrl did not
101 100 davidgb
--                                    process all possible situations
102
--
103
-- 3.0     John Kent     2002-10      Changed Status bits to match MC6805
104
--                                    Added CTS, RTS, Baud rate control & Software Reset
105
-- 3.1     John Kent     2003-01-05   Added Word Format control a'la mc6850
106
-- 3.2     John Kent     2003-07-19   Latched Data input to UART
107
-- 3.3     John Kent     2004-01-16   Integrated clkunit in rxunit & txunit
108
--                                    TX / RX Baud Clock now external
109
--                                    also supports x1 clock and DCD. 
110
-- 3.4     John Kent     2005-09-13   Removed LoadCS signal. 
111 138 davidgb
--                                    Fixed ReadCS and Read 
112 100 davidgb
--                                    in miniuart_DCD_Init process
113
-- 3.5     John Kent     2006-11-28   Cleaned up code.
114
--
115
-- 4.0     John Kent     2007-02-03   Renamed ACIA6850
116
-- 4.1     John Kent     2007-02-06   Made software reset synchronous
117
-- 4.2     John Kent     2007-02-25   Changed sensitivity lists
118
--                                    Rearranged Reset process.
119 138 davidgb
-- 4.3     John Kent     2010-06-17   Updated header
120
-- 4.4     John Kent     2010-08-27   Combined with ACIA_RX & ACIA_TX
121
--                                    Renamed to acia6850
122 197 davidgb
-- 4.5     John Kent     2012-02-04   Re-arranged Rx & Tx Baud clock edge detect.
123
-- 4.6     John Kent     3021-01-30   Double sample RxC, TxC, and RxD with cpu_clk
124
--                                    for 125MHz Clock on Zybo Z7 board.
125 138 davidgb
--
126
 
127 100 davidgb
library ieee;
128
  use ieee.std_logic_1164.all;
129 138 davidgb
  use ieee.numeric_std.all;
130 100 davidgb
  use ieee.std_logic_unsigned.all;
131 118 dilbert57
--library unisim;
132
--  use unisim.vcomponents.all;
133 100 davidgb
 
134
-----------------------------------------------------------------------
135
-- Entity for ACIA_6850                                              --
136
-----------------------------------------------------------------------
137
 
138
entity acia6850 is
139
  port (
140
    --
141
    -- CPU Interface signals
142
    --
143 197 davidgb
    clk      : in  std_logic;                     -- CPU Clock
144 100 davidgb
    rst      : in  std_logic;                     -- Reset input (active high)
145
    cs       : in  std_logic;                     -- miniUART Chip Select
146
    addr     : in  std_logic;                     -- Register Select
147
    rw       : in  std_logic;                     -- Read / Not Write
148
    data_in  : in  std_logic_vector(7 downto 0);  -- Data Bus In 
149 138 davidgb
    data_out : out std_logic_vector(7 downto 0);  -- Data Bus Out
150
    irq      : out std_logic;                     -- Interrupt Request out
151 100 davidgb
    --
152
    -- RS232 Interface Signals
153
    --
154
    RxC   : in  std_logic;              -- Receive Baud Clock
155
    TxC   : in  std_logic;              -- Transmit Baud Clock
156
    RxD   : in  std_logic;              -- Receive Data
157
    TxD   : out std_logic;              -- Transmit Data
158
    DCD_n : in  std_logic;              -- Data Carrier Detect
159
    CTS_n : in  std_logic;              -- Clear To Send
160
    RTS_n : out std_logic               -- Request To send
161
    );
162
end acia6850;  --================== End of entity ==============================--
163
 
164
-------------------------------------------------------------------------------
165
-- Architecture for ACIA_6850 Interface registees
166
-------------------------------------------------------------------------------
167
 
168
architecture rtl of acia6850 is
169
 
170
  -----------------------------------------------------------------------------
171 197 davidgb
  -- Reset Signals
172 100 davidgb
  -----------------------------------------------------------------------------
173 197 davidgb
  signal ac_rst        : std_logic;          -- Reset (Software & Hardware)
174
  signal rx_rst        : std_logic;          -- Receive Reset (Software & Hardware)
175
  signal tx_rst        : std_logic;          -- Transmit Reset (Software & Hardware)
176 100 davidgb
 
177
  --------------------------------------------------------------------
178 197 davidgb
  --  Status Register: status_reg 
179 100 davidgb
  ----------------------------------------------------------------------
180
  --
181
  -----------+--------+-------+--------+--------+--------+--------+--------+
182
  --  Irq    | PErr   | OErr  | FErr   |  CTS   |  DCD   | TxRdy  | RxRdy  |
183 138 davidgb
  -----------+--------+-------+--------+--------+--------+--------+--------+
184 100 davidgb
  --
185
  -- Irq   - Bit[7] - Interrupt request
186
  -- PErr  - Bit[6] - Receive Parity error (parity bit does not match)
187
  -- OErr  - Bit[5] - Receive Overrun error (new character received before last read)
188
  -- FErr  - Bit[4] - Receive Framing Error (bad stop bit)
189
  -- CTS   - Bit[3] - Clear To Send level
190
  -- DCD   - Bit[2] - Data Carrier Detect (lost modem carrier)
191
  -- TxRdy - Bit[1] - Transmit Buffer Empty (ready to accept next transmit character)
192
  -- RxRdy - Bit[0] - Receive Data Ready (character received)
193
  -- 
194 197 davidgb
  constant RXRBIT       : integer := 0; -- Receive Data Ready
195
  constant TXRBIT       : integer := 1; -- Transmir Data Ready
196
  constant DCDBIT       : integer := 2; -- Data Carrier Detect
197
  constant CTSBIT       : integer := 3; -- Clear To Send (inverted)
198
  constant FERBIT       : integer := 4; -- Framing Error
199
  constant OERBIT       : integer := 5; -- Over Run Error
200
  constant PERBIT       : integer := 6; -- Parity error
201
  constant IRQBIT       : integer := 7; -- Interrupt Request Flag
202 138 davidgb
 
203 197 davidgb
 
204 100 davidgb
  ----------------------------------------------------------------------
205 197 davidgb
  --  Control Register: control_reg
206 100 davidgb
  ----------------------------------------------------------------------
207
  --
208
  -----------+--------+--------+--------+--------+--------+--------+--------+
209 197 davidgb
  --  RIEBIT | TX1BIT | TX0BIT | DATBIT | STPBIT | POEBIT | BD1BIT | BD0BIT |
210 100 davidgb
  -----------+--------+--------+--------+--------+--------+--------+--------+
211 197 davidgb
  -- RIEBIT - Bit[7]
212 100 davidgb
  -- 0       - Rx Interrupt disabled
213
  -- 1       - Rx Interrupt enabled
214 197 davidgb
  --
215
  -- TXnBIT - Bits[6..5]
216
  -- 0 0     - RTS low,  Tx Interrupt Disabled
217
  -- 0 1     - RTS low,  Tx Interrupt Enable
218
  -- 1 0     - RTS high, Tx interrupt Disabled
219
  -- 1 1     - RTS low,  Tx interrupt Disabled, send break
220
  --
221
  -- DATBIT, STPBIT, POEBIT - Bits[4..2]
222
  -- 0 0 0   - 7 data, 2 stop, even parity
223
  -- 0 0 1   - 7 data, 2 stop, odd  parity
224
  -- 0 1 0   - 7 data, 1 stop, even parity
225
  -- 0 1 1   - 7 data, 1 stop, odd  parity
226
  -- 1 0 0   - 8 data, 2 stop, no   parity
227
  -- 1 0 1   - 8 data, 1 stop, no   parity
228
  -- 1 1 0   - 8 data, 1 stop, even parity
229
  -- 1 1 1   - 8 data, 1 stop, odd  parity
230
  -- BDnBIT - Bits[1..0]
231 100 davidgb
  -- 0 0     - Baud Clk divide by 1
232
  -- 0 1     - Baud Clk divide by 16
233
  -- 1 0     - Baud Clk divide by 64
234
  -- 1 1     - reset
235
 
236 197 davidgb
  constant BD0BIT       : integer := 0; -- Baud clock divider 0=>1/64 1=>16/RESET
237
  constant BD1BIT       : integer := 1; -- Baud clock divider 0=>1/16 1=>64/RESET
238
  constant POEBIT       : integer := 2; -- parity 0=>even 1=>odd            (ctrl(DATBIT)=1 & ctrl(STPBIT)=0 => no parity)
239
  constant STPBIT       : integer := 3; -- stop bits 0=>2 stop 1=>1 stop    (ctrl(DATBIT)=1 & ctrl(STPBIT)=0 & ctrl(POEBIT)=1 => 1 stop bit)
240
  constant DATBIT       : integer := 4; -- data bits 0=>7 data bits 1=>8 data bits
241
  constant TX0BIT       : integer := 5; -- Transmit control 0=>TX IRQ disabled 1=>RTS_N low
242
  constant TX1BIT       : integer := 6; -- Transmit control 1=>TX IRQ disabled 0=>RTS_N low (ctrl(TX0BIT)=1 & ctrl(TX1BIT)=1 => break)
243
  constant RIEBIT       : integer := 7; -- receive interrupt enable
244 138 davidgb
 
245 197 davidgb
  signal status_reg     : std_logic_vector(7 downto 0) := (others => '0'); -- status register        IO+0 RW=1
246
  signal control_reg    : std_logic_vector(7 downto 0) := (others => '0'); -- control register       IO+0 RW=0
247
  signal rx_data_reg    : std_logic_vector(7 downto 0) := (others => '0'); -- receive data register  IO+1 RW=1
248
  signal tx_data_reg    : std_logic_vector(7 downto 0) := (others => '0'); -- transmit data registet IO+1 RW=0
249 100 davidgb
 
250 197 davidgb
  signal status_read    : std_logic := '0';   -- Read status register
251
  signal rx_data_read   : std_logic := '0';   -- Read receive buffer
252
  signal tx_data_write  : std_logic := '0';   -- Write Transmit buffer
253
 
254
  signal RxRdy          : std_logic := '0';   -- Receive Data ready
255
  signal TxRdy          : std_logic := '1';   -- Transmit buffer empty
256
  signal DCDInt         : std_logic := '0';   -- DCD Interrupt
257
  signal FErr           : std_logic := '0';   -- Receive Data ready
258
  signal OErr           : std_logic := '0';   -- Receive Data ready
259
  signal PErr           : std_logic := '0';   -- Receive Data ready
260
  signal TxIE           : std_logic := '0';   -- Transmit interrupt enable
261
  signal RxIE           : std_logic := '0';   -- Receive interrupt enable
262
 
263 139 davidgb
  --
264 197 davidgb
  -- status register error bit controls
265 100 davidgb
  --
266 197 davidgb
  signal status_rxr_set : std_logic := '0';
267
  signal status_txr_set : std_logic := '0';
268
  signal status_fer_set : std_logic := '0';
269
  signal status_fer_clr : std_logic := '0';
270
  signal status_oer_set : std_logic := '0';
271
  signal status_oer_clr : std_logic := '0';
272
  signal status_per_set : std_logic := '0';
273
  signal status_per_clr : std_logic := '0';
274 100 davidgb
 
275
 
276 197 davidgb
  type dcd_state_type is (DCD_State_Idle, DCD_State_Int, DCD_State_Reset);
277
 
278
  signal DCDState       : DCD_State_Type;     -- DCD Reset state sequencer
279
  signal DCDDel         : std_logic := '0';   -- Delayed DCD_n
280
  signal DCDEdge        : std_logic := '0';   -- Rising DCD_N Edge Pulse
281
 
282 100 davidgb
  -----------------------------------------------------------------------------
283 197 davidgb
  -- RX & TX state machine types
284
  -----------------------------------------------------------------------------
285
 
286
  type state_type is ( start_state, data_state, parity_state, stop_state,  idle_state );
287
 
288
  -----------------------------------------------------------------------------
289 100 davidgb
  -- RX Signals
290
  -----------------------------------------------------------------------------
291
 
292 197 davidgb
  signal rx_current_state : state_type;                 -- receive bit current state
293
  signal rx_next_state    : state_type;                 -- receive bit next state
294 138 davidgb
 
295 197 davidgb
  signal RxDat          : std_logic := '1';                     -- Resampled RxD bit
296
  signal RxDDel         : Std_Logic_Vector(1 downto 0) := "11"; -- Delayed RxD Input
297
  signal RxDEdge        : Std_Logic := '0';                     -- RxD Edge pulse
298
  signal RxCDel         : Std_Logic_Vector(1 downto 0) := "00"; -- Delayed RxC Input
299
  signal RxCEdge        : Std_Logic := '0';                     -- RxC Edge pulse
300
  signal RxClkCnt       : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Rx Baud Clock Counter
301
  signal RxBdClk        : Std_Logic := '0';             -- Rx Baud Clock
302
  signal RxBdDel        : Std_Logic := '0';             -- Delayed Rx Baud Clock
303
  signal RxBdEdgeRise   : Std_Logic := '0';             -- Rx Baud Clock rising edge
304
  signal RxBdEdgeFall   : Std_Logic := '0';             -- Rx Baud Clock falling edge
305 138 davidgb
 
306 197 davidgb
  signal rx_parity      : Std_Logic := '0';             -- Calculated RX parity bit
307
  signal rx_bit_count   : Std_Logic_Vector(3 downto 0) := (others => '0');  -- Rx Bit counter
308
  signal rx_shift_reg   : Std_Logic_Vector(7 downto 0) := (others => '0');  -- Shift Register
309
 
310 100 davidgb
  -----------------------------------------------------------------------------
311
  -- TX Signals
312
  -----------------------------------------------------------------------------
313
 
314 197 davidgb
  signal tx_current_state : state_type;                 -- Transmitter current state
315
  signal tx_next_state    : state_type;                 -- Transmitter next state
316 138 davidgb
 
317 197 davidgb
  signal TxOut          : std_logic := '1';             -- Transmit data bit
318
  signal TxDat          : std_logic := '1';             -- Transmit data bit
319
  signal TxCDel         : Std_Logic_Vector(1 downto 0) := "00";             -- Delayed TxC Input
320
  signal TxCEdge        : Std_Logic := '0';             -- TxC Edge pulse
321
  signal TxClkCnt       : Std_Logic_Vector(5 downto 0) := (others => '0');  -- Tx Baud Clock Counter
322
  signal TxBdClk        : Std_Logic := '0';             -- Tx Baud Clock
323
  signal TxBdDel        : Std_Logic := '0';             -- Delayed Tx Baud Clock
324
  signal TxBdEdgeRise   : Std_Logic := '0';             -- Tx Baud Clock rising edge
325
  signal TxBdEdgeFall   : Std_Logic := '0';             -- Tx Baud Clock falling edge
326 138 davidgb
 
327 197 davidgb
  signal tx_parity      : Std_logic := '0';              -- Parity Bit
328
  signal tx_bit_count   : Std_Logic_Vector(3 downto 0) := (others => '0');  -- Data Bit Counter
329
  signal tx_shift_reg   : Std_Logic_Vector(7 downto 0) := (others => '0');  -- Transmit shift register
330
  --
331
  -- Data register controls
332
  --
333
  type data_reg_type   is (data_reg_rst,  data_reg_load,   data_reg_idle);
334
  signal rx_data_ctrl   : data_reg_type;
335 100 davidgb
 
336 197 davidgb
  --
337
  -- Shift register controls
338
  --
339
  type shift_reg_type  is (shift_reg_rst, shift_reg_load, shift_reg_shift, shift_reg_idle);
340
  signal rx_shift_ctrl  : shift_reg_type;
341
  signal tx_shift_ctrl  : shift_reg_type;
342
 
343
  --
344
  -- Count register controls
345
  --  
346
  type count_reg_type  is (count_reg_rst, count_reg_decr,  count_reg_idle);
347
  signal rx_count_ctrl  : count_reg_type;
348
  signal tx_count_ctrl  : count_reg_type;
349
 
350 100 davidgb
begin
351
 
352 197 davidgb
---------------------------------------------------------------
353
-- ACIA Reset may be hardware or software
354
---------------------------------------------------------------
355 100 davidgb
  acia_reset : process( clk, rst, ac_rst, dcd_n )
356 138 davidgb
  begin
357 100 davidgb
    --
358 138 davidgb
    -- ACIA reset Synchronous 
359
    -- Includes software reset
360 100 davidgb
    --
361
    if falling_edge(clk) then
362 197 davidgb
      ac_rst <= (control_reg(1) and control_reg(0)) or rst;
363 100 davidgb
    end if;
364
    -- Receiver reset
365 138 davidgb
    rx_rst <= ac_rst or DCD_n;
366 100 davidgb
    -- Transmitter reset
367
    tx_rst <= ac_rst;
368
 
369
  end process;
370
 
371 197 davidgb
 
372
-----------------------------------------------------------------------------
373
-- Generate Read / Write strobes.
374
-----------------------------------------------------------------------------
375 100 davidgb
 
376 197 davidgb
  acia_read_write : process(clk, rst)
377 138 davidgb
  begin
378
    if falling_edge(clk) then
379 197 davidgb
      status_read   <= '0';
380
      tx_data_write <= '0';
381
      rx_data_read  <= '0';
382 138 davidgb
      if rst = '1' then
383 197 davidgb
        control_reg(1 downto 0) <= "11";
384
        control_reg(7 downto 2) <= (others => '0');
385
        tx_data_reg   <= (others => '0');
386 138 davidgb
      else
387
        if cs = '1' then
388 197 davidgb
          if addr = '0' then              -- Control / Status register
389 138 davidgb
            if rw = '0' then              -- write control register
390 197 davidgb
              control_reg   <= data_in;
391 138 davidgb
            else                          -- read status register
392 197 davidgb
              status_read   <= '1';
393 138 davidgb
            end if;
394
          else                            -- Data Register
395
            if rw = '0' then              -- write transmiter register
396 197 davidgb
              tx_data_reg <= data_in;
397
              tx_data_write <= '1';
398 138 davidgb
            else                          -- read receiver register
399 197 davidgb
              rx_data_read  <= '1';
400 138 davidgb
            end if;
401
          end if;
402
        end if;
403
      end if;
404
    end if;
405
  end process;
406
 
407 100 davidgb
  -----------------------------------------------------------------------------
408
  -- ACIA Status Register
409
  -----------------------------------------------------------------------------
410
 
411 197 davidgb
  acia_status : process( RxRdy, TxRdy, DCDInt, CTS_n, FErr, OErr, PErr, RxIE, TxIE,  status_reg, control_reg )
412 100 davidgb
  begin
413 197 davidgb
    TxIE <= (not control_reg(TX1BIT)) and control_reg(TX0BIT);
414
    RxIE <= control_reg(RIEBIT);
415
    status_reg(RXRBIT) <= RxRdy;
416
    status_reg(TXRBIT) <= TxRdy and (not CTS_n);
417
    status_reg(DCDBIT) <= DCDInt;                -- Data Carrier Detect
418
    status_reg(CTSBIT) <= CTS_n;                 -- Clear To Send
419
    status_reg(FERBIT) <= FErr;
420
    status_reg(OERBIT) <= OErr;
421
    status_reg(PERBIT) <= PErr;
422
    status_reg(IRQBIT) <= (RxIE and RxRdy) or
423
                          (RxIE and DCDInt) or
424
                          (TxIE and TxRdy);
425
    irq <= status_reg(IRQBIT);
426
  end process;
427
 
428
  -----------------------------------------------------------------------------
429
  -- ACIA Rx data ready status
430
  -----------------------------------------------------------------------------
431
 
432
  acia_rx_data_ready : process( clk, rx_rst, RxBdEdgeFall, status_rxr_set )
433
  begin
434 100 davidgb
    if falling_edge( clk ) then
435 197 davidgb
      if rx_rst = '1' then
436
        RxRdy <= '0';
437
      else
438
        if RxBdEdgeFall = '1' and status_rxr_set = '1' then
439
          RxRdy <= '1';
440
        elsif rx_data_read  = '1' then
441
          RxRdy <= '0';
442
        end if;
443
      end if;
444 138 davidgb
    end if;
445 100 davidgb
  end process;
446
 
447 197 davidgb
 
448 139 davidgb
  -----------------------------------------------------------------------------
449 197 davidgb
  -- ACIA Tx data ready status
450 139 davidgb
  -----------------------------------------------------------------------------
451 100 davidgb
 
452 197 davidgb
  acia_tx_data_ready : process( clk, tx_rst, TxBdEdgeRise, status_txr_set )
453 100 davidgb
  begin
454 197 davidgb
    if falling_edge( clk ) then
455
      if tx_rst = '1' then
456
         TxRdy <= '1';
457
      else
458
        if TxBdEdgeRise = '1' and status_txr_set = '1' then
459
          TxRdy <= '1';
460
        elsif  tx_data_write  = '1' then
461
          TxRdy <= '0';
462
        end if;
463
      end if;
464
    end if;
465
  end process;
466 100 davidgb
 
467 197 davidgb
 
468
  -----------------------------------------------------------------------------
469
  -- ACIA Framing Error
470
  -----------------------------------------------------------------------------
471
 
472
  acia_fer_status : process( clk )
473
  begin
474
    if falling_edge( clk ) then
475
      if rx_rst = '1' then
476
        FErr <= '0';
477
      elsif RxBdEdgeFall = '1' then
478
        if status_fer_clr = '1' then
479
          FErr <= '0';
480
        end if;
481
        if status_fer_set = '1' then
482
          FErr <= '1';
483
        end if;
484
      end if;
485
    end if;
486 100 davidgb
  end process;
487
 
488 197 davidgb
  -----------------------------------------------------------------------------
489
  -- ACIA Over-run Error
490
  -----------------------------------------------------------------------------
491 100 davidgb
 
492 197 davidgb
  acia_oer_status : process( clk )
493 100 davidgb
  begin
494 197 davidgb
    if falling_edge( clk ) then
495
      if rx_rst = '1' then
496
        OErr <= '0';
497
      elsif RxBdEdgeFall = '1' then
498
        if status_oer_set = '1' then
499
          OErr <= '1';
500
        end if;
501
        if status_oer_clr = '1' or rx_data_read = '1' then
502
          OErr <= '0';
503
        end if;
504
      end if;
505 100 davidgb
    end if;
506
  end process;
507
 
508
 
509 197 davidgb
  -----------------------------------------------------------------------------
510
  -- ACIA Parity Error
511
  -----------------------------------------------------------------------------
512 139 davidgb
 
513 197 davidgb
  acia_per_status : process( clk )
514
  begin
515
    if falling_edge( clk ) then
516
      if rx_rst = '1' then
517
        PErr <= '0';
518
      elsif RxBdEdgeFall = '1' and status_per_set = '1' then
519
        PErr <= '1';
520
      elsif RxBdEdgeFall = '1' and status_per_clr = '1' then
521
        PErr <= '0';
522
      elsif rx_data_read = '1' then
523
        PErr <= '0';
524
      end if;
525
    end if;
526
  end process;
527
 
528
---------------------------------------------------------------
529
-- Set Data Output Multiplexer
530
--------------------------------------------------------------
531
 
532
  acia_data_mux : process(addr, rx_data_reg, status_reg)
533
  begin
534
    if addr = '1' then
535
      data_out <= rx_data_reg;               -- read receiver register
536
    else
537
      data_out <= status_reg;               -- read status register
538
    end if;
539
  end process;
540
 
541
---------------------------------------------------------------
542
-- Data Carrier Detect Edge rising edge detect
543
---------------------------------------------------------------
544 100 davidgb
  acia_dcd_edge : process( clk, ac_rst )
545
  begin
546
    if falling_edge(clk) then
547
      if ac_rst = '1' then
548
        DCDDel  <= '0';
549
        DCDEdge <= '0';
550 138 davidgb
      else
551 100 davidgb
        DCDDel  <= DCD_n;
552 138 davidgb
        DCDEdge <= DCD_n and (not DCDDel);
553 100 davidgb
      end if;
554
    end if;
555
  end process;
556
 
557
 
558 197 davidgb
---------------------------------------------------------------
559
-- Data Carrier Detect Interrupt
560
---------------------------------------------------------------
561
-- If Data Carrier is lost, an interrupt is generated
562
-- To clear the interrupt, first read the status register
563
--      then read the data receive register
564
 
565 100 davidgb
  acia_dcd_int : process( clk, ac_rst )
566
  begin
567
    if falling_edge(clk) then
568
      if ac_rst = '1' then
569
        DCDInt   <= '0';
570
        DCDState <= DCD_State_Idle;
571 138 davidgb
      else
572 100 davidgb
        case DCDState is
573
        when DCD_State_Idle =>
574
          -- DCD Edge activates interrupt
575
          if DCDEdge = '1' then
576
            DCDInt   <= '1';
577
            DCDState <= DCD_State_Int;
578
          end if;
579
        when DCD_State_Int =>
580
          -- To reset DCD interrupt, 
581
          -- First read status
582 197 davidgb
          if status_read = '1' then
583 100 davidgb
            DCDState <= DCD_State_Reset;
584
          end if;
585
        when DCD_State_Reset =>
586
          -- Then read receive register
587 197 davidgb
          if rx_data_read = '1' then
588 100 davidgb
            DCDInt   <= '0';
589
            DCDState <= DCD_State_Idle;
590
          end if;
591
        when others =>
592
          null;
593 138 davidgb
        end case;
594 100 davidgb
      end if;
595
    end if;
596
  end process;
597
 
598 197 davidgb
 
599 100 davidgb
  ---------------------------------------------------------------------
600
  -- Receiver Clock Edge Detection
601
  ---------------------------------------------------------------------
602 197 davidgb
  -- A rising edge will produce a one CPU clock cycle pulse
603
  --
604 100 davidgb
  acia_rx_clock_edge : process( clk, rx_rst )
605
  begin
606
    if falling_edge(clk) then
607
      if rx_rst = '1' then
608 197 davidgb
        RxCDel  <= "00";
609
        RxCEdge <= '0';
610 100 davidgb
      else
611 197 davidgb
        --
612
        -- RxClkEdge is one CPU clock cycle wide
613
        --
614
        RxCDel(0) <= RxC;
615
        RxCDel(1) <= RxCDel(0);
616
        RxCEdge <= (not RxCDel(1)) and RxCDel(0);
617 100 davidgb
      end if;
618
    end if;
619
  end process;
620
 
621
  ---------------------------------------------------------------------
622
  -- Receiver Data Edge Detection
623
  ---------------------------------------------------------------------
624 197 davidgb
  --
625
  -- If there is a falling edge on the RxD line
626
  -- and the ACIA receiver is in the start, stop or idle state 
627
  -- RxDatEdge is generated to reset the Baud Clock divide
628
  -- so that it is synchronized to the edge of the data
629
  -- 2021-01-30 JEK Double clock RxD
630
  acia_rx_data_edge : process( clk, rx_rst, RxD, RxDDel )
631 100 davidgb
  begin
632 138 davidgb
    if falling_edge(clk) then
633 197 davidgb
      if (rx_rst = '1') then
634
        RxDDel(0) <= RxD;
635
                  RxDDel(1) <= RxDDel(0);
636
        RxDEdge <= '0';
637 100 davidgb
      else
638 197 davidgb
        RxDDel(0) <= RxD;
639
                  RxDDel(1) <= RxDDel(0);
640
        RxDEdge <= not(RxDDel(0)) and RxDDel(1);
641 100 davidgb
      end if;
642
    end if;
643
  end process;
644
 
645
  ---------------------------------------------------------------------
646 197 davidgb
  -- Receiver Clock Divider
647 100 davidgb
  ---------------------------------------------------------------------
648 197 davidgb
  -- Hold the Rx Clock divider in reset when the receiver is disabled
649
  -- Advance the count only on a rising Rx clock edge
650
  --
651
  acia_rx_clock_divide : process( clk, rx_rst, RxDEdge, RxCEdge )
652 100 davidgb
  begin
653 138 davidgb
    if falling_edge(clk) then
654 197 davidgb
      if (rx_rst = '1') or (RxDEdge = '1') then
655
        --
656
        -- Reset counter on rx_rst or falling data edge
657
        --
658
        RxClkCnt  <= (others => '0');
659
      elsif RxCEdge = '1' then
660
        --         
661
        -- increment count on Rx Clock edge
662
        --
663
        RxClkCnt <= RxClkCnt + "000001";
664 100 davidgb
      end if;
665
    end if;
666
  end process;
667
 
668 139 davidgb
 
669 197 davidgb
-----------------------------------------------------------------------------
670
-- ACIA RX Baud select
671
-----------------------------------------------------------------------------
672
-- 2021-01-30 JEK change RxC to RxCDel(0)
673
  acia_rx_baud_control : process(clk, control_reg, RxC, RxClkCnt )
674 100 davidgb
  begin
675 197 davidgb
    ---------------------------------------------------------------------
676
    -- Receive Baud Clock Selector
677
    ---------------------------------------------------------------------
678
    -- control_reg(BD1BIT downto BD0BIT)
679
    -- 0 0     - Baud Clk divide by 1
680
    -- 0 1     - Baud Clk divide by 16
681
    -- 1 0     - Baud Clk divide by 64
682
    -- 1 1     - reset
683 100 davidgb
    if falling_edge(clk) then
684 197 davidgb
      case control_reg(BD1BIT downto BD0BIT) is
685
      when "00" =>                               -- Div by 1
686
        RxBdClk <= RxCDel(0);
687
      when "01" =>                               -- Div by 16
688
        RxBdClk <= RxClkCnt(3);
689
      when "10" =>                               -- Div by 64
690
        RxBdClk <= RxClkCnt(5);
691
      when others =>                          -- Software reset
692
        RxBdClk <= '0';
693
      end case;
694 100 davidgb
    end if;
695 197 davidgb
 
696 100 davidgb
  end process;
697
 
698 197 davidgb
 
699 100 davidgb
  ---------------------------------------------------------------------
700 197 davidgb
  -- Receiver Baud Clock Edge Detection
701 100 davidgb
  ---------------------------------------------------------------------
702 197 davidgb
  -- A Rising Baud Clock edge will produce a single CPU clock pulse
703 100 davidgb
  --
704 197 davidgb
  acia_rx_baud_edge : process( clk, rx_rst, RxBdClk, RxBdDel )
705 100 davidgb
  begin
706 197 davidgb
    if falling_edge(clk) then
707
      if rx_rst = '1' then
708
        RxBdDel      <= '0';
709
        RxBdEdgeRise <= '0';
710
        RxBdEdgeFall <= '0';
711
      else
712
        RxBdDel      <= RxBdClk;
713
        RxBdEdgeRise <= not(RxBdDel) and     RxBdClk;
714
        RxBdEdgeFall <=     RxBdDel  and not(RxBdClk);
715
      end if;
716
    end if;
717 100 davidgb
  end process;
718
 
719
  ---------------------------------------------------------------------
720
  -- Receiver process
721
  ---------------------------------------------------------------------
722
  -- WdFmt - Bits[4..2]
723
  -- 0 0 0   - 7 data, even parity, 2 stop
724
  -- 0 0 1   - 7 data, odd  parity, 2 stop
725
  -- 0 1 0   - 7 data, even parity, 1 stop
726
  -- 0 1 1   - 7 data, odd  parity, 1 stop
727
  -- 1 0 0   - 8 data, no   parity, 2 stop
728
  -- 1 0 1   - 8 data, no   parity, 1 stop
729
  -- 1 1 0   - 8 data, even parity, 1 stop
730
  -- 1 1 1   - 8 data, odd  parity, 1 stop
731 197 davidgb
  --
732
  -- Registers activated on rising bit clock edge
733
  -- State transitions on falling bit clock edge
734
  --
735
  acia_rx_receive : process( rx_current_state, control_reg, rx_bit_count, RxDDel, RxDat, rx_parity, RxRdy )
736
  begin
737
          rx_data_ctrl   <= data_reg_idle;
738
          rx_shift_ctrl  <= shift_reg_idle;
739
          rx_next_state  <= start_state;
740 139 davidgb
 
741 197 davidgb
          status_rxr_set <= '0';                       -- receive data ready
742
          status_fer_clr <= '0';                       -- framing error status
743
          status_fer_set <= '0';                       -- framing error status
744
          status_oer_clr <= '0';                       -- over-run error status
745
          status_oer_set <= '0';                       -- over-run error status
746
          status_per_clr <= '0';                       -- parity  error status
747
          status_per_set <= '0';                       -- parity  error status
748
 
749
          case rx_current_state is
750
          when start_state =>
751
            rx_shift_ctrl <= shift_reg_rst;            -- Reset Shift register on rising baud clock
752
            if RxDat = '0' then                        -- RxDat = '0' => start bit
753
              rx_next_state <= data_state;             -- if low, start shifting in data
754 100 davidgb
            end if;
755
 
756 197 davidgb
          when data_state =>                           -- Receiving data bits
757
            --  on rising baud clock edge 
758
            rx_shift_ctrl <= shift_reg_shift;          -- shift in data bit
759
 
760
            -- on falling baud clock edge transition state
761
            if rx_bit_count = "0000" then               -- All bits shifted in ?
762
              --                                       -- yes, transition to parity or stop state
763
              -- if control_reg(DATBIT) = '1' and control_reg(STPBIT) = '0'
764
              -- then 8 data bit, no parity
765
              --
766
              if control_reg(DATBIT)='1' and control_reg(STPBIT)='0' then
767
                rx_next_state  <= stop_state;          -- 8 data, 1 or 2 stops, no parity => stop_state
768 100 davidgb
              else
769 197 davidgb
                rx_next_state <= parity_state;         -- control_reg(DATBIT) = '0' => 7 data + parity or
770
              end if;                                  -- control_reg(STPBIT) = '1' => 8 data + parity => parity_state
771
            else
772
              rx_next_state <= data_state;             -- bit count none zero => remain in data state
773 100 davidgb
            end if;
774
 
775 197 davidgb
          when parity_state =>                         -- Receive Parity bit
776
            -- on rising baud clock edge:
777
            if control_reg(DATBIT) = '0' then          -- if 7 data bits, shift parity into MSB
778
              rx_shift_ctrl <= shift_reg_shift;        -- 7 data + parity
779 100 davidgb
            end if;
780 197 davidgb
 
781
            -- on falling baud clock edge, set parity
782
            if rx_parity = (RxDat xor control_reg(POEBIT)) then
783
              status_per_set <= '1';                   -- set parity  error status
784 100 davidgb
            else
785 197 davidgb
              status_per_clr <= '1';                   -- resetset parity  error status
786 100 davidgb
            end if;
787 197 davidgb
            rx_next_state <= stop_state;
788 100 davidgb
 
789 197 davidgb
          when stop_state =>                           -- stop bit (Only one required for RX)
790
            -- on falling baud clock edge
791
            rx_data_ctrl   <= data_reg_load;             -- load receive data reg with shift register
792
            status_rxr_set <= '1';                       -- flag receive data ready
793
 
794
            -- on falling baud clock edge
795
            if control_reg(DATBIT)='1' and control_reg(STPBIT)='0' then
796
                status_per_clr <= '1';                 -- reset parity  error status if no parity
797
            end if;
798
 
799
            -- on falling baud clock edge
800
            if RxRdy = '1' then                        -- Has previous data been read ? 
801
              status_oer_set <= '1';                   -- no, set over-run  error status
802 100 davidgb
            else
803 197 davidgb
              status_oer_clr <= '1';                   -- yes, reset over-run  error status
804 100 davidgb
            end if;
805 197 davidgb
 
806
            -- on falling baud clock edge
807
            if RxDat = '1' then                          -- stop bit received ?
808
              status_fer_clr <= '1';                   -- yes, reset framing error status
809 100 davidgb
            else
810 197 davidgb
              status_fer_set <= '1';                   -- no, set framing error status
811 100 davidgb
            end if;
812
 
813 197 davidgb
            -- on falling baud clock edge
814
            if RxDat = '0' then                        -- wait until RxDat returns high
815
              rx_next_state  <= idle_state;
816
            end if;
817
 
818
          when idle_state =>
819
            if RxDat = '0' then                        -- wait until RxD returns high
820
              rx_next_state <= idle_state;
821
            end if;
822
 
823 100 davidgb
          when others =>
824 197 davidgb
            null;
825 100 davidgb
          end case;
826 197 davidgb
  end process;
827
 
828
  ---------------------------------------------------------------------
829
  -- Rx State machine
830
  ---------------------------------------------------------------------
831
  --
832
  -- State machine transitions on the falling edge of the Rx Baud clock
833
  --
834
  acia_rx_state : process(clk, rst )
835
  begin
836
    if falling_edge( clk ) then
837
      if rx_rst = '1' then
838
        rx_current_state <= start_state;
839
      else
840
        if RxBdEdgeFall = '1' then
841
          rx_current_state <= rx_next_state;
842 100 davidgb
        end if;
843
      end if;
844
    end if;
845
 
846
  end process;
847
 
848 139 davidgb
 
849 197 davidgb
  -----------------------------------------------------------------------------
850
  -- ACIA Rx Shift Register
851
  -----------------------------------------------------------------------------
852
  -- 2021-01-30 JEK change RxD to RxDDel(0)
853
  --
854
  acia_rx_shift_reg : process( clk, rx_rst, RxBdEdgeRise, rx_shift_reg, RxDDel, rx_parity )
855 100 davidgb
  begin
856 197 davidgb
    if falling_edge( clk ) then
857 100 davidgb
      if rx_rst = '1' then
858 197 davidgb
        RxDat <= '1';
859
        rx_bit_count <= (others=>'0');
860
        rx_shift_reg <= (others=>'0');
861
        rx_parity    <= '0';
862
      elsif RxBdEdgeRise = '1' then
863
        RxDat <= RxDDel(0);
864
        case rx_shift_ctrl is
865
        when shift_reg_rst =>
866
          if control_reg(DATBIT) = '0' then  -- control_reg(DATBIT) = '0' => 7 data bits
867
            rx_bit_count <= "0111";
868
          else                               -- control_reg(DATBIT) = '1' => 8 data bits
869
            rx_bit_count <= "1000";
870
          end if;
871
          rx_shift_reg <= (others=>'0');
872
          rx_parity    <= '0';
873
        when shift_reg_shift =>
874
          rx_bit_count <= rx_bit_count - "0001";
875
          rx_shift_reg <= RxDDel(0) & rx_shift_reg(7 downto 1);
876
          rx_parity    <= rx_parity xor RxDDel(0);
877
        when others =>
878
          null;
879
        end case;
880 100 davidgb
      end if;
881 138 davidgb
    end if;
882 100 davidgb
  end process;
883
 
884 197 davidgb
  -----------------------------------------------------------------------------
885
  -- ACIA Rx Data Register
886
  -----------------------------------------------------------------------------
887
 
888
  acia_rx_data_reg : process( clk, rx_rst, rx_shift_reg )
889
  begin
890
    if falling_edge( clk ) then
891
      if rx_rst = '1' then
892
        rx_data_reg <= (others=>'0');
893
      elsif RxBdEdgeFall = '1' then
894
        case rx_data_ctrl is
895
        when data_reg_rst =>
896
          rx_data_reg <= (others=>'0');
897
        when data_reg_load =>
898
          rx_data_reg  <= rx_shift_reg;
899
        when others =>
900
          null;
901
        end case;
902
      end if;
903
    end if;
904
  end process;
905
 
906
  -----------------------------------------------------------------------------
907
  -- ACIA TX control
908
  -----------------------------------------------------------------------------
909
 
910
  acia_tx_control : process(control_reg, TxDat )
911
  begin
912
    case control_reg(TX1BIT downto TX0BIT) is
913
      when "00" =>                      -- Disable TX Interrupts, Assert RTS
914
        TxD   <= TxDat;
915
        RTS_n <= '0';
916
      when "01" =>                      -- Enable TX interrupts, Assert RTS
917
        TxD   <= TxDat;
918
        RTS_n <= '0';
919
      when "10" =>                      -- Disable Tx Interrupts, Clear RTS
920
        TxD   <= TxDat;
921
        RTS_n <= '1';
922
      when "11" =>                      -- Disable Tx interrupts, Assert RTS, send break
923
        TxD   <= '0';
924
        RTS_n <= '0';
925
      when others =>
926
        null;
927
    end case;
928
  end process;
929
 
930 100 davidgb
  ---------------------------------------------------------------------
931
  -- Transmit Clock Edge Detection
932 197 davidgb
  -- A rising edge will produce a one clock cycle pulse
933 100 davidgb
  ---------------------------------------------------------------------
934 197 davidgb
  -- 2021-01-30 JEK add one more bit to TxCDel. Double sample TxC
935 100 davidgb
  acia_tx_clock_edge : process( Clk, tx_rst )
936
  begin
937
    if falling_edge(clk) then
938
      if tx_rst = '1' then
939 197 davidgb
        TxCDel(1 downto 0) <= "00";
940
        TxCEdge <= '0';
941 100 davidgb
      else
942 197 davidgb
        TxCDel(0) <= TxC;
943
                  TxCDel(1) <= RxCDel(0);
944
        TxCEdge <= (not TxCDel(1)) and TxCDel(0);
945 100 davidgb
      end if;
946
    end if;
947
  end process;
948
 
949
  ---------------------------------------------------------------------
950
  -- Transmit Clock Divider
951
  -- Advance the count only on an input clock pulse
952
  ---------------------------------------------------------------------
953
 
954
  acia_tx_clock_divide : process( clk, tx_rst )
955
  begin
956
    if falling_edge(clk) then
957
      if tx_rst = '1' then
958
        TxClkCnt <= (others=>'0');
959 197 davidgb
      elsif TxCEdge = '1' then
960 100 davidgb
        TxClkCnt <= TxClkCnt + "000001";
961
      end if;
962
    end if;
963
  end process;
964
 
965 139 davidgb
 
966 197 davidgb
-----------------------------------------------------------------------------
967
-- ACIA TX Baud select
968
-----------------------------------------------------------------------------
969
-- 2021-01-30 JEK change TxC to TxCDel(0)
970
  acia_tx_baud_select : process(clk, control_reg, TxDat, TxCDel, TxClkCnt )
971 100 davidgb
  begin
972 197 davidgb
 
973
    ---------------------------------------------------------------------
974
    -- Transmit Baud Clock Selector
975
    ---------------------------------------------------------------------
976
    -- control_reg(BD1BIT downto BD0BIT)
977 100 davidgb
    -- 0 0     - Baud Clk divide by 1
978
    -- 0 1     - Baud Clk divide by 16
979
    -- 1 0     - Baud Clk divide by 64
980
    -- 1 1     - reset
981 197 davidgb
    if falling_edge(clk) then
982
      case control_reg(BD1BIT downto BD0BIT) is
983 100 davidgb
      when "00" =>                               -- Div by 1
984 197 davidgb
        TxBdClk <= TxCDel(0);
985 100 davidgb
      when "01" =>                               -- Div by 16
986
        TxBdClk <= TxClkCnt(3);
987
      when "10" =>                               -- Div by 64
988
        TxBdClk <= TxClkCnt(5);
989
      when others =>                          -- Software reset
990
        TxBdClk <= '0';
991 197 davidgb
      end case;
992
    end if;
993
 
994 100 davidgb
  end process;
995
 
996 197 davidgb
 
997
  ---------------------------------------------------------------------
998
  -- Transmit Baud Clock Edge Detection
999
  ---------------------------------------------------------------------
1000
  -- A Falling edge will produce a single pulse on TxBdEdgeFall
1001
  --
1002
  acia_tx_baud_edge : process( clk, tx_rst )
1003
  begin
1004
    if falling_edge(clk) then
1005
      if tx_rst = '1' then
1006
        TxBdDel      <= '0';
1007
        TxBdEdgeRise <= '0';
1008
        TxBdEdgeFall <= '0';
1009
      else
1010
        TxBdDel  <= TxBdClk;
1011
        TxBdEdgeRise <= (not TxBdDel) and TxBdClk;
1012
        TxBdEdgeFall <= TxBdDel and (not TxBdClk);
1013
      end if;
1014
    end if;
1015
  end process;
1016
 
1017 100 davidgb
  -----------------------------------------------------------------------------
1018
  -- Implements the Tx unit
1019
  -----------------------------------------------------------------------------
1020
  -- WdFmt - Bits[4..2]
1021
  -- 0 0 0   - 7 data, even parity, 2 stop
1022
  -- 0 0 1   - 7 data, odd  parity, 2 stop
1023
  -- 0 1 0   - 7 data, even parity, 1 stop
1024
  -- 0 1 1   - 7 data, odd  parity, 1 stop
1025
  -- 1 0 0   - 8 data, no   parity, 2 stop
1026
  -- 1 0 1   - 8 data, no   parity, 1 stop
1027
  -- 1 1 0   - 8 data, even parity, 1 stop
1028
  -- 1 1 1   - 8 data, odd  parity, 1 stop
1029 197 davidgb
  acia_tx_transmit : process( tx_current_state, TxRdy, tx_bit_count, tx_shift_reg, control_reg, tx_parity )
1030 100 davidgb
  begin
1031 197 davidgb
          status_txr_set <= '0';
1032
          case tx_current_state is
1033
          when idle_state =>
1034
            TxOut <= '1';
1035
            tx_shift_ctrl <= shift_reg_idle;
1036
            if TxRdy = '0' then
1037
              tx_next_state <= start_state;
1038 100 davidgb
            else
1039 197 davidgb
              tx_next_state <= idle_state;
1040 100 davidgb
            end if;
1041
 
1042 197 davidgb
          when start_state =>
1043
            TxOut         <= '0';                    -- Start bit
1044
            tx_shift_ctrl <= shift_reg_load;         -- Load Shift reg with Tx Data
1045
            tx_next_state <= data_state;
1046
 
1047
          when data_state =>
1048
            TxOut <= tx_shift_reg(0);
1049
            tx_shift_ctrl <= shift_reg_shift;        -- shift tx shift reg
1050
            if tx_bit_count = "000" then
1051
              if (control_reg(DATBIT) = '1') and (control_reg(STPBIT) = '0') then
1052
                if control_reg(POEBIT) = '0' then    -- 8 data bits
1053
                  tx_next_state <= stop_state;       -- 2 stops
1054 100 davidgb
                else
1055 197 davidgb
                  tx_next_state <= idle_state;       -- 1 stop
1056 100 davidgb
                end if;
1057
              else
1058 197 davidgb
                tx_next_state <= parity_state;        -- parity
1059 138 davidgb
              end if;
1060 197 davidgb
            else
1061
              tx_next_state <= data_state;
1062 100 davidgb
            end if;
1063
 
1064 197 davidgb
          when parity_state =>                        -- 7/8 data + parity bit
1065
            if control_reg(POEBIT) = '0' then
1066
              TxOut <= not(tx_parity);                -- even parity
1067 100 davidgb
            else
1068 197 davidgb
              TxOut <= tx_parity;                     -- odd parity
1069 100 davidgb
            end if;
1070 197 davidgb
            tx_shift_ctrl <= shift_reg_idle;
1071
            if control_reg(STPBIT) = '0' then
1072
              tx_next_state <= stop_state;            -- 2 stops
1073 138 davidgb
            else
1074 197 davidgb
              tx_next_state <= idle_state;            -- 1 stop
1075 100 davidgb
            end if;
1076
 
1077 197 davidgb
          when stop_state =>                          -- first of two stop bits
1078
            TxOut          <= '1';
1079
            tx_shift_ctrl  <= shift_reg_idle;
1080
            status_txr_set <= '1';
1081
            tx_next_state  <= idle_state;
1082 100 davidgb
 
1083 197 davidgb
 --         when others =>
1084
 --           null;
1085
 
1086 138 davidgb
          end case;
1087 197 davidgb
  end process;
1088
 
1089
  ---------------------------------------------------------------------
1090
  -- Tx State machine
1091
  ---------------------------------------------------------------------
1092
  --
1093
  -- State machine transitions on the rising edge of the Tx Baud clock
1094
  --
1095
  acia_tx_state : process(clk, tx_rst )
1096
  begin
1097
     if falling_edge( clk ) then
1098
      if tx_rst = '1' then
1099
        tx_current_state <= idle_state;
1100
      else
1101
        if TxBdEdgeRise = '1' then
1102
          tx_current_state <= tx_next_state;
1103 100 davidgb
        end if;
1104
      end if;
1105
    end if;
1106
  end process;
1107 138 davidgb
 
1108 197 davidgb
  -----------------------------------------------------------------------------
1109
  -- ACIA tx Shift Register
1110
  -----------------------------------------------------------------------------
1111 100 davidgb
 
1112 197 davidgb
  acia_tx_shift_reg : process( clk, TxBdEdgeFall, tx_shift_ctrl, tx_data_reg, tx_shift_reg, tx_parity )
1113 100 davidgb
  begin
1114 197 davidgb
    if falling_edge( clk ) then
1115 100 davidgb
      if tx_rst = '1' then
1116 197 davidgb
        tx_bit_count <= (others=>'0');
1117
        tx_shift_reg <= (others=>'1');
1118
        tx_parity    <= '0';
1119
        TxDat        <= '1';
1120
      elsif TxBdEdgeFall = '1' then
1121
        TxDat <= TxOut;
1122
        case tx_shift_ctrl is
1123
        when shift_reg_load =>
1124
          if control_reg(DATBIT) = '0' then  -- control_reg(DATBIT) = '0' => 7 data bits
1125
            tx_bit_count <= "0111";
1126
          else                               -- control_reg(DATBIT) = '1' => 8 data bits
1127
            tx_bit_count <= "1000";
1128
          end if;
1129
          tx_shift_reg  <= tx_data_reg;
1130
          tx_parity     <= '0';
1131
        when shift_reg_shift =>
1132
          tx_bit_count <= tx_bit_count - "0001";
1133
          tx_shift_reg <= '1' & tx_shift_reg(7 downto 1);
1134
          tx_parity    <= tx_parity xor tx_shift_reg(0);
1135
        when others =>
1136
          null;
1137
        end case;
1138 100 davidgb
      end if;
1139 138 davidgb
    end if;
1140 100 davidgb
  end process;
1141
 
1142 197 davidgb
 
1143 100 davidgb
end rtl;
1144
 

powered by: WebSVN 2.1.0

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