-- Small Risk Processor SRP
-- supported instructions : LW, SW, ADD, SUB, AND, OR, SLT, BEQ, J
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;
use IEEE.STD_LOGIC_UNSIGNED.all;

use WORK.ALU_PKG.all;

entity SRP is
    port ( Clock   : in  std_logic;
	   Reset   : in  std_logic;               -- reset when it is '1' 
	   Iadd    : out std_logic_vector (5 downto 0);   -- Address for IROM
	   Inst    : in  std_logic_vector (31 downto 0);  -- Instruction from IROM
	   Dadd    : out std_logic_vector (5 downto 0);   -- Address for DRAM
	   WE      : out std_logic;               -- DRAM Write Enable
           Wtdata  : out std_logic_vector (31 downto 0);  -- Write data to DRAM
	   Rddata  : in  std_logic_vector (31 downto 0) );  -- Read data from DRAM
end entity SRP;

architecture RTL of SRP is

-- program counter
  signal pc    :std_logic_vector(31 downto 0);
  signal pc4   :std_logic_vector(31 downto 0); -- pc4 <= pc+4;
-- register file
  type RegType is array (0 to 31) of std_logic_vector(31 downto 0);
  signal reg   :RegType := (others => conv_std_logic_vector(0,32));
  signal regout1 : std_logic_vector(31 downto 0);
  signal regout2 : std_logic_vector(31 downto 0);
-- ALU
  signal alu_zero : std_logic :='0';

-- other sgnals
  signal opcode  :  std_logic_vector(5 downto 0); -- Inst(31-26)
  signal rs      :  std_logic_vector(4 downto 0); -- Inst(25-21)
  signal rt      :  std_logic_vector(4 downto 0); -- Inst(20-16)
  signal rd      :  std_logic_vector(4 downto 0); -- Inst(15-11)
  signal func    :  std_logic_vector(5 downto 0); -- Inst(5-0)
  signal sgnexd  :  std_logic_vector(31 downto 0); -- sign extended ir(15-0)

begin

  opcode <= Inst(31 downto 26);
  rs     <= Inst(25 downto 21);
  rt     <= Inst(20 downto 16);
  rd     <= Inst(15 downto 11);
  func   <= Inst( 5 downto  0);
  sgnexd <= Inst(15) & Inst(15) & Inst(15) & Inst(15) &
            Inst(15) & Inst(15) & Inst(15) & Inst(15) &
            Inst(15) & Inst(15) & Inst(15) & Inst(15) &
            Inst(15) & Inst(15) & Inst(15) & Inst(15) & Inst(15 downto 0);


--------------------
-- PC
--------------------
  pc4 <= pc + 4;

  PC_UNIT: process (Clock) begin
    if rising_edge(Clock) then
      if (Reset = '1') then
        pc <= (others => '0');
      else
        if (opcode = OP_J) then
          pc <= pc4(31 downto 28) & Inst(25 downto 0) & "00";
        elsif ((opcode = OP_BEQ) and (alu_zero='1')) then
          pc <=pc4 + (sgnexd(29 downto 0) & "00");
        else
          pc <=pc4;
        end if;
      end if;
    end if;
  end process PC_UNIT;



--------------------
-- IROM control
--------------------
Iadd <= pc(7 downto 2);


end architecture RTL;
