use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
+----d1 = acc
+----d2 = memory
entity alu_core is
generic ( dsize : integer := 8
);
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
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
----
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;
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;
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;
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
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");
zero <= 'Z';
carry_out <= 'Z';
overflow <= 'Z';
+
+ abl <= bal;
+ abh <= bah;
end if; --if (arith_en_n = '') then
end process;
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
end rtl;
------------------
-
----------------------------------------
--- data bus buffer
----------------------------------------
end rtl;
-
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);
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
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
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
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;
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";
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');
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);
);
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 ------------
----------------------------------------------
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);
-------------------------------
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);
---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
phi2 <= not input_clk;
set_clk <= input_clk;
trigger_clk <= not input_clk;
+
r_nw <= dbuf_r_nw;
+ reset_l <= "00000000";
+ reset_h <= "10000000";
--------------------------------------------------
status_reg,
inst_we_n,
ad_oe_n,
+ dbuf_int_oe_n,
+ pc_inc_n,
pcl_cmd,
pch_cmd,
sp_cmd,
, 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);
--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);
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));
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;