Files
lt16lab/soc/core/decoder_pre.vhd
Thomas Fehmel 657a54ba18 Initial Commit
2016-10-18 14:21:45 +02:00

104 lines
3.4 KiB
VHDL

-- See the file "LICENSE" for the full license governing this code. --
library ieee;
use ieee.std_logic_1164.all;
use work.lt16x32_internal.all;
-- the decoder_pre checks the new instruction for basic data, which is needed in the finite state machine as input.
-- it is fully combinatoric
entity decoder_pre is
port(
-- signals from instruction memory
input : in imem_dec;
-- signals to decoder finite state machine
output : out pre_fsm
);
end entity decoder_pre;
architecture RTL of decoder_pre is
begin
-- decodes instruction memory input and outputs signals to finite state machine
decode : process(input) is
-- fetched instruction, 16 bit instructions stored in (15 downto 0) bits
variable instruction : std_logic_vector(31 downto 0);
-- width of fetched instruction
variable instruction_width : instruction_width_type;
-- instruction mode, temporary storage for clean logic/output seperation
variable instruction_mode : instruction_mode_type;
begin
-- needed to avoid latch generation for upper half word
instruction := (others => '0');
if (input.ready = '1') then
-- instruction memory is ready
-- get relevant instruction from instruction word and extract instruction width
case input.instruction_halfword_select is
when '0' => -- 32bit aligned, might be 32bit instruction
if (input.read_data(31 downto 28) = "1111") then
-- is 32 bit instruction
instruction_width := sel_32bit;
instruction(31 downto 0) := std_logic_vector(input.read_data(31 downto 0));
else
-- is 16 bit instruction
instruction_width := sel_16bit;
instruction(15 downto 0) := std_logic_vector(input.read_data(31 downto 16));
end if;
when '1' => -- lower 16bit, always 16 bit instruction
instruction_width := sel_16bit;
instruction(15 downto 0) := std_logic_vector(input.read_data(15 downto 0));
when others =>
instruction_width := sel_16bit;
instruction(15 downto 0) := op_or & "0000" & "0000" & "0000";
assert false report "instruction halfword select must be either 0 or 1" severity warning;
end case;
-- check for special, multicycle or normal instructions
if (instruction_width = sel_16bit) then
-- 16 bit instructions
if (instruction(15 downto 10) = op_bct & op_bct_call) then
-- instruction is call
instruction_mode := sel_call;
elsif (instruction(15 downto 10) = op_bct & op_bct_trap) then
-- instruction is trap
instruction_mode := sel_trap;
elsif (instruction(15 downto 9) = op_bct & op_bct_reti) then
-- instruction is reti
instruction_mode := sel_reti;
elsif (instruction(15 downto 10) = op_bct & op_bct_branch) then
-- instruction is branch
instruction_mode := sel_branch;
elsif (instruction(15 downto 10) = op_bct & op_bct_table) then
-- instruction is branch to table
instruction_mode := sel_branch;
else
-- no special instruction
instruction_mode := sel_normal16;
end if;
else
-- 32bit instructions
instruction_mode := sel_normal32;
end if;
else
-- imem not ready
instruction(15 downto 0) := nop16;
instruction_mode := sel_stall;
end if;
-- output
output.instruction <= instruction;
output.mode <= instruction_mode;
end process decode;
end architecture RTL;