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

Subversion Repositories pdp8

[/] [pdp8/] [trunk/] [pdp8/] [uart/] [uart_rx.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 trurl
--------------------------------------------------------------------
2
--!
3
--! PDP-8 Processor
4
--!
5
--! \brief
6
--!      KL8E Generic UART Receiver
7
--!
8
--! \details
9
--!      The UART Receiver is hard configured for:
10
--!      - 8 data bits
11
--!      - no parity
12
--!      - 1 stop bit
13
--!
14
--! \note
15
--!      This UART primitive receiver is kept simple
16
--!      intentionally and is therefore unbuffered.  If you
17
--!      require a double buffered UART, then you will need to
18
--!      layer a set of buffers on top of this device.
19
--!
20
--! \file
21
--!      uart_rx.vhd
22
--!
23
--! \author
24
--!      Rob Doyle - doyle (at) cox (dot) net
25
--!
26
--------------------------------------------------------------------
27
--
28
--  Copyright (C) 2009, 2010, 2011, 2012 Rob Doyle
29
--
30
-- This source file may be used and distributed without
31
-- restriction provided that this copyright statement is not
32
-- removed from the file and that any derivative work contains
33
-- the original copyright notice and the associated disclaimer.
34
--
35
-- This source file is free software; you can redistribute it
36
-- and/or modify it under the terms of the GNU Lesser General
37
-- Public License as published by the Free Software Foundation;
38
-- version 2.1 of the License.
39
--
40
-- This source is distributed in the hope that it will be
41
-- useful, but WITHOUT ANY WARRANTY; without even the implied
42
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
43
-- PURPOSE. See the GNU Lesser General Public License for more
44
-- details.
45
--
46
-- You should have received a copy of the GNU Lesser General
47
-- Public License along with this source; if not, download it
48
-- from http://www.gnu.org/licenses/lgpl.txt
49
--
50
--------------------------------------------------------------------
51
--
52
-- Comments are formatted for doxygen
53
--
54
 
55
library ieee;                                   --! IEEE Library
56
use ieee.std_logic_1164.all;                    --! IEEE 1164
57
use work.uart_types.all;                        --! UART Types
58
use work.cpu_types.all;                         --! CPU Types
59
 
60
--
61
--! KL8E Generic UART Receiver Entity
62
--
63
 
64
entity eUART_RX is port (
65
    sys   : in  sys_t;                          --! Clock/Reset
66
    clkBR : in  std_logic;                      --! Clock Enable (for Baud Rate)
67
    rxd   : in  std_logic;                      --! Serial Data In
68
    intr  : out std_logic;                      --! Data Received
69
    data  : out ascii_t                         --! Data Output
70
);
71
end eUART_RX;
72
 
73
--
74
--! KL8E Generic UART Receiver RTL
75
--
76
 
77
architecture rtl of eUART_RX is
78
    type   state_t is (stateIdle,               --! Idle
79
                       stateStart,              --! Working on Start Bit
80
                       stateBit0,               --! Working on Bit 0
81
                       stateBit1,               --! Working on Bit 1
82
                       stateBit2,               --! Working on Bit 2
83
                       stateBit3,               --! Working on Bit 3
84
                       stateBit4,               --! Working on Bit 4
85
                       stateBit5,               --! Working on Bit 5
86
                       stateBit6,               --! Working on Bit 6
87
                       stateBit7,               --! Working on Bit 7
88
                       stateStop,               --! Working on Stop Bit
89
                       stateDone);              --! Generate Intr
90
    signal state   : state_t;                   --! Receiver State
91
    signal rxReg   : ascii_t;                   --! Receiver Register
92
    signal rxdd    : std_logic_vector(0 to 1);  --! Demet RXD
93
 
94
begin
95
 
96
    --
97
    --! This process synchronizes the Received Data to this clock
98
    --! domain.
99
    --
100
 
101
    DEMET_RXD : process(sys)
102
    begin
103
        if sys.rst = '1' then
104
            rxdd <= (others => '0');
105
        elsif rising_edge(sys.clk) then
106
            rxdd(0) <= rxd;
107
            rxdd(1) <= rxdd(0);
108
        end if;
109
    end process DEMET_RXD;
110
 
111
 
112
    --
113
    --! UART Receiver:
114
    --!  The clkBR is 16 clocks per bit.  The UART receives LSB first.
115
    --!
116
    --!  The state machine is initialized to the idle state where it
117
    --!  looks for a start bit.  When it find the 'edge' of the start
118
    --!  bit starts the state machine which does the following:
119
    --!
120
    --!  -# Continuously sample the start bit for half a bit period.
121
    --!     If the start bit is narrower than half a bit then, go back
122
    --!     to the idle state and look for a real start bit.   Othewise,
123
    --!  -# Delay one bit time from the middle of the Start bit and
124
    --!     sample bit D7 (LSB), then
125
    --!  -# Delay one bit time from the middle of D7 and sample bit D6, then
126
    --!  -# Delay one bit time from the middle of D6 and sample bit D5, then
127
    --!  -# Delay one bit time from the middle of D5 and sample bit D4, then
128
    --!  -# Delay one bit time from the middle of D4 and sample bit D3, then
129
    --!  -# Delay one bit time from the middle of D3 and sample bit D2, then
130
    --!  -# Delay one bit time from the middle of D2 and sample bit D1, then
131
    --!  -# Delay one bit time from the middle of D1 and sample bit D0, then
132
    --!  -# Delay one bit time from the middle of D0 and sample Stop
133
    --!     Bit, then
134
    --!  -# Generate INTR pulse for one clock cycle, then
135
    --!  -# go back to idle state and wait for a stop bit.
136
    --!
137
 
138
    UARTRX : process(sys)
139
        variable brdiv : integer range 0 to 15;
140
    begin
141
        if sys.rst = '1' then
142
 
143
            state <= stateIdle;
144
            rxReg <= (others => '0');
145
            brdiv := 0;
146
 
147
        elsif rising_edge(sys.clk) then
148
 
149
            case state is
150
 
151
                --
152
                -- Reciever is Idle
153
                --
154
 
155
                when stateIdle =>
156
                    if clkBR = '1' then
157
                        if rxdd(1) = '0' then
158
                            state <= stateStart;
159
                            brdiv := 8;
160
                        end if;
161
                    end if;
162
 
163
                --
164
                -- Receive Start Bit
165
                --
166
 
167
                when stateStart =>
168
                    if clkBR = '1' then
169
                        if rxdd(1) = '0' then
170
                            if brdiv = 0 then
171
                                brdiv := 15;
172
                                state <= stateBit7;
173
                            else
174
                                brdiv := brdiv - 1;
175
                            end if;
176
                        else
177
                            state <= stateIdle;
178
                        end if;
179
                    end if;
180
 
181
                --
182
                -- Receive Bit 7 (LSB)
183
                --
184
 
185
                when stateBit7 =>
186
                    if clkBR = '1' then
187
                        if brdiv = 0 then
188
                            brdiv := 15;
189
                            rxReg <= rxdd(1) & rxReg(0 to 6);
190
                            state <= stateBit6;
191
                        else
192
                            brdiv := brdiv - 1;
193
                        end if;
194
                    end if;
195
 
196
                --
197
                -- Receive Bit 6 
198
                --
199
 
200
                when stateBit6 =>
201
                    if clkBR = '1' then
202
                        if brdiv = 0 then
203
                            brdiv := 15;
204
                            rxReg <= rxdd(1) & rxReg(0 to 6);
205
                            state <= stateBit5;
206
                        else
207
                            brdiv := brdiv - 1;
208
                        end if;
209
                    end if;
210
 
211
                --
212
                -- Receive Bit 5
213
                --
214
 
215
                when stateBit5 =>
216
                    if clkBR = '1' then
217
                        if brdiv = 0 then
218
                            brdiv := 15;
219
                            rxReg <= rxdd(1) & rxReg(0 to 6);
220
                            state <= stateBit4;
221
                        else
222
                            brdiv := brdiv - 1;
223
                        end if;
224
                    end if;
225
 
226
                --
227
                -- Receive Bit 4 
228
                --
229
 
230
                when stateBit4 =>
231
                    if clkBR = '1' then
232
                        if brdiv = 0 then
233
                            brdiv := 15;
234
                            rxReg <= rxdd(1) & rxReg(0 to 6);
235
                            state <= stateBit3;
236
                        else
237
                            brdiv := brdiv - 1;
238
                        end if;
239
                    end if;
240
 
241
                --
242
                -- Receive Bit 3
243
                --
244
 
245
                when stateBit3 =>
246
                    if clkBR = '1' then
247
                        if brdiv = 0 then
248
                            brdiv := 15;
249
                            rxReg <= rxdd(1) & rxReg(0 to 6);
250
                            state <= stateBit2;
251
                        else
252
                            brdiv := brdiv - 1;
253
                        end if;
254
                    end if;
255
 
256
                --
257
                -- Receive Bit 2
258
                --
259
 
260
                when stateBit2 =>
261
                    if clkBR = '1' then
262
                        if brdiv = 0 then
263
                            brdiv := 15;
264
                            rxReg <= rxdd(1) & rxReg(0 to 6);
265
                            state <= stateBit1;
266
                        else
267
                            brdiv := brdiv - 1;
268
                        end if;
269
                    end if;
270
 
271
                --
272
                -- Receive Bit 1
273
                --
274
 
275
                when stateBit1 =>
276
                    if clkBR = '1' then
277
                        if brdiv = 0 then
278
                            brdiv := 15;
279
                            rxReg <= rxdd(1) & rxReg(0 to 6);
280
                            state <= stateBit0;
281
                        else
282
                            brdiv := brdiv - 1;
283
                        end if;
284
                    end if;
285
 
286
                --
287
                -- Receive Bit 0 (MSB)
288
                --
289
 
290
                when stateBit0 =>
291
                    if clkBR = '1' then
292
                        if brdiv = 0 then
293
                            brdiv := 15;
294
                            rxReg <= rxdd(1) & rxReg(0 to 6);
295
                            state <= stateStop;
296
                        else
297
                            brdiv := brdiv - 1;
298
                        end if;
299
                    end if;
300
 
301
                --
302
                -- Receive Stop Bit
303
                --
304
 
305
                 when stateStop =>
306
                    if clkBR = '1' then
307
                        if brdiv = 0 then
308
                            state <= stateDone;
309
                        else
310
                            brdiv := brdiv - 1;
311
                        end if;
312
                    end if;
313
 
314
                --
315
                -- Generate Interrupt
316
                --
317
 
318
               when stateDone =>
319
                  state <= stateIdle;
320
 
321
            end case;
322
        end if;
323
    end process UARTRX;
324
 
325
    data <= rxReg;
326
    intr <= '1' when state = stateDone else '0';
327
 
328
end rtl;

powered by: WebSVN 2.1.0

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