-- =============================================================================================================
-- *
-- * Copyright (c) University of York
-- *
-- * File Name: debug.vhd
-- *
-- * Version: V3.0
-- *
-- * Release Date:
-- *
-- * Author(s): M.Freeman
-- *
-- * Description: SimpleCPU simulation disassembler
-- *
-- * Conditions of Use: THIS CODE IS COPYRIGHT AND IS SUPPLIED "AS IS" WITHOUT WARRANTY OF ANY KIND, INCLUDING,
-- *                    BUT NOT LIMITED TO, ANY IMPLIED WARRANTY OF MERCHANTABILITY AND FITNESS FOR A
-- *                    PARTICULAR PURPOSE.
-- *
-- * Notes:
-- *
-- =============================================================================================================

-- INSTR   IR15 IR14 IR13 IR12 IR11 IR10 IR09 IR08 IR07 IR06 IR05 IR04 IR03 IR02 IR01 IR00  
-- MOVE    0    0    0    0    X    X    X    X    K    K    K    K    K    K    K    K
-- ADD     0    0    0    1    X    X    X    X    K    K    K    K    K    K    K    K
-- SUB     0    0    1    0    X    X    X    X    K    K    K    K    K    K    K    K
-- AND     0    0    1    1    X    X    X    X    K    K    K    K    K    K    K    K

-- LOAD    0    1    0    0    A    A    A    A    A    A    A    A    A    A    A    A
-- STORE   0    1    0    1    A    A    A    A    A    A    A    A    A    A    A    A
-- ADDM    0    1    1    0    A    A    A    A    A    A    A    A    A    A    A    A
-- SUBM    0    1    1    1    A    A    A    A    A    A    A    A    A    A    A    A

-- JUMPU   1    0    0    0    A    A    A    A    A    A    A    A    A    A    A    A
-- JUMPZ   1    0    0    1    A    A    A    A    A    A    A    A    A    A    A    A
-- JUMPNZ  1    0    1    0    A    A    A    A    A    A    A    A    A    A    A    A


LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;

ENTITY debug IS
PORT (
  CLK  : IN STD_LOGIC ;
  CLR  : IN STD_LOGIC ;
  ADDR : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
  DATA : IN STD_LOGIC_VECTOR(15 DOWNTO 0)  );
END debug;

ARCHITECTURE debug_arch OF debug IS

  TYPE state_type IS (fetch, decode, execute);
	 
  TYPE opcode_type IS (MOVE, ADD, SUB, BW_AND,
                       LOAD, STORE, ADDM, SUBM,
                       JUMP, JUMP_Z, JUMP_NZ,						  
                       NU, XX );	
	 
  SIGNAL opcode : opcode_type;
  SIGNAL imm12  : STD_LOGIC_VECTOR(11 downto 0);
  SIGNAL phase  : state_type ;

BEGIN

  simulation: PROCESS (clk, clr)

    VARIABLE present_state: state_type;
	 
  BEGIN
    IF clr = '1'
    THEN 
      present_state := fetch;
    ELSIF clk='1' and clk'event
    THEN  
	   phase <= present_state;
      CASE present_state IS
        WHEN fetch => 
		    present_state := decode;
          CASE DATA(15 downto 14) IS
            WHEN "00" =>
              CASE DATA(13 downto 12) IS
                WHEN "00" => 
                  opcode <= MOVE;
                  imm12 <= "0000" & DATA(7 downto 0);
                WHEN "01" => 
                  opcode <= ADD;
                  imm12 <= "0000" & DATA(7 downto 0);
                WHEN "10" => 
                  opcode <= SUB;
                  imm12 <= "0000" & DATA(7 downto 0);
                WHEN "11" => 
                  opcode <= BW_AND;
                  imm12 <= "0000" & DATA(7 downto 0);
					 WHEN OTHERS => 
                  opcode <= XX;
                  imm12 <= "XXXXXXXXXXXX";
              END CASE;						
            WHEN "01" =>
              CASE DATA(13 downto 12) IS
                WHEN "00" => 
                  opcode <= LOAD;
                  imm12 <= DATA(11 downto 0);
                WHEN "01" => 
                  opcode <= STORE;
                  imm12 <= DATA(11 downto 0);					
                WHEN "10" => 
                  opcode <= ADDM;
                  imm12 <= DATA(11 downto 0);
                WHEN "11" => 
                  opcode <= SUBM;
                  imm12 <= DATA(11 downto 0);
                WHEN OTHERS => 
                  opcode <= XX;
                  imm12 <= "XXXXXXXXXXXX";
				  END CASE;
            WHEN "10"   =>
              CASE DATA(13 downto 12) IS
                WHEN "00" => 
                  opcode <= JUMP;
                  imm12 <= DATA(11 downto 0);
                WHEN "01" => 
                  opcode <= JUMP_Z;
                  imm12 <= DATA(11 downto 0);
                WHEN "10" => 
                  opcode <= JUMP_NZ;
                  imm12 <= DATA(11 downto 0);				
                WHEN OTHERS => 
                  opcode <= XX;
                  imm12 <= "XXXXXXXXXXXX";	
              END CASE;	
            WHEN "11"   =>	
              opcode <= XX;
              imm12 <= "XXXXXXXXXXXX";	
            WHEN OTHERS => 
              opcode <= XX;
              imm12 <= "XXXXXXXXXXXX";
				END CASE;
        WHEN decode => 
          present_state := execute;
		  WHEN execute => 
          present_state := fetch;
        WHEN OTHERS =>
          null;
      END CASE;		  
    END IF;
  END PROCESS simulation;

END debug_arch;

  
