OSDN Git Service

- alu work started.
authorastoria-d <astoria-d@mail.goo.ne.jp>
Sat, 15 Jun 2013 04:41:38 +0000 (13:41 +0900)
committerastoria-d <astoria-d@mail.goo.ne.jp>
Sat, 15 Jun 2013 04:41:38 +0000 (13:41 +0900)
- cmp instruction ok.

simulation/cpu/alu.vhd
simulation/cpu/decoder.vhd
simulation/cpu/mos6502.vhd

index cca2f2f..e0d4f22 100644 (file)
@@ -3,11 +3,13 @@
 ----------------------------
 library ieee;
 use ieee.std_logic_1164.all;
+use ieee.std_logic_unsigned.all;
 
 entity alu is 
     generic (   dsize : integer := 8
             );
     port (  clk             : in std_logic;
+            alu_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_in          : in std_logic_vector (dsize - 1 downto 0);
@@ -21,10 +23,117 @@ entity alu is
 end alu;
 
 architecture rtl of alu is
-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);
+
+procedure d_print(msg : string) is
+use std.textio.all;
+use ieee.std_logic_textio.all;
+variable out_l : line;
+begin
+    write(out_l, msg);
+    writeline(output, out_l);
+end  procedure;
+
+begin
+
+    alu_p : process (alu_en_n)
+    variable res : 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;
+
+    begin
+    if (alu_en_n = '0') then
+            --instruction is aaabbbcc format.
+            if instruction (1 downto 0) = "01" then
+                if instruction (7 downto 5) = "000" then
+                    d_print("ora");
+                elsif instruction (7 downto 5) = "001" then
+                    d_print("and");
+                elsif instruction (7 downto 5) = "010" then
+                    d_print("eor");
+                elsif instruction (7 downto 5) = "011" then
+                    d_print("adc");
+                elsif instruction (7 downto 5) = "110" then
+                    d_print("cmp");
+                    --set n/v/z flag
+                    res := acc_in - int_d_bus;
+                    set_n(res);
+                    set_z(res);
+                    --ovf flag set when acc < mem .
+                    if (res(7) = '1') then
+                        overflow <= '1';
+                    else
+                        overflow <= '0';
+                    end if;
+
+                    --no register update.
+                    int_d_bus <= (others => 'Z');
+                    acc_out <= (others => 'Z');
+                    carry_out <= 'Z';
+
+                elsif instruction (7 downto 5) = "111" then
+                    d_print("sbc");
+                end if;
+            elsif instruction (1 downto 0) = "10" then
+                if instruction (7 downto 5) = "000" then
+                    d_print("asl");
+                elsif instruction (7 downto 5) = "001" then
+                    d_print("rol");
+                elsif instruction (7 downto 5) = "010" then
+                    d_print("lsr");
+                elsif instruction (7 downto 5) = "011" then
+                    d_print("ror");
+                elsif instruction (7 downto 5) = "100" then
+                    d_print("stx");
+                elsif instruction (7 downto 5) = "101" then
+                    d_print("ldx");
+                elsif instruction (7 downto 5) = "110" then
+                    d_print("dec");
+                elsif instruction (7 downto 5) = "111" then
+                    d_print("inc");
+                end if;
+            elsif instruction (1 downto 0) = "00" then
+                if instruction (7 downto 5) = "001" then
+                    d_print("bit");
+                elsif instruction (7 downto 5) = "010" then
+                    d_print("jmp");
+                elsif instruction (7 downto 5) = "011" then
+                    d_print("jmp");
+                elsif instruction (7 downto 5) = "100" then
+                    d_print("sty");
+                elsif instruction (7 downto 5) = "101" then
+                    d_print("ldy");
+                elsif instruction (7 downto 5) = "110" then
+                    d_print("cpy");
+                elsif instruction (7 downto 5) = "111" then
+                    d_print("cpx");
+                end if; --if instruction (7 downto 5) = "001" then
+            end if; --if instruction (1 downto 0) = "01"
+    else
+        int_d_bus <= (others => 'Z');
+        acc_out <= (others => 'Z');
+        negative <= 'Z';
+        zero <= 'Z';
+        carry_out <= 'Z';
+        overflow <= 'Z';
+    end if; --if (alu_en_n = '') then
+    end process;
 
 end rtl;
 
index 5695498..e7d0d84 100644 (file)
@@ -16,6 +16,7 @@ entity decoder is
             next_cycle      : out std_logic_vector (4 downto 0);
             status_reg      : inout std_logic_vector (dsize - 1 downto 0);
             inst_we_n       : out std_logic;
+            alu_en_n        : out std_logic;
             ad_oe_n         : out std_logic;
             pcl_inc_n       : out std_logic;
             pcl_d_we_n      : out std_logic;
@@ -197,6 +198,7 @@ begin
     pcl_inc_n <= '0';
 
     --disable the last opration pins.
+    alu_en_n <= '1';
     x_oe_n <= '1';
     y_oe_n <= '1';
     x_we_n <= '1';
@@ -266,6 +268,14 @@ begin
     status_reg <= "10000010";
 end  procedure;
 
+procedure set_nzv_from_alu is
+begin
+    --status register n/z/v bit update.
+    stat_alu_we_n <= '0';
+    stat_dec_oe_n <= '1';
+    status_reg <= "11000010";
+end  procedure;
+
 --flag on/off instruction
 procedure set_flag (int_flg : in integer; val : in std_logic) is
 begin
@@ -670,6 +680,9 @@ end  procedure;
                 elsif instruction  = conv_std_logic_vector(16#c9#, dsize) then
                     --imm
                     d_print("cmp");
+                    fetch_imm;
+                    alu_en_n <= '0';
+                    set_nzv_from_alu;
 
                 elsif instruction  = conv_std_logic_vector(16#c5#, dsize) then
                     --zp
@@ -1333,6 +1346,7 @@ end  procedure;
             elsif exec_cycle = R0 then
                 d_print(string'("reset"));
 
+                alu_en_n <= '1';
                 ad_oe_n <= '1';
                 pcl_d_we_n <= '1';
                 pcl_a_we_n <= '1';
index dfa8d93..a1e5855 100644 (file)
@@ -58,6 +58,7 @@ architecture rtl of mos6502 is
                 next_cycle      : out std_logic_vector (4 downto 0);
                 status_reg      : inout std_logic_vector (dsize - 1 downto 0);
                 inst_we_n       : out std_logic;
+                alu_en_n        : out std_logic;
                 ad_oe_n         : out std_logic;
                 pcl_inc_n       : out std_logic;
                 pcl_d_we_n      : out std_logic;
@@ -111,6 +112,27 @@ architecture rtl of mos6502 is
             );
     end component;
 
+
+    component alu
+        generic (   dsize : integer := 8
+                );
+        port (  clk             : in std_logic;
+                alu_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_in          : in std_logic_vector (dsize - 1 downto 0);
+                acc_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;
+
+    ----------------------------------------------
+    ---------- register declareration ------------
+    ----------------------------------------------
     component dff
         generic (
                 dsize : integer := 8
@@ -253,6 +275,9 @@ architecture rtl of mos6502 is
     );
     end component;
 
+    ----------------------------------------------
+    ------------ signal declareration ------------
+    ----------------------------------------------
     signal set_clk : std_logic;
     signal trigger_clk : std_logic;
 
@@ -291,6 +316,7 @@ architecture rtl of mos6502 is
     signal acc_d_we_n      : std_logic;
     signal acc_alu_we_n    : std_logic;
     signal acc_d_oe_n      : std_logic;
+    signal alu_en_n        : std_logic;
     signal alu_in          : std_logic_vector(dsize - 1 downto 0);
     signal alu_out         : std_logic_vector(dsize - 1 downto 0);
 
@@ -340,9 +366,12 @@ architecture rtl of mos6502 is
     signal status_reg : std_logic_vector (dsize - 1 downto 0);
 
     signal check_bit     : std_logic_vector(1 to 5);
+
 begin
 
-    ---instances....
+    ---------------------------------------
+    -------------- instances --------------
+    ---------------------------------------
     dec_inst : decoder generic map (dsize) 
             port map(set_clk, 
                     trigger_clk, 
@@ -355,6 +384,7 @@ begin
                     next_cycle,
                     status_reg, 
                     inst_we_n, 
+                    alu_en_n,
                     ad_oe_n, 
                     pcl_inc_n, 
                     pcl_d_we_n, 
@@ -406,6 +436,13 @@ begin
                     , check_bit --check bit.
                     );
 
+    alu_inst : alu generic map (dsize) 
+            port map (trigger_clk, alu_en_n, instruction, 
+                internal_dbus, alu_in, alu_out,
+                status_reg(0), 
+                alu_n, alu_z, alu_c, alu_v
+            );
+
     --cpu execution cycle number
     exec_cycle_inst : dff generic map (5) 
             port map(trigger_clk, '0', '0', next_cycle, exec_cycle);
@@ -495,6 +532,10 @@ begin
         end if;
     end process;
 
+------------------------------------------------------------
+------------------------ for debug... ----------------------
+------------------------------------------------------------
+
     dbg_p : process (set_clk)
 use std.textio.all;
 use ieee.std_logic_textio.all;