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

Subversion Repositories System09

[/] [System09/] [trunk/] [rtl/] [VHDL/] [ACIA_6850.vhd] - Blame information for rev 82

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

Line No. Rev Author Line
1 19 dilbert57
--===========================================================================--
2
--
3
--  S Y N T H E Z I A B L E    ACIA 6850   C O R E
4
--
5
--  www.OpenCores.Org - January 2007
6
--  This core adheres to the GNU public license  
7
--
8
-- Design units   : 6850 ACIA core
9
--
10
-- File name      : ACIA6850.vhd
11
--
12
-- Purpose        : Implements an RS232 Asynchronous serial communications device 
13
--                  
14
-- Dependencies   : ieee.std_logic_1164
15
--                  ieee.numeric_std
16
--                  unisim.vcomponents
17
--
18
--===========================================================================--
19
-------------------------------------------------------------------------------
20
-- Revision list
21
-- Version   Author                 Date           Changes
22
--
23
-- 0.1      Ovidiu Lupas     15 January 2000       New model
24
-- 1.0      Ovidiu Lupas     January  2000         Synthesis optimizations
25
-- 2.0      Ovidiu Lupas     April    2000         Bugs removed - RSBusCtrl
26
--          the RSBusCtrl did not process all possible situations
27
--
28
--        olupas@opencores.org
29
--
30
-- 3.0      John Kent        October  2002         Changed Status bits to match mc6805
31
--                                                 Added CTS, RTS, Baud rate control
32
--                                                 & Software Reset
33
-- 3.1      John Kent        5 January 2003        Added Word Format control a'la mc6850
34
-- 3.2      John Kent        19 July 2003          Latched Data input to UART
35
-- 3.3      John Kent        16 January 2004       Integrated clkunit in rxunit & txunit
36
--                                                 Now has external TX 7 RX Baud Clock
37
--                                                 inputs like the MC6850... 
38
--                                                 also supports x1 clock and DCD. 
39
-- 3.4          John Kent                       13 September 2005               Removed LoadCS signal. 
40
--                                                                                                                                      Fixed ReadCS and Read in "if" in
41
--                                                                                                                                      miniuart_DCD_Init process
42
-- 3.5      John Kent         28 November 2006     Cleaned up code.
43
--
44
-- 4.0      John Kent         3 February 2007      renamed ACIA6850
45
-- 4.1      John Kent         6 February 2007      Made software reset synchronous
46
--      4.2      John Kent         25 February 2007     Changed sensitivity lists
47
--                                                 Rearranged Reset process.
48
--        dilbert57@opencores.org
49
--
50
library ieee;
51
   use ieee.std_logic_1164.all;
52
   use ieee.numeric_std.all;
53
--library unisim;
54
--      use unisim.vcomponents.all;
55
 
56
-----------------------------------------------------------------------
57
-- Entity for ACIA_6850                                              --
58
-----------------------------------------------------------------------
59
 
60
entity ACIA_6850 is
61
  port (
62
     --
63
          -- CPU signals
64
          --
65
     clk      : in  Std_Logic;  -- System Clock
66
     rst      : in  Std_Logic;  -- Reset input (active high)
67
     cs       : in  Std_Logic;  -- miniUART Chip Select
68
     rw       : in  Std_Logic;  -- Read / Not Write
69
     irq      : out Std_Logic;  -- Interrupt
70
     Addr     : in  Std_Logic;  -- Register Select
71
     DataIn   : in  Std_Logic_Vector(7 downto 0); -- Data Bus In 
72
     DataOut  : out Std_Logic_Vector(7 downto 0); -- Data Bus Out
73
     --
74
          -- Uart Signals
75
          --
76
     RxC      : in  Std_Logic;  -- Receive Baud Clock
77
     TxC      : in  Std_Logic;  -- Transmit Baud Clock
78
     RxD      : in  Std_Logic;  -- Receive Data
79
     TxD      : out Std_Logic;  -- Transmit Data
80
          DCD_n    : in  Std_Logic;  -- Data Carrier Detect
81
     CTS_n    : in  Std_Logic;  -- Clear To Send
82
     RTS_n    : out Std_Logic );  -- Request To send
83
end ACIA_6850; --================== End of entity ==============================--
84
 
85
-------------------------------------------------------------------------------
86
-- Architecture for ACIA_6850 Interface registees
87
-------------------------------------------------------------------------------
88
 
89
architecture rtl of ACIA_6850 is
90
 
91
  type DCD_State_Type is ( DCD_State_Idle, DCD_State_Int, DCD_State_Reset );
92
 
93
  -----------------------------------------------------------------------------
94
  -- Signals
95
  -----------------------------------------------------------------------------
96
 
97
  ----------------------------------------------------------------------
98
  --  Status Register: StatReg 
99
  ----------------------------------------------------------------------
100
  --
101
  -- IO address + 0 Read
102
  --
103
  -----------+--------+-------+--------+--------+--------+--------+--------+
104
  --  Irq    | PErr   | OErr  | FErr   |  CTS   |  DCD   |  TxBE  |  RxDR  |
105
  -----------+--------+-------+--------+--------+--------+--------+--------+
106
  -- Irq  - Bit[7] - Interrupt request
107
  -- PErr - Bit[6] - Receive Parity error (parity bit does not match)
108
  -- OErr - Bit[5] - Receive Overrun error (new character received before last read)
109
  -- FErr - Bit[4] - Receive Framing Error (bad stop bit)
110
  -- CTS  - Bit[3] - Clear To Send level
111
  -- DCD  - Bit[2] - Data Carrier Detect (lost modem carrier)
112
  -- TxBE - Bit[1] - Transmit Buffer Empty (ready to accept next transmit character)
113
  -- RxDR - Bit[0] - Receive Data Ready (character received)
114
  -- 
115
  signal StatReg : Std_Logic_Vector(7 downto 0) := (others => '0'); -- status register
116
 
117
  ----------------------------------------------------------------------
118
  --  Control Register: CtrlReg
119
  ----------------------------------------------------------------------
120
  --
121
  -- IO address + 0 Write
122
  --
123
  -----------+--------+--------+--------+--------+--------+--------+--------+
124
  --  RxIEnb |TxCtl(1)|TxCtl(0)|WdFmt(2)|WdFmt(1)|WdFmt(0)|BdCtl(1)|BdCtl(0)|
125
  -----------+--------+--------+--------+--------+--------+--------+--------+
126
  -- RxIEnb - Bit[7]
127
  -- 0       - Rx Interrupt disabled
128
  -- 1       - Rx Interrupt enabled
129
  -- TxCtl - Bits[6..5]
130
  -- 0 1     - Tx Interrupt Enable
131
  -- 1 0     - RTS high
132
  -- WdFmt - Bits[4..2]
133
  -- 0 0 0   - 7 data, even parity, 2 stop
134
  -- 0 0 1   - 7 data, odd  parity, 2 stop
135
  -- 0 1 0   - 7 data, even parity, 1 stop
136
  -- 0 1 1   - 7 data, odd  parity, 1 stop
137
  -- 1 0 0   - 8 data, no   parity, 2 stop
138
  -- 1 0 1   - 8 data, no   parity, 1 stop
139
  -- 1 1 0   - 8 data, even parity, 1 stop
140
  -- 1 1 1   - 8 data, odd  parity, 1 stop
141
  -- BdCtl - Bits[1..0]
142
  -- 0 0     - Baud Clk divide by 1
143
  -- 0 1     - Baud Clk divide by 16
144
  -- 1 0     - Baud Clk divide by 64
145
  -- 1 1     - reset
146
  signal CtrlReg : Std_Logic_Vector(7 downto 0) := (others => '0'); -- control register
147
 
148
  ----------------------------------------------------------------------
149
  -- Receive Register
150
  ----------------------------------------------------------------------
151
  --
152
  -- IO address + 1     Read
153
  --
154
  signal RecvReg : Std_Logic_Vector(7 downto 0) := (others => '0');
155
  ----------------------------------------------------------------------
156
  -- Transmit Register
157
  ----------------------------------------------------------------------
158
  --
159
  -- IO address + 1     Write
160
  --
161
  signal TranReg : Std_Logic_Vector(7 downto 0) := (others => '0');
162
 
163
  signal Reset    : Std_Logic;  -- Reset (Software & Hardware)
164
  signal RxRst    : Std_Logic;  -- Receive Reset (Software & Hardware)
165
  signal TxRst    : Std_Logic;  -- Transmit Reset (Software & Hardware)
166
  signal TxDbit   : Std_Logic;  -- Transmit data bit
167
  signal RxDR     : Std_Logic := '0';  -- Receive Data ready
168
  signal TxBE     : Std_Logic := '0';  -- Transmit buffer empty
169
 
170
  signal FErr     : Std_Logic := '0';  -- Frame error
171
  signal OErr     : Std_Logic := '0';  -- Output error
172
  signal PErr     : Std_Logic := '0';  -- Parity Error
173
 
174
  signal TxIEnb   : Std_Logic := '0';  -- Transmit interrupt enable
175
  signal RxIEnb   : Std_Logic := '0';  -- Receive interrupt enable
176
 
177
  signal ReadRR   : Std_Logic := '0';  -- Read receive buffer
178
  signal WriteTR  : Std_Logic := '0';  -- Write transmit buffer
179
  signal ReadSR   : Std_Logic := '0';  -- Read Status register
180
 
181
  signal DCDState : DCD_State_Type;    -- DCD Reset state sequencer
182
  signal DCDDel   : Std_Logic := '0';  -- Delayed DCD_n
183
  signal DCDEdge  : Std_Logic := '0';  -- Rising DCD_N Edge Pulse
184
  signal DCDInt   : Std_Logic := '0';  -- DCD Interrupt
185
 
186
  -----------------------------------------------------------------------------
187
  -- ACIA Receiver
188
  -----------------------------------------------------------------------------
189
  component ACIA_RX
190
  port (
191
     Clk     : in  Std_Logic;                    -- Bus Clock signal
192
     RxRst   : in  Std_Logic;                    -- Reset input
193
     RxRd    : in  Std_Logic;                    -- Read data strobe
194
     WdFmt   : in  Std_Logic_Vector(2 downto 0); -- word format
195
     BdFmt   : in  Std_Logic_Vector(1 downto 0); -- baud format
196
     RxClk   : in  Std_Logic;                    -- Receive clock input
197
     RxDat   : in  Std_Logic;                    -- Receive data bit input
198
     RxFErr  : out Std_Logic;                    -- Framing Error Status signal
199
     RxOErr  : out Std_Logic;                    -- Overrun Error Status signal
200
          RxPErr  : out Std_logic;                    -- Parity Error Status signal
201
     RxRdy   : out Std_Logic;                    -- Data Ready Status signal
202
     RxDout  : out Std_Logic_Vector(7 downto 0));-- Receive data bus output
203
  end component;
204
 
205
  -----------------------------------------------------------------------------
206
  -- ACIA Transmitter
207
  -----------------------------------------------------------------------------
208
  component ACIA_TX
209
  port (
210
     Clk    : in  Std_Logic;                    -- Bus Clock signal
211
     TxRst  : in  Std_Logic;                    -- Reset input
212
     TxWr   : in  Std_Logic;                    -- Load transmit data strobe
213
     TxDin  : in  Std_Logic_Vector(7 downto 0); -- Transmit data bus input
214
     WdFmt  : in  Std_Logic_Vector(2 downto 0); -- Word format Control signal
215
     BdFmt  : in  Std_Logic_Vector(1 downto 0); -- Baud format Control signal
216
     TxClk  : in  Std_Logic;                    -- Transmit clock input
217
     TxDat  : out Std_Logic;                    -- Transmit data bit output
218
     TxEmp  : out Std_Logic );                  -- Tx buffer empty status signal
219
  end component;
220
 
221
begin
222
  -----------------------------------------------------------------------------
223
  -- Instantiation of internal components
224
  -----------------------------------------------------------------------------
225
 
226
  RxDev   : ACIA_RX  port map (
227
                Clk      => clk,
228
                                         RxRst    => RxRst,
229
                                         RxRd     => ReadRR,
230
                                         WdFmt    => CtrlReg(4 downto 2),
231
                                         BdFmt    => CtrlReg(1 downto 0),
232
                                         RxClk    => RxC,
233
                                         RxDat    => RxD,
234
                                         RxFErr   => FErr,
235
                                         RxOErr   => OErr,
236
                                         RxPErr   => PErr,
237
                                         RxRdy    => RxDR,
238
                                         RxDout   => RecvReg
239
                                         );
240
 
241
 
242
  TxDev   : ACIA_TX  port map (
243
                Clk      => clk,
244
                                         TxRst    => TxRst,
245
                                         TxWr     => WriteTR,
246
                                         TxDin    => TranReg,
247
                                         WdFmt    => CtrlReg(4 downto 2),
248
                                         BdFmt    => CtrlReg(1 downto 0),
249
                                         TxClk    => TxC,
250
                                         TxDat    => TxDbit,
251
                                         TxEmp    => TxBE
252
                                         );
253
 
254
---------------------------------------------------------------
255
-- ACIA Reset may be hardware or software
256
---------------------------------------------------------------
257
ACIA_Reset : process( clk, rst, Reset, DCD_n )
258
begin
259
    -- Asynchronous External reset
260
    if rst = '1' then
261
           Reset <= '1';
262
    elsif clk'Event and clk = '0' then
263
           -- Synchronous Software reset
264
           Reset <= CtrlReg(1) and CtrlReg(0);
265
         end if;
266
         -- Transmitter reset
267
         TxRst <= Reset;
268
         -- Receiver reset
269
         RxRst <= Reset or DCD_n;
270
 
271
end process;
272
 
273
  -----------------------------------------------------------------------------
274
  -- ACIA Status Register
275
  -----------------------------------------------------------------------------
276
--
277
--ACIA_Status : process(clk,  Reset, TxIEnb, RxIEnb,
278
--                          RxDR, TxBE,  DCD_n, CTS_n, DCDInt,
279
--                          FErr, OErr,  PErr )
280
ACIA_Status : process(Reset, clk )
281
  begin
282
    if Reset = '1' then
283
       StatReg <= (others => '0');
284
    elsif clk'event and clk='0' then
285
                 StatReg(0) <= RxDR;   -- Receive Data Ready
286
       StatReg(1) <= TxBE and (not CTS_n); -- Transmit Buffer Empty
287
            StatReg(2) <= DCDInt; -- Data Carrier Detect
288
                 StatReg(3) <= CTS_n;  -- Clear To Send
289
       StatReg(4) <= FErr;   -- Framing error
290
       StatReg(5) <= OErr;   -- Overrun error
291
       StatReg(6) <= PErr;   -- Parity error
292
                 StatReg(7) <= (RxIEnb and RxDR)   or
293
                               (RxIEnb and DCDInt) or
294
                               (TxIEnb and TxBE);
295
    end if;
296
  end process;
297
 
298
 
299
-----------------------------------------------------------------------------
300
-- ACIA Transmit Control
301
-----------------------------------------------------------------------------
302
 
303
ACIA_Control : process( CtrlReg, TxDbit )
304
begin
305
    case CtrlReg(6 downto 5) is
306
         when "00" => -- Disable TX Interrupts, Assert RTS
307
           RTS_n  <= '0';
308
                TxD    <= TxDbit;
309
                TxIEnb <= '0';
310
    when "01" => -- Enable TX interrupts, Assert RTS
311
           RTS_n  <= '0';
312
                TxD    <= TxDbit;
313
                TxIEnb <= '1';
314
    when "10" => -- Disable Tx Interrupts, Clear RTS
315
           RTS_n  <= '1';
316
                TxD    <= TxDbit;
317
                TxIEnb <= '0';
318
    when "11" => -- Disable Tx interrupts, Assert RTS, send break
319
           RTS_n  <= '0';
320
                TxD    <= '0';
321
                TxIEnb <= '0';
322
    when others =>
323
           null;
324
         end case;
325
 
326
         RxIEnb <= CtrlReg(7);
327
 
328
end process;
329
 
330
-----------------------------------------------------------------------------
331
-- Generate Read / Write strobes.
332
-----------------------------------------------------------------------------
333
 
334
--ACIA_Read_Write:  process(clk, Reset, cs, rw, Addr, DataIn )
335
ACIA_Read_Write:  process(clk, Reset )
336
begin
337
  if reset = '1' then
338
            CtrlReg <= (others => '0');
339
                 TranReg <= (others => '0');
340
                 ReadRR  <= '0';
341
                 WriteTR <= '0';
342
                 ReadSR <= '0';
343
        elsif clk'event and clk='0' then
344
       ReadRR  <= '0';
345
       WriteTR <= '0';
346
       ReadSR  <= '0';
347
            if cs = '1' then
348
              if Addr = '0' then -- Control / Status register
349
                     if rw = '0' then   -- write control register
350
                            CtrlReg <= DataIn;
351
                          else               -- read status register
352
                            ReadSR      <= '1';
353
                          end if;
354
              else                                         -- Data Register
355
                     if rw = '0' then   -- write transmiter register
356
             TranReg <= DataIn;
357
                  WriteTR <= '1';
358
                else               -- read receiver register
359
             ReadRR  <= '1';
360
                          end if; -- rw
361
                   end if; -- Addr
362
            end if;  -- cs
363
   end if; -- clk / reset
364
end process;
365
 
366
---------------------------------------------------------------
367
-- Set Data Output Multiplexer
368
--------------------------------------------------------------
369
 
370
ACIA_Data_Mux: process(Addr, StatReg, RecvReg)
371
begin
372
         if Addr = '1' then
373
                 DataOut <= RecvReg;   -- read receiver register
374
         else
375
                 DataOut <= StatReg;   -- read status register
376
         end if; -- Addr
377
    irq <= StatReg(7);
378
end process;
379
 
380
 
381
---------------------------------------------------------------
382
-- Data Carrier Detect Edge rising edge detect
383
---------------------------------------------------------------
384
--ACIA_DCD_edge : process( reset, clk, DCD_n, DCDDel    )
385
ACIA_DCD_edge : process( reset, clk     )
386
begin
387
   if reset = '1' then
388
           DCDEdge <= '0';
389
                DCDDel  <= '0';
390
   elsif clk'event and clk = '0' then
391
           DCDDel <= DCD_n;
392
                DCDEdge <= DCD_n and (not DCDDel);
393
   end if;
394
end process;
395
 
396
 
397
---------------------------------------------------------------
398
-- Data Carrier Detect Interrupt
399
---------------------------------------------------------------
400
-- If Data Carrier is lost, an interrupt is generated
401
-- To clear the interrupt, first read the status register
402
--      then read the data receive register
403
--
404
--ACIA_DCD_Int : process( reset, clk, DCDState, DCDEdge, ReadRR, ReadSR )
405
ACIA_DCD_Int : process( reset, clk )
406
begin
407
   if reset = '1' then
408
           DCDInt   <= '0';
409
                DCDState <= DCD_State_Idle;
410
   elsif clk'event and clk = '0' then
411
           case DCDState is
412
                when DCD_State_Idle =>
413
                   -- DCD Edge activates interrupt
414
                   if DCDEdge = '1' then
415
                      DCDInt     <= '1';
416
                           DCDState   <= DCD_State_Int;
417
                   end if;
418
           when DCD_State_Int =>
419
                   -- To reset DCD interrupt, 
420
                        -- First read status
421
                   if ReadSR = '1' then
422
                           DCDState <= DCD_State_Reset;
423
                   end if;
424
                when DCD_State_Reset =>
425
                   -- Then read receive register
426
                   if ReadRR = '1' then
427
                                DCDInt   <= '0';
428
                                DCDState <= DCD_State_Idle;
429
         end if;
430
      when others =>
431
         null;
432
      end case;
433
   end if; -- clk / reset
434
end process;
435
 
436
end rtl; --===================== End of architecture =======================--
437
 

powered by: WebSVN 2.1.0

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