---------------------------------------------------------------------------------- -- Company: -- Engineer: Jim Plusquellic -- -- Create Date: 16:04:58 09/23/2009 -- Design Name: -- Module Name: InstructionDecoder -- 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.NUMERIC_STD.all; -- opcode and subcode are 3 bit fields of the leftmost portion of the instruction register. -- d_bit is direction bit (the next field of the IR) and prog_mode is a special external -- input that allows the microcontroller to be placed into program mode. Here, it forces -- the opcode to be no-op which controls the PC incrementing operations to add to the -- address sequentially so the instruction memory can be loaded up externally. The rest -- of the signals are 1-bit outputs that control the datapath. entity InstrDecoder is Port ( opcode : in std_logic_vector(2 downto 0); subcode : in std_logic_vector(2 downto 0); d_bit, prog_mode : in std_logic; aluwf_ins, movf_ins, call_ins, movlw_ins, goto_ins, retn_ins, noop_ins, skwcf_ins : out std_logic; add_ins, sub_ins, and_ins, or_ins, xor_ins, inv_ins, shltf_ins, shrtf_ins : out std_logic; skwgf_ins, skwlf_ins, skwef_ins, skwnf_ins, movwf_ins, movfw_ins : out std_logic; read_ctrl, write_ctrl : out std_logic ); end InstrDecoder; architecture beh of InstrDecoder is signal alu_instruction, skip_instruction, move_instruction, move_literal_instruction : std_logic; signal opc : std_logic_vector(2 downto 0); begin -- Force the opcode to NOOP (110) when in program mode, else pass opcode unchanged -- this simplifies the PC increment operation. with prog_mode select opc <= "110" when '1', opcode when others; -- Opcode decoder 3-bits - 8 instructions alu_instruction <= '1' when opc = "000" else '0'; move_instruction <= '1' when opc = "001" else '0'; call_ins <= '1' when opc = "010" else '0'; move_literal_instruction <= '1' when opc = "011" else '0'; goto_ins <= '1' when opc = "100" else '0'; retn_ins <= '1' when opc = "101" else '0'; noop_ins <= '1' when opc = "110" else '0'; skip_instruction <= '1' when opc = "111" else '0'; -- aluwf_ins instructions -- subcode is three bits add_ins <= '1' when alu_instruction = '1' and subcode = "000" else '0'; sub_ins <= '1' when alu_instruction = '1' and subcode = "001" else '0'; and_ins <= '1' when alu_instruction = '1' and subcode = "010" else '0'; or_ins <= '1' when alu_instruction = '1' and subcode = "011" else '0'; xor_ins <= '1' when alu_instruction = '1' and subcode = "100" else '0'; inv_ins <= '1' when alu_instruction = '1' and subcode = "101" else '0'; shltf_ins <= '1' when alu_instruction = '1' and subcode = "110" else '0'; shrtf_ins <= '1' when alu_instruction = '1' and subcode = "111" else '0'; -- skwcf_ins instruction decoder skwgf_ins <= '1' when skip_instruction = '1' and subcode(1 downto 0) = "00" else '0'; skwlf_ins <= '1' when skip_instruction = '1' and subcode(1 downto 0) = "01" else '0'; skwef_ins <= '1' when skip_instruction = '1' and subcode(1 downto 0) = "10" else '0'; skwnf_ins <= '1' when skip_instruction = '1' and subcode(1 downto 0) = "11" else '0'; -- movf_ins: uses D bit to determine if move from W to F (0) or F to W (1). movwf_ins <= '1' when move_instruction = '1' and d_bit = '0' else '0'; movfw_ins <= '1' when move_instruction = '1' and d_bit = '1' else '0'; -- Memory Control Signlas read_ctrl <= skip_instruction or alu_instruction or move_instruction; write_ctrl <= alu_instruction or move_instruction or move_literal_instruction; aluwf_ins <= alu_instruction; skwcf_ins <= skip_instruction; movf_ins <= move_instruction; movlw_ins <= move_literal_instruction; end beh;