BlinkenArea - GitList
Repositories
Blog
Wiki
mips_sys
Code
Commits
Branches
Tags
Search
Tree:
c2b0401
Branches
Tags
master
mips_sys
mips
decoder.vhd
added file headers
Stefan Schuermans
commited
c2b0401
at 2012-04-08 11:54:40
decoder.vhd
Blame
History
Raw
-- MIPS I system -- Copyright 2011-2012 Stefan Schuermans <stefan@schuermans.info> -- Copyleft GNU public license V2 or later -- http://www.gnu.org/copyleft/gpl.html 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_reg_s: OUT std_logic_vector( 4 DOWNTO 0); o_reg_t: OUT std_logic_vector( 4 DOWNTO 0); o_reg_d: 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; o_ldst: OUT t_ldst ); 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_ext_op: std_logic_vector(4 DOWNTO 0); SIGNAL s_func: std_logic_vector(5 DOWNTO 0); SIGNAL s_enc_type: t_enc_type; BEGIN s_opcode <= i_instr(31 DOWNTO 26); s_ext_op <= i_instr(20 DOWNTO 16); s_func <= i_instr( 5 DOWNTO 0); 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 "000011" => s_enc_type <= enc_jmp; WHEN OTHERS => s_enc_type <= enc_imm; END CASE; END PROCESS p_enc_type; p_reg_s: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_reg_s <= i_instr(25 DOWNTO 21); WHEN enc_imm => o_reg_s <= i_instr(25 DOWNTO 21); WHEN OTHERS => o_reg_s <= "00000"; END CASE; END PROCESS p_reg_s; p_reg_t: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_reg_t <= i_instr(20 DOWNTO 16); WHEN enc_imm => o_reg_t <= i_instr(20 DOWNTO 16); WHEN OTHERS => o_reg_t <= "00000"; END CASE; END PROCESS p_reg_t; p_reg_d: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_reg => o_reg_d <= i_instr(15 DOWNTO 11); WHEN OTHERS => o_reg_d <= "00000"; END CASE; END PROCESS p_reg_d; 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_imm_16: PROCESS(i_instr, s_enc_type) BEGIN CASE s_enc_type IS WHEN enc_imm => 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_jmp => 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_ext_op, s_func) BEGIN o_op <= op_none; o_link <= link_none; o_cmp <= cmp_none; o_alu <= alu_none; o_imm <= imm_none; o_ldst <= ldst_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; WHEN "010000" => o_op <= op_mfhi; WHEN "010001" => o_op <= op_mthi; WHEN "010010" => o_op <= op_mflo; WHEN "010011" => o_op <= op_mtlo; WHEN "011000" => o_op <= op_mult; WHEN "011001" => o_op <= op_multu; WHEN "011010" => o_op <= op_div; WHEN "011011" => o_op <= op_divu; 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_sltu; WHEN OTHERS => NULL; END CASE; WHEN "000001" => o_op <= op_j; o_imm <= imm_16se; IF s_ext_op(0) = '1' THEN o_cmp <= cmp_gez; ELSE o_cmp <= cmp_ltz; END IF; IF s_ext_op(4) = '1' THEN o_link <= link_link; ELSE o_link <= link_none; END IF; WHEN "000010" => o_op <= op_j; o_imm <= imm_26; WHEN "000011" => o_op <= op_j; o_link <= link_link; o_imm <= imm_26; WHEN "000100" => o_op <= op_j; o_cmp <= cmp_eq; o_imm <= imm_16se; WHEN "000101" => o_op <= op_j; o_cmp <= cmp_ne; o_imm <= imm_16se; WHEN "000110" => o_op <= op_j; o_cmp <= cmp_lez; o_imm <= imm_16se; WHEN "000111" => o_op <= op_j; o_cmp <= cmp_gtz; o_imm <= imm_16se; 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_sltu; 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; WHEN "001111" => o_op <= op_alu; o_alu <= alu_up; o_imm <= imm_16ze; WHEN "100000" => o_op <= op_l; o_imm <= imm_16se; o_ldst <= ldst_b; WHEN "100001" => o_op <= op_l; o_imm <= imm_16se; o_ldst <= ldst_h; WHEN "100010" => o_op <= op_l; o_imm <= imm_16se; o_ldst <= ldst_wl; WHEN "100011" => o_op <= op_l; o_imm <= imm_16se; o_ldst <= ldst_w; WHEN "100100" => o_op <= op_l; o_imm <= imm_16se; o_ldst <= ldst_bu; WHEN "100101" => o_op <= op_l; o_imm <= imm_16se; o_ldst <= ldst_hu; WHEN "100110" => o_op <= op_l; o_imm <= imm_16se; o_ldst <= ldst_wr; WHEN "101000" => o_op <= op_s; o_imm <= imm_16se; o_ldst <= ldst_b; WHEN "101001" => o_op <= op_s; o_imm <= imm_16se; o_ldst <= ldst_h; WHEN "101010" => o_op <= op_s; o_imm <= imm_16se; o_ldst <= ldst_wl; WHEN "101011" => o_op <= op_s; o_imm <= imm_16se; o_ldst <= ldst_w; WHEN "101110" => o_op <= op_s; o_imm <= imm_16se; o_ldst <= ldst_wr; WHEN OTHERS => NULL; END CASE; END PROCESS p_op; END ARCHITECTURE a_mips_decoder;