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

Subversion Repositories pdp8

[/] [pdp8/] [trunk/] [pdp8/] [pr8e.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
--!      PR8E Paper Tape Reader (PTR)
7
--!
8
--! \details
9
--!      This device provides a PR8E register set compatible
10
--!      interface to a serial Decitek 762 Paper Tape Reader (PTR).
11
--!
12
--!      What follows is specific to the Decitek 762 PTR:
13
--!
14
--!      There is bi-directional serial interface between the PR8E
15
--!      controller and the PTR.  The PR8E sends command to the PTR
16
--!      and the PTR responds with data.
17
--!
18
--!      The interface operates as follows:
19
--!      -# The PR8E sends a 'Single Step Right' command (ASCII
20
--!         character 'R') to PTR which advances the paper tape one
21
--!         character.
22
--!      -# The PTR responds by sending the character that was read
23
--!         back from the paper tape to the PR8E.
24
--!
25
--! \note
26
--!      The DEC PR8E Paper Tape Reader interface is fundamentally
27
--!      incompatible with many inexpensive serial Paper Tape
28
--!      Readers.   The inexpensive paper tape readers simply
29
--!      stream bytes into the interface.  Some may add a XON/XOFF
30
--!      interface.
31
--!
32
--!      A compatible Paper Tape Reader must send one character and
33
--!      wait for the interface to command the Paper Tape reader
34
--!      to send the next character.
35
--!
36
--! \file
37
--!      pr8e.vhd
38
--!
39
--! \author
40
--!      Rob Doyle - doyle (at) cox (dot) net
41
--!
42
--------------------------------------------------------------------
43
--
44
--  Copyright (C) 2009, 2010, 2011, 2012 Rob Doyle
45
--
46
-- This source file may be used and distributed without
47
-- restriction provided that this copyright statement is not
48
-- removed from the file and that any derivative work contains
49
-- the original copyright notice and the associated disclaimer.
50
--
51
-- This source file is free software; you can redistribute it
52
-- and/or modify it under the terms of the GNU Lesser General
53
-- Public License as published by the Free Software Foundation;
54
-- version 2.1 of the License.
55
--
56
-- This source is distributed in the hope that it will be
57
-- useful, but WITHOUT ANY WARRANTY; without even the implied
58
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
59
-- PURPOSE. See the GNU Lesser General Public License for more
60
-- details.
61
--
62
-- You should have received a copy of the GNU Lesser General
63
-- Public License along with this source; if not, download it
64
-- from http://www.gnu.org/licenses/lgpl.txt
65
--
66
--------------------------------------------------------------------
67
--
68
-- Comments are formatted for doxygen
69
--
70
 
71
library ieee;                                   --! IEEE Library
72
use ieee.std_logic_1164.all;                    --! IEEE 1164
73
use work.uart_types.all;                        --! UART Types
74
use work.pr8e_types.all;                        --! PR8E Types
75
use work.cpu_types.all;                         --! CPU Types
76
 
77
--
78
--! PR8E Serial Paper Tape Reader Entity
79
--
80
 
81
entity ePR8E is port (
82
    sys       : in  sys_t;                      --! Clock/Reset
83
    uartBR    : in  uartBR_t;                   --! Baud Rate Select
84
    uartHS    : in  uartHS_t;                   --! Handshaking Select
85
    ptrdevNUM : in  devNUM_t;                   --! PTR IOT Device
86
    ptpdevNUM : in  devNUM_t;                   --! PTP IOT Device
87
    cpu       : in  cpu_t;                      --! CPU Input
88
    dev       : out dev_t;                      --! Device Output
89
    cts       : in  std_logic;                  --! CTS In
90
    rts       : out std_logic;                  --! RTS Out
91
    rxd       : in  std_logic;                  --! Serial Data In
92
    txd       : out std_logic                   --! Serial Data Out
93
);
94
end ePR8E;
95
 
96
--
97
--! PR8E Serial Paper Tape Reader RTL
98
--
99
 
100
architecture rtl of ePR8E is
101
    signal   clkBR     : std_logic;             --! 16x Baud Rate Clock Enable
102
    -- PR8E Registers
103
    signal   ieCLR     : std_logic;             --! Clear Interrupt Enable Register
104
    signal   ieSET     : std_logic;             --! Set Interrupt Enable Register
105
    signal   ieREG     : std_logic;             --! Interrupt Enable Register
106
    signal   flagCLR   : std_logic;             --! Clear Flag Register
107
    signal   flagREG   : std_logic;             --! Flag REG
108
    signal   dataREG   : data_t;                --! Received Data Register
109
    -- RX signals
110
    signal   rxIntr    : std_logic;             --! UART Receiver has data
111
    signal   rxData    : ascii_t;               --! UART Receiver Data
112
    -- TX signals
113
    signal   start     : std_logic;             --! Start
114
    signal   lastStart : std_logic;             --! Last start
115
    signal   loadUART  : std_logic;             --! Load Transmitter UART
116
    constant ascii_R   : ascii_t := x"52";      --! The letter 'R' in ascii
117
 
118
begin
119
 
120
    --
121
    --! PR8E Bus Interface
122
    --!
123
    --! \details
124
    --!     The Bus Interface decodes the individual PR8E IOT instructions.
125
    --!     The various operations: Enable Interrupts, Disable Interrupts,
126
    --!     Clear Flag are decoded and provided to the synchronous process
127
    --!     that maintains the PR8E register state.
128
    --!
129
    --! \note
130
    --!     The Bus Interface is totally asynchronous.  The dev.ack,
131
    --!     dev.skip, and dev.devc signals are combinationally derived from
132
    --!     CPU output bus signals.  These signals will be sampled by the
133
    --!     CPU on the device bus input on the next clock cycle.
134
    --
135
 
136
    PR8E_BUSINTF : process(cpu.buss, ptrdevNUM, ptpdevNUM, flagREG, ieREG, dataREG)
137
    begin
138
 
139
        dev     <= nulldev;
140
        ieSET   <= '0';
141
        ieCLR   <= '0';
142
        flagCLR <= '0';
143
        start   <= '0';
144
 
145
        if cpu.buss.addr(0 to 2) = opIOT and cpu.buss.lxdar = '1' then
146
 
147
            --
148
            -- Reader IOTs
149
            --
150
 
151
            if cpu.buss.addr(3 to 8) = ptrdevNUM then
152
 
153
                case cpu.buss.addr(9 to 11) is
154
 
155
                    --
156
                    -- IOT 6xx0: RPE - Set Reader/Punch Interrupt Enable
157
                    --  Sets the Reader/Punch interrupt enable flip-flop
158
                    --  so that an interrupt request will be generated
159
                    --  when the reader or punch flag is set.
160
 
161
                    when opRPE =>
162
                        dev.ack  <= '1';
163
                        dev.devc <= devWR;
164
                        dev.skip <= '0';
165
                        ieSET    <= '1';
166
 
167
                    --
168
                    -- IOT 6xx1: RSF - Skip on Reader Flag
169
                    --  This senses the reader flag.  If the reader flag
170
                    --  is set, then the next instructon is skipped.
171
                    --
172
 
173
                    when opRSF =>
174
                        dev.ack  <= '1';
175
                        dev.devc <= devWR;
176
                        dev.skip <= flagREG;
177
 
178
                    --
179
                    --IOT 6xx2: RRB - Read Reader Buffer.
180
                    -- ORs the contents of the reader buffer into
181
                    -- AC(4 to 11) and clears the reader flag.
182
                    --
183
 
184
                    when opRRB =>
185
                        dev.ack  <= '1';
186
                        dev.devc <= devRD;
187
                        dev.skip <= '0';
188
                        flagCLR  <= '1';
189
 
190
                    --
191
                    -- IOT 6xx4: RFC - Reader Fetch Character.
192
                    --  Clears the reader flag.  Loads one character
193
                    --  into the RB from tape and sets the reader flag.
194
                    --
195
 
196
                    when opRFC =>
197
                        dev.ack  <= '1';
198
                        dev.devc <= devRD;
199
                        dev.skip <= '0';
200
                        flagCLR  <= '1';
201
                        start    <= '1';
202
 
203
                    --
204
                    -- IOT 6xx6: RRC - Read reader character and fetch next char
205
                    --  The content of the reader buffer is ORed into the AC.
206
                    --  The flag is immediately cleared, and a new character is
207
                    --  read from tape into the reader buffer.  The flags is
208
                    --  then set.
209
                    --  This is a microprogrammed combination of RRB (6012) and
210
                    --  RFC (6014).
211
                    --
212
 
213
                    when opRCC =>
214
                        dev.ack  <= '1';
215
                        dev.devc <= devRD;
216
                        dev.skip <= '0';
217
                        flagCLR  <= '1';
218
                        start    <= '1';
219
 
220
                    --
221
                    -- Everything else
222
                    --
223
 
224
                    when others =>
225
                        null;
226
 
227
                end case;
228
 
229
            --
230
            -- Punch IOTs
231
            --
232
 
233
            elsif cpu.buss.addr(3 to 8) = ptpdevNUM then
234
 
235
                --
236
                -- IOT 6xx0: PCE - Clear Reader/Punch Interrupt Enable
237
                --  Clears the read/punch interrupt enable flip-flop
238
                --  so that interrupts cannot be generated.
239
                --
240
 
241
                if cpu.buss.addr(9 to 11) = opPCE then
242
                    dev.ack  <= '1';
243
                    dev.devc <= devWR;
244
                    dev.skip <= '0';
245
                    ieCLR    <= '1';
246
                end if;
247
 
248
            end if;
249
        end if;
250
 
251
        dev.intr <= flagREG and ieREG;
252
        dev.data <= dataREG;
253
 
254
    end process PR8E_BUSINTF;
255
 
256
    --
257
    --! This process maintains the PR8E Registers
258
    --!
259
    --! -# The Reader Flag is cleared by initialize or CAF (IOCLR)
260
    --! -# The Interupt Enable is set by initialize or CAF (IOCLR)
261
    --
262
 
263
    REG_PR8E : process(sys)
264
    begin
265
        if sys.rst = '1' then
266
 
267
            ieREG   <= '1';
268
            flagREG <= '0';
269
            dataREG <= (others => '0');
270
 
271
        elsif rising_edge(sys.clk) then
272
 
273
            if cpu.buss.ioclr = '1' then
274
 
275
                ieREG   <= '1';
276
                flagREG <= '0';
277
                dataREG <= (others => '0');
278
 
279
            else
280
 
281
                --
282
                -- Update Interrupt Enable Register
283
                --
284
 
285
                if ieCLR = '1' then
286
                    ieREG <= '0';
287
                elsif ieSET = '1' then
288
                    ieREG <= '1';
289
                end if;
290
 
291
                --
292
                -- Update Flag Register
293
                --
294
 
295
                if flagCLR = '1' then
296
                    flagREG <= '0';
297
                elsif rxIntr = '1' then
298
                    flagREG <= '1';
299
                end if;
300
 
301
                --
302
                -- Update Data Register
303
                --
304
 
305
                if rxIntr = '1' then
306
                    dataREG <= "0000" & rxData;
307
                end if;
308
 
309
                --
310
                -- Send Command to get next character
311
                --
312
 
313
                if start = '1' and lastStart = '0' then
314
                    loadUART <= '1';
315
                end if;
316
                lastStart <= start;
317
 
318
            end if;
319
        end if;
320
    end process REG_PR8E;
321
 
322
    --
323
    --! UART Baud Rate Generator
324
    --
325
 
326
    iUART_BRG : entity work.eUART_BRG port map (
327
        sys    => sys,
328
        uartBR => uartBR,
329
        clkBR  => clkBR
330
    );
331
 
332
    --
333
    --! The UART Receiver is used for receiving the data from
334
    --! the PTR.
335
    --
336
 
337
    iUART_RX : entity work.eUART_RX port map (
338
        sys   => sys,
339
        clkBR => clkBR,
340
        rxd   => rxd,
341
        intr  => rxIntr,
342
        data  => rxData
343
    );
344
 
345
    --
346
    --! The UART Transmitter sends commands to the PTR.
347
    --!
348
    --! \note
349
    --! -# this UART is hardwired to send the "Single Step
350
    --!    Right" command to the PTR, and
351
    --! -# the "intr" response is ignored because the PTR
352
    --!    should respond with the charcter that was read
353
    --!    from the paper tape.  The UART_RX will catch that
354
    --!    event.
355
    --
356
 
357
    iUART_TX : entity work.eUART_TX port map (
358
        sys   => sys,
359
        clkBR => clkBR,
360
        data  => ascii_R,
361
        load  => loadUART,
362
        intr  => open,
363
        txd   => txd
364
    );
365
 
366
end rtl;

powered by: WebSVN 2.1.0

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