ENTITY decode IS
--------------------------------------------------------------------------------
GENERIC (
- USE_HW_MUL_g : BOOLEAN := FALSE;
- USE_BARREL_g : BOOLEAN := FALSE
+ USE_HW_MUL_g : BOOLEAN := TRUE;
+ USE_BARREL_g : BOOLEAN := TRUE;
+ COMPATIBILITY_MODE_g : BOOLEAN := FALSE
);
PORT (
IF2ID_i : IN IF2ID_Type;
ID2EX_o : OUT ID2EX_Type;
--
INT_CTRL_i : IN INT_CTRL_Type;
- ID2CTRL_o : OUT ID2CTRL_Type
+ ID2CTRL_o : OUT ID2CTRL_Type;
+ --
+ noLiteOpc_o : OUT STD_LOGIC
);
END ENTITY decode;
ARCHITECTURE rtl OF decode IS
--------------------------------------------------------------------------------
- SIGNAL noLiteOpc_s : STD_LOGIC;
-
BEGIN
p_decode:
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 FSL_Mode_v : STD_LOGIC_VECTOR ( 4 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 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;
rB_v := instruction_v (15 DOWNTO 11);
IMM16_v := instruction_v (15 DOWNTO 0);
IMM_Lock_v := '0';
- delayBit_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;
mem_Action_v := NO_MEM;
transfer_Size_v := WORD;
wrb_Action_v := WRB_EX;
- FSL_Mode_v := "01010";
-- 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_s <= '0';
+ noLiteOpc_o <= '0';
IF (INT_CTRL_i.setup_int = '1') THEN
CASE opcIx_v (5 DOWNTO 4) IS
- WHEN "00" => -- ADD / RSUB / CMP
- IF (opcIx_v(0) = '1') THEN -- RSUB / CMP
+ 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
ELSE -- xxxC
alu_Cin_v := FROM_MSR;
END IF;
- IF ((opcIx_v(3 DOWNTO 0) = "0101") AND (IMM16_v(0)= '1')) THEN
- -- special CMP(U) and not RSUB(I)K
+ 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
END IF;
END IF;
- WHEN "01" => -- MUL / BS / FSL
+ 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_s <= '1';
+ noLiteOpc_o <= '1';
END IF;
WHEN "001" => -- BS
IF (USE_BARREL_g = TRUE) THEN
END IF;
END IF;
ELSE
- noLiteOpc_s <= '1';
+ noLiteOpc_o <= '1';
END IF;
- WHEN "011" => -- FSL
- IF (opcIx_v(3) = '0') THEN
- FSL_Mode_v := instruction_v(10 DOWNTO 6);
- ELSE
- FSL_Mode_v := instruction_v(15 DOWNTO 11);
- END IF;
- IF (FSL_Mode_v(4) = '0') THEN
- alu_Action_v := A_FSL_GET;
- wrb_Action_v := WRB_FSL;
+ 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
- alu_Action_v := A_FSL_PUT;
- wrb_Action_v := NO_WRB;
+ noLiteOpc_o <= '1';
END IF;
- msr_Action_v := UPDATE_CARRY;
WHEN OTHERS =>
- noLiteOpc_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
WHEN "10" =>
WHEN "10" => -- SRL
alu_Cin_v := CIN_ZERO;
WHEN OTHERS =>
- noLiteOpc_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
alu_Action_v := A_SHIFT;
msr_Action_v := UPDATE_CARRY;
WHEN "111" => -- SEXT16
alu_Action_v := A_SEXT16;
WHEN OTHERS =>
- noLiteOpc_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM
IMM_Lock_v := '1';
alu_Action_v := A_NOP;
wrb_Action_v := NO_WRB;
ELSIF (opcIx_v (3 DOWNTO 0) = "1101") THEN
- CASE rD_v IS
- WHEN "10001" => -- RTID
+ CASE rD_v (3 DOWNTO 0) IS
+ WHEN "0001" => -- RTI(D)
int_busy_v := '0';
- WHEN "10000" => -- RTSD
--- WHEN "10010" => -- RTBD
--- WHEN "10100" => -- RTED
+ WHEN "0000" => -- RTS(D)
WHEN OTHERS =>
- noLiteOpc_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
alu_Action_v := A_ADD;
branch_Action_v := BR;
wrb_Action_v := NO_WRB;
- delayBit_v := '1';
+ 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_MTS;
wrb_Action_v := NO_WRB;
WHEN OTHERS =>
- noLiteOpc_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24)
ELSE
ELSE
alu_Op2_v := ALU_IN_NOT_IMM;
END IF;
- WHEN "110" => -- BR(I)
+ WHEN "110" => -- BR(I)(D)
IF (rA_v(2) = '1') THEN
branch_Action_v := BRL;
ELSE
ELSE
alu_Op1_v := ALU_IN_PC;
END IF;
- IF (rA_v(4) = '1') THEN
- delayBit_v := '1';
- 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
WHEN "0101" => -- BGE
branch_Action_v := BGE;
WHEN OTHERS =>
- noLiteOpc_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
alu_Action_v := A_ADD;
alu_Op1_v := ALU_IN_PC;
- delayBit_v := rD_v(4);
- wrb_Action_v := NO_WRB; -- evaluate and update/overwrite in exeq
+ 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_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
END IF;
WHEN "11" =>
- 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_s <= '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;
+ 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_s <= '1';
+ noLiteOpc_o <= '1';
END CASE;
ID2EX_o.mem_Action <= mem_Action_v;
ID2EX_o.transfer_Size <= transfer_Size_v;
ID2EX_o.wrb_Action <= wrb_Action_v;
- ID2EX_o.FSL_Non_blocking <= FSL_Mode_v(3);
- ID2EX_o.FSL_Control <= FSL_Mode_v(2);
- ID2EX_o.FSL_Test <= FSL_Mode_v(1);
- ID2EX_o.FSL_Atomic <= FSL_Mode_v(0);
--
- ID2CTRL_o.delayBit <= delayBit_v;
- ID2CTRL_o.int_busy <= int_busy_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;