From 1c00d6412b896d3c18eb318743d0f382dca97c64 Mon Sep 17 00:00:00 2001 From: astoria-d Date: Mon, 17 Jun 2013 14:02:31 +0900 Subject: [PATCH] code re-write working... --- simulation/cpu/alu.vhd | 140 ++++++++++++++++++++++++++++----------- simulation/cpu/cpu_registers.vhd | 7 +- simulation/cpu/decoder.vhd | 31 +++++++-- simulation/cpu/mos6502.vhd | 107 ++++++++++++++++++++++++++---- 4 files changed, 221 insertions(+), 64 deletions(-) diff --git a/simulation/cpu/alu.vhd b/simulation/cpu/alu.vhd index 38072bd..b2044ce 100644 --- a/simulation/cpu/alu.vhd +++ b/simulation/cpu/alu.vhd @@ -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; diff --git a/simulation/cpu/cpu_registers.vhd b/simulation/cpu/cpu_registers.vhd index 0c56f26..dccd997 100644 --- a/simulation/cpu/cpu_registers.vhd +++ b/simulation/cpu/cpu_registers.vhd @@ -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; - diff --git a/simulation/cpu/decoder.vhd b/simulation/cpu/decoder.vhd index 4c163e8..00afdd5 100644 --- a/simulation/cpu/decoder.vhd +++ b/simulation/cpu/decoder.vhd @@ -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'); diff --git a/simulation/cpu/mos6502.vhd b/simulation/cpu/mos6502.vhd index 1730304..4de5f6e 100644 --- a/simulation/cpu/mos6502.vhd +++ b/simulation/cpu/mos6502.vhd @@ -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; -- 2.11.0