/[projet1]/users/jede/electronique/vhdl/T6502_65816/T65.vhd
Defence Force logotype

Contents of /users/jede/electronique/vhdl/T6502_65816/T65.vhd

Parent Directory Parent Directory | Revision Log Revision Log


Revision 710 - (show annotations)
Tue Nov 1 12:36:41 2011 UTC (8 years, 7 months ago) by Jede
File size: 15927 byte(s)


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

  ViewVC Help
Powered by ViewVC 1.1.26