From d5b585f31816dac12117f828b2c06f2fdefd092d Mon Sep 17 00:00:00 2001 From: Martin Meloun Date: Wed, 2 Oct 2013 11:59:07 +0200 Subject: [PATCH] Add back support for delay slot, but with writing PC+4 when linking and using delay slot Signed-off-by: Martin Meloun --- hw/core_ctrl.vhd | 22 +++++------- hw/decode.vhd | 90 +++++++++++++++++------------------------------- hw/exeq.vhd | 24 ++++++++----- hw/fetch.vhd | 38 ++++++++++---------- hw/mbl_Pkg.vhd | 9 ++--- 5 files changed, 80 insertions(+), 103 deletions(-) diff --git a/hw/core_ctrl.vhd b/hw/core_ctrl.vhd index 991a1c2..897a941 100644 --- a/hw/core_ctrl.vhd +++ b/hw/core_ctrl.vhd @@ -34,7 +34,6 @@ ENTITY core_ctrl IS clk_i : IN STD_LOGIC; rst_i : IN STD_LOGIC; halt_i : IN STD_LOGIC; - bad_op_i : IN STD_LOGIC; int_i : IN STD_LOGIC; trace_i : IN STD_LOGIC; trace_kick_i : IN STD_LOGIC; @@ -49,6 +48,7 @@ ENTITY core_ctrl IS -- decode to exeq pipeline registers ID2EX_REG_i : IN ID2EX_Type; ID2EX_REG_o : OUT ID2EX_Type; + delay_bit_o : OUT STD_LOGIC; -- GPRF control gprf_clken_o : OUT STD_LOGIC; -- exeq to fetch feedback registers @@ -117,7 +117,7 @@ BEGIN imem_addr_o <= IF2ID_REG_i.program_counter; -- Tracing -- Reset_s is 1 when rst_i is one and then gets deactivated - core_clken_s <= reset_s OR ((NOT bad_op_i) AND (((NOT trace_i) AND (NOT exeq_halt_i)) OR trace_kick_i)); + core_clken_s <= reset_s OR (((NOT trace_i) AND (NOT exeq_halt_i)) OR trace_kick_i); core_clken_o <= core_clken_s; -- clock/wait control lines clken_s <= MEM2CTRL_i.clken OR rst_i; @@ -126,11 +126,12 @@ BEGIN gprf_clken_o <= clken_s; -- signals for clearing the ID2EX and EX2MEM registers during branches flush_ID2EX_s <= ((EX2IF_REG_i.take_branch AND (NOT delayBit_r)) OR EX2IF_REG_r.take_branch) WHEN COMPATIBILITY_MODE_g = TRUE - ELSE (EX2IF_REG_i.take_branch OR EX2IF_REG_r.take_branch OR EX2CTRL_REG_i.flush_first OR flush_first_r OR - ((NOT EX2CTRL_REG_i.ignore_state) AND (NOT ignore_state_r) AND flush_second_2r)); + ELSE ((EX2IF_REG_i.take_branch AND (NOT delayBit_r)) OR EX2IF_REG_r.take_branch OR EX2CTRL_REG_i.flush_first OR + flush_first_r OR ((NOT EX2CTRL_REG_i.ignore_state) AND (NOT ignore_state_r) AND flush_second_2r)); flush_EX2MEM_s <= HAZARD_WRB_i.hazard; -- outputs that need to be readable too, so needing shadowing signals ID2EX_REG_o <= ID2EX_REG_r; + delay_bit_o <= delayBit_r; EX2IF_REG_o <= EX2IF_REG_r; IMM_LOCK_o <= IMM_LOCK_r; HAZARD_WRB_o <= HAZARD_WRB_r; @@ -242,10 +243,9 @@ regd_proc: lp_rst_MSR; lp_rst_HAZARD_WRB; lp_rst_MEM_REG; + delayBit_r <= '0'; - IF (COMPATIBILITY_MODE_g = TRUE) THEN - delayBit_r <= '0'; - ELSE + IF (COMPATIBILITY_MODE_g = FALSE) THEN flush_first_r <= '0'; flush_second_r <= '0'; flush_second_2r <= '0'; @@ -286,9 +286,7 @@ regd_proc: IF ((reset_s = '1') OR (flush_ID2EX_s = '1')) THEN setup_int_r <= '0'; lp_rst_ID2EX_REG; - IF (COMPATIBILITY_MODE_g = TRUE) THEN - delayBit_r <= '0'; - END IF; + delayBit_r <= '0'; -- check for the need and possibility to handle active interrupt requests ELSIF (((int_i = '1') OR (MEM2CTRL_i.int = '1')) AND (MSR_i.IE = '1') AND (ID2CTRL_i.int_busy = '0') AND (int_busy_r = '0') AND @@ -305,9 +303,7 @@ regd_proc: ELSIF (clken_pipe_s = '1') THEN setup_int_r <= '0'; ID2EX_REG_r <= ID2EX_REG_i; - IF (COMPATIBILITY_MODE_g = TRUE) THEN - delayBit_r <= ID2CTRL_i.delayBit; - END IF; + delayBit_r <= ID2CTRL_i.delayBit; END IF; -- exeq-to-mem unit registers IF ((reset_s = '1') OR (flush_EX2MEM_s = '1')) THEN diff --git a/hw/decode.vhd b/hw/decode.vhd index cf681e0..67e207c 100644 --- a/hw/decode.vhd +++ b/hw/decode.vhd @@ -38,9 +38,7 @@ ENTITY decode IS ID2EX_o : OUT ID2EX_Type; -- INT_CTRL_i : IN INT_CTRL_Type; - ID2CTRL_o : OUT ID2CTRL_Type; - -- - noLiteOpc_o : OUT STD_LOGIC + ID2CTRL_o : OUT ID2CTRL_Type ); END ENTITY decode; @@ -87,9 +85,8 @@ p_decode: 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 + delayBit_v := '0'; + IF (COMPATIBILITY_MODE_g = FALSE) THEN it_Action_v := NO_IT; END IF; condition_raw_v := (others => '1'); @@ -104,8 +101,6 @@ p_decode: -- 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 @@ -164,8 +159,6 @@ p_decode: WHEN "000" => -- MUL IF (USE_HW_MUL_g = TRUE) THEN alu_Action_v := A_MUL; - ELSE - noLiteOpc_o <= '1'; END IF; WHEN "001" => -- BS @@ -177,8 +170,6 @@ p_decode: ELSE alu_Action_v := A_BSRL; END IF; - ELSE - noLiteOpc_o <= '1'; END IF; WHEN "010" | "011" => -- CMP(U) @@ -188,8 +179,6 @@ p_decode: ELSE alu_Action_v := A_CMP; END IF; - ELSE - noLiteOpc_o <= '1'; END IF; WHEN "100" | "101" => -- IT(U) / ITT(U) / ITE(U) @@ -201,24 +190,18 @@ p_decode: 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'; + WHEN "00" => it_Action_v := IT; + WHEN "01" => it_Action_v := ITT; + WHEN "10" => it_Action_v := ITE; + WHEN OTHERS => NULL; 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'; + NULL; END CASE; WHEN "10" => @@ -234,7 +217,7 @@ p_decode: WHEN "10" => -- SRL alu_Cin_v := CIN_ZERO; WHEN OTHERS => - noLiteOpc_o <= '1'; + NULL; END CASE; alu_Action_v := A_SHIFT; msr_Action_v := UPDATE_CARRY; @@ -244,7 +227,7 @@ p_decode: WHEN "111" => -- SEXT16 alu_Action_v := A_SEXT16; WHEN OTHERS => - noLiteOpc_o <= '1'; + NULL; END CASE; ELSIF (opcIx_v (3 DOWNTO 0) = "1100") THEN -- IMM @@ -257,17 +240,14 @@ p_decode: CASE rD_v (3 DOWNTO 0) IS WHEN "0001" => -- RTI(D) int_busy_v := '0'; - WHEN "0000" => -- RTS(D) - WHEN OTHERS => - noLiteOpc_o <= '1'; + WHEN OTHERS => -- RTS(D) + NULL; 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; + delayBit_v := rD_v(4); ELSIF (opcIx_v (3 DOWNTO 0) = "0101") THEN @@ -278,7 +258,7 @@ p_decode: alu_Action_v := A_MTS; wrb_Action_v := NO_WRB; WHEN OTHERS => - noLiteOpc_o <= '1'; + NULL; END CASE; rB_v := (OTHERS => '0'); -- in order to prevent occasional hazards (r16, r24) @@ -300,35 +280,31 @@ p_decode: 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); + + IF (rA_v(2) = '1') THEN + branch_Action_v := BRL; + ELSE + branch_Action_v := BR; + wrb_Action_v := NO_WRB; END IF; + alu_Action_v := A_ADD; + delayBit_v := rA_v(4); 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 + 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 WHEN OTHERS => - noLiteOpc_o <= '1'; + NULL; END CASE; END IF; @@ -343,8 +319,7 @@ p_decode: WHEN "00" => transfer_Size_v := BYTE; WHEN "01" => transfer_Size_v := HALFWORD; WHEN "10" => transfer_Size_v := WORD; - WHEN OTHERS => - noLiteOpc_o <= '1'; + WHEN OTHERS => NULL; END CASE; IF (opcIx_v(2) = '0') THEN mem_Action_v := RD_MEM; @@ -356,7 +331,7 @@ p_decode: END IF; WHEN OTHERS => - noLiteOpc_o <= '1'; + NULL; END CASE; @@ -401,13 +376,10 @@ p_decode: 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; + ID2CTRL_o.delayBit <= delayBit_v; + ID2CTRL_o.int_busy <= int_busy_v; END PROCESS; diff --git a/hw/exeq.vhd b/hw/exeq.vhd index 0347712..3921422 100644 --- a/hw/exeq.vhd +++ b/hw/exeq.vhd @@ -37,7 +37,10 @@ ENTITY exeq IS ); PORT ( + IF2ID_i : IN IF2ID_Type; + -- ID2EX_i : IN ID2EX_Type; + delayBit_i : IN STD_LOGIC; GPRF2EX_i : IN GPRF2EX_Type; EX2IF_o : OUT EX2IF_Type; EX2CTRL_o : OUT EX2CTRL_Type; @@ -68,7 +71,7 @@ BEGIN p_exeq: PROCESS (ID2EX_i, GPRF2EX_i, EX_WRB_i, MEM_WRB_i, - IMM_LOCK_i, MSR_i, HAZARD_WRB_i) + IF2ID_i, delayBit_i, IMM_LOCK_i, MSR_i, HAZARD_WRB_i) -- function needed by BSLL (only if USE_BARREL_g = TRUE) FUNCTION reverse_bits ( word32 : STD_LOGIC_VECTOR (31 DOWNTO 0) ) @@ -173,11 +176,11 @@ p_exeq: IMM32_v := hi16_v & ID2EX_i.IMM16; CASE ID2EX_i.alu_Op1 IS - WHEN ALU_IN_REGA => in1_v := data_rA_v; - WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v; - WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter; - WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS; - WHEN OTHERS => NULL; + WHEN ALU_IN_REGA => in1_v := data_rA_v; + WHEN ALU_IN_NOT_REGA => in1_v := NOT data_rA_v; + WHEN ALU_IN_PC => in1_v := ID2EX_i.program_counter; + WHEN ALU_IN_ZERO => in1_v := C_32_ZEROS; + WHEN OTHERS => NULL; END CASE; CASE ID2EX_i.alu_Op2 IS @@ -382,8 +385,13 @@ p_exeq: EX2MEM_o.wrix_rD <= ID2EX_i.curr_rD; IF (ID2EX_i.branch_Action = BRL) THEN EX2MEM_o.wrb_Action <= WRB_EX; - EX2MEM_o.exeq_result <= ID2EX_i.program_counter; - EX2MEM_o.data_rD <= ID2EX_i.program_counter; + IF (COMPATIBILITY_MODE_g = TRUE) OR (delayBit_i = '0') THEN + EX2MEM_o.exeq_result <= ID2EX_i.program_counter; + EX2MEM_o.data_rD <= ID2EX_i.program_counter; + ELSE + EX2MEM_o.exeq_result <= IF2ID_i.program_counter; + EX2MEM_o.data_rD <= IF2ID_i.program_counter; + END IF; -- set data_rD_v, although unused, to prevent an inferred latch data_rD_v := GPRF2EX_i.data_rD; ELSE diff --git a/hw/fetch.vhd b/hw/fetch.vhd index 359f816..e9a0a30 100644 --- a/hw/fetch.vhd +++ b/hw/fetch.vhd @@ -21,15 +21,15 @@ USE WORK.mbl_Pkg.all; -------------------------------------------------------------------------------- ENTITY fetch IS -------------------------------------------------------------------------------- - PORT ( - prog_cntr_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0); - inc_pc_i : IN STD_LOGIC; - EX2IF_i : IN EX2IF_Type; - IF2ID_o : OUT IF2ID_Type - ); + PORT + ( + prog_cntr_i : IN STD_LOGIC_VECTOR (31 DOWNTO 0); + inc_pc_i : IN STD_LOGIC; + EX2IF_i : IN EX2IF_Type; + IF2ID_o : OUT IF2ID_Type + ); END ENTITY fetch; - -------------------------------------------------------------------------------- ARCHITECTURE rtl OF fetch IS -------------------------------------------------------------------------------- @@ -37,17 +37,17 @@ ARCHITECTURE rtl OF fetch IS BEGIN p_fetch: - PROCESS ( prog_cntr_i, inc_pc_i, EX2IF_i ) - VARIABLE next_pc_v : STD_LOGIC_VECTOR (31 DOWNTO 0); - VARIABLE incVal_v : STD_LOGIC_VECTOR (31 DOWNTO 0); - BEGIN - incVal_v := X"0000000" & '0' & inc_pc_i & "00"; - ep_add32nc ( prog_cntr_i, incVal_v, '0', next_pc_v ); - IF (EX2IF_i.take_branch = '0') THEN - IF2ID_o.program_counter <= next_pc_v; - ELSE - IF2ID_o.program_counter <= EX2IF_i.branch_target; - END IF; - END PROCESS; + PROCESS ( prog_cntr_i, inc_pc_i, EX2IF_i ) + VARIABLE next_pc_v : STD_LOGIC_VECTOR (31 DOWNTO 0); + VARIABLE incVal_v : STD_LOGIC_VECTOR (31 DOWNTO 0); + BEGIN + incVal_v := X"0000000" & '0' & inc_pc_i & "00"; + ep_add32nc ( prog_cntr_i, incVal_v, '0', next_pc_v ); + IF (EX2IF_i.take_branch = '0') THEN + IF2ID_o.program_counter <= next_pc_v; + ELSE + IF2ID_o.program_counter <= EX2IF_i.branch_target; + END IF; + END PROCESS; END ARCHITECTURE rtl; diff --git a/hw/mbl_Pkg.vhd b/hw/mbl_Pkg.vhd index 0f48b09..ec7c25b 100644 --- a/hw/mbl_Pkg.vhd +++ b/hw/mbl_Pkg.vhd @@ -213,9 +213,7 @@ PACKAGE mbl_Pkg IS ID2EX_o : OUT ID2EX_Type; -- INT_CTRL_i : IN INT_CTRL_Type; - ID2CTRL_o : OUT ID2CTRL_Type; - -- - noLiteOpc_o : OUT STD_LOGIC + ID2CTRL_o : OUT ID2CTRL_Type ); END COMPONENT; @@ -228,7 +226,10 @@ PACKAGE mbl_Pkg IS ); PORT ( + IF2ID_i : IN IF2ID_Type; + -- ID2EX_i : IN ID2EX_Type; + delayBit_i : IN STD_LOGIC; GPRF2EX_i : IN GPRF2EX_Type; EX2IF_o : OUT EX2IF_Type; EX2CTRL_o : OUT EX2CTRL_Type; @@ -277,7 +278,6 @@ PACKAGE mbl_Pkg IS clk_i : IN STD_LOGIC; rst_i : IN STD_LOGIC; halt_i : IN STD_LOGIC; - bad_op_i : IN STD_LOGIC; int_i : IN STD_LOGIC; trace_i : IN STD_LOGIC; trace_kick_i : IN STD_LOGIC; @@ -292,6 +292,7 @@ PACKAGE mbl_Pkg IS -- decode to exeq pipeline registers ID2EX_REG_i : IN ID2EX_Type; ID2EX_REG_o : OUT ID2EX_Type; + delay_bit_o : OUT STD_LOGIC; -- GPRF control gprf_clken_o : OUT STD_LOGIC; -- exeq to fetch feedback registers -- 2.39.2