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

Subversion Repositories t65

[/] [t65/] [trunk/] [rtl/] [vhdl/] [T65.vhd] - Blame information for rev 12

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 7 jesus
--
2
-- 65xx compatible microprocessor core
3
--
4
-- Version : 0246
5
--
6
-- Copyright (c) 2002 Daniel Wallner (jesus@opencores.org)
7
--
8
-- All rights reserved
9
--
10
-- Redistribution and use in source and synthezised forms, with or without
11
-- modification, are permitted provided that the following conditions are met:
12
--
13
-- Redistributions of source code must retain the above copyright notice,
14
-- this list of conditions and the following disclaimer.
15
--
16
-- Redistributions in synthesized form must reproduce the above copyright
17
-- notice, this list of conditions and the following disclaimer in the
18
-- documentation and/or other materials provided with the distribution.
19
--
20
-- Neither the name of the author nor the names of other contributors may
21
-- be used to endorse or promote products derived from this software without
22
-- specific prior written permission.
23
--
24
-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
26
-- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27
-- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE
28
-- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
-- POSSIBILITY OF SUCH DAMAGE.
35
--
36
-- Please report bugs to the author, but before you do so, please
37
-- make sure that this is not a derivative work and that
38
-- you have the latest version of this file.
39
--
40
-- The latest version of this file can be found at:
41
--      http://www.opencores.org/cvsweb.shtml/t65/
42
--
43
-- Limitations :
44
--
45
-- 65C02 and 65C816 modes are incomplete
46
-- Undocumented instructions are not supported
47
-- Some interface signals behaves incorrect
48
--
49
-- File history :
50
--
51
--      0246 : First release
52
--
53
 
54
library IEEE;
55
use IEEE.std_logic_1164.all;
56
use IEEE.numeric_std.all;
57
use work.T65_Pack.all;
58
 
59
entity T65 is
60
        port(
61
                Mode    : in std_logic_vector(1 downto 0);       -- "00" => 6502, "01" => 65C02, "10" => 65C816
62
                Res_n   : in std_logic;
63
                Clk             : in std_logic;
64
                Rdy             : in std_logic;
65
                Abort_n : in std_logic;
66
                IRQ_n   : in std_logic;
67
                NMI_n   : in std_logic;
68
                SO_n    : in std_logic;
69
                R_W_n   : out std_logic;
70
                Sync    : out std_logic;
71
                EF              : out std_logic;
72
                MF              : out std_logic;
73
                XF              : out std_logic;
74
                ML_n    : out std_logic;
75
                VP_n    : out std_logic;
76
                VDA             : out std_logic;
77
                VPA             : out std_logic;
78
                A               : out std_logic_vector(23 downto 0);
79
                DI              : in std_logic_vector(7 downto 0);
80
                DO              : out std_logic_vector(7 downto 0)
81
        );
82
end T65;
83
 
84
architecture rtl of T65 is
85
 
86
        -- Registers
87
        signal ABC, X, Y, D             : std_logic_vector(15 downto 0);
88
        signal P, AD, DL                : std_logic_vector(7 downto 0);
89
        signal BAH                              : std_logic_vector(7 downto 0);
90
        signal BAL                              : std_logic_vector(8 downto 0);
91
        signal PBR                              : std_logic_vector(7 downto 0);
92
        signal DBR                              : std_logic_vector(7 downto 0);
93
        signal PC                               : unsigned(15 downto 0);
94
        signal S                                : unsigned(15 downto 0);
95
        signal EF_i                             : std_logic;
96
        signal MF_i                             : std_logic;
97
        signal XF_i                             : std_logic;
98
 
99
        signal IR                               : std_logic_vector(7 downto 0);
100
 
101
        signal MCycle                   : std_logic_vector(2 downto 0);
102
 
103
        signal Mode_r                   : std_logic_vector(1 downto 0);
104
        signal ALU_Op_r                 : std_logic_vector(3 downto 0);
105
        signal Write_Data_r             : std_logic_vector(2 downto 0);
106
        signal Set_Addr_To_r    : std_logic_vector(1 downto 0);
107
 
108
        signal PCAdder                  : unsigned(8 downto 0);
109
 
110
        signal RstCycle                 : std_logic;
111
        signal IRQCycle                 : std_logic;
112
        signal NMICycle                 : std_logic;
113
 
114
        signal B_o                              : std_logic;
115
        signal SO_n_o                   : std_logic;
116
        signal IRQ_n_o                  : std_logic;
117
        signal NMI_n_o                  : std_logic;
118
        signal NMIAct                   : std_logic;
119
 
120
        signal Break                    : std_logic;
121
 
122
        -- ALU signals
123
        signal BusA                             : std_logic_vector(7 downto 0);
124
        signal BusA_r                   : std_logic_vector(7 downto 0);
125
        signal BusB                             : std_logic_vector(7 downto 0);
126
        signal ALU_Q                    : std_logic_vector(7 downto 0);
127
        signal P_Out                    : std_logic_vector(7 downto 0);
128
 
129
        -- Micro code outputs
130
        signal LCycle                   : std_logic_vector(2 downto 0);
131
        signal ALU_Op                   : std_logic_vector(3 downto 0);
132
        signal Set_BusA_To              : std_logic_vector(2 downto 0);
133
        signal Set_Addr_To              : std_logic_vector(1 downto 0);
134
        signal Write_Data               : std_logic_vector(2 downto 0);
135
        signal Jump                             : std_logic_vector(1 downto 0);
136
        signal BAAdd                    : std_logic_vector(1 downto 0);
137
        signal BreakAtNA                : std_logic;
138
        signal ADAdd                    : std_logic;
139
        signal PCAdd                    : std_logic;
140
        signal Inc_S                    : std_logic;
141
        signal Dec_S                    : std_logic;
142
        signal LDA                              : std_logic;
143
        signal LDP                              : std_logic;
144
        signal LDX                              : std_logic;
145
        signal LDY                              : std_logic;
146
        signal LDS                              : std_logic;
147
        signal LDDI                             : std_logic;
148
        signal LDALU                    : std_logic;
149
        signal LDAD                             : std_logic;
150
        signal LDBAL                    : std_logic;
151
        signal LDBAH                    : std_logic;
152
        signal SaveP                    : std_logic;
153
        signal Write                    : std_logic;
154
 
155
begin
156
 
157
        Sync <= '1' when MCycle = "000" else '0';
158
        EF <= EF_i;
159
        MF <= MF_i;
160
        XF <= XF_i;
161
        ML_n <= '0' when IR(7 downto 6) /= "10" and IR(2 downto 1) = "11" and MCycle(2 downto 1) /= "00" else '1';
162
        VP_n <= '0' when IRQCycle = '1' and (MCycle = "101" or MCycle = "110") else '1';
163
        VDA     <= '1' when Set_Addr_To_r /= "000" else '0';             -- Incorrect !!!!!!!!!!!!
164
        VPA     <= '1' when Jump(1) = '0' else '0';                               -- Incorrect !!!!!!!!!!!!
165
 
166
        mcode : T65_MCode
167
                port map(
168
                        Mode => Mode_r,
169
                        IR => IR,
170
                        MCycle => MCycle,
171
                        P => P,
172
                        LCycle => LCycle,
173
                        ALU_Op => ALU_Op,
174
                        Set_BusA_To => Set_BusA_To,
175
                        Set_Addr_To => Set_Addr_To,
176
                        Write_Data => Write_Data,
177
                        Jump => Jump,
178
                        BAAdd => BAAdd,
179
                        BreakAtNA => BreakAtNA,
180
                        ADAdd => ADAdd,
181
                        PCAdd => PCAdd,
182
                        Inc_S => Inc_S,
183
                        Dec_S => Dec_S,
184
                        LDA => LDA,
185
                        LDP => LDP,
186
                        LDX => LDX,
187
                        LDY => LDY,
188
                        LDS => LDS,
189
                        LDDI => LDDI,
190
                        LDALU => LDALU,
191
                        LDAD => LDAD,
192
                        LDBAL => LDBAL,
193
                        LDBAH => LDBAH,
194
                        SaveP => SaveP,
195
                        Write => Write);
196
 
197
        alu : T65_ALU
198
                port map(
199
                        Mode => Mode_r,
200
                        Op => ALU_Op_r,
201
                        BusA => BusA_r,
202
                        BusB => BusB,
203
                        P_In => P,
204
                        P_Out => P_Out,
205
                        Q => ALU_Q);
206
 
207
        process (Res_n, Clk)
208
        begin
209
                if Res_n = '0' then
210
                        PC <= (others => '0');  -- Program Counter
211
                        IR <= "00000000";
212
 
213
                        S <= (others => '0');    -- Dummy !!!!!!!!!!!!!!!!!!!!!
214
 
215
                        D <= (others => '0');
216
                        PBR <= (others => '0');
217
                        DBR <= (others => '0');
218
 
219
                        Mode_r <= (others => '0');
220
                        ALU_Op_r <= "1100";
221
                        Write_Data_r <= "000";
222
                        Set_Addr_To_r <= "00";
223
 
224
                        R_W_n <= '1';
225
                        EF_i <= '1';
226
                        MF_i <= '1';
227
                        XF_i <= '1';
228
 
229
                elsif Clk'event and Clk = '1' then
230
                        if Rdy = '1' then
231
                                R_W_n <= not Write or RstCycle;
232
 
233
                                D <= (others => '1');   -- Dummy
234
                                PBR <= (others => '1'); -- Dummy
235
                                DBR <= (others => '1'); -- Dummy
236
                                EF_i <= '0';     -- Dummy
237
                                MF_i <= '0';     -- Dummy
238
                                XF_i <= '0';     -- Dummy
239
 
240
                                if MCycle  = "000" then
241
                                        Mode_r <= Mode;
242
 
243
                                        if IRQCycle = '0' and NMICycle = '0' then
244
                                                PC <= PC + 1;
245
                                        end if;
246
 
247
                                        if IRQCycle = '1' or NMICycle = '1' then
248
                                                IR <= "00000000";
249
                                        else
250
                                                IR <= DI;
251
                                        end if;
252
                                end if;
253
 
254
                                ALU_Op_r <= ALU_Op;
255
                                Write_Data_r <= Write_Data;
256
                                if Break = '1' then
257
                                        Set_Addr_To_r <= "00";
258
                                else
259
                                        Set_Addr_To_r <= Set_Addr_To;
260
                                end if;
261
 
262
                                if Inc_S = '1' then
263
                                        S <= S + 1;
264
                                end if;
265
                                if Dec_S = '1' and RstCycle = '0' then
266
                                        S <= S - 1;
267
                                end if;
268
                                if LDS = '1' then
269
                                        S(7 downto 0) <= unsigned(ALU_Q);
270
                                end if;
271
 
272
                                if IR = "00000000" and MCycle = "001" and IRQCycle = '0' and NMICycle = '0' then
273
                                        PC <= PC + 1;
274
                                end if;
275
                                case Jump is
276
                                when "01" =>
277
                                        PC <= PC + 1;
278
                                when "10" =>
279
                                        PC <= unsigned(DI & DL);
280
                                when "11" =>
281
                                        if PCAdder(8) = '1' then
282
                                                if DL(7) = '0' then
283
                                                        PC(15 downto 8) <= PC(15 downto 8) + 1;
284
                                                else
285
                                                        PC(15 downto 8) <= PC(15 downto 8) - 1;
286
                                                end if;
287
                                        end if;
288
                                        PC(7 downto 0) <= PCAdder(7 downto 0);
289
                                when others =>
290
                                end case;
291
                        end if;
292
                end if;
293
        end process;
294
 
295
        process (Clk)
296
        begin
297
                if Clk'event and Clk = '1' then
298
                        if Rdy = '1' then
299
                                if MCycle = "000" then
300
                                        if LDA = '1' then
301
                                                ABC(7 downto 0) <= ALU_Q;
302
                                        end if;
303
                                        if LDX = '1' then
304
                                                X(7 downto 0) <= ALU_Q;
305
                                        end if;
306
                                        if LDY = '1' then
307
                                                Y(7 downto 0) <= ALU_Q;
308
                                        end if;
309
                                        if (LDA or LDX or LDY) = '1' then
310
                                                P <= P_Out;
311
                                        end if;
312
                                end if;
313
                                if SaveP = '1' then
314
                                        P <= P_Out;
315
                                end if;
316
                                if LDP = '1' then
317
                                        P <= ALU_Q;
318
                                end if;
319
                                if IR(4 downto 0) = "11000" then
320
                                        case IR(7 downto 5) is
321
                                        when "000" =>
322
                                                P(Flag_C) <= '0';
323
                                        when "001" =>
324
                                                P(Flag_C) <= '1';
325
                                        when "010" =>
326
                                                P(Flag_I) <= '0';
327
                                        when "011" =>
328
                                                P(Flag_I) <= '1';
329
                                        when "101" =>
330
                                                P(Flag_V) <= '0';
331
                                        when "110" =>
332
                                                P(Flag_D) <= '0';
333
                                        when "111" =>
334
                                                P(Flag_D) <= '1';
335
                                        when others =>
336
                                        end case;
337
                                end if;
338
                                if IR = "00000000" and MCycle = "011" and RstCycle = '0' and NMICycle = '0' then
339
                                        P(Flag_B) <= '1';
340
                                end if;
341
                                if IR = "00000000" and MCycle = "100" and RstCycle = '0' and NMICycle = '0' then
342
                                        P(Flag_I) <= '1';
343
                                        P(Flag_B) <= B_o;
344
                                end if;
345
                                if SO_n_o = '1' and SO_n = '0' then
346
                                        P(Flag_V) <= '1';
347
                                end if;
348
                                if RstCycle = '1' and Mode_r /= "00" then
349
                                        P(Flag_1) <= '1';
350
                                        P(Flag_D) <= '0';
351
                                        P(Flag_I) <= '1';
352
                                end if;
353
                                P(Flag_1) <= '1';
354
 
355
                                B_o     <= P(Flag_B);
356
                                SO_n_o <= SO_n;
357
                                IRQ_n_o <= IRQ_n;
358
                                NMI_n_o <= NMI_n;
359
                        end if;
360
                end if;
361
        end process;
362
 
363
---------------------------------------------------------------------------
364
--
365
-- Buses
366
--
367
---------------------------------------------------------------------------
368
 
369
        process (Res_n, Clk)
370
        begin
371
                if Res_n = '0' then
372
                        BusA_r <= (others => '0');
373
                        BusB <= (others => '0');
374
                        AD <= (others => '0');
375
                        BAL <= (others => '0');
376
                        BAH <= (others => '0');
377
                        DL <= (others => '0');
378
                elsif Clk'event and Clk = '1' then
379
                        if Rdy = '1' then
380
                                BusA_r <= BusA;
381
                                BusB <= DI;
382
 
383
                                case BAAdd is
384
                                when "01" =>
385
                                        -- BA Inc
386
                                        AD <= std_logic_vector(unsigned(AD) + 1);
387
                                        BAL <= std_logic_vector(unsigned(BAL) + 1);
388
                                when "10" =>
389
                                        -- BA Add
390
                                        BAL <= std_logic_vector(resize(unsigned(BAL(7 downto 0)),9) + resize(unsigned(BusA),9));
391
                                when "11" =>
392
                                        -- BA Adj
393
                                        if BAL(8) = '1' then
394
                                                BAH <= std_logic_vector(unsigned(BAH) + 1);
395
                                        end if;
396
                                when others =>
397
                                end case;
398
 
399
                                if ADAdd = '1' then
400
                                        AD <= std_logic_vector(unsigned(AD) + unsigned(X(7 downto 0)));
401
                                end if;
402
 
403
                                if IR = "00000000" then
404
                                        BAL <= (others => '1');
405
                                        BAH <= (others => '1');
406
                                        if RstCycle = '1' then
407
                                                BAL(2 downto 0) <= "100";
408
                                        elsif NMICycle = '1' then
409
                                                BAL(2 downto 0) <= "010";
410
                                        else
411
                                                BAL(2 downto 0) <= "110";
412
                                        end if;
413
                                        if Set_addr_To_r = "11" then
414
                                                BAL(0) <= '1';
415
                                        end if;
416
                                end if;
417
 
418
 
419
                                if LDDI = '1' then
420
                                        DL <= DI;
421
                                end if;
422
                                if LDALU = '1' then
423
                                        DL <= ALU_Q;
424
                                end if;
425
                                if LDAD = '1' then
426
                                        AD <= DI;
427
                                end if;
428
                                if LDBAL = '1' then
429
                                        BAL(7 downto 0) <= DI;
430
                                end if;
431
                                if LDBAH = '1' then
432
                                        BAH <= DI;
433
                                end if;
434
                        end if;
435
                end if;
436
        end process;
437
 
438
        Break <= (BreakAtNA and not BAL(8)) or (PCAdd and not PCAdder(8));
439
 
440
        PCAdder <= resize(PC(7 downto 0),9) + resize(unsigned(DL(7) & DL),9) when PCAdd = '1' else "0" & PC(7 downto 0);
441
 
442
        with Set_BusA_To select
443
                BusA <= DI when "000",
444
                        ABC(7 downto 0) when "001",
445
                        X(7 downto 0) when "010",
446
                        Y(7 downto 0) when "011",
447
                        std_logic_vector(S(7 downto 0)) when "100",
448
                        P when "101",
449
                        (others => '-') when others;
450
 
451
        with Set_Addr_To_r select
452
                A <= "0000000000000001" & std_logic_vector(S(7 downto 0)) when "01",
453
                        DBR & "00000000" & AD when "10",
454
                        "00000000" & BAH & BAL(7 downto 0) when "11",
455
                        PBR & std_logic_vector(PC(15 downto 8)) & std_logic_vector(PCAdder(7 downto 0)) when others;
456
 
457
        with Write_Data_r select
458
                DO <= DL when "000",
459
                        ABC(7 downto 0) when "001",
460
                        X(7 downto 0) when "010",
461
                        Y(7 downto 0) when "011",
462
                        std_logic_vector(S(7 downto 0)) when "100",
463
                        P when "101",
464
                        std_logic_vector(PC(7 downto 0)) when "110",
465
                        std_logic_vector(PC(15 downto 8)) when others;
466
 
467
-------------------------------------------------------------------------
468
--
469
-- Main state machine
470
--
471
-------------------------------------------------------------------------
472
 
473
        process (Res_n, Clk)
474
        begin
475
                if Res_n = '0' then
476
                        MCycle <= "001";
477
                        RstCycle <= '1';
478
                        IRQCycle <= '0';
479
                        NMICycle <= '0';
480
                        NMIAct <= '0';
481
                elsif Clk'event and Clk = '1' then
482
                        if Rdy = '1' then
483
                                if MCycle = LCycle or Break = '1' then
484
                                        MCycle <= "000";
485
                                        RstCycle <= '0';
486
                                        IRQCycle <= '0';
487
                                        NMICycle <= '0';
488
                                        if NMIAct = '1' then
489
                                                NMICycle <= '1';
490
                                        elsif IRQ_n_o = '0' and P(Flag_I) = '0' then
491
                                                IRQCycle <= '1';
492
                                        end if;
493
                                else
494
                                        MCycle <= std_logic_vector(unsigned(MCycle) + 1);
495
                                end if;
496
 
497
                                if NMICycle = '1' then
498
                                        NMIAct <= '0';
499
                                end if;
500
                                if NMI_n_o = '1' and NMI_n = '0' then
501
                                        NMIAct <= '1';
502
                                end if;
503
                        end if;
504
                end if;
505
        end process;
506
 
507
end;

powered by: WebSVN 2.1.0

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