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

Subversion Repositories pdp8

[/] [pdp8/] [trunk/] [pdp8/] [busmux.vhd] - Blame information for rev 6

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
--!      PDP8 Bus Multiplexer
7
--!
8
--! \details
9
--!      This package contains the multiplexer that simulates a
10
--!      bi-directional bus.
11
--!
12
--!      External IOTs are different that other bus cycles.  If
13
--!      an external IOT is not implemented, it behaves like a
14
--!      no-op.  In order to keep the system from 'hanging' on
15
--!      a unimplemented IOT, this device start an ACK  Timer
16
--!      when an external IOT is detected.  If no external device
17
--!      acknowledges the IOT cycle, the ACK Timer will handle it
18
--!      when it times out.  The ACK Timer should be set for
19
--!      longer than the most amount of wait-states for a normal
20
--!      bus cycle.
21
--!
22
--! \todo
23
--!      DMA Request and DMA Grant logic is incorrect.  This code
24
--!      assumes the only DMA source is the disk.   The DMA should
25
--!      be aribrated like everything else.
26
--!
27
--! \file
28
--!      busmux.vhd
29
--!
30
--! \author
31
--!      Rob Doyle - doyle (at) cox (dot) net
32
--!
33
--------------------------------------------------------------------
34
--
35
--  Copyright (C) 2009, 2010, 2011, 2012 Rob Doyle
36
--
37
-- This source file may be used and distributed without
38
-- restriction provided that this copyright statement is not
39
-- removed from the file and that any derivative work contains
40
-- the original copyright notice and the associated disclaimer.
41
--
42
-- This source file is free software; you can redistribute it
43
-- and/or modify it under the terms of the GNU Lesser General
44
-- Public License as published by the Free Software Foundation;
45
-- version 2.1 of the License.
46
--
47
-- This source is distributed in the hope that it will be
48
-- useful, but WITHOUT ANY WARRANTY; without even the implied
49
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
50
-- PURPOSE. See the GNU Lesser General Public License for more
51
-- details.
52
--
53
-- You should have received a copy of the GNU Lesser General
54
-- Public License along with this source; if not, download it
55
-- from http://www.gnu.org/licenses/lgpl.txt
56
--
57
--------------------------------------------------------------------
58
--
59
-- Comments are formatted for doxygen
60
--
61
 
62
library ieee;                                   --! IEEE Library
63
use ieee.std_logic_1164.all;                    --! IEEE 1164
64
use work.cpu_types.all;                         --! CPU Types
65
 
66
--
67
--! PDP8 Bus Multiplexer Entity
68
--
69
 
70
entity eBUSMUX is port (
71
    sys      : in  sys_t;                       --! Clock / Reset
72
    cpu      : in  cpu_t;                       --! CPU Registers
73
    ramDEV   : in  dev_t;                       --! RAM Device
74
    diskDEV  : in  dev_t;                       --! DISK Disk Device
75
    tty1DEV  : in  dev_t;                       --! TTY1 Device
76
    tty2DEV  : in  dev_t;                       --! TTY2 Device
77
    lprDEV   : in  dev_t;                       --! LPR Device
78
    ptrDEV   : in  dev_t;                       --! PTR Device
79
    rtcDEV   : in  dev_t;                       --! Real Time Clock
80
    xramDEV  : in  dev_t;                       --! External RAM Device
81
    romDEV   : in  dev_t;                       --! ROM Device
82
    panelDEV : in  dev_t;                       --! Front Panel Device
83
    postDEV  : in  dev_t;                       --! POST Device
84
    mmapDEV  : in  dev_t;                       --! Memory Map Device
85
    cpuDEV   : out dev_t                        --! CPU Device
86
);
87
end eBUSMUX;
88
 
89
--
90
--!  PDP8 Bus Multiplexer RTL
91
--
92
 
93
architecture rtl of eBUSMUX is
94
 
95
    type   ackSTATE_t is (idle, run, done);
96
    signal ackSTATE   : ackSTATE_t;
97
    signal ackSTART   : std_logic;
98
    signal ackIOT     : std_logic;
99
    signal ackTIMER   : integer range 0 to 10;
100
    signal ackDEV     : std_logic;
101
    signal muxDEV     : dev_t;
102
 
103
begin
104
 
105
    --
106
    --! ACK Timer:
107
    --! This process will eventually generate a Bus Ack for an
108
    --! unimplemented internal IOT.
109
    --
110
 
111
    ACK_TIMER : process(sys)
112
    begin
113
        if sys.rst = '1' then
114
            ackTIMER <= 0;
115
            ackSTATE <= idle;
116
        elsif rising_edge(sys.clk) then
117
            case ackSTATE is
118
                when idle =>
119
                    if ackSTART = '1' then
120
                        ackTIMER <= ackTIMER + 1;
121
                        ackSTATE <= run;
122
                    else
123
                        ackTIMER <= 0;
124
                    end if;
125
                when run =>
126
                    if ackDEV = '1' then
127
                        ackState <= idle;
128
                    else
129
                        if ackTIMER = 10 then
130
                            ackTIMER <= 0;
131
                            ackSTATE <= done;
132
                        else
133
                            ackTIMER <= ackTIMER + 1;
134
                        end if;
135
                    end if;
136
                when done =>
137
                    ackSTATE <= idle;
138
                when others =>
139
                    null;
140
            end case;
141
        end if;
142
    end process ACK_TIMER;
143
 
144
    --
145
    -- ackIOT during last state of state machine
146
    --
147
 
148
    ackIOT       <= '1' when ackSTATE = done else
149
                    '0';
150
 
151
    --
152
    -- This is the bus multiplexer.  It simulates a bi-directional bus.
153
    --
154
 
155
    muxDEV       <= ramDEV   when ramDEV.ack   = '1' else
156
                    diskDEV  when diskDEV.ack  = '1' else
157
                    tty1DEV  when tty1DEV.ack  = '1' else
158
                    tty2DEV  when tty2DEV.ack  = '1' else
159
                    lprDEV   when lprDEV.ack   = '1' else
160
                    ptrDEV   when ptrDEV.ack   = '1' else
161
                    rtcDEV   when rtcDEV.ack   = '1' else
162
                    xramDEV  when xramDEV.ack  = '1' else
163
                    romDEV   when romDEV.ack   = '1' else
164
                    panelDEV when panelDEV.ack = '1' else
165
                    postDEV  when postDEV.ack  = '1' else
166
                    mmapDEV  when mmapDEV.ack  = '1' else
167
                    nullDEV;
168
 
169
    --
170
    --! Detect External IOTs for ACK timer.
171
    --
172
 
173
    ackSTART     <= '1' when ((cpu.buss.lxdar = '1' and cpu.buss.wr = '1' and muxDEV.ack = '0') or
174
                              (cpu.buss.lxdar = '1' and cpu.buss.rd = '1' and muxDEV.ack = '0')) else
175
                    '0';
176
 
177
    --
178
    -- ACK is combinational.  This is the fastest way to
179
    -- generate an ACK signal.
180
    --
181
 
182
    ackDEV       <= ramDEV.ack  or diskDEV.ack or tty1DEV.ack or tty2DEV.ack or lprDEV.ack   or
183
                    ptrDEV.ack  or rtcDEV.ack  or xramDEV.ack or romDEV.ack  or panelDEV.ack or
184
                    postDEV.ack or mmapDEV.ack;
185
 
186
    --
187
    -- Muxed signals.
188
    --
189
 
190
    cpuDEV.ack   <= ackDEV or ackIOT;
191
    cpuDEV.devc  <= muxDEV.devc;
192
    cpuDEV.skip  <= muxDEV.skip;
193
 
194
    --
195
    -- INTR  comes from most IO Devices
196
    -- CPREQ comes from Panel only
197
    --
198
 
199
    cpuDEV.intr  <= diskDEV.intr or tty1DEV.intr or tty2DEV.intr or lprDEV.intr or ptrDEV.intr or rtcDEV.intr;
200
    cpuDEV.cpreq <= panelDEV.intr;
201
 
202
    --
203
    -- FIXME: This isn't right.  It should arbirtrate, but right
204
    -- now disk is the only DMA.
205
    --
206
 
207
    cpuDEV.dma   <= diskDEV.dma;
208
    cpuDEV.data  <= diskDEV.data when cpu.buss.dmagnt = '1' and diskDEV.dma.wr = '1' else
209
                    muxDEV.data;
210
 
211
end rtl;

powered by: WebSVN 2.1.0

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