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

Subversion Repositories System09

[/] [System09/] [rev_86/] [rtl/] [VHDL/] [ACIA_RX.vhd] - Blame information for rev 184

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 for the System68/09
9
--
10
-- File name      : ACIA_RX.vhd
11
--
12
-- Purpose        : Implements a 6850 ACIA device for communication purposes 
13
--                  between the cpu68/09 cpu and the Host computer through
14
--                  an RS-232 communication protocol.
15
--                  
16
-- Dependencies   : ieee.std_logic_1164.all;
17
--                  ieee.numeric_std.all;
18
--                  ieee.std_logic_unsigned.all;
19
--                  unisim.vcomponents.all;
20
--
21
--===========================================================================--
22
-------------------------------------------------------------------------------
23
-- Revision list
24
-- Version   Author                 Date                        Changes
25
--
26
-- 0.1      Ovidiu Lupas     15 January 2000                   New model
27
-- 2.0      Ovidiu Lupas     17 April   2000  samples counter cleared for bit 0
28
--        olupas@opencores.org
29
--
30
-- 3.0      John Kent         5 January 2003  Added 6850 word format control
31
-- 3.1      John Kent        12 January 2003  Significantly revamped receive code.
32
-- 3.2      John Kent        10 January 2004  Rewrite of code.
33
-- 4.0      John Kent        3 February 2007  Renamed to ACIA 6850
34
--                                            Removed input debounce
35
-- 4.1      John Kent         4 February 2007 Cleaned up Rx state machine
36
--      4.2      John Kent        25 February 2007 Modified sensitivity lists
37
--
38
--        dilbert57@opencores.org
39
-------------------------------------------------------------------------------
40
--
41
-- Description    : Implements the receive unit of the ACIA_6850 core.
42
--                  Samples 16 times the RxD line and retain the value
43
--                  in the middle of the time interval. 
44
--
45
library ieee;
46
   use ieee.std_logic_1164.all;
47
   use ieee.numeric_std.all;
48
   use ieee.std_logic_unsigned.all;
49
--library unisim;
50
--      use unisim.vcomponents.all;
51
 
52
-------------------------------------------------------------------------------
53
-- Entity for the ACIA Receiver
54
-------------------------------------------------------------------------------
55
entity ACIA_RX is
56
  port (
57
     Clk    : in  Std_Logic;                    -- Clock signal
58
     RxRst  : in  Std_Logic;                    -- Reset input
59
     RxRd   : in  Std_Logic;                    -- Read data strobe
60
     WdFmt  : in  Std_Logic_Vector(2 downto 0); -- word format
61
     BdFmt  : in  Std_Logic_Vector(1 downto 0); -- baud format
62
     RxClk  : in  Std_Logic;                    -- RS-232 clock input
63
     RxDat  : in  Std_Logic;                    -- RS-232 data input
64
     RxFErr : out Std_Logic;                    -- Framing Error status
65
     RxOErr : out Std_Logic;                    -- Over Run Error Status
66
          RxPErr : out Std_logic;                    -- Parity Error Status
67
     RxRdy  : out Std_Logic;                    -- Data Ready Status
68
     RxDout : out Std_Logic_Vector(7 downto 0)
69
          );
70
end ACIA_RX; --================== End of entity ==============================--
71
 
72
-------------------------------------------------------------------------------
73
-- Architecture for ACIA receiver
74
-------------------------------------------------------------------------------
75
 
76
architecture rtl of ACIA_RX is
77
 
78
  type RxStateType is ( RxStart_State, RxData_state,
79
                                                                RxParity_state, RxStop_state );
80
 
81
  -----------------------------------------------------------------------------
82
  -- Signals
83
  -----------------------------------------------------------------------------
84
  signal RxDatDel0  : Std_Logic := '0';             -- Delayed Rx Data
85
  signal RxDatDel1  : Std_Logic := '0';             -- Delayed Rx Data
86
  signal RxDatDel2  : Std_Logic := '0';             -- Delayed Rx Data
87
  signal RxDatEdge  : Std_Logic := '0';             -- Rx Data Edge pulse
88
  signal RxClkDel   : Std_Logic := '0';             -- Delayed Rx Input Clock
89
  signal RxClkEdge  : Std_Logic := '0';             -- Rx Input Clock Edge pulse
90
  signal RxStart    : Std_Logic := '0';             -- Rx Start request
91
  signal RxEnable   : Std_Logic := '0';             -- Rx Enabled
92
  signal RxClkCnt   : Std_Logic_Vector(5 downto 0) := (others => '0'); -- Rx Baud Clock Counter
93
  signal RxBdClk    : Std_Logic := '0';             -- Rx Baud Clock
94
  signal RxBdDel    : Std_Logic := '0';             -- Delayed Rx Baud Clock
95
  signal RxBdEdge   : Std_Logic := '0';             -- Rx Baud Clock Edge pulse
96
 
97
  signal RxReady    : Std_Logic := '0';             -- Data Ready flag
98
  signal RxReq      : Std_Logic := '0';             -- Rx Data Valid
99
  signal RxAck      : Std_Logic := '0';             -- Rx Data Valid
100
  signal RxParity   : Std_Logic := '0';             -- Calculated RX parity bit
101
  signal RxState    : RxStateType;           -- receive bit state
102
  signal RxBitCount : Std_Logic_Vector(2 downto 0) := (others => '0');  -- Rx Bit counter
103
  signal RxShiftReg : Std_Logic_Vector(7 downto 0) := (others => '0');  -- Shift Register
104
 
105
begin
106
 
107
  ---------------------------------------------------------------------
108
  -- Receiver Clock Edge Detection
109
  ---------------------------------------------------------------------
110
  -- A rising edge will produce a one clock cycle pulse
111
  --
112
--  acia_rx_clock_edge : process( Clk, RxRst, RxClk, RxClkDel )
113
  acia_rx_clock_edge : process( RxRst, Clk )
114
  begin
115
    if RxRst = '1' then
116
           RxClkDel  <= '0';
117
                RxClkEdge <= '0';
118
         elsif Clk'event and Clk = '0' then
119
           RxClkDel  <= RxClk;
120
                RxClkEdge <= (not RxClkDel) and RxClk;
121
         end if;
122
  end process;
123
 
124
  ---------------------------------------------------------------------
125
  -- Receiver Data Edge Detection
126
  ---------------------------------------------------------------------
127
  -- A falling edge will produce a pulse on RxClk wide
128
  --
129
--  acia_rx_data_edge : process(Clk, RxRst, RxClkEdge, RxDat, RxDatDel0, RxDatDel1, RxDatDel2 )
130
  acia_rx_data_edge : process( RxRst, Clk )
131
  begin
132
    if RxRst = '1' then
133
           RxDatDel0 <= '0';
134
           RxDatDel1 <= '0';
135
           RxDatDel2 <= '0';
136
                RxDatEdge <= '0';
137
         elsif Clk'event and Clk = '0' then
138
--         if RxClkEdge = '1' then
139
             RxDatDel0 <= RxDat;
140
             RxDatDel1 <= RxDatDel0;
141
             RxDatDel2 <= RxDatDel1;
142
                  RxDatEdge <= RxDatDel0 and (not RxDat);
143
--    end if;
144
         end if;
145
  end process;
146
 
147
  ---------------------------------------------------------------------
148
  -- Receiver Start / Stop
149
  ---------------------------------------------------------------------
150
  -- Enable the receive clock on detection of a start bit
151
  -- Disable the receive clock after a byte is received.
152
  -- 
153
--  acia_rx_start_stop : process( Clk, RxRst, RxDatEdge, RxAck, RxStart, RxEnable )
154
  acia_rx_start_stop : process( RxRst, Clk )
155
  begin
156
    if RxRst = '1' then
157
        RxEnable <= '0';
158
                  RxStart  <= '0';
159
    elsif Clk'event and Clk='0' then
160
        if (RxEnable = '0') and (RxDatEdge = '1') then
161
                    -- Data Edge detected 
162
                         -- Request Start and Enable Receive Clock.
163
          RxEnable <= '1';
164
                         RxStart  <= '1';
165
                  else
166
                    if (RxStart = '1') and (RxAck = '1') then
167
                           -- Data is being received
168
                                -- reset start request
169
                                RxStart <= '0';
170
                         else
171
                           -- Data has now been received
172
                                -- Disable Receiver until next start bit
173
                           if (RxStart = '0') and (RxAck = '0') then
174
                             RxEnable <= '0';
175
                                end if;
176
                         end if; -- RxStart
177
        end if; -- RxDatEdge
178
    end if; -- clk / RxRst
179
  end process;
180
 
181
  ---------------------------------------------------------------------
182
  -- Receiver Clock Divider
183
  ---------------------------------------------------------------------
184
  -- Hold the Rx Clock divider in reset when the receiver is disabled
185
  -- Advance the count only on a rising Rx clock edge
186
  --
187
--  acia_rx_clock_divide : process( Clk, RxRst, RxEnable, RxClkEdge, RxClkCnt )
188
  acia_rx_clock_divide : process( RxRst, Clk )
189
  begin
190
    if RxRst = '1' then
191
           RxClkCnt  <= (others => '0');
192
         elsif Clk'event and Clk = '0' then
193
--         if RxEnable = '0' then
194
      if RxDatEdge = '1' then
195
                    RxClkCnt <= (others => '0');   -- reset on falling data edge
196
                else
197
                  if RxClkEdge = '1' then          -- increment count on Clock edge
198
                    RxClkCnt <= RxClkCnt + "000001";
199
        end if; -- RxClkEdge
200
      end if; -- RxState
201
         end if;         -- clk / RxRst
202
  end process;
203
 
204
  ---------------------------------------------------------------------
205
  -- Receiver Baud Clock Selector
206
  ---------------------------------------------------------------------
207
  -- BdFmt
208
  -- 0 0     - Baud Clk divide by 1
209
  -- 0 1     - Baud Clk divide by 16
210
  -- 1 0     - Baud Clk divide by 64
211
  -- 1 1     - Reset
212
  --
213
  acia_rx_baud_clock_select : process( BdFmt, RxClk, RxClkCnt )
214
  begin
215
    case BdFmt is
216
         when "00" =>     -- Div by 1
217
           RxBdClk <= RxClk;
218
         when "01" =>     -- Div by 16
219
           RxBdClk <= RxClkCnt(3);
220
         when "10" =>     -- Div by 64
221
           RxBdClk <= RxClkCnt(5);
222
         when others =>  -- RxRst
223
           RxBdClk <= '0';
224
    end case;
225
  end process;
226
 
227
  ---------------------------------------------------------------------
228
  -- Receiver Baud Clock Edge Detect
229
  ---------------------------------------------------------------------
230
  --
231
  -- Generate one clock strobe on rising baud clock edge
232
  --
233
--  acia_rx_baud_clock_edge : process( Clk, RxRst, RxBdClk, RxBdDel )
234
  acia_rx_baud_clock_edge : process( RxRst, Clk )
235
  begin
236
    if RxRst = '1' then
237
           RxBdDel  <= '0';
238
                RxBdEdge <= '0';
239
         elsif Clk'event and Clk = '0' then
240
           RxBdDel  <= RxBdClk;
241
                RxBdEdge <= RxBdClk and (not RxBdDel);
242
         end if;
243
  end process;
244
 
245
  ---------------------------------------------------------------------
246
  -- Receiver process
247
  ---------------------------------------------------------------------
248
  -- WdFmt - Bits[4..2]
249
  -- 0 0 0   - 7 data, even parity, 2 stop
250
  -- 0 0 1   - 7 data, odd  parity, 2 stop
251
  -- 0 1 0   - 7 data, even parity, 1 stop
252
  -- 0 1 1   - 7 data, odd  parity, 1 stop
253
  -- 1 0 0   - 8 data, no   parity, 2 stop
254
  -- 1 0 1   - 8 data, no   parity, 1 stop
255
  -- 1 1 0   - 8 data, even parity, 1 stop
256
  -- 1 1 1   - 8 data, odd  parity, 1 stop
257
--  acia_rx_receive : process( Clk, RxRst, RxState, RxBdEdge, RxDatDel2, RxBitCount, RxReady, RxShiftReg )
258
  acia_rx_receive : process( RxRst, Clk )
259
  begin
260
    if RxRst = '1' then
261
        RxFErr     <= '0';
262
        RxOErr     <= '0';
263
                  RxPErr     <= '0';
264
        RxShiftReg <= (others => '0');         -- Resert Shift register
265
                  RxDOut     <= (others => '0');
266
                  RxParity   <= '0';                     -- reset Parity bit
267
                  RxAck      <= '0';                     -- Receiving data
268
                  RxBitCount <= (others => '0');
269
        RxState    <= RxStart_state;
270
    elsif Clk'event and Clk='0' then
271
        if RxBdEdge = '1' then
272
          case RxState is
273
          when RxStart_state =>
274
            RxShiftReg <= (others => '0');     -- Reset Shift register
275
                      RxParity   <= '0';                 -- Parity bit
276
                           if WdFmt(2) = '0' then
277
                                  -- WdFmt(2) = '0' => 7 data
278
                        RxBitCount <= "110";
279
                                else
280
                                  -- WdFmt(2) = '1' => 8 data                            
281
                        RxBitCount <= "111";
282
                                end if;
283
                           if RxDatDel2 = '0' then            -- look for start request
284
              RxState <= RxData_state;         -- yes, read data
285
                           end if;
286
 
287
          when RxData_state => -- data bits 0 to 6
288
            RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1);
289
                           RxParity   <= RxParity xor RxDatDel2;
290
                                RxAck      <= '1';                                -- Flag receive in progress
291
            RxBitCount <= RxBitCount - "001";
292
                                if RxBitCount = "000" then
293
                             if WdFmt(2) = '0' then           -- WdFmt(2) = '0' => 7 data
294
                 RxState <= RxParity_state;    -- 7 bits always has parity
295
                             else                             -- WdFmt(2) = '1' => 8 data                                
296
                               if WdFmt(1) = '0' then
297
                  RxState <= RxStop_state;     -- WdFmt(1) = '0' no parity
298
                                    else
299
                  RxState <= RxParity_state;   -- WdFmt(1) = '1' parity
300
                               end if;  -- WdFmt(1)
301
                                  end if; -- WdFmt(2)
302
                                end if; -- RxBitCount
303
 
304
               when RxParity_state =>               -- parity bit
305
                           if WdFmt(2) = '0' then             -- 7 data, shift right
306
              RxShiftReg <= RxDatDel2 & RxShiftReg(7 downto 1); -- 7 data + parity
307
            end if;
308
                                if WdFmt(0) = '0' then             -- parity polarity ?
309
                                  if RxParity = RxDatDel2 then     -- check even parity
310
                                          RxPErr <= '1';
311
                                  else
312
                                          RxPErr <= '0';
313
                                  end if;
314
                                else
315
                                  if RxParity = RxDatDel2 then     -- check for odd parity
316
                                          RxPErr <= '0';
317
                                  else
318
                                          RxPErr <= '1';
319
                                  end if;
320
                                end if;
321
            RxState <= RxStop_state;
322
 
323
          when RxStop_state =>                 -- stop bit (Only one required for RX)
324
                                RxAck  <= '0';                     -- Flag Receive Complete
325
                                RxDOut <= RxShiftReg;
326
            if RxDatDel2 = '1' then            -- stop bit expected
327
              RxFErr <= '0';                   -- yes, no framing error
328
            else
329
              RxFErr <= '1';                   -- no, framing error
330
            end if;
331
            if RxReady = '1' then              -- Has previous data been read ? 
332
              RxOErr <= '1';                   -- no, overrun error
333
            else
334
              RxOErr <= '0';                   -- yes, no over run error
335
            end if;
336
            RxState <= RxStart_state;
337
 
338
          when others =>
339
                                RxAck   <= '0';                     -- Flag Receive Complete
340
            RxState <= RxStart_state;
341
          end case; -- RxState
342
 
343
        end if; -- RxBdEdge
344
    end if; -- clk / RxRst
345
 
346
  end process;
347
 
348
  ---------------------------------------------------------------------
349
  -- Receiver Read process
350
  ---------------------------------------------------------------------
351
--  acia_rx_read : process(Clk, RxRst, RxRd, RxReq, RxAck, RxReady )
352
  acia_rx_read : process( RxRst, Clk, RxReady )
353
  begin
354
    if RxRst = '1' then
355
        RxReady <= '0';
356
                  RxReq   <= '0';
357
    elsif Clk'event and Clk='0' then
358
        if RxRd = '1' then
359
                    -- Data was read, Reset data ready
360
                         -- Request more data
361
          RxReady <= '0';
362
                         RxReq   <= '1';
363
                  else
364
                    if RxReq = '1' and RxAck = '1' then
365
                           -- Data is being received
366
                                -- reset receive request
367
                                RxReq   <= '0';
368
                         else
369
                           -- Data now received
370
                                -- Flag RxReady and read Shift Register
371
                           if RxReq = '0' and RxAck = '0' then
372
                             RxReady <= '1';
373
                                end if;
374
                         end if; -- RxReq
375
        end if; -- RxRd
376
    end if; -- clk / RxRst
377
    RxRdy  <= RxReady;
378
  end process;
379
 
380
end rtl; --==================== End of architecture ====================--

powered by: WebSVN 2.1.0

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