2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.conv_std_logic_vector;
4 use ieee.std_logic_unsigned.conv_integer;
7 generic (dsize : integer := 8);
8 port ( set_clk : in std_logic;
9 trig_clk : in std_logic;
14 instruction : in std_logic_vector (dsize - 1 downto 0);
15 status_reg : inout std_logic_vector (dsize - 1 downto 0);
16 ad_oe_n : out std_logic;
17 pcl_d_we_n : out std_logic;
18 pcl_a_we_n : out std_logic;
19 pcl_d_oe_n : out std_logic;
20 pcl_a_oe_n : out std_logic;
21 pch_d_we_n : out std_logic;
22 pch_a_we_n : out std_logic;
23 pch_d_oe_n : out std_logic;
24 pch_a_oe_n : out std_logic;
25 pc_inc_n : out std_logic;
26 inst_we_n : out std_logic;
27 dbuf_int_oe_n : out std_logic;
28 dl_al_we_n : out std_logic;
29 dl_ah_we_n : out std_logic;
30 dl_dl_oe_n : out std_logic;
31 dl_dh_oe_n : out std_logic;
32 dl_al_oe_n : out std_logic;
33 dl_ah_oe_n : out std_logic;
34 sp_we_n : out std_logic;
35 sp_push_n : out std_logic;
36 sp_pop_n : out std_logic;
37 sp_int_d_oe_n : out std_logic;
38 sp_int_a_oe_n : out std_logic;
39 acc_d_we_n : out std_logic;
40 acc_alu_we_n : out std_logic;
41 acc_d_oe_n : out std_logic;
42 acc_alu_oe_n : out std_logic;
43 x_we_n : out std_logic;
44 x_oe_n : out std_logic;
45 x_calc_n : out std_logic;
46 y_we_n : out std_logic;
47 y_oe_n : out std_logic;
48 y_calc_n : out std_logic;
49 ea_ah_oe_n : out std_logic;
50 ea_al_oe_n : out std_logic;
51 ea_carry : in std_logic;
52 stat_dec_we_n : out std_logic;
53 stat_dec_oe_n : out std_logic;
54 stat_bus_we_n : out std_logic;
55 stat_bus_oe_n : out std_logic;
57 dbg_show_pc : out std_logic
61 architecture rtl of decoder is
63 procedure d_print(msg : string) is
65 use ieee.std_logic_textio.all;
66 variable out_l : line;
69 writeline(output, out_l);
72 procedure d_print(msg : string; sig : std_logic_vector) is
74 use ieee.std_logic_textio.all;
75 variable out_l : line;
79 writeline(output, out_l);
82 procedure d_print(msg : string; ival : integer) is
84 use ieee.std_logic_textio.all;
85 variable out_l : line;
89 writeline(output, out_l);
92 ---ival : 0x0000 - 0xffff
93 function conv_hex16(ival : integer) return string is
94 variable tmp1, tmp2, tmp3, tmp4 : integer;
95 --variable ret : string (1 to 4) := "0000";
96 variable hex_chr: string (1 to 16) := "0123456789abcdef";
98 tmp4 := ival / 16 ** 3;
99 tmp3 := (ival mod 16 ** 3) / 16 ** 2;
100 tmp2 := (ival mod 16 ** 2) / 16 ** 1;
101 tmp1 := ival mod 16 ** 1;
102 return hex_chr(tmp4 + 1) & hex_chr(tmp3 + 1)
103 & hex_chr(tmp2 + 1) & hex_chr(tmp1 + 1);
106 function conv_hex8(ival : integer) return string is
107 variable tmp1, tmp2 : integer;
108 variable hex_chr: string (1 to 16) := "0123456789abcdef";
110 tmp2 := (ival mod 16 ** 2) / 16 ** 1;
111 tmp1 := ival mod 16 ** 1;
112 return hex_chr(tmp2 + 1) & hex_chr(tmp1 + 1);
116 type exec_cycle is (reset0, reset1, reset2, reset3, reset4, reset5,
117 --exec0 = fetch, exec1=decode
118 fetch, decode, exec2, exec3, exec4, exec5,
121 type addr_mode is ( ad_imm,
123 ad_zp, ad_zpx, ad_zpy,
124 ad_abs, ad_absx, ad_absy,
125 ad_indir_x, ad_indir_y,
129 signal cur_cycle : exec_cycle;
131 -- SR Flags (bit 7 to bit 0):
136 -- 3 D .... Decimal (use BCD for arithmetics)
137 -- 2 I .... Interrupt (IRQ disable)
140 constant st_N : integer := 7;
141 constant st_V : integer := 6;
142 constant st_B : integer := 4;
143 constant st_D : integer := 3;
144 constant st_I : integer := 2;
145 constant st_Z : integer := 1;
146 constant st_C : integer := 0;
148 ---case instruction consists of aaabbbcc form,
149 ---return addressing mode for each opcode.
150 function decode_addr_mode (instruction : in std_logic_vector (dsize - 1 downto 0))
153 if instruction (1 downto 0) = "01" then
154 if instruction (4 downto 2) = "000" then
157 elsif instruction (4 downto 2) = "001" then
159 elsif instruction (4 downto 2) = "010" then
161 elsif instruction (4 downto 2) = "011" then
163 elsif instruction (4 downto 2) = "100" then
166 elsif instruction (4 downto 2) = "101" then
168 elsif instruction (4 downto 2) = "110" then
170 elsif instruction (4 downto 2) = "111" then
173 elsif instruction (1 downto 0) = "10" then
175 --bbb is 000, 001, 010, 011, 101, 111 only.
176 if instruction (4 downto 2) = "000" then
178 elsif instruction (4 downto 2) = "001" then
180 elsif instruction (4 downto 2) = "010" then
182 elsif instruction (4 downto 2) = "011" then
184 elsif instruction (4 downto 2) = "101" then
186 elsif instruction (4 downto 2) = "111" then
192 elsif instruction (1 downto 0) = "00" then
193 --d_print("cc=00 group...");
194 ---bbb part is 000, 001, 011, 101, 111 only.
195 if instruction (4 downto 2) = "000" then
197 elsif instruction (4 downto 2) = "001" then
199 elsif instruction (4 downto 2) = "011" then
201 elsif instruction (4 downto 2) = "101" then
203 elsif instruction (4 downto 2) = "111" then
210 end if; --if instruction (1 downto 0) = "01" then
215 main_p : process (set_clk, trig_clk, res_n)
216 variable single_inst : boolean;
217 variable status_reg_old : std_logic_vector(dsize - 1 downto 0);
218 variable cur_mode : addr_mode;
221 if (res_n'event and res_n = '0') then
222 d_print(string'("reset"));
236 dbuf_int_oe_n <= '1';
246 sp_int_d_oe_n <= '1';
247 sp_int_a_oe_n <= '1';
256 stat_dec_we_n <= '1';
257 stat_dec_oe_n <= '1';
258 stat_bus_we_n <= '1';
259 stat_bus_oe_n <= '1';
267 if (set_clk'event and set_clk = '1') then
268 d_print(string'("-"));
270 if cur_cycle = reset0 then
272 elsif cur_cycle = reset1 then
274 elsif cur_cycle = reset2 then
276 elsif cur_cycle = reset3 then
278 elsif cur_cycle = reset4 then
280 elsif cur_cycle = reset5 then
283 elsif cur_cycle = fetch then
285 d_print(string'("fetch 1"));
299 dbuf_int_oe_n <= '1';
300 stat_dec_we_n <= '1';
301 stat_bus_we_n <= '1';
319 status_reg <= (others => 'Z');
320 stat_dec_oe_n <= '0';
322 elsif cur_cycle = decode then
324 d_print("decode and execute inst: "
325 & conv_hex8(conv_integer(instruction)));
327 --grab instruction register data.
330 ---single byte instruction.
331 single_inst := false;
333 if instruction = conv_std_logic_vector(16#8a#, dsize) then
336 elsif instruction = conv_std_logic_vector(16#9a#, dsize) then
341 elsif instruction = conv_std_logic_vector(16#aa#, dsize) then
344 elsif instruction = conv_std_logic_vector(16#ba#, dsize) then
347 elsif instruction = conv_std_logic_vector(16#ca#, dsize) then
350 elsif instruction = conv_std_logic_vector(16#ea#, dsize) then
353 elsif instruction = conv_std_logic_vector(16#08#, dsize) then
356 elsif instruction = conv_std_logic_vector(16#28#, dsize) then
359 elsif instruction = conv_std_logic_vector(16#48#, dsize) then
362 elsif instruction = conv_std_logic_vector(16#68#, dsize) then
365 elsif instruction = conv_std_logic_vector(16#88#, dsize) then
368 elsif instruction = conv_std_logic_vector(16#a8#, dsize) then
371 elsif instruction = conv_std_logic_vector(16#c8#, dsize) then
374 elsif instruction = conv_std_logic_vector(16#e8#, dsize) then
377 elsif instruction = conv_std_logic_vector(16#18#, dsize) then
380 elsif instruction = conv_std_logic_vector(16#38#, dsize) then
383 elsif instruction = conv_std_logic_vector(16#58#, dsize) then
386 elsif instruction = conv_std_logic_vector(16#78#, dsize) then
389 status_reg_old := status_reg;
390 stat_dec_oe_n <= '1';
391 stat_dec_we_n <= '0';
392 status_reg(7 downto st_I + 1)
393 <= status_reg_old (7 downto st_I + 1);
394 status_reg(st_I - 1 downto 0)
395 <= status_reg_old (st_I - 1 downto 0);
396 status_reg(st_I) <= '1';
397 elsif instruction = conv_std_logic_vector(16#98#, dsize) then
400 elsif instruction = conv_std_logic_vector(16#b8#, dsize) then
403 elsif instruction = conv_std_logic_vector(16#d8#, dsize) then
406 elsif instruction = conv_std_logic_vector(16#f8#, dsize) then
418 if instruction = conv_std_logic_vector(16#00#, dsize) then
420 elsif instruction = conv_std_logic_vector(16#20#, dsize) then
421 d_print("jsr abs 2");
426 dbuf_int_oe_n <= '0';
431 elsif instruction = conv_std_logic_vector(16#40#, dsize) then
433 elsif instruction = conv_std_logic_vector(16#60#, dsize) then
439 --pop stack (decrement only)
441 sp_int_a_oe_n <= '0';
444 elsif instruction (4 downto 0) = "10000" then
445 ---conditional branch instruction..
448 ---instruction consists of aaabbbcc form.
450 ---addressing mode identifier
451 cur_mode := decode_addr_mode(instruction);
453 if cur_mode = ad_imm then
454 d_print("immediate");
458 --send data from data bus buffer.
459 --receiver is instruction dependent.
460 dbuf_int_oe_n <= '0';
462 elsif cur_mode = ad_acc then
463 elsif cur_mode = ad_zp then
464 elsif cur_mode = ad_zpx then
465 elsif cur_mode = ad_zpy then
466 elsif cur_mode = ad_abs then
468 --fetch next opcode (abs low).
472 --latch abs low data.
473 dbuf_int_oe_n <= '0';
476 elsif cur_mode = ad_absx then
478 --same as abs until cycle 3.
482 --latch abs low data.
483 dbuf_int_oe_n <= '0';
484 dbuf_int_oe_n <= '0';
487 elsif cur_mode = ad_absy then
488 elsif cur_mode = ad_indir_x then
489 elsif cur_mode = ad_indir_y then
492 report ("unknow addressing mode.") severity failure;
493 cur_cycle <= err_cycle;
494 end if; --if cur_mode = ad_imm then
496 if instruction (1 downto 0) = "01" then
499 if instruction (7 downto 5) = "000" then
501 elsif instruction (7 downto 5) = "001" then
503 elsif instruction (7 downto 5) = "010" then
505 elsif instruction (7 downto 5) = "011" then
507 elsif instruction (7 downto 5) = "100" then
508 if (cur_mode = ad_imm) then
511 elsif instruction (7 downto 5) = "101" then
512 if (cur_mode = ad_imm) then
515 --status register n/z bit update.
516 stat_dec_oe_n <= '1';
517 status_reg <= "10000010";
518 stat_bus_we_n <= '0';
520 elsif instruction (7 downto 5) = "110" then
522 elsif instruction (7 downto 5) = "111" then
526 report ("unknow instruction") severity failure;
527 cur_cycle <= err_cycle;
529 elsif instruction (1 downto 0) = "10" then
532 if instruction (7 downto 5) = "000" then
534 elsif instruction (7 downto 5) = "001" then
536 elsif instruction (7 downto 5) = "010" then
538 elsif instruction (7 downto 5) = "011" then
540 elsif instruction (7 downto 5) = "100" then
542 elsif instruction (7 downto 5) = "101" then
543 if (cur_mode = ad_imm) then
546 --status register n/z bit update.
547 stat_dec_oe_n <= '1';
548 status_reg <= "10000010";
549 stat_bus_we_n <= '0';
551 elsif instruction (7 downto 5) = "110" then
553 elsif instruction (7 downto 5) = "111" then
557 report ("unknow instruction") severity failure;
558 cur_cycle <= err_cycle;
561 elsif instruction (1 downto 0) = "00" then
562 --d_print("cc=00 group...");
564 if instruction (7 downto 5) = "001" then
566 elsif instruction (7 downto 5) = "010" then
567 --jmp always absolute addressing
570 elsif instruction (7 downto 5) = "011" then
571 --d_print("jmp (abs) 2");
573 elsif instruction (7 downto 5) = "100" then
575 elsif instruction (7 downto 5) = "101" then
576 if (cur_mode = ad_imm) then
579 --status register n/z bit update.
580 stat_dec_oe_n <= '1';
581 status_reg <= "10000010";
582 stat_bus_we_n <= '0';
584 elsif instruction (7 downto 5) = "110" then
586 elsif instruction (7 downto 5) = "111" then
590 report ("unknow instruction") severity failure;
591 cur_cycle <= err_cycle;
592 end if; --if instruction (7 downto 5) = "001" then
593 end if; --if instruction (1 downto 0) = "01"
594 end if; --if instruction = conv_std_logic_vector(16#00#, dsize)
595 end if; --if single_inst
597 elsif cur_cycle = exec2 then
599 if instruction = conv_std_logic_vector(16#00#, dsize) then
601 elsif instruction = conv_std_logic_vector(16#20#, dsize) then
606 dbuf_int_oe_n <= '1';
609 --push return addr high into stack.
612 sp_int_a_oe_n <= '0';
615 elsif instruction = conv_std_logic_vector(16#40#, dsize) then
616 elsif instruction = conv_std_logic_vector(16#60#, dsize) then
619 sp_int_a_oe_n <= '0';
623 elsif instruction (4 downto 0) = "10000" then
624 ---conditional branch instruction..
627 if cur_mode = ad_abs then
634 dbuf_int_oe_n <= '0';
636 --pc_inc is '0'. only jump is '1'.
638 elsif cur_mode = ad_absx then
645 dbuf_int_oe_n <= '0';
648 end if; --if cur_mode = ad_abs then
650 if instruction (1 downto 0) = "00" then
651 if instruction (7 downto 5) = "010" then
655 --pcl set from adl bus.
662 end if; --if instruction (7 downto 5) = "010" then
663 elsif instruction (1 downto 0) = "01" then
664 if instruction (7 downto 5) = "100" then
668 end if; --if instruction (1 downto 0) = "00" then
669 end if; --if instruction = conv_std_logic_vector(16#00#, dsize)
671 elsif cur_cycle = exec3 then
673 if instruction = conv_std_logic_vector(16#00#, dsize) then
674 elsif instruction = conv_std_logic_vector(16#20#, dsize) then
678 --push return addr low into stack.
681 sp_int_a_oe_n <= '0';
685 elsif instruction = conv_std_logic_vector(16#40#, dsize) then
686 elsif instruction = conv_std_logic_vector(16#60#, dsize) then
688 --stack decrement stop.
692 dbuf_int_oe_n <= '0';
696 sp_int_a_oe_n <= '0';
699 elsif instruction (4 downto 0) = "10000" then
700 ---conditional branch instruction..
702 if cur_mode = ad_abs then
707 dbuf_int_oe_n <= '1';
715 elsif cur_mode = ad_absx then
720 dbuf_int_oe_n <= '1';
723 -----calucurate and output effective addr low
730 end if; --if cur_mode = ad_abs then
732 if instruction (1 downto 0) = "00" then
733 elsif instruction (1 downto 0) = "01" then
734 if instruction (7 downto 5) = "100" then
736 --output acc memory..
739 elsif instruction (7 downto 5) = "101" then
741 --if page boundary is crossed, redo in the next cycle.
744 end if; --instruction (1 downto 0) = "00"
745 end if; --if instruction = conv_std_logic_vector(16#00#, dsize)
747 elsif cur_cycle = exec4 then
749 if instruction = conv_std_logic_vector(16#00#, dsize) then
750 elsif instruction = conv_std_logic_vector(16#20#, dsize) then
754 sp_int_a_oe_n <= '1';
763 elsif instruction = conv_std_logic_vector(16#40#, dsize) then
764 elsif instruction = conv_std_logic_vector(16#60#, dsize) then
766 sp_int_a_oe_n <= '1';
770 dbuf_int_oe_n <= '0';
774 elsif instruction (4 downto 0) = "10000" then
775 ---conditional branch instruction..
777 if cur_mode = ad_absx then
778 if ea_carry = '0' then
779 --case page boundary crossed.
780 d_print("absx 5 (page boudary crossed.)");
785 -----effective addr low is remorized in the calc.
792 --case page boundary not crossed. do the fetch op.
793 d_print("absx 5 (fetch)");
803 --cur_cycle <= decode;
806 if instruction (1 downto 0) = "00" then
807 elsif instruction (1 downto 0) = "01" then
808 if instruction (7 downto 5) = "100" then
810 --output acc memory..
813 elsif instruction (7 downto 5) = "101" then
815 --if page boundary is crossed, redo in the next cycle.
818 end if; --instruction (1 downto 0) = "00"
819 end if; --if instruction = conv_std_logic_vector(16#00#, dsize)
821 elsif cur_cycle = exec5 then
823 if instruction = conv_std_logic_vector(16#00#, dsize) then
824 elsif instruction = conv_std_logic_vector(16#20#, dsize) then
833 dbuf_int_oe_n <= '0';
840 elsif instruction = conv_std_logic_vector(16#40#, dsize) then
841 elsif instruction = conv_std_logic_vector(16#60#, dsize) then
843 dbuf_int_oe_n <= '1';
849 elsif instruction (4 downto 0) = "10000" then
850 ---conditional branch instruction..
852 if instruction (1 downto 0) = "00" then
853 end if; --instruction (1 downto 0) = "00"
854 end if; --if instruction = conv_std_logic_vector(16#00#, dsize)
856 elsif cur_cycle = err_cycle then
857 ---stop decoding... > CPU stop.
860 report ("unknow status") severity failure;
861 cur_cycle <= err_cycle;
862 end if; --if cur_cycle = reset0 then
863 end if; --if (set_clk'event and set_clk = '1')
867 dbg_p : process (set_clk)
869 if (set_clk'event and set_clk= '0' and cur_cycle = decode) then
873 end if; --if (trigger_clk'event and trigger_clk = '1')