USE IEEE.std_logic_1164.all;
USE WORK.mbl_Pkg.all;
-
--------------------------------------------------------------------------------
ENTITY decode IS
--------------------------------------------------------------------------------
- GENERIC (
- USE_HW_MUL_g : BOOLEAN := TRUE;
- USE_BARREL_g : BOOLEAN := TRUE;
- COMPATIBILITY_MODE_g : BOOLEAN := FALSE
- );
- PORT (
- IF2ID_i : IN IF2ID_Type;
- imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
- --
- ID2GPRF_o : OUT ID2GPRF_Type;
- ID2EX_o : OUT ID2EX_Type;
- --
- INT_CTRL_i : IN INT_CTRL_Type;
- ID2CTRL_o : OUT ID2CTRL_Type;
- --
- noLiteOpc_o : OUT STD_LOGIC
- );
+ GENERIC
+ (
+ USE_HW_MUL_g : BOOLEAN := TRUE;
+ USE_BARREL_g : BOOLEAN := TRUE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
+ );
+ PORT
+ (
+ IF2ID_i : IN IF2ID_Type;
+ imem_data_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0);
+ --
+ ID2GPRF_o : OUT ID2GPRF_Type;
+ ID2EX_o : OUT ID2EX_Type;
+ --
+ INT_CTRL_i : IN INT_CTRL_Type;
+ ID2CTRL_o : OUT ID2CTRL_Type;
+ --
+ noLiteOpc_o : OUT STD_LOGIC
+ );
END ENTITY decode;
-
--------------------------------------------------------------------------------
ARCHITECTURE rtl OF decode IS
--------------------------------------------------------------------------------
BEGIN
p_decode:
- PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
-
- VARIABLE prog_counter_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE opcIx_v : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
- VARIABLE instruction_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
- VARIABLE rD_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- VARIABLE rA_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- VARIABLE rB_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
- VARIABLE IMM16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
- VARIABLE code_x26_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
- VARIABLE IMM_Lock_v : STD_LOGIC;
- VARIABLE alu_Action_v : ALU_ACTION_Type;
- VARIABLE alu_Op1_v : ALU_IN1_Type;
- VARIABLE alu_Op2_v : ALU_IN2_Type;
- VARIABLE alu_Cin_v : ALU_CIN_Type;
- VARIABLE msr_Action_v : MSR_ACTION_Type;
- VARIABLE branch_Action_v : BRANCH_ACTION_Type;
- VARIABLE delayBit_v : STD_LOGIC;
- VARIABLE mem_Action_v : MEM_ACTION_Type;
- VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
- VARIABLE wrb_Action_v : WRB_ACTION_Type;
- VARIABLE int_busy_v : STD_LOGIC;
- VARIABLE cmp_Cond_v : CMP_COND_Type;
- VARIABLE cmp_Cond_Type_v : CMP_COND_TYPE_Type;
-
- BEGIN
- prog_counter_v := IF2ID_i.program_counter;
- instruction_v := imem_data_i;
- opcIx_v := instruction_v (31 DOWNTO 26);
- rD_v := instruction_v (25 DOWNTO 21);
- rA_v := instruction_v (20 DOWNTO 16);
- rB_v := instruction_v (15 DOWNTO 11);
- IMM16_v := instruction_v (15 DOWNTO 0);
- IMM_Lock_v := '0';
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := '0';
- ELSE
- cmp_cond_v := COND_ALL;
- cmp_cond_type_v := COND_TYPE_ALL;
- END IF;
- alu_Cin_v := CIN_ZERO;
- alu_Action_v := A_NOP;
- msr_Action_v := KEEP_CARRY;
- branch_Action_v := NO_BR;
- mem_Action_v := NO_MEM;
- transfer_Size_v := WORD;
- wrb_Action_v := WRB_EX;
- -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
- code_x26_v := instruction_v(6) & instruction_v(5) & instruction_v(0);
- int_busy_v := INT_CTRL_i.int_busy;
- -- for debugging purposes
- noLiteOpc_o <= '0';
-
- IF (INT_CTRL_i.setup_int = '1') THEN
-
- alu_Op1_v := ALU_IN_ZERO;
- alu_Op2_v := ALU_IN_IMM;
- IMM16_v := X"0010"; -- address of _interrupt_handler vector
- prog_counter_v := INT_CTRL_i.rti_target; -- delayed program counter
- alu_Action_v := A_ADD;
- rD_v := "01110"; -- r14 reserved for storing program_counter
- rA_v := (OTHERS => '0'); -- also set rA and rB to avoid possible ...
- rB_v := (OTHERS => '0'); -- ... erronuous hazard detection in exeq module
- int_busy_v := '1';
- branch_Action_v := BRL;
-
- ELSE
-
- alu_Op1_v := ALU_IN_REGA;
- IF (opcIx_v(3) = '0') THEN
- alu_Op2_v := ALU_IN_REGB;
- ELSE
- alu_Op2_v := ALU_IN_IMM;
- END IF;
-
- CASE opcIx_v (5 DOWNTO 4) IS
-
- WHEN "00" => -- ADD / RSUB
- IF (opcIx_v(0) = '1') THEN -- RSUB
- alu_Op1_v := ALU_IN_NOT_REGA;
- END IF;
- IF (opcIx_v(1) = '0') THEN -- xxx
- IF (opcIx_v(0) = '0') THEN
- alu_Cin_v := CIN_ZERO;
- ELSE
- alu_Cin_v := CIN_ONE;
- END IF;
- ELSE -- xxxC
- alu_Cin_v := FROM_MSR;
- END IF;
- IF ((COMPATIBILITY_MODE_g = TRUE) AND (opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
- -- special CMP(U) and not RSUB(I)K, supported only in compatibility mode
- IF (IMM16_v(1) = '1') THEN -- U-bit set, CMPU
- alu_Action_v := A_CMPU;
- ELSE
- alu_Action_v := A_CMP;
- END IF;
- ELSE
- alu_Action_v := A_ADD;
- IF (opcIx_v(2) = '0') THEN
- msr_Action_v := UPDATE_CARRY;
- END IF;
- END IF;
-
- WHEN "01" => -- MUL / BS
- CASE opcIx_v (2 DOWNTO 0) IS
- WHEN "000" => -- MUL
- IF (USE_HW_MUL_g = TRUE) THEN
- alu_Action_v := A_MUL;
- ELSE
- noLiteOpc_o <= '1';
- END IF;
- WHEN "001" => -- BS
- IF (USE_BARREL_g = TRUE) THEN
- IF (instruction_v(10) = '1') THEN
- alu_Action_v := A_BSLL;
- ELSE
- IF (instruction_v(9) = '1') THEN
- alu_Action_v := A_BSRA;
- ELSE
- alu_Action_v := A_BSRL;
- END IF;
- END IF;
- ELSE
- noLiteOpc_o <= '1';
- END IF;
- WHEN "010" => -- CMP / CMPU / CMPI (new format)
- IF (COMPATIBILITY_MODE_g = FALSE) THEN
- IF (IMM16_v(5) = '1') THEN -- U-bit set, CMPU
- alu_Action_v := A_CMPU;
- ELSE
- alu_Action_v := A_CMP;
- END IF;
-
- IF (opcIx_v(3) = '0') THEN -- IT, ITT, ITE is not available to CMPI
- CASE IMM16_v(4 downto 3) IS
- WHEN "00" =>
- cmp_Cond_Type_v := COND_TYPE_ALL;
- WHEN "01" =>
- cmp_Cond_Type_v := COND_TYPE_IF_THEN;
- WHEN "10" =>
- cmp_Cond_Type_v := COND_TYPE_IF_THEN_THEN;
- WHEN "11" =>
- cmp_Cond_Type_v := COND_TYPE_IF_THEN_ELSE;
- WHEN OTHERS =>
- NULL;
- END CASE;
-
- CASE IMM16_v(2 downto 0) IS
- WHEN "001" =>
- cmp_Cond_v := COND_EQ;
- WHEN "010" =>
- cmp_Cond_v := COND_NE;
- WHEN "011" =>
- cmp_Cond_v := COND_LT;
- WHEN "100" =>
- cmp_Cond_v := COND_LE;
- WHEN "101" =>
- cmp_Cond_v := COND_GT;
- WHEN "110" =>
- cmp_Cond_v := COND_GE;
- WHEN OTHERS =>
- NULL;
- END CASE;
- END IF;
- ELSE
- noLiteOpc_o <= '1';
- END IF;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
-
- WHEN "10" =>
- IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
- CASE code_x26_v IS
- WHEN "001" | "011" | "101" =>
- CASE code_x26_v(2 DOWNTO 1) IS
- WHEN "00" => -- SRA
- alu_Cin_v := FROM_IN1;
- WHEN "01" => -- SRC
- alu_Cin_v := FROM_MSR;
- WHEN "10" => -- SRL
- alu_Cin_v := CIN_ZERO;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- alu_Action_v := A_SHIFT;
- msr_Action_v := UPDATE_CARRY;
- WHEN "110" => -- SEXT8
- alu_Action_v := A_SEXT8;
- WHEN "111" => -- SEXT16
- alu_Action_v := A_SEXT16;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM
- IMM_Lock_v := '1';
- -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
- alu_Action_v := A_NOP;
- wrb_Action_v := NO_WRB;
- ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
- CASE rD_v (3 DOWNTO 0) IS
- WHEN "0001" => -- RTI(D)
- int_busy_v := '0';
- WHEN "0000" => -- RTS(D)
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- alu_Action_v := A_ADD;
- branch_Action_v := BR;
- wrb_Action_v := NO_WRB;
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := rD_v(4);
- END IF;
- ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
- CASE IMM16_v IS
- WHEN X"8001" => -- MFS (MSR only)
- alu_Action_v := A_MFS;
- WHEN X"C001" => -- MTS (MSR only)
- alu_Action_v := A_MTS;
- wrb_Action_v := NO_WRB;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24)
- ELSE
- CASE opcIx_v (2 DOWNTO 0) IS
- WHEN "000" =>
- alu_Action_v := A_OR;
- WHEN "001" =>
- alu_Action_v := A_AND;
- WHEN "010" =>
- alu_Action_v := A_XOR;
- WHEN "011" =>
- alu_Action_v := A_AND;
- IF (opcIx_v(3) = '0') THEN
- alu_Op2_v := ALU_IN_NOT_REGB;
- ELSE
- alu_Op2_v := ALU_IN_NOT_IMM;
- END IF;
- WHEN "110" => -- BR(I)(D)
- IF (rA_v(2) = '1') THEN
- branch_Action_v := BRL;
- ELSE
- branch_Action_v := BR;
- wrb_Action_v := NO_WRB;
- END IF;
- IF (rA_v(3) = '1') THEN
- alu_Op1_v := ALU_IN_ZERO;
- ELSE
- alu_Op1_v := ALU_IN_PC;
- END IF;
- alu_Action_v := A_ADD;
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := rA_v(4);
- END IF;
- WHEN "111" =>
- CASE rD_v(3 DOWNTO 0) IS
- WHEN "0000" => -- BEQ
- branch_Action_v := BEQ;
- WHEN "0001" => -- BNE
- branch_Action_v := BNE;
- WHEN "0010" => -- BLT
- branch_Action_v := BLT;
- WHEN "0011" => -- BLE
- branch_Action_v := BLE;
- WHEN "0100" => -- BGT
- branch_Action_v := BGT;
- WHEN "0101" => -- BGE
- branch_Action_v := BGE;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- alu_Action_v := A_ADD;
- alu_Op1_v := ALU_IN_PC;
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- delayBit_v := rD_v(4);
- END IF;
- wrb_Action_v := NO_WRB; -- evaluate and update/overwrite in exeq
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- END IF;
-
- WHEN "11" =>
- IF (opcIx_v (3 DOWNTO 0) = "1111") THEN -- HALT
- alu_Action_v := A_HALT;
- wrb_Action_v := NO_WRB;
- ELSE
- alu_Action_v := A_ADD;
- CASE opcIx_v (1 DOWNTO 0) IS
- WHEN "00" => transfer_Size_v := BYTE;
- WHEN "01" => transfer_Size_v := HALFWORD;
- WHEN "10" => transfer_Size_v := WORD;
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
- END CASE;
- IF (opcIx_v(2) = '0') THEN
- mem_Action_v := RD_MEM;
- wrb_Action_v := WRB_MEM;
- ELSE
- mem_Action_v := WR_MEM;
- wrb_Action_v := NO_WRB;
- END IF;
- END IF;
-
- WHEN OTHERS =>
- noLiteOpc_o <= '1';
-
- END CASE;
-
- END IF; -- interrupt test
-
- ID2GPRF_o.rdix_rA <= rA_v;
- ID2GPRF_o.rdix_rB <= rB_v;
- ID2GPRF_o.rdix_rD <= rD_v;
-
- ID2EX_o.program_counter <= prog_counter_v;
- ID2EX_o.rdix_rA <= rA_v;
- ID2EX_o.rdix_rB <= rB_v;
- ID2EX_o.curr_rD <= rD_v;
- ID2EX_o.alu_Action <= alu_Action_v;
- ID2EX_o.alu_Op1 <= alu_Op1_v;
- ID2EX_o.alu_Op2 <= alu_Op2_v;
- ID2EX_o.alu_Cin <= alu_Cin_v;
- ID2EX_o.IMM16 <= IMM16_v;
- ID2EX_o.IMM_Lock <= IMM_Lock_v;
- ID2EX_o.msr_Action <= msr_Action_v;
- ID2EX_o.branch_Action <= branch_Action_v;
- ID2EX_o.mem_Action <= mem_Action_v;
- ID2EX_o.transfer_Size <= transfer_Size_v;
- ID2EX_o.wrb_Action <= wrb_Action_v;
- --
- IF (COMPATIBILITY_MODE_g = TRUE) THEN
- ID2CTRL_o.delayBit <= delayBit_v;
- ELSE
- ID2EX_o.cmp_Cond <= cmp_Cond_v;
- ID2EX_o.cmp_Cond_Type <= cmp_Cond_Type_v;
- END IF;
- ID2CTRL_o.int_busy <= int_busy_v;
-
- END PROCESS;
+ PROCESS (IF2ID_i, imem_data_i, INT_CTRL_i) IS
+
+ VARIABLE prog_counter_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE opcIx_v : STD_LOGIC_VECTOR ( 5 DOWNTO 0);
+ VARIABLE instruction_v : STD_LOGIC_VECTOR (31 DOWNTO 0);
+ VARIABLE rD_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE rA_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE rB_v : STD_LOGIC_VECTOR ( 4 DOWNTO 0);
+ VARIABLE IMM16_v : STD_LOGIC_VECTOR (15 DOWNTO 0);
+ VARIABLE code_x26_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
+ VARIABLE IMM_Lock_v : STD_LOGIC;
+ VARIABLE alu_Action_v : ALU_ACTION_Type;
+ VARIABLE alu_Op1_v : ALU_IN1_Type;
+ VARIABLE alu_Op2_v : ALU_IN2_Type;
+ VARIABLE alu_Cin_v : ALU_CIN_Type;
+ VARIABLE msr_Action_v : MSR_ACTION_Type;
+ VARIABLE branch_Action_v : BRANCH_ACTION_Type;
+ VARIABLE it_Action_v : IT_ACTION_Type;
+ VARIABLE delayBit_v : STD_LOGIC;
+ VARIABLE mem_Action_v : MEM_ACTION_Type;
+ VARIABLE transfer_Size_v : TRANSFER_SIZE_Type;
+ VARIABLE wrb_Action_v : WRB_ACTION_Type;
+ VARIABLE int_busy_v : STD_LOGIC;
+ VARIABLE condition_raw_v : STD_LOGIC_VECTOR ( 2 DOWNTO 0);
+ VARIABLE halt_v : STD_LOGIC;
+
+ BEGIN
+
+ prog_counter_v := IF2ID_i.program_counter;
+ instruction_v := imem_data_i;
+ opcIx_v := instruction_v (31 DOWNTO 26);
+ rD_v := instruction_v (25 DOWNTO 21);
+ rA_v := instruction_v (20 DOWNTO 16);
+ rB_v := instruction_v (15 DOWNTO 11);
+ IMM16_v := instruction_v (15 DOWNTO 0);
+ IMM_Lock_v := '0';
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := '0';
+ ELSE
+ it_Action_v := NO_IT;
+ END IF;
+ condition_raw_v := (others => '1');
+ alu_Cin_v := CIN_ZERO;
+ alu_Action_v := A_NOP;
+ msr_Action_v := KEEP_CARRY;
+ branch_Action_v := NO_BR;
+ mem_Action_v := NO_MEM;
+ transfer_Size_v := WORD;
+ wrb_Action_v := WRB_EX;
+ halt_v := '0';
+ -- for decoding SEXT16, SEXT8, SRC, SRC or SRL
+ code_x26_v := instruction_v(6) & instruction_v(5) & instruction_v(0);
+ int_busy_v := INT_CTRL_i.int_busy;
+ -- for debugging purposes
+ noLiteOpc_o <= '0';
+
+ IF (INT_CTRL_i.setup_int = '1') THEN
+
+ alu_Op1_v := ALU_IN_ZERO;
+ alu_Op2_v := ALU_IN_IMM;
+ IMM16_v := X"0010"; -- address of _interrupt_handler vector
+ prog_counter_v := INT_CTRL_i.rti_target; -- delayed program counter
+ alu_Action_v := A_ADD;
+ rD_v := "01110"; -- r14 reserved for storing program_counter
+ rA_v := (OTHERS => '0'); -- also set rA and rB to avoid possible ...
+ rB_v := (OTHERS => '0'); -- ... erronuous hazard detection in exeq module
+ int_busy_v := '1';
+ branch_Action_v := BRL;
+
+ ELSE
+
+ alu_Op1_v := ALU_IN_REGA;
+ IF (opcIx_v(3) = '0') THEN
+ alu_Op2_v := ALU_IN_REGB;
+ ELSE
+ alu_Op2_v := ALU_IN_IMM;
+ END IF;
+
+ CASE opcIx_v (5 DOWNTO 4) IS
+
+ WHEN "00" => -- ADD / RSUB
+ IF (opcIx_v(0) = '1') THEN -- RSUB
+ alu_Op1_v := ALU_IN_NOT_REGA;
+ END IF;
+ IF (opcIx_v(1) = '0') THEN -- xxx
+ IF (opcIx_v(0) = '0') THEN
+ alu_Cin_v := CIN_ZERO;
+ ELSE
+ alu_Cin_v := CIN_ONE;
+ END IF;
+ ELSE -- xxxC
+ alu_Cin_v := FROM_MSR;
+ END IF;
+ IF ((COMPATIBILITY_MODE_g = TRUE) AND (opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
+ -- special CMP(U) and not RSUB(I)K, supported only in compatibility mode
+ IF (IMM16_v(1) = '1') THEN -- U-bit set, CMPU
+ alu_Action_v := A_CMPU;
+ ELSE
+ alu_Action_v := A_CMP;
+ END IF;
+ ELSE
+ alu_Action_v := A_ADD;
+ IF (opcIx_v(2) = '0') THEN
+ msr_Action_v := UPDATE_CARRY;
+ END IF;
+ END IF;
+
+ WHEN "01" => -- MUL / BS
+
+ CASE opcIx_v (2 DOWNTO 0) IS
+ WHEN "000" => -- MUL
+ IF (USE_HW_MUL_g = TRUE) THEN
+ alu_Action_v := A_MUL;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN "001" => -- BS
+ IF (USE_BARREL_g = TRUE) THEN
+ IF (instruction_v(10) = '1') THEN
+ alu_Action_v := A_BSLL;
+ ELSIF (instruction_v(9) = '1') THEN
+ alu_Action_v := A_BSRA;
+ ELSE
+ alu_Action_v := A_BSRL;
+ END IF;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN "010" | "011" => -- CMP(U)
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ IF (opcIx_v(0) = '1') THEN
+ alu_Action_v := A_CMPU;
+ ELSE
+ alu_Action_v := A_CMP;
+ END IF;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN "100" | "101" => -- IT(U) / ITT(U) / ITE(U)
+ IF (COMPATIBILITY_MODE_g = FALSE) THEN
+ IF (opcIx_v(0) = '1') THEN
+ alu_Action_v := A_CMPU;
+ ELSE
+ alu_Action_v := A_CMP;
+ END IF;
+
+ CASE rD_v(4 downto 3) IS
+ WHEN "00" =>
+ it_Action_v := IT;
+ WHEN "01" =>
+ it_Action_v := ITT;
+ WHEN "10" =>
+ it_Action_v := ITE;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ condition_raw_v := rD_v(2 downto 0);
+ -- IT instruction isn't writing to anything
+ wrb_Action_v := NO_WRB;
+ ELSE
+ noLiteOpc_o <= '1';
+ END IF;
+
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+
+ WHEN "10" =>
+ IF (opcIx_v (3 DOWNTO 0) = "0100") THEN
+ CASE code_x26_v IS
+
+ WHEN "001" | "011" | "101" =>
+ CASE code_x26_v(2 DOWNTO 1) IS
+ WHEN "00" => -- SRA
+ alu_Cin_v := FROM_IN1;
+ WHEN "01" => -- SRC
+ alu_Cin_v := FROM_MSR;
+ WHEN "10" => -- SRL
+ alu_Cin_v := CIN_ZERO;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ alu_Action_v := A_SHIFT;
+ msr_Action_v := UPDATE_CARRY;
+
+ WHEN "110" => -- SEXT8
+ alu_Action_v := A_SEXT8;
+ WHEN "111" => -- SEXT16
+ alu_Action_v := A_SEXT16;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+
+ ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM
+ IMM_Lock_v := '1';
+ -- always: IMM_LOCK_o.IMM16 <= IMM16_v;
+ alu_Action_v := A_NOP;
+ wrb_Action_v := NO_WRB;
+ ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
+
+ CASE rD_v (3 DOWNTO 0) IS
+ WHEN "0001" => -- RTI(D)
+ int_busy_v := '0';
+ WHEN "0000" => -- RTS(D)
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+
+ alu_Action_v := A_ADD;
+ branch_Action_v := BR;
+ wrb_Action_v := NO_WRB;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := rD_v(4);
+ END IF;
+
+ ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN
+
+ CASE IMM16_v IS
+ WHEN X"8001" => -- MFS (MSR only)
+ alu_Action_v := A_MFS;
+ WHEN X"C001" => -- MTS (MSR only)
+ alu_Action_v := A_MTS;
+ wrb_Action_v := NO_WRB;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24)
+
+ ELSE
+
+ CASE opcIx_v (2 DOWNTO 0) IS
+ WHEN "000" =>
+ alu_Action_v := A_OR;
+ WHEN "001" =>
+ alu_Action_v := A_AND;
+ WHEN "010" =>
+ alu_Action_v := A_XOR;
+ WHEN "011" =>
+ alu_Action_v := A_AND;
+ IF (opcIx_v(3) = '0') THEN
+ alu_Op2_v := ALU_IN_NOT_REGB;
+ ELSE
+ alu_Op2_v := ALU_IN_NOT_IMM;
+ END IF;
+
+ WHEN "110" => -- BR(I)(D)
+ IF (rA_v(2) = '1') THEN
+ branch_Action_v := BRL;
+ ELSE
+ branch_Action_v := BR;
+ wrb_Action_v := NO_WRB;
+ END IF;
+
+ IF (rA_v(3) = '1') THEN
+ alu_Op1_v := ALU_IN_ZERO;
+ ELSE
+ alu_Op1_v := ALU_IN_PC;
+ END IF;
+ alu_Action_v := A_ADD;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := rA_v(4);
+ END IF;
+
+ WHEN "111" =>
+ condition_raw_v := rD_v(2 downto 0); -- Conditional branching
+ branch_Action_v := BR;
+ alu_Action_v := A_ADD;
+ alu_Op1_v := ALU_IN_PC;
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ delayBit_v := rD_v(4);
+ END IF;
+ wrb_Action_v := NO_WRB; -- evaluate and update/overwrite in exeq
+
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ END IF;
+
+ WHEN "11" =>
+ IF (opcIx_v (3 DOWNTO 0) = "1111") THEN -- HALT
+ alu_Action_v := A_NOP;
+ wrb_Action_v := NO_WRB;
+ halt_v := '1';
+ ELSE
+ alu_Action_v := A_ADD;
+ CASE opcIx_v (1 DOWNTO 0) IS
+ WHEN "00" => transfer_Size_v := BYTE;
+ WHEN "01" => transfer_Size_v := HALFWORD;
+ WHEN "10" => transfer_Size_v := WORD;
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+ END CASE;
+ IF (opcIx_v(2) = '0') THEN
+ mem_Action_v := RD_MEM;
+ wrb_Action_v := WRB_MEM;
+ ELSE
+ mem_Action_v := WR_MEM;
+ wrb_Action_v := NO_WRB;
+ END IF;
+ END IF;
+
+ WHEN OTHERS =>
+ noLiteOpc_o <= '1';
+
+ END CASE;
+
+ END IF; -- interrupt test
+
+ ID2GPRF_o.rdix_rA <= rA_v;
+ ID2GPRF_o.rdix_rB <= rB_v;
+ ID2GPRF_o.rdix_rD <= rD_v;
+
+ ID2EX_o.program_counter <= prog_counter_v;
+ ID2EX_o.rdix_rA <= rA_v;
+ ID2EX_o.rdix_rB <= rB_v;
+ ID2EX_o.curr_rD <= rD_v;
+ ID2EX_o.alu_Action <= alu_Action_v;
+ ID2EX_o.alu_Op1 <= alu_Op1_v;
+ ID2EX_o.alu_Op2 <= alu_Op2_v;
+ ID2EX_o.alu_Cin <= alu_Cin_v;
+ ID2EX_o.IMM16 <= IMM16_v;
+ ID2EX_o.IMM_Lock <= IMM_Lock_v;
+ ID2EX_o.msr_Action <= msr_Action_v;
+ ID2EX_o.branch_Action <= branch_Action_v;
+ ID2EX_o.it_Action <= it_Action_v;
+ ID2EX_o.mem_Action <= mem_Action_v;
+ ID2EX_o.transfer_Size <= transfer_Size_v;
+ ID2EX_o.wrb_Action <= wrb_Action_v;
+ ID2EX_o.halt <= halt_v;
+ --
+ CASE condition_raw_v IS
+ WHEN "000" =>
+ ID2EX_o.condition <= COND_EQ;
+ WHEN "001" =>
+ ID2EX_o.condition <= COND_NE;
+ WHEN "010" =>
+ ID2EX_o.condition <= COND_LT;
+ WHEN "011" =>
+ ID2EX_o.condition <= COND_LE;
+ WHEN "100" =>
+ ID2EX_o.condition <= COND_GT;
+ WHEN "101" =>
+ ID2EX_o.condition <= COND_GE;
+ WHEN "111" =>
+ ID2EX_o.condition <= COND_ALL;
+ WHEN OTHERS =>
+ ID2EX_o.condition <= COND_ALL;
+ noLiteOpc_o <= '1';
+ END CASE;
+ --
+ IF (COMPATIBILITY_MODE_g = TRUE) THEN
+ ID2CTRL_o.delayBit <= delayBit_v;
+ END IF;
+ ID2CTRL_o.int_busy <= int_busy_v;
+
+ END PROCESS;
END ARCHITECTURE rtl;