-- 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';                -- ALU zero flag
  signal alu_rst  : std_logic_vector(31 downto 0);  -- ALU result

-- 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;

--------------------
-- Register File
--------------------
-- READ operation
  regout1 <= reg(conv_integer(rs));
  regout2 <= reg(conv_integer(rt));

-- WRITE operation
  RFILE_WT: process (Clock)
  begin
    if rising_edge(Clock) then
      if (opcode = OP_ALU) and (rd /= R0) then
        reg(conv_integer(rd)) <= alu_rst; 
      elsif (opcode = OP_LW) and (rt /= R0) then
        reg(conv_integer(rt)) <= Rddata ;
      else null;
      end if;
    end if;
  end process RFILE_WT;

--------------------
-- ALU
-------------------

-- WRITE YOUR CODE!


-------------------
-- DATA RAM CONTROL
-------------------

-- WRITE YOUR CODE!


--------------------
-- IROM control
--------------------
Iadd <= pc(7 downto 2);


end architecture RTL;
