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

Subversion Repositories pdp8

[/] [pdp8/] [trunk/] [pdp8/] [dk8e.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
--!      DK8E Real Time Clock
7
--!
8
--! \details
9
--!      This device emulates a K8EA/DK8EC/DK8EP Real Time Clock
10
--!      (RTC).  The RTC configuration is controlled by the 'swRTC'
11
--!      input which is typically routed to a DIP switch.
12
--!
13
--!      The following interrupt rates can be acheived:
14
--!      -#   000 : 1 Hz (DK8EC)
15
--!      -#   001 : 50 Hz (DK8EC)
16
--!      -#   010 : 100 Hz (DK8-EA with 50 Hz Primary Power)
17
--!      -#   011 : 120 Hz (DK8-EA with 60 Hz Primary Power)
18
--!      -#   100 : 500 Hz (DK8-EC)
19
--!      -#   101 : 5 KHz (DK8-EC)
20
--!      -#   110 : Variable (DK8-EP)
21
--!      -#   111 : Variable (DK8-ES)
22
--!
23
--! \todo
24
--!      This file is mostly a stub.  The DK8E needs to be
25
--!      implemented.
26
--!
27
--! \file
28
--!      dk8e.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.dk8e_types.all;                        --! DK8E Types
65
use work.cpu_types.all;                         --! CPU Types
66
 
67
--
68
--! DK8E Real Time Clock Entity
69
--
70
 
71
entity eDK8E is port (
72
    sys       : in  sys_t;                      --! Clock/Reset
73
    swRTC     : in  swRTC_t;                    --! Baud Rate Select
74
    devNUM    : in  devNUM_t;                   --! IOT Device
75
    cpu       : in  cpu_t;                      --! CPU Input
76
    dev       : out dev_t;                      --! Device Output
77
    schmittIN : in  schmitt_t;                  --! Schmitt Trigger Inputs
78
    clkTRIG   : out std_logic                   --! Trigger Output
79
);
80
end eDK8E;
81
 
82
--
83
--! DK8E Real Time Clock RTL
84
--
85
 
86
architecture rtl of eDK8E is
87
 
88
    type   clkOP_t    is (clkopNOP,
89
                          clkopCLZE,
90
                          clkopCLDE,
91
                          clkopCLAB);
92
 
93
    signal clkOP      : clkOP_t;                --! Decoded Clock IOT Operation
94
 
95
    signal clkIeMUX   : std_logic;              --! Clock Interrupt Enable MUX
96
    signal clkIeREG   : std_logic;              --! Clock Interrupt Enable REG
97
 
98
    signal clkIrMUX   : std_logic;              --! Clock Interrupt Request MUX
99
    signal clkIrREG   : std_logic;              --! Clock Interrupt Request REG
100
 
101
 
102
    signal clkEnREG   : data_t;                 --! Clock Enable Register
103
    signal clkEnMUX   : data_t;                 --! Clock Enable Multiplexor
104
    signal clkCntREG  : data_t;                 --! Clock Count Register
105
    signal clkBufREG  : data_t;                 --! Clock Buffer Register
106
    signal clkStatREG : data_t;                 --! Clock Status Register
107
 
108
    alias  clkEnCE    : std_logic                is clkEnREG(0);        --! Clock Enable
109
    alias  clkEnME    : std_logic_vector(0 to 1) is clkEnREG(1 to 2);   --! Mode Enable
110
    alias  clkEnRE    : std_logic_vector(0 to 2) is clkEnReg(3 to 5);   --! Rate Enable
111
 
112
    signal count      : integer range 0 to 49999999;
113
 
114
begin
115
 
116
    --
117
    --! Bus Decoder
118
    --
119
 
120
    DK8E_BUSINTF : process(cpu.buss, devNUM, swRTC, clkEnREG, clkIeREG,
121
                           clkIrREG, clkStatREG, clkBufREG, clkCntREG)
122
    begin
123
 
124
        dev      <= nulldev;
125
        clkOP    <= clkopNOP;
126
        clkEnMUX <= clkEnREG;
127
        clkIeMUX <= clkIeREG;
128
        clkIrMUX <= clkIrREG;
129
 
130
        if cpu.buss.addr(0 to 2) = opIOT and cpu.buss.addr(3 to 8) = devNUM and cpu.buss.lxdar = '1' then
131
 
132
            case cpu.buss.addr(9 to 11) is
133
 
134
                --
135
                -- IOT 6xx0: DK8-EA - NOP
136
                --           DK8-EC - NOP
137
                --           DK8-EP - CLZE: Clear Clock Enable Register Per AC
138
                --
139
 
140
                when opCLZE =>
141
                    if swRTC = clkDK8EP then
142
                        dev.ack  <= '1';
143
                        dev.devc <= devWR;
144
                        dev.skip <= '0';
145
                        clkOP    <= clkopCLZE;
146
                        clkEnMUX <= clkEnREG and not cpu.buss.data;
147
                    end if;
148
 
149
                --
150
                -- IOT 6xx1: DK8-EA - CLEI: Enable Interrupts
151
                --           DK8-EC - CLEI: Enable Interrupts
152
                --           DK8-EP - CLSK: Skip on Clock Interrupt
153
 
154
                when opCLSK =>
155
                    if ((swRTC = clkDK8EA1) or
156
                        (swRTC = clkDK8EA2) or
157
                        (swRTC = clkDK8EC1) or
158
                        (swRTC = clkDK8EC2) or
159
                        (swRTC = clkDK8EC3) or
160
                        (swRTC = clkDK8EC4)) then
161
                        dev.ack  <= '1';
162
                        dev.devc <= devWR;
163
                        dev.skip <= '0';
164
                        clkIeMUX <= '1';
165
                    elsif swRTC = clkDK8EP then
166
                        dev.ack  <= '1';
167
                        dev.devc <= devWR;
168
                        dev.skip <= '1';  -- FIXME
169
                    end if;
170
 
171
                --
172
                -- IOT 6xx2: DK8-EA - CLDI: Disable Interrupts
173
                --           DK8-EC - CLDI: Disable Interrupts
174
                --           DK8-EP - CLDE: Set Clock Enable Register Per AC
175
                --
176
 
177
                when opCLDE =>
178
                    if ((swRTC = clkDK8EA1) or
179
                        (swRTC = clkDK8EA2) or
180
                        (swRTC = clkDK8EC1) or
181
                        (swRTC = clkDK8EC2) or
182
                        (swRTC = clkDK8EC3) or
183
                        (swRTC = clkDK8EC4)) then
184
                        dev.ack  <= '1';
185
                        dev.devc <= devWR;
186
                        dev.skip <= '0';
187
                        clkIeMUX <= '0';
188
                    elsif swRTC = clkDK8EP then
189
                        dev.ack  <= '1';
190
                        dev.devc <= devWR;
191
                        dev.skip <= '0';
192
                        clkOP    <= clkopCLDE;
193
                        clkEnMUX <= clkEnREG or cpu.buss.data;
194
                    end if;
195
 
196
                --
197
                -- IOT 6xx3: DK8-EA - CLSK: Skip on Clock Flag and Clear Flag
198
                --           DK8-EC - CLSK: Skip on Clock Flag and Clear Flag
199
                --           DK8-EP - CLAB: AC Register to Clock Buffer Register
200
                --
201
 
202
                when opCLAB =>
203
                    if ((swRTC = clkDK8EA1) or
204
                        (swRTC = clkDK8EA2) or
205
                        (swRTC = clkDK8EC1) or
206
                        (swRTC = clkDK8EC2) or
207
                        (swRTC = clkDK8EC3) or
208
                        (swRTC = clkDK8EC4)) then
209
                        dev.ack  <= '1';
210
                        dev.devc <= devWR;
211
                        dev.skip <= clkIrREG and clkIeREG;
212
                        clkIrMUX <= '0';
213
                    elsif swRTC = clkDK8EP then
214
                        dev.ack  <= '1';
215
                        dev.devc <= devRD;
216
                        dev.skip <= '0';
217
                        clkOP    <= clkopCLAB;
218
                    end if;
219
 
220
                --
221
                -- IOT 6xx4: DK8-EA - NOP
222
                --           DK8-EC - NOP
223
                --           DK8-EP - CLEN: Clock Enable Register to AC
224
                --
225
 
226
                when opCLEN =>
227
                     if swRTC = clkDK8EP then
228
                         dev.ack  <= '1';
229
                         dev.devc <= devRD;
230
                         dev.skip <= '0';
231
                         dev.data <= clkEnREG;
232
                    end if;
233
 
234
                --
235
                -- IOT 6xx5: DK8-EA - NOP
236
                --           DK8-EC - NOP
237
                --           DK8-EP - CLSA: Status Register to AC
238
                --
239
 
240
                when opCLSA =>
241
                    if swRTC = clkDK8EP then
242
                        dev.ack  <= '1';
243
                        dev.devc <= devRDCLR;
244
                        dev.skip <= '0';
245
                        dev.data <= clkStatREG;
246
                        clkOP    <= clkopNOP;
247
                    end if;
248
 
249
                --
250
                -- IOT 6xx6: DK8-EA - NOP
251
                --           DK8-EC - NOP
252
                --           DK8-EP - CLBA: Clock Buffer Register to AC
253
                --
254
 
255
                when opCLBA =>
256
                    if swRTC = clkDK8EP then
257
                        dev.ack  <= '1';
258
                        dev.devc <= devRDCLR;
259
                        dev.skip <= '0';
260
                        dev.data <= clkBufREG;
261
                        clkOP    <= clkopNOP;
262
                    end if;
263
 
264
                --
265
                -- IOT 6xx7: DK8-EA - NOP
266
                --           DK8-EC - NOP
267
                --           DK8-EP - CLCA: Clock Count Register to AC
268
                --
269
 
270
                when opCLCA =>
271
                    if swRTC = clkDK8EP then
272
                        dev.ack  <= '1';
273
                        dev.devc <= devRDCLR;
274
                        dev.skip <= '0';
275
                        dev.data <= clkCntREG;
276
                        clkOP    <= clkopNOP;
277
                    end if;
278
 
279
                --
280
                -- Anything Else?
281
                --
282
 
283
                when others =>
284
                    null;
285
 
286
            end case;
287
        end if;
288
 
289
        dev.intr <= clkIrREG and clkIeREG;
290
 
291
    end process DK8E_BUSINTF;
292
 
293
    --
294
    --! DK8E Registers
295
    --! \todo
296
    --!    This is really broken and generates some nasty warnings.
297
    --!
298
 
299
    DK8E_REGS : process(sys)
300
 
301
    begin
302
        if sys.rst = '1' then
303
 
304
             clkEnREG   <= (others => '0');
305
             clkCntREG  <= (others => '0');
306
             clkBufREG  <= (others => '0');
307
             clkStatREG <= (others => '0');
308
 
309
        elsif rising_edge(sys.clk) then
310
 
311
            if cpu.buss.ioclr = '1' then
312
 
313
                clkEnREG   <= (others => '0');
314
                clkCntREG  <= (others => '0');
315
                clkBufREG  <= (others => '0');
316
                clkStatREG <= (others => '0');
317
 
318
            else
319
 
320
                case clkOP is
321
                    when clkopNOP =>
322
                    when clkopCLZE =>
323
                    when clkopCLDE =>
324
                    when clkopCLAB =>
325
                    when others =>
326
                        null;
327
                end case;
328
 
329
            end if;
330
        end if;
331
    end process DK8E_REGS;
332
 
333
    --
334
    --! DK8-EA/DK8-EC Interrupt Flag
335
    --
336
 
337
    DK8E_INTR : process(sys)
338
    begin
339
        if sys.rst = '1' then
340
            clkIeREG <= '0';
341
        elsif rising_edge(sys.clk) then
342
            if cpu.buss.ioclr = '1' then
343
                clkIeREG <= '0';
344
            else
345
               clkIeREG <= clkIeMUX;
346
            end if;
347
        end if;
348
    end process DK8E_INTR;
349
 
350
    --
351
    --! DK8-EA/DK8-EC Down Counter
352
    --
353
 
354
    DK8E_COUNTER : process(sys)
355
    begin
356
        if sys.rst = '1' then
357
            count    <= 0;
358
            clkIrREG <= '0';
359
        elsif rising_edge(sys.clk) then
360
            if cpu.buss.ioclr = '1' then
361
                count    <= 0;
362
                clkIrREG <= '0';
363
            elsif ((swRTC = clkDK8EA1 and count =   500000) or  -- 100 Hz
364
                   (swRTC = clkDK8EA2 and count =   416667) or  -- 120 Hz
365
                   (swRTC = clkDK8EC1 and count = 50000000) or  -- 1 Hz
366
                   (swRTC = clkDK8EC2 and count =  1000000) or  -- 50 Hz
367
                   (swRTC = clkDK8EC3 and count =   100000) or  -- 500 Hz
368
                   (swRTC = clkDK8EC4 and count =    10000)) then  -- 5KHz
369
                count    <= 0;
370
                clkIrREG <= '1';
371
            else
372
                count <= count + 1;
373
                clkIrREG <= clkIrMUX;
374
            end if;
375
        end if;
376
    end process DK8E_COUNTER;
377
 
378
end rtl;

powered by: WebSVN 2.1.0

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