SimpleProcessorCore/src/FetchDecode.vhd

176 lines
4.8 KiB
VHDL

----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date: 16:16:43 05/10/2011
-- Design Name:
-- Module Name: FetchDecode - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
library work;
use work.cpupkg.all;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;
-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
entity FetchDecode is
Port(
iClk : in std_logic;
iReset : in std_logic;
idData : in DATA;
icAddrSel : in std_logic;
icLoadInstr : in std_logic;
icJump : in std_logic;
icNextPC : in std_logic;
odPC : out ADDRESS;
idPC : in ADDRESS;
icUsePC : in std_logic;
odAddress : out ADDRESS;
odImmidiate : out DATA;
odRegAsel : out std_logic_vector(4 downto 0);
odRegBsel : out std_logic_vector(4 downto 0);
odRegINsel : out std_logic_vector(4 downto 0);
ocOperation : out OPTYPE
);
end FetchDecode;
architecture Behavioral of FetchDecode is
signal sdPC, sdPC_next : ADDRESS;
signal sdAdr, sdAdr_next : ADDRESS;
signal sdImmidate, sdImmidiate_next : DATA;
signal sdRegAsel, sdRegAsel_next : std_logic_vector(4 downto 0);
signal sdRegBsel, sdRegBsel_next : std_logic_vector(4 downto 0);
signal sdRegINsel, sdRegINsel_next : std_logic_vector(4 downto 0);
signal scOp, scOp_next : OPTYPE;
begin
Transition: process(idData, sdImmidate, icLoadInstr, icJump, icNextPC, sdAdr, sdPC, scOp, sdRegAsel, sdRegBsel, sdRegINsel, icUsePC, idPC)
begin
-- defaults
sdAdr_next <= sdAdr;
sdPC_next <= sdPC;
scOp_next <= scOp;
sdImmidiate_next <= sdImmidate;
sdRegAsel_next <= sdRegAsel;
sdRegBsel_next <= sdRegBsel;
sdRegINsel_next <= sdRegINsel;
--! ISA Definition
if (icLoadInstr = '1') then
sdAdr_next <= idData(15 downto 0);
sdImmidiate_next <= "0000000000000000" & idData(15 downto 0);
sdRegINsel_next <= idData(25 downto 21);
sdRegAsel_next <= idData(20 downto 16);
sdRegBsel_next <= idData(15 downto 11);
case idData(31 downto 26) is
when "000000" => scOp_next <= shl;
when "000001" => scOp_next <= shr;
when "000010" => scOp_next <= sto;
when "000011" => scOp_next <= loa;
when "000100" => scOp_next <= add;
when "000101" => scOp_next <= sub;
when "000110" => scOp_next <= addc;
when "000111" => scOp_next <= subc;
when "001000" => scOp_next <= opor;
when "001001" => scOp_next <= opand;
when "001010" => scOp_next <= opxor;
when "001011" => scOp_next <= opnot;
when "001100" => scOp_next <= jpz;
when "001101" => scOp_next <= jpc;
when "001110" => scOp_next <= jmp;
when "001111" => scOP_next <= li;
when "010000" => scOp_next <= jmc;
when "010001" => scOp_next <= ret;
when others => scOp_next <= hlt;
end case;
end if;
if (icUsePC = '1') then
sdPC_next <= idPC;
end if;
if (icJump = '1') then
sdPC_next <= sdAdr;
end if;
if (icNextPC = '1') then
sdPC_next <= sdPC + '1';
end if;
end process;
-- Execute Transition
process(iClk, iReset)
begin
if (iReset = '1') then
sdPC <= (others => '0');
sdAdr <= (others => '0');
sdImmidate <= (others=>'0');
sdRegAsel <= (others=>'0');
sdRegBsel <= (others=>'0');
sdRegINsel <= (others=>'0');
scOp <= hlt;
elsif (rising_edge(iClk)) then
sdPC <= sdPC_next;
sdAdr <= sdAdr_next;
scOp <= scOp_next;
sdImmidate <= sdImmidiate_next;
sdRegAsel <= sdRegAsel_next;
sdRegBsel <= sdRegBsel_next;
sdRegINsel <= sdRegINsel_next;
end if;
end process;
-- Output
odAddress <= idPC when icUsePC = '1' else
sdAdr when icAddrSel = '0' and icLoadInstr = '0' else
sdAdr_next when icAddrSel = '0' and icLoadInstr = '1' else
sdPC; -- addr_sel = '1'
odPC <= sdPC;
ocOperation <= scOp when icLoadInstr = '0' else
scOp_next;
odImmidiate <= sdImmidate when icLoadInstr = '0' else sdImmidiate_next;
odRegAsel <= sdRegAsel when icLoadInstr = '0' else sdRegAsel_next;
odRegBsel <= sdRegBsel when icLoadInstr = '0' else sdRegBsel_next;
odRegINsel <= sdRegINsel when icLoadInstr = '0' else sdRegINsel_next;
end Behavioral;