OSDN Git Service

code re-write working...
authorastoria-d <astoria-d@mail.goo.ne.jp>
Mon, 17 Jun 2013 05:02:31 +0000 (14:02 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Mon, 17 Jun 2013 05:02:31 +0000 (14:02 +0900)
simulation/cpu/alu.vhd
simulation/cpu/cpu_registers.vhd
simulation/cpu/decoder.vhd
simulation/cpu/mos6502.vhd

index 38072bd..b2044ce 100644 (file)
@@ -6,6 +6,8 @@ library ieee;
 use ieee.std_logic_1164.all;
 use ieee.std_logic_unsigned.all;
 
+----d1 = acc
+----d2 = memory
 entity alu_core is 
     generic (   dsize : integer := 8
             );
@@ -44,11 +46,13 @@ constant ALU_SL     : std_logic_vector (3 downto 0) := "0111";
 constant ALU_SR     : std_logic_vector (3 downto 0) := "1000";
 constant ALU_RL     : std_logic_vector (3 downto 0) := "1001";
 constant ALU_RR     : std_logic_vector (3 downto 0) := "1010";
+constant ALU_INC    : std_logic_vector (3 downto 0) := "1011";
+constant ALU_DEC    : std_logic_vector (3 downto 0) := "1100";
 
 begin
 
     alu_p : process (sel, d1, d2, carry_in)
-    variable res : std_logic_vector (dsize - 1 downto 0);
+    variable res : std_logic_vector (dsize downto 0);
 
 procedure set_n (data : in std_logic_vector (dsize - 1 downto 0)) is
 begin
@@ -79,10 +83,11 @@ end procedure;
     elsif sel = ALU_BIT then
         ----
     elsif sel = ALU_ADC then
-        res := d1 + d2 + carry_in;
+        res := ('0' & d1) + ('0' & d2) + carry_in;
     elsif sel = ALU_SBC then
         ----
     elsif sel = ALU_CMP then
+        res := d1 - d2;
     elsif sel = ALU_SL then
         ----
     elsif sel = ALU_SR then
@@ -91,10 +96,14 @@ end procedure;
         ----
     elsif sel = ALU_RR then
         ----
+    elsif sel = ALU_INC then
+        res := ('0' & d1) + "000000001";
+        d_out <= res(dsize - 1 downto 0);
+    elsif sel = ALU_DEC then
+        res := ('0' & d1) - "000000001";
     end if;
-
-    set_n(res);
-    set_z(res);
+    set_n(res(dsize - 1 downto 0));
+    set_z(res(dsize - 1 downto 0));
 
     end process;
 
@@ -112,11 +121,21 @@ entity alu is
     generic (   dsize : integer := 8
             );
     port (  clk             : in std_logic;
+            pc_inc_n        : in std_logic;
+            abs_ea_n        : in std_logic;
+            zp_ea_n         : in std_logic;
             arith_en_n      : in std_logic;
             instruction     : in std_logic_vector (dsize - 1 downto 0);
             int_d_bus       : inout std_logic_vector (dsize - 1 downto 0);
             acc_out         : in std_logic_vector (dsize - 1 downto 0);
             acc_in          : out std_logic_vector (dsize - 1 downto 0);
+            index_bus       : in std_logic_vector (dsize - 1 downto 0);
+            bal             : in std_logic_vector (dsize - 1 downto 0);
+            bah             : in std_logic_vector (dsize - 1 downto 0);
+            abl             : out std_logic_vector (dsize - 1 downto 0);
+            abh             : out std_logic_vector (dsize - 1 downto 0);
+            pcl             : out std_logic_vector (dsize - 1 downto 0);
+            pch             : out std_logic_vector (dsize - 1 downto 0);
             carry_in        : in std_logic;
             negative        : out std_logic;
             zero            : out std_logic;
@@ -127,6 +146,50 @@ end alu;
 
 architecture rtl of alu is
 
+component d_flip_flop
+    generic (
+            dsize : integer := 8
+            );
+    port (  
+            clk     : in std_logic;
+            res_n   : in std_logic;
+            set_n   : in std_logic;
+            we_n    : in std_logic;
+            d       : in std_logic_vector (dsize - 1 downto 0);
+            q       : out std_logic_vector (dsize - 1 downto 0)
+        );
+end component;
+
+component alu_core
+    generic (   dsize : integer := 8
+            );
+    port ( 
+            sel         : in std_logic_vector (3 downto 0);
+            d1          : in std_logic_vector (dsize - 1 downto 0);
+            d2          : in std_logic_vector (dsize - 1 downto 0);
+            d_out       : out std_logic_vector (dsize - 1 downto 0);
+            carry_in    : in std_logic;
+            negative    : out std_logic;
+            zero        : out std_logic;
+            carry_out   : out std_logic;
+            overflow    : out std_logic
+    );
+end component;
+
+constant ALU_AND    : std_logic_vector (3 downto 0) := "0000";
+constant ALU_EOR    : std_logic_vector (3 downto 0) := "0001";
+constant ALU_OR     : std_logic_vector (3 downto 0) := "0010";
+constant ALU_BIT    : std_logic_vector (3 downto 0) := "0011";
+constant ALU_ADC    : std_logic_vector (3 downto 0) := "0100";
+constant ALU_SBC    : std_logic_vector (3 downto 0) := "0101";
+constant ALU_CMP    : std_logic_vector (3 downto 0) := "0110";
+constant ALU_SL     : std_logic_vector (3 downto 0) := "0111";
+constant ALU_SR     : std_logic_vector (3 downto 0) := "1000";
+constant ALU_RL     : std_logic_vector (3 downto 0) := "1001";
+constant ALU_RR     : std_logic_vector (3 downto 0) := "1010";
+constant ALU_INC    : std_logic_vector (3 downto 0) := "1011";
+constant ALU_DEC    : std_logic_vector (3 downto 0) := "1100";
+
 procedure d_print(msg : string) is
 use std.textio.all;
 use ieee.std_logic_textio.all;
@@ -136,32 +199,37 @@ begin
     writeline(output, out_l);
 end  procedure;
 
-begin
+signal sel : std_logic_vector (3 downto 0);
+signal d1 : std_logic_vector (dsize - 1 downto 0);
+signal d2 : std_logic_vector (dsize - 1 downto 0);
+signal d_out : std_logic_vector (dsize - 1 downto 0);
 
-    alu_p : process (arith_en_n, instruction, acc_out, int_d_bus, carry_in)
-    variable res : std_logic_vector (dsize - 1 downto 0);
+signal bal_reg : std_logic_vector (dsize - 1 downto 0);
+signal bah_reg : std_logic_vector (dsize - 1 downto 0);
 
-procedure set_n (data : in std_logic_vector (dsize - 1 downto 0)) is
 begin
-    if (data(7) = '1') then
-        negative <= '1';
-    else
-        negative <= '0';
-    end if;
-end procedure;
 
-procedure set_z (data : in std_logic_vector (dsize - 1 downto 0)) is
-begin
-    if  (data(7) or data(6) or data(5) or data(4) or 
-        data(3) or data(2) or data(1) or data(0)) = '0' then
-        zero <= '1';
-    else
-        zero <= '0';
-    end if;
-end procedure;
+    bal_inst : d_flip_flop generic map (dsize) 
+            port map(clk, '1', '1', '1', bal, bal_reg);
+    bah_inst : d_flip_flop generic map (dsize) 
+            port map(clk, '1', '1', '1', bah, bah_reg);
+
+    alu_inst : alu_core generic map (dsize)
+            port map (sel, d1, d2, d_out, 
+                    carry_in, negative, zero, carry_out, overflow);
 
+    alu_p : process (clk, pc_inc_n, abs_ea_n, zp_ea_n, arith_en_n, instruction, 
+                    int_d_bus, acc_out, index_bus, bal, bal, carry_in, d_out)
     begin
-    if (arith_en_n = '0') then
+    if (pc_inc_n = '0') then
+        sel <= ALU_INC;
+        d1 <= bal;
+        pcl <= d_out;
+
+        abl <= bal;
+        abh <= bah;
+
+    elsif (arith_en_n = '0') then
             --instruction is aaabbbcc format.
             if instruction (1 downto 0) = "01" then
                 if instruction (7 downto 5) = "000" then
@@ -175,21 +243,10 @@ end procedure;
                 elsif instruction (7 downto 5) = "110" then
                     d_print("cmp");
                     --cmpare A - M.
-                    --set n/z/c flag
-                    res := acc_out - int_d_bus;
-                    set_n(res);
-                    set_z(res);
-                    --carry flag set when acc >= mem, namely res is positive.
-                    if (acc_out >= int_d_bus) then
-                        carry_out <= '1';
-                    else
-                        carry_out <= '0';
-                    end if;
-
-                    --no register update.
-                    int_d_bus <= (others => 'Z');
-                    acc_in <= (others => 'Z');
-                    overflow <= 'Z';
+                    sel <= ALU_CMP;
+                    d1 <= acc_out;
+                    d2 <= int_d_bus;
+                    acc_in <= d_out;
 
                 elsif instruction (7 downto 5) = "111" then
                     d_print("sbc");
@@ -236,6 +293,9 @@ end procedure;
         zero <= 'Z';
         carry_out <= 'Z';
         overflow <= 'Z';
+
+        abl <= bal;
+        abh <= bah;
     end if; --if (arith_en_n = '') then
     end process;
 
index 0c56f26..dccd997 100644 (file)
@@ -23,11 +23,11 @@ end d_flip_flop;
 architecture rtl of d_flip_flop is
 begin
 
-    process (clk, res_n, set_n)
+    process (clk, res_n, set_n, d)
     begin
         if (res_n = '0') then
             q <= (others => '0');
-        elsif (clk'event and clk = '1' and set_n = '0') then
+        elsif (set_n = '0') then
             q <= d;
         elsif (clk'event and clk = '1') then
             if (we_n = '0') then
@@ -168,8 +168,6 @@ begin
 end rtl;
 
 
------------------
-
 ----------------------------------------
 --- data bus buffer
 ----------------------------------------
@@ -289,4 +287,3 @@ begin
 
 end rtl;
 
-
index 4c163e8..00afdd5 100644 (file)
@@ -17,6 +17,8 @@ entity decoder is
             status_reg      : inout std_logic_vector (dsize - 1 downto 0);
             inst_we_n       : out std_logic;
             ad_oe_n         : out std_logic;
+            dbuf_int_oe_n   : out std_logic;
+            pc_inc_n        : out std_logic;
             pcl_cmd         : out std_logic_vector(3 downto 0);
             pch_cmd         : out std_logic_vector(3 downto 0);
             sp_cmd          : out std_logic_vector(3 downto 0);
@@ -143,18 +145,30 @@ end;
 procedure fetch_inst is
 begin
     ad_oe_n <= '0';
-    inst_we_n <= '0';
     back_oe(pcl_cmd, '0');
     back_oe(pch_cmd, '0');
+    back_we(pcl_cmd, '0');
+    inst_we_n <= '0';
+    pc_inc_n <= '0';
     r_nw <= '1';
     --pcl_inc_n <= '0';
 
+    --disable the last opration pins.
+    dbuf_int_oe_n <= '1';
+    sp_cmd <= "1111";
+    acc_cmd <= "1111";
+    x_cmd <= "1111";
+    y_cmd <= "1111";
     d_print(string'("fetch 1"));
 end;
 
 ---common routine for single byte instruction.
 procedure single_inst is
 begin
+    back_oe(pcl_cmd, '1');
+    back_oe(pch_cmd, '1');
+    pc_inc_n <= '1';
+    next_cycle <= T0;
 end  procedure;
 
 procedure fetch_imm is
@@ -238,7 +252,7 @@ end  procedure;
 
         if (res_n = '0') then
             --pc l/h is reset vector.
-            pcl_cmd <= "1110";
+            pcl_cmd <= "1011";
             pch_cmd <= "1011";
             next_cycle <= R0;
         elsif (res_n'event and res_n = '1') then
@@ -252,7 +266,7 @@ end  procedure;
             if exec_cycle = T0 then
                 --cycle #1
                 fetch_inst;
-                --next_cycle <= T1;
+                next_cycle <= T1;
 
             elsif exec_cycle = T1 or exec_cycle = T2 or exec_cycle = T3 or 
                 exec_cycle = T4 or exec_cycle = T5 or exec_cycle = T6 or 
@@ -262,6 +276,10 @@ end  procedure;
                 if exec_cycle = T1 then
                     d_print("decode and execute inst: " 
                             & conv_hex8(conv_integer(instruction)));
+                    --disable pin for jmp/abs [xy] page boundary case.
+                    back_we(pcl_cmd, '1');
+                    back_we(pch_cmd, '1');
+
                     --grab instruction register data.
                     inst_we_n <= '1';
                 end if;
@@ -933,6 +951,11 @@ end  procedure;
             elsif exec_cycle = R0 then
                 d_print(string'("reset"));
 
+                next_cycle <= R1;
+                inst_we_n <= '1';
+                ad_oe_n <= '1';
+                dbuf_int_oe_n <= '1';
+                pc_inc_n <= '1';
                 pcl_cmd <= "1111";
                 pch_cmd <= "1111";
                 sp_cmd <= "1111";
@@ -940,8 +963,6 @@ end  procedure;
                 x_cmd <= "1111";
                 y_cmd <= "1111";
                 r_nw <= '1';
-
-                next_cycle <= R1;
             elsif exec_cycle = R1 then
                 next_cycle <= R2;
                 front_we(pch_cmd, '1');
index 1730304..4de5f6e 100644 (file)
@@ -38,6 +38,8 @@ component decoder
             status_reg      : inout std_logic_vector (dsize - 1 downto 0);
             inst_we_n       : out std_logic;
             ad_oe_n         : out std_logic;
+            dbuf_int_oe_n   : out std_logic;
+            pc_inc_n        : out std_logic;
             pcl_cmd         : out std_logic_vector(3 downto 0);
             pch_cmd         : out std_logic_vector(3 downto 0);
             sp_cmd          : out std_logic_vector(3 downto 0);
@@ -50,6 +52,33 @@ component decoder
         );
 end component;
 
+component alu
+    generic (   dsize : integer := 8
+            );
+    port (  clk             : in std_logic;
+            pc_inc_n        : in std_logic;
+            abs_ea_n        : in std_logic;
+            zp_ea_n         : in std_logic;
+            arith_en_n      : in std_logic;
+            instruction     : in std_logic_vector (dsize - 1 downto 0);
+            int_d_bus       : inout std_logic_vector (dsize - 1 downto 0);
+            acc_out         : in std_logic_vector (dsize - 1 downto 0);
+            acc_in          : out std_logic_vector (dsize - 1 downto 0);
+            index_bus       : in std_logic_vector (dsize - 1 downto 0);
+            bal             : in std_logic_vector (dsize - 1 downto 0);
+            bah             : in std_logic_vector (dsize - 1 downto 0);
+            abl             : out std_logic_vector (dsize - 1 downto 0);
+            abh             : out std_logic_vector (dsize - 1 downto 0);
+            pcl             : out std_logic_vector (dsize - 1 downto 0);
+            pch             : out std_logic_vector (dsize - 1 downto 0);
+            carry_in        : in std_logic;
+            negative        : out std_logic;
+            zero            : out std_logic;
+            carry_out       : out std_logic;
+            overflow        : out std_logic
+    );
+end component;
+
     ----------------------------------------------
     ------------ register declaration ------------
     ----------------------------------------------
@@ -143,6 +172,17 @@ end component;
     signal dl_al_oe_n : std_logic;
     signal dl_ah_oe_n : std_logic;
 
+    signal pc_inc_n : std_logic;
+    signal abs_ea_n : std_logic;
+    signal zp_ea_n : std_logic;
+    signal arith_en_n : std_logic;
+                    
+    signal alu_n : std_logic;
+    signal alu_z : std_logic;
+    signal alu_c_in : std_logic;
+    signal alu_c : std_logic;
+    signal alu_v : std_logic;
+
     ----control line for dual port registers.
     signal pcl_cmd : std_logic_vector(3 downto 0);
     signal pch_cmd : std_logic_vector(3 downto 0);
@@ -156,13 +196,18 @@ end component;
     -------------------------------
     signal instruction : std_logic_vector(dsize - 1 downto 0);
     
-    signal alu_h : std_logic_vector(dsize - 1 downto 0);
-    signal alu_l : std_logic_vector(dsize - 1 downto 0);
+    signal bah : std_logic_vector(dsize - 1 downto 0);
+    signal bal : std_logic_vector(dsize - 1 downto 0);
     signal index_bus : std_logic_vector(dsize - 1 downto 0);
 
     signal acc_in : std_logic_vector(dsize - 1 downto 0);
     signal acc_out : std_logic_vector(dsize - 1 downto 0);
 
+    signal pcl_in : std_logic_vector(dsize - 1 downto 0);
+    signal pch_in : std_logic_vector(dsize - 1 downto 0);
+    signal pcl_back : std_logic_vector(dsize - 1 downto 0);
+    signal pch_back : std_logic_vector(dsize - 1 downto 0);
+
     --not used bus.
     signal null_bus : std_logic_vector(dsize - 1 downto 0);
 
@@ -173,6 +218,14 @@ end component;
     ---internal data bus
     signal d_bus : std_logic_vector(dsize - 1 downto 0);
 
+    ---reset vectors---
+    signal reset_l : std_logic_vector(dsize - 1 downto 0);
+    signal reset_h : std_logic_vector(dsize - 1 downto 0);
+    signal nmi_l : std_logic_vector(dsize - 1 downto 0);
+    signal nmi_h : std_logic_vector(dsize - 1 downto 0);
+    signal irq_l : std_logic_vector(dsize - 1 downto 0);
+    signal irq_h : std_logic_vector(dsize - 1 downto 0);
+
     signal check_bit     : std_logic_vector(1 to 5);
 
 begin
@@ -183,7 +236,10 @@ begin
     phi2 <= not input_clk;
     set_clk <= input_clk;
     trigger_clk <= not input_clk;
+
     r_nw <= dbuf_r_nw;
+    reset_l <= "00000000";
+    reset_h <= "10000000";
 
 
     --------------------------------------------------
@@ -203,6 +259,8 @@ begin
                     status_reg, 
                     inst_we_n, 
                     ad_oe_n, 
+                    dbuf_int_oe_n,
+                    pc_inc_n,
                     pcl_cmd,
                     pch_cmd,
                     sp_cmd,
@@ -213,6 +271,30 @@ begin
                     , check_bit --check bit.
                     );
 
+    alu_inst : alu generic map (dsize) 
+            port map (trigger_clk, 
+                    pc_inc_n,
+                    abs_ea_n,
+                    zp_ea_n,
+                    arith_en_n,
+                    instruction,
+                    d_bus,
+                    acc_out,
+                    acc_in,
+                    index_bus,
+                    bal,
+                    bah,
+                    abl,
+                    abh,
+                    pcl_back,
+                    pch_back,
+                    alu_c_in,
+                    alu_n,
+                    alu_z,
+                    alu_c,
+                    alu_v 
+                    );
+
     --cpu execution cycle number
     exec_cycle_inst : d_flip_flop generic map (6) 
             port map(trigger_clk, '1', '1', '0', next_cycle, exec_cycle);
@@ -223,21 +305,21 @@ begin
 
     --address operand data buffer.
     idl_l : input_data_latch generic map (dsize) 
-            port map(set_clk, dl_al_oe_n, dl_al_we_n, alu_l, d_bus);
+            port map(set_clk, dl_al_oe_n, dl_al_we_n, bal, d_bus);
     idl_h : input_data_latch generic map (dsize) 
-            port map(set_clk, dl_ah_oe_n, dl_ah_we_n, alu_h, d_bus);
+            port map(set_clk, dl_ah_oe_n, dl_ah_we_n, bah, d_bus);
 
     -------- registers --------
     ir : d_flip_flop generic map (dsize) 
             port map(trigger_clk, '1', '1', inst_we_n, d_io, instruction);
 
     pc_l : dual_dff generic map (dsize) 
-            port map(trigger_clk, '1', rst_n, pcl_cmd, d_bus, abl, alu_l);
+            port map(trigger_clk, '1', rst_n, pcl_cmd, pcl_in, pcl_back, bal);
     pc_h : dual_dff generic map (dsize) 
-            port map(trigger_clk, '1', rst_n, pch_cmd, d_bus, abh, alu_h);
+            port map(trigger_clk, '1', rst_n, pch_cmd, pch_in, pch_back, bah);
 
     sp : dual_dff generic map (dsize) 
-            port map(trigger_clk, rst_n, '1', sp_cmd, d_bus, abl, alu_l);
+            port map(trigger_clk, rst_n, '1', sp_cmd, d_bus, abl, bal);
 
     x : dual_dff generic map (dsize) 
             port map(trigger_clk, rst_n, '1', x_cmd, d_bus, null_bus, index_bus);
@@ -247,9 +329,6 @@ begin
     acc : dual_dff generic map (dsize) 
             port map(trigger_clk, rst_n, '1', acc_cmd, d_bus, acc_in, acc_out);
 
-    ---temporarily...
-    abl <= alu_l;
-    abh <= alu_h;
     --adh output is controlled by decoder.
     adh_buf : tri_state_buffer generic map (dsize)
             port map (ad_oe_n, abh, addr(asize - 1 downto dsize));
@@ -263,11 +342,11 @@ begin
     begin
         if (rst_n = '0') then
             --reset vector set to pc.
-            d_bus <= "10000000";
-            abl <= "00000000";
+            pcl_in <= reset_l ;
+            pch_in <= reset_h ;
         else
-            d_bus <= (others => 'Z');
-            abl <= (others => 'Z');
+            pcl_in <= d_bus;
+            pch_in <= d_bus;
         end if;
     end process;