LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; USE work.mips_types.all; ENTITY e_mips_decoder IS PORT ( i_instr: IN std_logic_vector(31 DOWNTO 0); o_src_s: OUT std_logic_vector( 4 DOWNTO 0); o_src_t: OUT std_logic_vector( 4 DOWNTO 0); o_dest: OUT std_logic_vector( 4 DOWNTO 0); o_imm_a: OUT std_logic_vector( 4 DOWNTO 0); o_imm_16: OUT std_logic_vector(15 DOWNTO 0); o_imm_26: OUT std_logic_vector(25 DOWNTO 0); o_op: OUT t_op; o_link: OUT t_link; o_cmp: OUT t_cmp; o_alu: OUT t_alu; o_imm: OUT t_imm ); END ENTITY e_mips_decoder; ARCHITECTURE a_mips_decoder OF e_mips_decoder IS TYPE t_enc_type IS (enc_reg, enc_imm, enc_jmp); SIGNAL s_opcode: std_logic_vector(5 DOWNTO 0); SIGNAL s_enc_type: t_enc_type; SIGNAL s_func: std_logic_vector(5 DOWNTO 0); BEGIN s_opcode <= i_instr(31 DOWNTO 26); p_enc_type: PROCESS(s_opcode) BEGIN CASE s_opcode IS WHEN "000000" => s_enc_type <= enc_reg; WHEN "000010" => s_enc_type <= enc_jmp; WHEN "011010" => s_enc_type <= enc_jmp; WHEN OTHERS => s_enc_type <= enc_imm; END CASE; END PROCESS p_enc_type; p_src_s: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_src_s <= i_instr(25 DOWNTO 21); WHEN enc_imm => o_src_s <= i_instr(25 DOWNTO 21); WHEN OTHERS => o_src_s <= "00000"; END CASE; END PROCESS p_src_s; p_src_t: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_src_t <= i_instr(20 DOWNTO 16); WHEN enc_imm => o_src_t <= i_instr(20 DOWNTO 16); WHEN OTHERS => o_src_t <= "00000"; END CASE; END PROCESS p_src_t; p_dest: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_dest <= i_instr(15 DOWNTO 11); WHEN OTHERS => o_dest <= "00000"; END CASE; END PROCESS p_dest; p_imm_a: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_imm_a <= i_instr(10 DOWNTO 6); WHEN OTHERS => o_imm_a <= "00000"; END CASE; END PROCESS p_imm_a; p_func: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => s_func <= i_instr(5 DOWNTO 0); WHEN OTHERS => s_func <= "000000"; END CASE; END PROCESS p_func; p_imm_16: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_imm_16 <= i_instr(15 DOWNTO 0); WHEN OTHERS => o_imm_16 <= X"0000"; END CASE; END PROCESS p_imm_16; p_imm_26: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_imm_26 <= i_instr(25 DOWNTO 0); WHEN OTHERS => o_imm_26 <= X"000000" & "00"; END CASE; END PROCESS p_imm_26; p_op: PROCESS(s_opcode, s_func) BEGIN o_op <= op_none; o_link <= link_none; o_cmp <= cmp_none; o_alu <= alu_none; o_imm <= imm_none; CASE s_opcode IS WHEN "000000" => CASE s_func IS WHEN "000000" => o_op <= op_alu; o_alu <= alu_sll; o_imm <= imm_a; WHEN "000010" => o_op <= op_alu; o_alu <= alu_srl; o_imm <= imm_a; WHEN "000011" => o_op <= op_alu; o_alu <= alu_sra; o_imm <= imm_a; WHEN "000100" => o_op <= op_alu; o_alu <= alu_sll; WHEN "000110" => o_op <= op_alu; o_alu <= alu_srl; WHEN "000111" => o_op <= op_alu; o_alu <= alu_sra; WHEN "001000" => o_op <= op_j; WHEN "001001" => o_op <= op_j; o_link <= link_link; -- TODO: 010xxx, 011xxx missing WHEN "100000" => o_op <= op_alu; o_alu <= alu_add; WHEN "100001" => o_op <= op_alu; o_alu <= alu_add; WHEN "100010" => o_op <= op_alu; o_alu <= alu_sub; WHEN "100011" => o_op <= op_alu; o_alu <= alu_sub; WHEN "100100" => o_op <= op_alu; o_alu <= alu_and; WHEN "100101" => o_op <= op_alu; o_alu <= alu_or; WHEN "100110" => o_op <= op_alu; o_alu <= alu_xor; WHEN "100111" => o_op <= op_alu; o_alu <= alu_nor; WHEN "101010" => o_op <= op_alu; o_alu <= alu_slt; WHEN "101011" => o_op <= op_alu; o_alu <= alu_slt; WHEN OTHERS => NULL; END CASE; WHEN "000010" => o_op <= op_j; WHEN "000011" => o_op <= op_j; o_link <= link_link; o_imm <= imm_26; WHEN "000100" => o_op <= op_b; o_cmp <= cmp_eq; WHEN "000101" => o_op <= op_b; o_cmp <= cmp_ne; WHEN "000110" => o_op <= op_b; o_cmp <= cmp_lez; WHEN "000111" => o_op <= op_b; o_cmp <= cmp_gtz; WHEN "001000" => o_op <= op_alu; o_alu <= alu_add; o_imm <= imm_16se; WHEN "001001" => o_op <= op_alu; o_alu <= alu_add; o_imm <= imm_16se; WHEN "001010" => o_op <= op_alu; o_alu <= alu_slt; o_imm <= imm_16se; WHEN "001011" => o_op <= op_alu; o_alu <= alu_slt; o_imm <= imm_16se; WHEN "001100" => o_op <= op_alu; o_alu <= alu_and; o_imm <= imm_16ze; WHEN "001101" => o_op <= op_alu; o_alu <= alu_or; o_imm <= imm_16ze; WHEN "001110" => o_op <= op_alu; o_alu <= alu_xor; o_imm <= imm_16ze; -- TODO: 011xxx, 100xxx, 101xxx missing WHEN OTHERS => NULL; END CASE; END PROCESS p_op; END ARCHITECTURE a_mips_decoder;