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

Subversion Repositories pdp8

[/] [pdp8/] [trunk/] [nexys2/] [nexys2_io.vhd] - Blame information for rev 3

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

Line No. Rev Author Line
1 2 trurl
 --------------------------------------------------------------------
2
--!
3
--! PDP-8 Processor
4
--!
5
--! \brief
6
--!      NEXYS2 Wrapper: Switch/LED IO 
7
--!
8
--! \details
9
--!      There is way too much Front Panel IO on this device for each
10
--!      bit of IO to have its own pin.  This package virtualizes the
11
--!      Front Panel IO in order to reduce the number of IO pins.
12
--!
13
--!      In this implementation, all of the Front Panel IO is
14
--!      multiplexed onto a 24-bit, bidirectional IO bus.  This
15
--!      yields to 48 bits of input and 48 bits of output.
16
--!
17
--!      A state machine controls the operation of the IO bus.
18
--!
19
--!      The reset signal to the CPU is carefully managed such that
20
--!      complete cycle of the state machine is executed before the
21
--!      reset signal to the CPU is negated.
22
--!
23
--! \file
24
--!      nexys2_io.vhd
25
--!
26
--! \author
27
--!      Rob Doyle - doyle (at) cox (dot) net
28
--------------------------------------------------------------------
29
--
30
--  Copyright (C) 2011, 2012 Rob Doyle
31
--
32
-- This source file may be used and distributed without
33
-- restriction provided that this copyright statement is not
34
-- removed from the file and that any derivative work contains
35
-- the original copyright notice and the associated disclaimer.
36
--
37
-- This source file is free software; you can redistribute it
38
-- and/or modify it under the terms of the GNU Lesser General
39
-- Public License as published by the Free Software Foundation;
40
-- version 2.1 of the License.
41
--
42
-- This source is distributed in the hope that it will be
43
-- useful, but WITHOUT ANY WARRANTY; without even the implied
44
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
45
-- PURPOSE. See the GNU Lesser General Public License for more
46
-- details.
47
--
48
-- You should have received a copy of the GNU Lesser General
49
-- Public License along with this source; if not, download it
50
-- from http://www.gnu.org/licenses/lgpl.txt
51
--
52
--------------------------------------------------------------------
53
--
54
-- Comments are formatted for doxygen
55
--
56
 
57
library ieee;                                   --! IEEE Library
58
use ieee.std_logic_1164.all;                    --! IEEE 1164
59
use ieee.numeric_std.all;                       --! IEEE Std Logic Unsigned
60
use work.uart_types.all;                        --! UART types
61
use work.dk8e_types.all;                        --! DK8E types
62
use work.kc8e_types.all;                        --! KC8E types
63
use work.kl8e_types.all;                        --! KL8E types
64
use work.cpu_types.all;                         --! CPU types
65
use work.nexys2_types.all;                      --! Nexys2 Board types
66
 
67
--
68
--! NEXYS2 Switch/LED IO Entity
69
--
70
 
71
entity eNEXYS2_IO is port (
72
    clk     : in    std_logic;                  --! Clock
73
    rstIN   : in    std_logic;                  --! Reset Input
74
    ttyBR   : out   uartBR_t;                   --! Baud Rate Configuration
75
    swCPU   : out   swCPU_t;                    --! CPU Configuration
76
    swOPT   : out   swOPT_t;                    --! Configuration Options
77
    swROT   : out   swROT_t;                    --! Rotary Switch
78
    swRTC   : out   swRTC_t;                    --! RTC Configuration
79
    swDATA  : out   swDATA_t;                   --! Data Switches
80
    swCNTL  : out   swCNTL_t;                   --! Control Switches
81
    ledRUN  : in    std_logic;                  --! Run LED
82
    ledADDR : in    xaddr_t;                    --! Address LEDS
83
    ledDATA : in    data_t;                     --! Data LEDS
84
    ioDATA  : inout iodata_t;                   --! IO Data
85
    inOEA_L : out   std_logic;                  --! Input Data A Output Enable 
86
    inOEB_L : out   std_logic;                  --! Input Data B Output Enable
87
    outLEA  : out   std_logic;                  --! Output Data A Latch Enable
88
    outLEB  : out   std_logic;                  --! Output Data B Latch Enable
89
    rst     : out   std_logic                   --! Reset Output
90
);
91
end eNEXYS2_IO;
92
 
93
--
94
--! NEXYS2 Switch/LED IO Entity RTL
95
--
96
 
97
architecture rtl of eNEXYS2_IO is
98
    type   state_t is (stateRESET,              --! State Machine Type
99
                       stateRESET1,
100
                       stateREADAsetup,
101
                       stateREADA,
102
                       stateREADAhold,
103
                       stateWRITEAsetup,
104
                       stateWRITEA,
105
                       stateWRITEAhold,
106
                       stateREADBsetup,
107
                       stateREADB,
108
                       stateREADBhold,
109
                       stateWRITEBsetup,
110
                       stateWRITEB,
111
                       stateWRITEBhold);
112
 
113
    signal clken  : std_logic;                  --! Clock enable
114
    signal state  : state_t;                    --! State Machine state
115
    signal inA    : iodata_t;                   --! A Input
116
    signal inB    : iodata_t;                   --! B Input
117
    signal outA   : iodata_t;                   --! A Output
118
    signal outB   : iodata_t;                   --! B Output
119
    signal rstb   : std_logic;                  --! Reset Signal
120
    signal swDEP  : std_logic;                  --! Undebounced Deposit
121
    signal swSTEP : std_logic;                  --! Undebounced Step
122
    signal swHALT : std_logic;                  --! Undebounced Halt
123
    signal swEXAM : std_logic;                  --! Undebounced Examine
124
    signal swCONT : std_logic;                  --! Undebounced Continue
125
 
126
begin
127
 
128
    --
129
    --! Clock Divider
130
    --
131
 
132
    CLKDIV : process(clk, rstIN)
133
        variable count : integer range 0 to 49;
134
    begin
135
        if rstIN = '1' then
136
            clken <= '0';
137
            count := 0;
138
        elsif rising_edge(clk) then
139
            if count = 49 then
140
                clken <= '1';
141
                count := 0;
142
            else
143
                clken <= '0';
144
                count := count + 1;
145
            end if;
146
        end if;
147
    end process CLKDIV;
148
 
149
    --
150
    --! This State Machine operates as follows:
151
    --!  -# the "A Input" onto the IO Bus, then
152
    --!  -# the "A Output" onto the IO Bus, then
153
    --!  -# the "B Input" onto the IO Bus, then 
154
    --!  -# the "B Output" onto the IO Bus.
155
    --
156
 
157
    IO_MACHINE : process(clk, rstIN)
158
 
159
    begin
160
 
161
        if rstIN = '1' then
162
            inA   <= (others => '0');
163
            inB   <= (others => '0');
164
            rstb  <= '1';
165
            state <= stateRESET;
166
 
167
        elsif rising_edge(clk) then
168
 
169
            if clken = '1' then
170
 
171
                case state is
172
 
173
                    --
174
                    -- The rst signal is unsynchronized.  Add a few states after
175
                    -- rst negation to get synchronized.
176
                    --
177
 
178
                    when stateRESET =>
179
                        state <= stateRESET1;
180
 
181
                    --
182
                    -- The rst signal is unsynchronized.  Add a few states after
183
                    -- rst negation to get synchronized.
184
                    --
185
 
186
                    when stateRESET1 =>
187
                        state <= stateREADAsetup;
188
 
189
                    --
190
                    -- Setup A input data
191
                    --
192
 
193
                    when stateREADAsetup =>
194
                        state <= stateREADA;
195
 
196
                    --
197
                    -- Read the A input data
198
                    --
199
 
200
                    when stateREADA =>
201
                        inA   <= not(ioDATA);
202
                        state <= stateREADAhold;
203
 
204
                    --
205
                    -- Hold A input data
206
                    --
207
 
208
                    when stateREADAhold =>
209
                        state <= stateWRITEAsetup;
210
 
211
                    --
212
                    -- Setup A output data
213
                    --
214
 
215
                    when stateWRITEAsetup =>
216
                        state <= stateWRITEA;
217
 
218
                    --
219
                    -- Write A output data
220
                    --
221
 
222
                    when stateWRITEA =>
223
                       state <= stateWRITEAhold;
224
 
225
                    --
226
                    -- Hold A output data
227
                    --
228
 
229
                    when stateWRITEAhold =>
230
                        state <= stateREADBsetup;
231
 
232
                    --
233
                    -- Setup B input data
234
                    --
235
 
236
                    when stateREADBsetup =>
237
                        state <= stateREADB;
238
 
239
                    --
240
                    -- Read B input data
241
                    --
242
 
243
                    when stateREADB =>
244
                        inB   <= not(ioDATA);
245
                        state <= stateREADBhold;
246
 
247
                    --
248
                    -- Hold B input data
249
                    --
250
 
251
                    when stateREADBhold =>
252
                        state <= stateWRITEBsetup;
253
 
254
                    --
255
                    -- Setup B output data
256
                    --
257
 
258
                    when stateWRITEBsetup =>
259
                        state <= stateWRITEB;
260
 
261
                    --
262
                    -- Write B output data
263
                    --
264
 
265
                    when stateWRITEB =>
266
                        state <= stateWRITEBhold;
267
 
268
                    --
269
                    -- Hold B output data
270
                    -- Take the CPU out of reset
271
                    --
272
 
273
                    when stateWRITEBhold =>
274
                        rstb  <= '0';
275
                        state <= stateREADAsetup;
276
 
277
                    --
278
                    -- Everything else
279
                    --
280
 
281
                    when others =>
282
                        state <= stateRESET;
283
 
284
                end case;
285
            end if;
286
        end if;
287
 
288
    end process IO_MACHINE;
289
 
290
    --
291
    -- Input Assignments - "A" Inputs
292
    --
293
 
294
    ttyBR(0)        <= inA( 0);
295
    ttyBR(1)        <= inA( 1);
296
    ttyBR(2)        <= inA( 2);
297
    ttyBR(3)        <= inA( 3);
298
    swCPU(0)        <= inA( 4);
299
    swCPU(1)        <= inA( 5);
300
    swCPU(2)        <= inA( 6);
301
    swCPU(3)        <= inA( 7);
302
    swOPT.KE8       <= inA( 8);
303
    swOPT.KM8E      <= inA( 9);
304
    swOPT.TSD       <= inA(10);
305
    swOPT.SP0       <= inA(11);
306
    swOPT.SP1       <= inA(12);
307
    swOPT.SP2       <= inA(13);
308
    swOPT.SP3       <= inA(14);
309
    swOPT.STARTUP   <= inA(15);
310
    swRTC(0)        <= inA(16);
311
    swRTC(1)        <= inA(17);
312
    swRTC(2)        <= inA(18);
313
    swCNTL.lock     <= inA(23);
314
 
315
    --
316
    -- Input Assignments - "B" Inputs
317
    --
318
 
319
    swROT(2)        <= inB( 0);
320
    swROT(1)        <= inB( 1);
321
    swROT(0)        <= inB( 2);
322
    swDEP           <= inB( 3);
323
    swSTEP          <= inB( 4);
324
    swHALT          <= inB( 5);
325
    swEXAM          <= inB( 6);
326
    swCONT          <= inB( 7);
327
    swCNTL.clear    <= not(inB( 8));
328
    swDATA(11)      <= inB( 9);
329
    swDATA(10)      <= inB(10);
330
    swDATA( 9)      <= inB(11);
331
    swDATA( 8)      <= inB(12);
332
    swDATA( 7)      <= inB(13);
333
    swDATA( 6)      <= inB(14);
334
    swDATA( 5)      <= inB(15);
335
    swDATA( 4)      <= inB(16);
336
    swDATA( 3)      <= inB(17);
337
    swDATA( 2)      <= inB(18);
338
    swDATA( 1)      <= inB(19);
339
    swDATA( 0)      <= inB(20);
340
    swCNTL.loadEXTD <= not(inB(21));
341
    swCNTL.loadADDR <= not(inB(22));
342
    swCNTL.boot     <= not(inB(23));
343
 
344
    --
345
    -- Output assignments
346
    --
347
 
348
    outA            <= not(ledDATA(11) & ledDATA(10) & ledDATA( 9) & ledDATA( 8) &
349
                           ledDATA( 7) & ledDATA( 6) & ledDATA( 5) & ledDATA( 4) &
350
                           ledDATA( 3) & ledDATA( 2) & ledDATA( 1) & ledDATA( 0) &
351
                           "000000000000");
352
 
353
    outB            <= not(ledRUN      & ledADDR(14) & ledADDR(13) & ledADDR(12) &
354
                           ledADDR(11) & ledADDR(10) & ledADDR( 9) & ledADDR( 8) &
355
                           ledADDR( 7) & ledADDR( 6) & ledADDR( 5) & ledADDR( 4) &
356
                           ledADDR( 3) & ledADDR( 2) & ledADDR( 1) & ledADDR( 0) &
357
                           "00000000");
358
 
359
    --
360
    -- Front Panel Switch Debounce
361
    --
362
 
363
    iDEBDEP : entity work.eNEXYS2_DEBOUNCE port map (
364
         clk   => clk,
365
         rst   => rstb,
366
         clken => clken,
367
         di    => swDEP,
368
         do    => swCNTL.dep
369
    );
370
 
371
    iDEBSTEP : entity work.eNEXYS2_DEBOUNCE port map (
372
         clk   => clk,
373
         rst   => rstb,
374
         clken => clken,
375
         di    => swSTEP,
376
         do    => swCNTL.step
377
    );
378
 
379
    iDEBHALT : entity work.eNEXYS2_DEBOUNCE port map (
380
         clk   => clk,
381
         rst   => rstb,
382
         clken => clken,
383
         di    => swHALT,
384
         do    => swCNTL.halt
385
    );
386
 
387
    iDEBEXAM : entity work.eNEXYS2_DEBOUNCE port map (
388
         clk   => clk,
389
         rst   => rstb,
390
         clken => clken,
391
         di    => swEXAM,
392
         do    => swCNTL.exam
393
    );
394
 
395
    iDEBCONT : entity work.eNEXYS2_DEBOUNCE port map (
396
         clk   => clk,
397
         rst   => rstb,
398
         clken => clken,
399
         di    => swCONT,
400
         do    => swCNTL.cont
401
    );
402
 
403
    --
404
    -- Combinational logic
405
    --
406
 
407
    rst             <= rstb;
408
 
409
    inOEA_L         <= '0' when ((state = stateREADAsetup) or
410
                                 (state = stateREADA)      or
411
                                 (state = stateREADAhold)) else
412
                       '1';
413
 
414
    inOEB_L         <= '0' when ((state = stateREADBsetup) or
415
                                 (state = stateREADB)      or
416
                                 (state = stateREADBhold)) else
417
                       '1';
418
 
419
    outLEA          <= '1' when (state = stateWRITEA) else
420
                       '0';
421
 
422
    outLEB          <= '1' when (state = stateWRITEB) else
423
                       '0';
424
 
425
    ioDATA          <= outA when ((state = stateWRITEAsetup) or
426
                                  (state = stateWRITEA)      or
427
                                  (state = stateWRITEAhold)) else
428
                       outB when ((state = stateWRITEBsetup) or
429
                                  (state = stateWRITEB)      or
430
                                  (state = stateWRITEBhold)) else
431
                       (others => 'Z');
432
 
433
end rtl;

powered by: WebSVN 2.1.0

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