OpenCores
URL https://opencores.org/ocsvn/system05/system05/trunk

Subversion Repositories system05

[/] [system05/] [trunk/] [rtl/] [vhdl/] [cpu05.vhd] - Rev 5

Go to most recent revision | Compare with Previous | Blame | View Log

--===========================================================================--
--
--  S Y N T H E Z I A B L E    CPU05   6805 comaptible CPU
--
--  This core adheres to the GNU public license  
--
-- File name      : cpu05.vhd
--
-- Purpose        : 6805 compatible CPU
--                  Differences to 6805
--                  64 K addressing range
--                  stack starts at $00FF and is 128 bytes deep
--                  
-- Dependencies   : ieee.Std_Logic_1164
--                  ieee.std_logic_unsigned
--
-- Author         : John E. Kent      
--
--
--=====================================================================
--
-- Revision History
--
--=====================================================================
--
-- 0.0   6 Sept 2002 - John Kent - design started
-- 0.1  30 May  2004 - John Kent - Initial release
--
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
entity cpu05 is
	port (	
	 clk       : in  std_logic;
    rst       : in  std_logic;
    vma       : out std_logic;
    rw        : out std_logic;
    addr      : out std_logic_vector(15 downto 0);
    data_in   : in  std_logic_vector(7 downto 0);
	 data_out  : out std_logic_vector(7 downto 0);
	 irq_ext   : in  std_logic;
	 irq_timer : in  std_logic;
	 irq_uart  : in  std_logic );
end;
 
architecture cpu_arch of cpu05 is
	type state_type is (reset_state, reset1_state, reset2_state,
                       fetch_state, decode_state, exec_state, halt_state,
	                    brbit_state,
 							  branch_state, bsr_state, jsr_state, jsr1_state, jmp_state,
							  swi_state, stop_state,
							  rti_state, rti_cc_state, rti_ac_state, rti_ix_state, rti_pch_state, rti_pcl_state,
							  rts_state, rts_pch_state, rts_pcl_state,
							  wait_state, wait1_state, wait2_state, wait3_state, wait4_state,
							  int_state, int1_state, int2_state, int3_state, int4_state, int5_state, int6_state,
                       dir_state, ext_state, ix2_state, ix1_state, ix0_state,
						     write_state );
	type addr_type is (reset_addr, idle_addr, fetch_addr, read_addr, write_addr, push_addr, pull_addr, vect_hi_addr, vect_lo_addr );
	type data_type is (ac_data, ix_data, cc_data, md_data, pc_lo_data, pc_hi_data );
	type pc_type is (reset_pc, latch_pc, inc_pc, jmp_pc, bra_pc, pull_lo_pc, pull_hi_pc );
   type ea_type is (reset_ea, latch_ea, fetch_first_ea, fetch_next_ea, loadix_ea, addix_ea, addpc_ea );
   type op_type is (reset_op, latch_op, fetch_op );
   type ac_type is (reset_ac, latch_ac, load_ac, pull_ac );
	type ix_type is (reset_ix, latch_ix, load_ix, pull_ix );
	type sp_type is (reset_sp, latch_sp, load_sp, inc_sp, dec_sp );
   type cc_type is (reset_cc, latch_cc, load_cc, pull_cc );
	type md_type is (reset_md, latch_md, load_md, fetch_md );
	type iv_type is (latch_iv, rst_iv, swi_iv, irq_iv, tim_iv, uart_iv );
	type left_type  is (ac_left, ix_left, md_left );
	type right_type is (md_right, bset_right, bclr_right, zero_right, one_right );
   type alu_type   is (alu_add, alu_adc, alu_sub, alu_sbc,
                       alu_and, alu_ora, alu_eor,
                       alu_tst, alu_inc, alu_dec, alu_clr, alu_neg, alu_com,
						     alu_lsr, alu_lsl, alu_ror, alu_rol, alu_asr,
						     alu_sei, alu_cli, alu_sec, alu_clc,
							  alu_bset, alu_bclr, alu_btst,
						     alu_ld, alu_st, alu_nop );
 
  constant HFLAG : integer := 4;
  constant IFLAG : integer := 3;
  constant NFLAG : integer := 2;
  constant ZFLAG : integer := 1;
  constant CFLAG : integer := 0;
 
	--
	-- internal registers
	--
  	signal ac:          std_logic_vector(7 downto 0);	-- accumulator
	signal ix:          std_logic_vector(7 downto 0);  -- index register
	signal sp:          std_logic_vector(6 downto 0);  -- stack pointer
	signal cc:          std_logic_vector(4 downto 0);  -- condition codes from alu
	signal pc:	        std_logic_vector(15 downto 0); -- program counter for opcode access
	signal ea:          std_logic_vector(15 downto 0); -- effective addres for memory access
	signal op:          std_logic_vector(7 downto 0);  -- opcode register
	signal md:          std_logic_vector(7 downto 0);  -- memory data
	signal iv:          std_logic_vector(2 downto 0);  -- interrupt vector number
	signal state:       state_type;
 
	--
	-- unregistered signals
	-- (combinational logic)
	--
   signal alu_left:    std_logic_vector(8 downto 0);  -- alu left input (bit 8 for carry)
   signal alu_right:   std_logic_vector(8 downto 0);  -- alu right input
	signal alu_out:     std_logic_vector(8 downto 0);  -- alu result output (unlatched)
	signal cc_out:      std_logic_vector(4 downto 0);  -- alu condition code outout (unlatched)
	signal bset_data_out: std_logic_vector(7 downto 0);
	signal bclr_data_out: std_logic_vector(7 downto 0);
	signal next_state:  state_type;
 
   --
	-- Syncronous Register Controls
	--
	signal ac_ctrl:     ac_type;
	signal ix_ctrl:     ix_type;
	signal sp_ctrl:     sp_type;
	signal cc_ctrl:     cc_type;
   signal pc_ctrl:     pc_type;
   signal ea_ctrl:     ea_type; 
   signal op_ctrl:     op_type;
	signal md_ctrl:     md_type;
   signal iv_ctrl:     iv_type;
 
	--
	-- Asynchronous Multiplexer Controls
	--
	signal addr_ctrl:   addr_type;       -- address bus mutiplexer
	signal data_ctrl: data_type;   -- data output mutiplexer
   signal left_ctrl:   left_type;       -- Left ALU input
	signal right_ctrl:  right_type;     -- Right ALU input
   signal alu_ctrl:    alu_type;        -- ALU opeartion
 
   --
	-- bit set decoder table
	--
   component bset_rom is
     port (
       addr     : in  Std_Logic_Vector(2 downto 0);
	    data     : out Std_Logic_Vector(7 downto 0)
     );
   end component bset_rom;
   --
	-- bit clear decoder table
	--
   component bclr_rom is
     port (
       addr     : in  Std_Logic_Vector(2 downto 0);
	    data     : out Std_Logic_Vector(7 downto 0)
     );
   end component bclr_rom;
 
begin
 
   rom_set : bset_rom port map (
	  addr       => op(3 downto 1),
     data       => bset_data_out
	  );
 
   rom_clear : bclr_rom port map (
 	  addr       => op(3 downto 1),
     data       => bclr_data_out
	  );
 
 
----------------------------------
--
-- opcode register
--
----------------------------------
 
op_reg: process( clk, op_ctrl, data_in, op )
begin
  if clk'event and clk = '0' then
    case op_ctrl is
	 when reset_op =>
	   op <= "10011101";	-- reset with NOP
  	 when fetch_op =>
      op <= data_in;
	 when others =>
--	 when latch_op =>
	   op <= op;
    end case;
  end if;
end process;
 
-----------------------------------
--
-- accumulator
--
------------------------------------
ac_reg : process( clk, ac_ctrl, alu_out, ac, ix, data_in )
begin
   if clk'event and clk = '0' then
     case ac_ctrl is
     when reset_ac =>             -- released from reset
	    ac <= "00000000";
	  when load_ac =>               -- single or dual operation
  	    ac <= alu_out(7 downto 0);
	  when pull_ac =>                -- read acc / increment sp
		 ac <= data_in;
  	  when others =>               -- halt on undefine states
--	  when latch_ac =>             -- no operation on acc
	    ac <= ac;
     end case;						
  end if;
end process;
 
------------------------------------
--
-- condition code register
--
------------------------------------
cc_reg : process( clk, cc_ctrl, cc_out  )
begin
  if clk'event and clk = '0' then
     case cc_ctrl is
     when reset_cc =>             -- released from reset
	    cc <= "00000";
	  when load_cc =>               -- single or dual operation
  	    cc <= cc_out;
	  when pull_cc =>                -- read cc / increment sp
		 cc <= data_in(4 downto 0);
  	  when others =>               -- halt on undefine states
--	  when latch_cc =>             -- no operation on acc
	    cc <= cc;
     end case;						
  end if;
end process;
 
------------------------------------
--
-- index register
--
------------------------------------
ix_reg : process( clk, ix_ctrl, alu_out, ac, ix, data_in )
begin
  if clk'event and clk = '0' then
    case ix_ctrl is
     when reset_ix =>                 -- released from reset
	    ix <= "00000000";
	  when load_ix =>                   -- execute /  = alu out
	    ix <= alu_out(7 downto 0);
	  when pull_ix =>                    -- read ixreg / increment sp
		 ix <= data_in;
  	  when others =>
--	  when latch_ix =>                 -- no change in ix
	    ix <= ix;
    end case;						
  end if;
end process;
 
 
------------------------------------
--
-- stack pointer
--
------------------------------------
sp_reg : process( clk, sp_ctrl, sp )
begin
  if clk'event and clk = '0' then
    case sp_ctrl is
     when reset_sp =>                 -- released from reset
       sp <= "1111111";
	  when inc_sp =>                   -- pop registers
	    sp <= sp + 1;
     when dec_sp =>                   -- push registes
		 sp <= sp - 1;
  	  when others =>
--	  when latch_sp =>                 -- no change in sp
 	    sp <= sp;
    end case;						
  end if;
end process;
 
------------------------------------
--
-- program counter
--
------------------------------------
pc_reg : process( clk, pc_ctrl, pc, ea, data_in )
variable offset : std_logic_vector(15 downto 0);
begin
  if clk'event and clk = '0' then
    case pc_ctrl is
     when reset_pc =>                 -- released from reset
       pc <= "0000000000000000";
	  when inc_pc =>                   -- fetch next opcode
	    pc <= pc + 1;
     when jmp_pc =>                   -- load pc with effective address
		 pc <= ea;
     when bra_pc =>                   -- add effective address to pc
	    if ea(7) = '0' then				  -- sign extend offset
		   offset := "00000000" & ea(7 downto 0);
       else
		   offset := "11111111" & ea(7 downto 0);
		 end if;
		 pc <= pc + offset;
     when pull_lo_pc =>               -- load pc lo byte from memory
		 pc(15 downto 8) <= pc(15 downto 8);
		 pc(7 downto 0)  <= data_in;
     when pull_hi_pc =>               -- load pc hi byte from memory
		 pc(15 downto 8) <= data_in;
		 pc(7 downto 0)  <= pc(7 downto 0);
	  when others =>                   -- halt on undefine states
--	  when latch_pc =>                 -- no change in pc
 	    pc <= pc;
    end case;						
  end if;
end process;
 
------------------------------------
--
-- effective address register
--
------------------------------------
ea_reg: process( clk, ea_ctrl, ea, pc, ix, data_in )
variable offset : std_logic_vector(15 downto 0);
begin
  if clk'event and clk = '0' then
    case ea_ctrl is
     when reset_ea =>                     -- released from reset / fetch
       ea <= "0000000000000000";
	  when loadix_ea =>                    -- load ea with index register
	    ea <= "00000000" & ix;
	  when addpc_ea =>                     -- add pc to ea
	    if ea(7) = '0' then				  -- sign extend offset
		   offset := "00000000" & ea(7 downto 0);
       else
		   offset := "11111111" & ea(7 downto 0);
		 end if;
	    ea <= offset + pc;
     when addix_ea =>                     -- add index register to ea
		 ea <= ea + ("00000000" & ix );
     when fetch_first_ea =>               -- load ea lo byte from memory
		 ea(15 downto 8) <= "00000000";
		 ea(7 downto 0) <= data_in;
     when fetch_next_ea =>               -- load ea with second from memory
		 ea(15 downto 8) <= ea(7 downto 0);
		 ea(7 downto 0) <= data_in;
  	  when others =>                   -- halt on undefine states
--	  when latch_ea =>                 -- no change in ea
	    ea <= ea;
    end case;						
  end if;
end process;
 
----------------------------------
--
-- memory data register 
-- latch memory byte input
--
----------------------------------
 
md_reg: process( clk, md_ctrl, data_in, md )
begin
  if clk'event and clk = '0' then
    case md_ctrl is
	 when reset_md =>
	   md <= "00000000";
	 when latch_md =>
	   md <= md;
  	 when load_md =>                  -- latch alu output
      md <= alu_out(7 downto 0);
  	 when fetch_md =>
      md <= data_in;
	 when others =>
      null;
    end case;
  end if;
end process;
 
----------------------------------
--
-- interrupt vector register
--
----------------------------------
 
iv_reg: process( clk, iv_ctrl, iv )
begin
  if clk'event and clk = '0' then
    case iv_ctrl is
	 when rst_iv =>
	   iv <= "111"; -- $FFFE/$FFFF
	 when swi_iv =>
	   iv <= "110"; -- $FFFC/$FFFD
  	 when irq_iv =>
      iv <= "101"; -- $FFFA/$FFFB
	 when tim_iv =>
	   iv <= "100"; -- $FFF8/$FFF9
    when uart_iv =>
	   iv <= "011"; -- $FFFA/$FFFB
	 when others =>
--	 when latch_iv =>
	   iv <= iv;
    end case;
  end if;
end process;
 
----------------------------------
--
-- Address output multiplexer
-- Work out which register to apply to the address bus
-- Note that the multiplexer output is asyncronous
--
----------------------------------
 
mux_addr: process( clk, addr_ctrl, pc, ea, sp, iv )
begin
   case addr_ctrl is
     when reset_addr =>                 -- when held in reset
       addr <= "1111111111111111";
  		 vma  <= '0';
		 rw   <= '1';
	  when fetch_addr =>                 -- fetch opcode from pc
		 addr <= pc;
  		 vma  <= '1';
		 rw   <= '1';
	  when read_addr =>                  -- read from memory
	    addr <= ea;
		 vma  <= '1';
		 rw   <= '1';
	  when write_addr =>                 -- write to memory
	    addr <= ea;
		 vma  <= '1';
		 rw   <= '0';
	  when pull_addr =>                  -- read from stack
	    addr <= ("000000001" & sp);
		 vma  <= '1';
		 rw   <= '1';
	  when push_addr =>                  -- write to stack
	    addr <= ("000000001" & sp);
		 vma  <= '1';
		 rw   <= '0';
	  when vect_hi_addr =>               -- fetch interrupt vector hi
	    addr <= "111111111111" & iv & "0";
		 vma  <= '1';
		 rw   <= '1';
	  when vect_lo_addr =>               -- fetch interrupt vector lo
	    addr <= "111111111111" & iv & "1";
		 vma  <= '1';
		 rw   <= '1';
  	  when others =>                   -- undefined all high
       addr <= "1111111111111111";
  		 vma  <= '0';
		 rw   <= '1';
   end case;						
end process;
 
----------------------------------
--
-- Data Output Multiplexer
-- select data to be written to memory
-- note that the output is asynchronous
--
----------------------------------
 
mux_data: process( clk, data_ctrl, md, pc, cc, ac, ix )
variable data_out_v : std_logic_vector(7 downto 0);
begin
    case data_ctrl is
  	 when cc_data =>                   -- save condition codes
      data_out <= "000" & cc;
  	 when ac_data =>                   -- save accumulator
      data_out <= ac;
  	 when ix_data =>                   -- save index register
      data_out <= ix;
  	 when pc_lo_data =>                  -- save pc low byte
      data_out <= pc(7 downto 0);
  	 when pc_hi_data =>
      data_out <= pc(15 downto 8); -- save pc high byte
	 when others =>
--  	 when md_data =>                  -- alu latched output
      data_out <= md;
    end case;
end process;
 
----------------------------------
--
-- alu left mux
-- asynchronous input as register is already latched
--
----------------------------------
 
mux_left: process( clk, left_ctrl, ac, ix, md )
begin
    case left_ctrl is
	 when ac_left =>
	   alu_left <= "0" & ac; -- dual op argument
	 when ix_left =>
	   alu_left <= "0" & ix; -- dual op argument
	 when md_left =>
	   alu_left <= "0" & md;
	 when others =>
      alu_left <= "000000000";
    end case;
end process;
 
 
----------------------------------
--
-- alu right mux
-- asynchronous input as register is already latched
--
----------------------------------
 
mux_right: process( clk, right_ctrl, data_in, bset_data_out, bclr_data_out, md )
begin
    case right_ctrl is
	 when bset_right =>
	   alu_right <= "0" & bset_data_out;
	 when bclr_right =>
      alu_right <= "0" & bclr_data_out;
	 when zero_right =>
	   alu_right <= "000000000";
	 when one_right =>
	   alu_right <= "000000001";
	 when others =>
--	 when md_right =>
	   alu_right <= "0" & md; -- dual op argument
  end case;
end process;
 
 
----------------------------------
--
-- Arithmetic Logic Unit
--
----------------------------------
 
mux_alu: process( clk, alu_ctrl, cc, alu_left, alu_right )
variable alu_v   : std_logic_vector(8 downto 0);
variable low_v   : std_logic_vector(4 downto 0);
variable high_v  : std_logic_vector(4 downto 0);
begin
 
    case alu_ctrl is
  	 when alu_bset =>
	   alu_v := alu_left or alu_right; 	-- bit
  	 when alu_bclr =>
	   alu_v := alu_left and alu_right; 	-- bclr
  	 when alu_btst =>
	   alu_v := alu_left and alu_right; 	-- tst
  	 when alu_add =>
		low_v   := ("0" & alu_left(3 downto 0)) + ("0" & alu_right(3 downto 0));
		high_v  := ("0" & alu_left(7 downto 4)) + ("0" & alu_right(7 downto 4)) + low_v(4);
	   alu_v   := high_v(4 downto 0) & low_v(3 downto 0); 	-- add
  	 when alu_adc =>
		low_v   := ("0" & alu_left(3 downto 0)) + ("0" & alu_right(3 downto 0)) + ("0000" & cc(CFLAG));
		high_v  := ("0" & alu_left(7 downto 4)) + ("0" & alu_right(7 downto 4)) + low_v(4);
	   alu_v   := high_v(4 downto 0) & low_v(3 downto 0); 	-- adc
  	 when alu_sub =>
	   alu_v   := alu_left - alu_right; 	-- sub / cmp
  	 when alu_sbc =>
	   alu_v   := alu_left - alu_right - ("00000000" & cc(CFLAG)); 	-- sbc
  	 when alu_and =>
	   alu_v   := alu_left and alu_right; 	-- and/bit
  	 when alu_ora =>
	   alu_v   := alu_left or alu_right; 	-- or
  	 when alu_eor =>
	   alu_v   := alu_left xor alu_right; 	-- eor/xor
  	 when alu_lsl =>
	   alu_v   := alu_left(7 downto 0) & "0"; 	-- lsl
  	 when alu_lsr =>
	   alu_v   := alu_left(0) & "0" & alu_left(7 downto 1); 	-- lsr
  	 when alu_asr =>
	   alu_v   := alu_left(0) & alu_left(7) & alu_left(7 downto 1); 	-- asr
  	 when alu_rol =>
	   alu_v   := alu_left(7 downto 0) & cc(CFLAG); 	-- rol
  	 when alu_ror =>
	   alu_v   := alu_left(0) & cc(CFLAG) & alu_left(7 downto 1); 	-- ror
  	 when alu_inc =>
	   alu_v   := alu_left + "000000001"; 	-- inc
  	 when alu_dec =>
	   alu_v   := alu_left(8 downto 0) - "000000001"; -- dec
  	 when alu_neg =>
	   alu_v   := "000000000" - alu_left(8 downto 0); 	-- neg
  	 when alu_com =>
	   alu_v   := not alu_left(8 downto 0); 	-- com
  	 when alu_clr =>
	   alu_v  := "000000000"; 	   -- clr
	 when alu_ld =>
	   alu_v  := alu_right(8 downto 0);
	 when alu_st =>
	   alu_v  := alu_left(8 downto 0);
  	 when others =>
	   alu_v  := alu_left(8 downto 0); -- nop
    end case;
 
	 --
	 -- carry bit
	 --
    case alu_ctrl is
  	 when alu_add | alu_adc | alu_sub | alu_sbc | 
  	      alu_lsl | alu_lsr | alu_rol | alu_ror | alu_asr |
  	      alu_neg | alu_com =>
      cc_out(CFLAG) <= alu_v(8);
	 when alu_btst =>
      cc_out(CFLAG) <= not( alu_v(7) or alu_v(6) or alu_v(5) or alu_v(4) or
	                   alu_v(3) or alu_v(2) or alu_v(1) or alu_v(0) );
  	 when alu_sec =>
      cc_out(CFLAG) <= '1';
  	 when alu_clc =>
      cc_out(CFLAG) <= '0';
  	 when others =>
      cc_out(CFLAG) <= cc(CFLAG);
    end case;
 
	 --
	 -- Zero flag
	 --
    case alu_ctrl is
  	 when alu_add | alu_adc | alu_sub | alu_sbc |
  	      alu_and | alu_ora | alu_eor |
  	      alu_lsl | alu_lsr | alu_rol | alu_ror | alu_asr |
  	      alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
		   alu_ld  | alu_st =>
      cc_out(ZFLAG) <= not( alu_v(7) or alu_v(6) or alu_v(5) or alu_v(4) or
	                         alu_v(3) or alu_v(2) or alu_v(1) or alu_v(0) );
  	 when others =>
      cc_out(ZFLAG) <= cc(ZFLAG);
    end case;
 
    --
	 -- negative flag
	 --
    case alu_ctrl is
  	 when alu_add | alu_adc | alu_sub | alu_sbc |
	      alu_and | alu_ora | alu_eor |
  	      alu_lsl | alu_lsr | alu_rol | alu_ror | alu_asr |
  	      alu_inc | alu_dec | alu_neg | alu_com | alu_clr |
			alu_ld  | alu_st =>
      cc_out(NFLAG) <= alu_v(7);
  	 when others =>
      cc_out(NFLAG) <= cc(NFLAG);
    end case;
 
    --
	 -- Interrupt mask flag
    --
    case alu_ctrl is
  	 when alu_sei =>
		cc_out(IFLAG) <= '1';               -- set interrupt mask
  	 when alu_cli =>
		cc_out(IFLAG) <= '0';               -- clear interrupt mask
  	 when others =>
		cc_out(IFLAG) <= cc(IFLAG);             -- interrupt mask
    end case;
 
    --
    -- Half Carry flag
	 --
    case alu_ctrl is
  	 when alu_add | alu_adc =>
		cc_out(HFLAG) <= low_v(4);
  	 when others =>
		cc_out(HFLAG) <= cc(HFLAG);
    end case;
 
	 alu_out <= alu_v;
 
end process;
 
 
------------------------------------
--
-- state sequencer
--
------------------------------------
 
sequencer : process( state, data_in, 
                     ac, cc, ix, sp, ea, md, pc, op,
                     irq_ext, irq_timer, irq_uart )
begin
		  case state is
--
-- RESET:
-- Here if processor held in reset
-- On release of reset go to RESET1
--
          when reset_state =>        -- release from reset
	         ac_ctrl    <= reset_ac;
	         cc_ctrl    <= reset_cc;
	         ix_ctrl    <= reset_ix;
	         sp_ctrl    <= reset_sp;
            pc_ctrl    <= reset_pc;
            op_ctrl    <= reset_op;
            ea_ctrl    <= reset_ea; 
	         md_ctrl    <= reset_md;
				iv_ctrl    <= rst_iv;
            left_ctrl  <= ac_left;        -- Left ALU input
	         right_ctrl <= md_right;       -- Right ALU input
            alu_ctrl   <= alu_nop;        -- ALU opeartion
	         addr_ctrl  <= reset_addr;     -- address bus mutiplexer
	         data_ctrl  <= md_data;        -- data output mutiplexer
			   next_state <= reset1_state;
--
-- RESET1:
-- address bus = reset vector hi
-- Load PC high with high byte
-- go to RESET2
--
          when reset1_state =>        -- fetch hi reset vector
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
				 pc_ctrl    <= pull_hi_pc;
             op_ctrl    <= latch_op;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= vect_hi_addr;
	          data_ctrl  <= md_data;       -- data output mutiplexer
			    next_state <= reset2_state;
--
-- RESET2:
-- address bus = reset vector lo
-- Load PC low with low byte
-- go to FETCH
-- 
          when reset2_state =>        -- fetch low reset vector
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
				 pc_ctrl    <= pull_lo_pc;
             op_ctrl    <= latch_op;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= vect_lo_addr;
	          data_ctrl  <= md_data;       -- data output mutiplexer
			    next_state <= fetch_state;
--
-- FETCH:
-- fetch opcode,
-- advance the pc,
-- clear the effective address (ea) register
-- goto DECODE
--
          when fetch_state =>         -- fetch instruction
             case op(7 downto 4) is
--				 when "0000" =>				-- BRSET/ BRCLR
--				   null;
--				 when "0001" =>				-- BSET/ BCLR
--				   null;
--				 when "0010" =>				-- BR conditional
--				   null;
--				 when "0011" =>				--	single op direct
--				   null;
				 when "0100" =>            -- single op accum
  	            ac_ctrl    <= load_ac;
					cc_ctrl    <= load_cc;
	            ix_ctrl    <= latch_ix;
	            sp_ctrl    <= latch_sp;
					left_ctrl  <= ac_left;
				   case op( 3 downto 0 ) is
				   when "0000" =>            -- neg
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_neg;
				   when "0011" =>            -- com
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_com;
				   when "0100" =>            -- lsr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_lsr;
				   when "0110" =>            -- ror
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_ror;
				   when "0111" =>            -- asr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_asr;
				   when "1000" =>            -- lsl
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_lsl;
				   when "1001" =>            -- rol
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_rol;
				   when "1010" =>            -- dec
					  right_ctrl <= one_right;
					  alu_ctrl   <= alu_dec;
				   when "1011" =>            -- undef
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
				   when "1100" =>            -- inc
					  right_ctrl <= one_right;
					  alu_ctrl   <= alu_inc;
				   when "1101" =>            -- tst
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_tst;
				   when "1110" =>            -- undef
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
				   when "1111" =>            -- clr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_clr;
					when others =>
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
					end case;
 
				 when "0101" =>            -- single op ix reg
  	            ac_ctrl    <= latch_ac;
					cc_ctrl    <= load_cc;
	            ix_ctrl    <= load_ix;
	            sp_ctrl    <= latch_sp;
					left_ctrl  <= ix_left;
				   case op( 3 downto 0 ) is
				   when "0000" =>            -- neg
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_neg;
				   when "0011" =>            -- com
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_com;
				   when "0100" =>            -- lsr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_lsr;
				   when "0110" =>            -- ror
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_ror;
				   when "0111" =>            -- asr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_asr;
				   when "1000" =>            -- lsl
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_lsl;
				   when "1001" =>            -- rol
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_rol;
				   when "1010" =>            -- dec
					  right_ctrl <= one_right;
					  alu_ctrl   <= alu_dec;
				   when "1011" =>            -- undef
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
				   when "1100" =>            -- inc
					  right_ctrl <= one_right;
					  alu_ctrl   <= alu_inc;
				   when "1101" =>            -- tst
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_tst;
				   when "1110" =>            -- undef
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
				   when "1111" =>            -- clr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_clr;
					when others =>
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
					end case;
--           when "0110" =>            -- single op IX1
--             null;
--           when "0111" =>            -- single op IX0
--             null;
--           when "1000" =>            -- inherent stack operators
--             null;
				 when "1001" =>            -- inherent operators
				   case op( 3 downto 0 ) is
--				   when "0000" =>            -- undef
--					  null;
--     		   when "0001" =>            -- undef
--					  null;
-- 				when "0010" =>            -- undef
--					  null;
--				   when "0011" =>            -- undef
--					  null;
--				   when "0100" =>            -- undef
--					  null;
--				   when "0101" =>            -- undef
--					  null;
--				   when "0110" =>            -- undef
--					  null;
				   when "0111" =>            -- tax
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= latch_cc;
                 ix_ctrl    <= load_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_st;
 
				   when "1000" =>            -- clc
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_clc;
 
				   when "1001" =>            -- sec
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_sec;
 
				   when "1010" =>            -- cli
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_cli;
 
				   when "1011" =>            -- sei
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_sei;
 
				   when "1100" =>            -- rsp
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= latch_cc;
                 ix_ctrl    <= latch_ix;
					  sp_ctrl    <= reset_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_nop;
 
--				   when "1101" =>            -- nop
--					  null;
--				   when "1110" =>            -- undef
--					  null;
				   when "1111" =>            -- txa
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= latch_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ix_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_st;
 
					when others =>
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= latch_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ix_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_nop;
					end case;
             --
			    -- dual operand addressing modes
			    --
				 when "1010" |            -- dual op imm
				      "1011" |            -- dual op dir
				      "1100" |            -- dual op ext
				      "1101" |            -- dual op ix2
				      "1110" |            -- dual op ix1
				      "1111" =>           -- dual op ix0
				   case op( 3 downto 0 ) is
				   when "0000" =>            -- sub
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_sub;
 				   when "0001" =>            -- cmp
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_sub;
 				   when "0010" =>            -- sbc
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_sbc;
				   when "0011" =>            -- cpx
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ix_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_sub;
				   when "0100" =>            -- and
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_and;
				   when "0101" =>            -- bit
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_and;
				   when "0110" =>            -- lda
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_ld;
				   when "0111" =>            -- sta
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_st;
				   when "1000" =>            -- eor
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_eor;
				   when "1001" =>            -- adc
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_adc;
				   when "1010" =>            -- ora
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_ora;
				   when "1011" =>            -- add
                 ac_ctrl    <= load_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_add;
--				   when "1100" =>            -- jmp
--					  null;
--				   when "1101" =>            -- jsr
--					  null;
				   when "1110" =>            -- ldx
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= load_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ix_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_ld;
				   when "1111" =>            -- stx
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= load_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ix_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_st;
					when others =>
                 ac_ctrl    <= latch_ac;
					  cc_ctrl    <= latch_cc;
                 ix_ctrl    <= latch_ix;
	              sp_ctrl    <= latch_sp;
					  left_ctrl  <= ac_left;
					  right_ctrl <= md_right;
					  alu_ctrl   <= alu_nop;
					end case;
				 when others =>
               ac_ctrl    <= latch_ac;
					cc_ctrl    <= latch_cc;
               ix_ctrl    <= latch_ix;
	            sp_ctrl    <= latch_sp;
					left_ctrl  <= ac_left;
					right_ctrl <= md_right;
					alu_ctrl   <= alu_nop;
				 end case;
 
             ea_ctrl    <= latch_ea; 
             md_ctrl    <= latch_md;
				 pc_ctrl    <= inc_pc;
             op_ctrl    <= fetch_op;
				 addr_ctrl  <= fetch_addr;
	          data_ctrl  <= md_data;       -- data output mutiplexer
             if irq_ext = '1' and cc(IFLAG) = '0' then
				   iv_ctrl    <= irq_iv;
					next_state <= int_state;
				 elsif irq_timer = '1' and cc(IFLAG) = '0' then
				   iv_ctrl    <= tim_iv;
					next_state <= int_state;
				 elsif irq_uart = '1' and cc(IFLAG) = '0' then
				   iv_ctrl    <= uart_iv;
					next_state <= int_state;
				 else
	            iv_ctrl    <= latch_iv;
			      next_state <= decode_state;
				 end if;
--
-- DECODE:
-- decode the new opcode, 
-- fetch the next byte into the low byte of the ea ,
-- work out if you need to advance the pc, (two or three byte op)
-- work out the next state based on the addressing mode.
-- evaluate conditional branch execution
--
          when decode_state =>             -- decode instruction / fetch next byte
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= fetch_first_ea; 
	          md_ctrl    <= fetch_md;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= fetch_addr;
	          data_ctrl  <= md_data;       -- data output mutiplexer
	   		 case op(7 downto 4) is -- addressing modes
				 --
				 -- branch on bit set / clear
				 --
	 	    	 when "0000" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc
				   next_state <= dir_state;
				 --
				 -- bit set / clear direct page
				 --
				 when "0001" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc
				   next_state <= dir_state;
				 --
				 -- branch on condition codes
             --   if condtion = true
             --       go to "branch" state
             --   if conition = false
             --       go to "fetch" state
				 --
				 when "0010" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc
				   case op(3 downto 0) is
					when "0000" => -- bra
					  next_state <= branch_state;
					when "0001" => -- brn
					  next_state <= fetch_state;
					when "0010" => -- bhi
					  if cc(CFLAG) = '0' and cc(ZFLAG) = '0' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "0011" => -- bls
					  if cc(CFLAG) = '1' or cc(ZFLAG) = '1' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "0100" => -- bcc
					  if cc(CFLAG) = '0' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "0101" => -- bcs
					  if cc(CFLAG) = '1' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "0110" => -- bne
					  if cc(ZFLAG) = '0' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "0111" => -- beq
					  if cc(ZFLAG) = '1' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1000" => -- bhcc
					  if cc(HFLAG) = '0' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1001" => -- bhcs
					  if cc(HFLAG) = '1' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1010" => -- bpl
					  if cc(NFLAG) = '0' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1011" => -- bmi
					  if cc(NFLAG) = '1' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1100" => -- bmc
					  if cc(IFLAG) = '0' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1101" => -- bms
					  if cc(IFLAG) = '1' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1110" => -- bil
					  if irq_ext = '0' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when "1111" => -- bih
					  if irq_ext = '1' then
					    next_state <= branch_state;
					  else
					    next_state <= fetch_state;
					  end if;
					when others =>
					  null;
					end case; -- end of conditional branch decode
				 --
				 -- Single Operand direct addressing
				 --
				 when "0011" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc (2 byte instruction)
				   next_state <= dir_state;
				 --
				 -- Single Operand accumulator
				 --
				 when "0100" =>
 				   pc_ctrl    <= latch_pc;
				   next_state <= fetch_state;
				 --
				 -- Single Operand index register
				 --
				 when "0101" =>
 				   pc_ctrl    <= latch_pc;
				   next_state <= fetch_state;
				 --
				 -- Single Operand memory 8 bit indexed
				 --
				 when "0110" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc (2 byte instruction)
				   next_state <= ix1_state;
				 --
				 -- Single Operand memory 0 bit indexed
				 --
				 when "0111" =>
 				   pc_ctrl    <= latch_pc;     -- hold the pc (1 byte instruction)
				   next_state <= ix0_state;
             --
				 -- stack and interrupt operators
				 --
  				 when "1000" =>
 				   pc_ctrl    <= latch_pc;
				   case op(3 downto 0) is
					when "0000" =>
					  next_state <= rti_state;
					when "0001" =>
					  next_state <= rts_state;
               when "0011" =>
					  next_state <= swi_state;
 				   when "1110" =>
					  next_state <= stop_state;
					when "1111" =>
					  next_state <= wait_state;
					when others =>
					  next_state <= fetch_state;
					end case; -- end of stack decode
				 --
				 -- Inherent operators
				 --
				 when "1001" =>
 				   pc_ctrl    <= latch_pc;
					next_state <= fetch_state;
				 --
				 -- dual operand immediate addressing
				 --
	          when "1010" =>
 				   pc_ctrl   <= inc_pc;     -- advance the pc (2 byte instruction)
				   case op(3 downto 0) is
					when "1101" => -- bsr
					  next_state <= bsr_state;
					when others =>
					  next_state <= fetch_state;
					end case;
				 --
				 -- dual operand direct addressing
				 --
				 when "1011" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc (2 byte instruction)
					next_state <= dir_state;
				 --
				 -- dual operand extended addressing
				 --
			    when "1100" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc (3 byte instruction)
				   next_state <= ext_state;
				 --
				 -- dual operand 16 bit indexed addressing
				 --
				 when "1101" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc (3 byte instruction)
					next_state <= ix2_state;
				 --
				 -- dual operand 8 bit indexed addressing
				 --
			    when "1110" =>
 				   pc_ctrl    <= inc_pc;     -- advance the pc (3 byte instruction)
					next_state <= ix1_state;
				 --
				 -- dual operand direct page indexed addressing
				 --
				 when "1111" =>
 				   pc_ctrl    <= latch_pc;
					next_state <= ix0_state;
             --
				 -- catch undefined states
				 --
				 when others =>
 				   pc_ctrl    <= latch_pc;
				   next_state <= fetch_state;
				 end case; 
				 -- end of instruction decode state
			  --
			  -- perform addressing state sequence
			  --
			  when ext_state => -- fetch second address byte
  	          ac_ctrl    <= latch_ac;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
	          cc_ctrl    <= latch_cc;
 				 pc_ctrl    <= inc_pc;
             ea_ctrl    <= fetch_next_ea; 
             op_ctrl    <= latch_op;
	          md_ctrl    <= latch_md;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= fetch_addr;     -- read effective address
	          data_ctrl  <= pc_lo_data;       -- read memory data
			    next_state <= dir_state;
 
			  when ix2_state => -- fetch second index offest byte
  	          ac_ctrl    <= latch_ac;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
	          cc_ctrl    <= latch_cc;
 				 pc_ctrl    <= inc_pc;
             ea_ctrl    <= fetch_next_ea; 
             op_ctrl    <= latch_op;
	          md_ctrl    <= fetch_md;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= fetch_addr;
	          data_ctrl  <= pc_lo_data;
			    next_state <= ix1_state;
 
			  when ix1_state => -- add ixreg to effective address
  	          ac_ctrl    <= latch_ac;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
	          cc_ctrl    <= latch_cc;
 				 pc_ctrl    <= latch_pc;
             ea_ctrl    <= addix_ea; 
             op_ctrl    <= latch_op;
	          md_ctrl    <= latch_md;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= pc_lo_data;
			    next_state <= dir_state;
 
			  when ix0_state => -- load effective address with ixreg
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= loadix_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= pc_lo_data;
			    next_state <= dir_state;
 
			  when dir_state => -- read memory cycle
  	          ac_ctrl    <= latch_ac;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
	          cc_ctrl    <= latch_cc;
             ea_ctrl    <= latch_ea; 
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
	          data_ctrl  <= pc_lo_data;
				 case op(7 downto 4) is
				 when "0000" |  -- BRSET / BRCLR
				      "0001" |  -- BSET / BCLR
				      "0011" |  -- single op DIR
				      "0110" |  -- single op IX1
						"0111" => -- single op IX0
	            md_ctrl    <= fetch_md;
               left_ctrl  <= ac_left;       -- Left ALU input
	            right_ctrl <= md_right;      -- Right ALU input
               alu_ctrl   <= alu_nop;       -- ALU opeartion
				   addr_ctrl  <= read_addr;     -- read effective address
			      next_state <= exec_state;
				 when "1011" |     -- dual op direct
				      "1100" |     -- dual op extended
				      "1101" |     -- dual op ix2
				      "1110" |     -- dual op ix1
				      "1111" =>    -- dual op ix0
				   case op(3 downto 0) is
					when "0111" =>   -- sta
	              md_ctrl    <= load_md;
                 left_ctrl  <= ac_left;       -- Left ALU input
	              right_ctrl <= md_right;      -- Right ALU input
                 alu_ctrl   <= alu_st;        -- ALU opeartion
				     addr_ctrl  <= idle_addr;     -- read effective address
					  next_state <= write_state;
               when "1100" =>  -- jmp
	              md_ctrl    <= latch_md;
                 left_ctrl  <= ac_left;       -- Left ALU input
	              right_ctrl <= md_right;      -- Right ALU input
                 alu_ctrl   <= alu_nop;       -- ALU opeartion
				     addr_ctrl  <= idle_addr;     -- idle address
					  next_state <= jmp_state;
               when "1101" =>  -- jsr
	              md_ctrl    <= latch_md;
                 left_ctrl  <= ac_left;       -- Left ALU input
	              right_ctrl <= md_right;      -- Right ALU input
                 alu_ctrl   <= alu_nop;       -- ALU opeartion
				     addr_ctrl  <= idle_addr;     -- idle address
					  next_state <= jsr_state;
					when "1111" =>  -- stx
	              md_ctrl    <= load_md;
                 left_ctrl  <= ix_left;       -- Left ALU input
	              right_ctrl <= md_right;      -- Right ALU input
                 alu_ctrl   <= alu_st;       -- ALU opeartion
				     addr_ctrl  <= idle_addr;     -- read effective address
					  next_state <= write_state;
					when others =>
	              md_ctrl    <= fetch_md;
                 left_ctrl  <= ac_left;       -- Left ALU input
	              right_ctrl <= md_right;      -- Right ALU input
                 alu_ctrl   <= alu_nop;       -- ALU opeartion
				     addr_ctrl  <= read_addr;     -- read effective address
					  next_state <= fetch_state;
					end case;
			    when others =>
	            md_ctrl    <= fetch_md;
               left_ctrl  <= ac_left;       -- Left ALU input
	            right_ctrl <= md_right;      -- Right ALU input
               alu_ctrl   <= alu_nop;       -- ALU opeartion
				   addr_ctrl  <= read_addr;     -- read effective address
				   next_state <= fetch_state;
             end case;
 
           --
			  -- EXECUTE:
			  -- decode opcode
           -- to determine if output of the ALU is transfered to a register
			  -- or if alu output is written back to memory
           --
			  -- if opcode = dual operand                 or
			  --    opcode = single operand accum / ixreg or
			  --    opcode = branch on bit                then
			  --    goto fetch_state
			  --
			  -- if opcode = single operand memory        or
			  --    opcode = bit set / clear              or
			  --    goto write_state
			  --
			  when exec_state => -- execute alu operation
 				 pc_ctrl    <= latch_pc;
             ea_ctrl    <= latch_ea; 
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= md_data;
 
             case op(7 downto 4) is
				 when "0000" =>            -- branch set / clear
  	            ac_ctrl    <= latch_ac;
	            ix_ctrl    <= latch_ix;
	            sp_ctrl    <= latch_sp;
					left_ctrl  <= md_left;
					right_ctrl <= bset_right;
					alu_ctrl   <= alu_btst;
               md_ctrl    <= load_md;
					cc_ctrl    <= load_cc;
				   next_state <= brbit_state;
 
 				 when "0001" =>            -- bit set / clear
  	            ac_ctrl    <= latch_ac;
	            ix_ctrl    <= latch_ix;
	            sp_ctrl    <= latch_sp;
				   case op(0) is
					when '0' =>             -- bset
					  left_ctrl  <= md_left;
					  right_ctrl <= bset_right;
					  alu_ctrl   <= alu_ora;
                 md_ctrl    <= load_md;
					  cc_ctrl    <= load_cc;
 
					when '1' =>             -- bclr
					  left_ctrl  <= md_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_and;
                 md_ctrl    <= load_md;
					  cc_ctrl    <= load_cc;
 
					when others =>
					  left_ctrl  <= md_left;
					  right_ctrl <= bclr_right;
					  alu_ctrl   <= alu_nop;
                 md_ctrl    <= latch_md;
					  cc_ctrl    <= latch_cc;
					end case;
				   next_state <= write_state;
 
				 when "0011" |            -- single op direct
				      "0110" |            -- single op ix1
				      "0111" =>           -- single op ix0
  	            ac_ctrl    <= latch_ac;
	            ix_ctrl    <= latch_ix;
	            sp_ctrl    <= latch_sp;
					left_ctrl  <= md_left;
               md_ctrl    <= load_md;
					cc_ctrl    <= load_cc;
				   case op( 3 downto 0 ) is
				   when "0000" =>            -- neg
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_neg;
				   when "0011" =>            -- com
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_com;
				   when "0100" =>            -- lsr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_lsr;
				   when "0110" =>            -- ror
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_ror;
				   when "0111" =>            -- asr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_asr;
				   when "1000" =>            -- lsl
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_lsl;
				   when "1001" =>            -- rol
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_rol;
				   when "1010" =>            -- dec
					  right_ctrl <= one_right;
					  alu_ctrl   <= alu_dec;
				   when "1011" =>            -- undef
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
				   when "1100" =>            -- inc
					  right_ctrl <= one_right;
					  alu_ctrl   <= alu_inc;
				   when "1101" =>            -- tst
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_tst;
				   when "1110" =>            -- undef
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
				   when "1111" =>            -- clr
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_clr;
					when others =>
					  right_ctrl <= zero_right;
					  alu_ctrl   <= alu_nop;
					end case;
				   next_state <= write_state;
 
			    when others =>
  	            ac_ctrl    <= latch_ac;
					cc_ctrl    <= latch_cc;
	            ix_ctrl    <= latch_ix;
	            sp_ctrl    <= latch_sp;
               md_ctrl    <= latch_md;
					left_ctrl  <= md_left;
					right_ctrl <= zero_right;
					alu_ctrl   <= alu_nop;
					next_state <= fetch_state;
			    end case;
           --
			  -- WRITE:
			  -- write latched alu output to memory pointed to by ea register
			  -- go to fetch state
			  --
			  when write_state => -- write alu output to memory
  	          ac_ctrl    <= latch_ac;
			    cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
             md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
			    left_ctrl  <= md_left;
			    right_ctrl <= zero_right;
				 alu_ctrl   <= alu_nop;
				 addr_ctrl  <= write_addr;
			    data_ctrl  <= md_data;        -- select latched alu output to data bus
			    next_state <= fetch_state;
			  --
			  -- BRBIT
			  -- Branch on condition of bit
			  -- fetch the address offset
			  -- advance the pc
           -- evaluate the carry bit to determine if we take the branch
			  -- Carry = 0 if tested bit set
			  -- Carry = 1 if tested bit clear
			  -- op(0) = 0 if BRSET
			  -- op(0) = 1 if BRCLR
			  -- if carry = '1'
			  --   goto branch state
			  -- else
			  --   goto execute state
			  -- 
			  when brbit_state => -- fetch address offset
  	          ac_ctrl    <= latch_ac;
			    cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
				 ea_ctrl    <= fetch_first_ea;
             md_ctrl    <= latch_md;
				 pc_ctrl    <= inc_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
			    left_ctrl  <= md_left;
			    right_ctrl <= zero_right;
				 alu_ctrl   <= alu_nop;
				 addr_ctrl  <= fetch_addr;
			    data_ctrl  <= md_data;        -- select latched alu output to data bus
			    if (cc(CFLAG) xor op(0)) = '0' then -- check this ... I think it's right
			      next_state <= branch_state;
				 else
				   next_state <= fetch_state;
				 end if;
 
           --
			  -- BRANCH:
			  -- take conditional branch
			  -- branch (pc relative addressing)
           -- add effective address (ea register) to pc
           -- go to "fetch" state
           ---
			  when branch_state => -- calculate branch address
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= bra_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= idle_addr;     -- idle address bus
	          data_ctrl  <= md_data;       -- read memory data
	          next_state <= fetch_state;
			  --
			  -- jump to subroutine
			  --
			  when bsr_state =>     -- calculate effective jump address
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= addpc_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU operation
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= md_data;
			    next_state <= jsr_state;
 
			  when jsr_state =>     -- store pc low / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= push_addr;     -- write stack address
	          data_ctrl  <= pc_lo_data;    -- write PC low
			    next_state <= jsr1_state;
 
			  when jsr1_state =>    -- store pc high / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= push_addr;     -- write stack address
	          data_ctrl  <= pc_hi_data;    -- write PC high
			    next_state <= jmp_state;
			  --
			  -- jump to address
			  --
			  when jmp_state =>     -- load pc with effective address
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= jmp_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion (do nothing)
				 addr_ctrl  <= idle_addr;     -- idle address
	          data_ctrl  <= pc_lo_data;    -- 
			    next_state <= fetch_state;
			  --
			  -- return from subroutine
			  --
			  when rts_state => -- increment stack pointer
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= inc_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= md_data;
			    next_state <= rts_pch_state;
 
			  when rts_pch_state => -- load pc high return address / increment sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= inc_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= pull_hi_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= pull_addr;
	          data_ctrl  <= pc_hi_data;
			    next_state <= rts_pcl_state;
 
			  when rts_pcl_state => -- load pc low return address
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= pull_lo_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= pull_addr;
	          data_ctrl  <= pc_lo_data;
			    next_state <= fetch_state;
 
			  --
			  --
			  -- return from interrupt
			  --
			  when rti_state => -- increment sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= inc_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= fetch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= md_data;
			    next_state <= rti_cc_state;
 
			  when rti_cc_state => -- read cc / increment sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= pull_cc;			-- read Condition codes
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= inc_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= pull_addr;     -- read stack address
	          data_ctrl  <= cc_data;       -- output old CC
			    next_state <= rti_ac_state;
 
			  when rti_ac_state => -- read acc / increment sp
  	          ac_ctrl    <= pull_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= inc_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= pull_addr;     -- read stack address
	          data_ctrl  <= ac_data;       -- output Accumulator
			    next_state <= rti_ix_state;
 
			  when rti_ix_state => -- read ix / increment sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= pull_ix;		  -- read IX register
	          sp_ctrl    <= inc_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= pull_addr;     -- read stack address
	          data_ctrl  <= ix_data;       -- output old ix register
			    next_state <= rti_pch_state;
 
			  when rti_pch_state => -- read pc hi / increment sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= inc_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= pull_hi_pc;	   -- read PC high
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= pull_addr;		-- read stack address
	          data_ctrl  <= pc_hi_data;		-- output old PC high
			    next_state <= rti_pcl_state;
 
			  when rti_pcl_state => -- read pc lo
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= pull_lo_pc;		-- read PC low
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= pull_addr;		-- read stack address
	          data_ctrl  <= pc_lo_data;		-- output old PC Low
			    next_state <= fetch_state;
           --
			  -- sofwtare interrupt (or any others interrupt state)
			  --
			  when swi_state =>
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= swi_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= md_data;
			    next_state <= int_state;
 
			  --
			  -- any sort of interrupt
			  --
			  when int_state =>  -- store pc low / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= pc_lo_data;
			    next_state <= int1_state;
 
			  when int1_state => -- store pc hi / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= pc_hi_data;
			    next_state <= int2_state;
 
           when int2_state => -- store ix / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= ix_data;
				 next_state <= int3_state;
 
           when int3_state => -- store ac / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= ac_data;
				 next_state <= int4_state;
 
           when int4_state => -- store cc / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU opeartion
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= cc_data;
				 next_state <= int5_state;
 
           when int5_state => -- fetch pc hi = int vector hi
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= load_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= pull_hi_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_sei;       -- ALU operation
				 addr_ctrl  <= vect_hi_addr;
	          data_ctrl  <= pc_hi_data;
				 next_state <= int6_state;
 
           when int6_state => -- fetch pc low = int vector low
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= load_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= pull_lo_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_sei;       -- ALU operation
				 addr_ctrl  <= vect_lo_addr;
	          data_ctrl  <= pc_lo_data;
				 next_state <= fetch_state;
			  --
			  -- stop the processor
			  --
			  when stop_state =>
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU operation
				 addr_ctrl  <= idle_addr;
	          data_ctrl  <= md_data;
			    next_state <= stop_state;
           --
			  -- wait for interrupt
			  --
			  when wait_state => -- push pclow / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU operation
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= pc_lo_data;
			    next_state <= wait1_state;
 
			  when wait1_state => -- push pchi / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU operation
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= pc_hi_data;
			    next_state <= wait2_state;
 
           when wait2_state => -- push ix / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU operation
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= ix_data;
				 next_state <= wait3_state;
 
           when wait3_state => -- push ac / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU operation
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= ac_data;
				 next_state <= wait4_state;
 
           when wait4_state => -- push cc / decrement sp
  	          ac_ctrl    <= latch_ac;
	          cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= dec_sp;
             ea_ctrl    <= latch_ea; 
	          md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
             left_ctrl  <= ac_left;       -- Left ALU input
	          right_ctrl <= md_right;      -- Right ALU input
             alu_ctrl   <= alu_nop;       -- ALU operation
				 addr_ctrl  <= push_addr;
	          data_ctrl  <= cc_data;
				 next_state <= halt_state;
           --
			  -- halt cpu
			  --
  			  when halt_state => -- halt on halt
  	          ac_ctrl    <= latch_ac;
			    cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
             md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
			    left_ctrl  <= md_left;
			    right_ctrl <= zero_right;
				 alu_ctrl   <= alu_nop;
				 addr_ctrl  <= idle_addr;
			    data_ctrl  <= md_data;        -- select latched alu output to data bus
			    next_state <= halt_state;
           --
			  -- undefined instruction
		     --
  			  when others => -- halt on undefine states
  	          ac_ctrl    <= latch_ac;
			    cc_ctrl    <= latch_cc;
	          ix_ctrl    <= latch_ix;
	          sp_ctrl    <= latch_sp;
             ea_ctrl    <= latch_ea; 
             md_ctrl    <= latch_md;
 				 pc_ctrl    <= latch_pc;
             op_ctrl    <= latch_op;
	          iv_ctrl    <= latch_iv;
			    left_ctrl  <= md_left;
			    right_ctrl <= zero_right;
				 alu_ctrl   <= alu_nop;
				 addr_ctrl  <= idle_addr;
			    data_ctrl  <= md_data;        -- select latched alu output to data bus
			    next_state <= halt_state;
 
		  end case;						
 
end process;
--------------------------------
--
-- state machine
--
--------------------------------
 
change_state: process( clk, rst, state )
begin
  if rst = '1' then
 	 state <= reset_state;
  elsif clk'event and clk = '0' then
    state <= next_state;
  end if;
end process;
	-- output
 
end CPU_ARCH;
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.