📄 decode_gti.vhd
字号:
if_pc_incr2 <= '1' when Dbg_Stop_Instr_Fetch_delay = '0' else '0'; if_pc_incr3 <= '1' when not if_hold_incr_MMU else '0'; if_pc_incr4 <= '1' when not (if_buffer_full and not if_addr_lookup_MMU) else '0'; if_pc_incr_carry_and_1 : carry_and generic map ( C_TARGET => C_TARGET) -- [TARGET_FAMILY_TYPE] port map (Carry_IN => if_pc_incr1, -- [in std_logic] A => if_pc_incr2, -- [in std_logic] Carry_OUT => if_pc_incr_carry1); -- [out std_logic] if_pc_incr_carry_and_2 : carry_and generic map ( C_TARGET => C_TARGET) -- [TARGET_FAMILY_TYPE] port map (Carry_IN => if_pc_incr_carry1, -- [in std_logic] A => if_pc_incr3, -- [in std_logic] Carry_OUT => if_pc_incr_carry2); -- [out std_logic] if_pc_incr_carry_and_3 : carry_and generic map ( C_TARGET => C_TARGET) -- [TARGET_FAMILY_TYPE] port map (Carry_IN => if_pc_incr_carry2, -- [in std_logic] A => if_pc_incr4, -- [in std_logic] Carry_OUT => if_pc_incr_carry3); -- [out std_logic] if_pc_incr <= (if_pc_incr_carry3 = '1'); Dbg_Stop_Instr_Fetch_DFF: process (Clk) is begin -- process Dbg_Stop_Instr_Fetch_DFF if Clk'event and Clk = '1' then -- rising clock edge if reset_bool then Dbg_Stop_Instr_Fetch_delay <= '0'; else Dbg_Stop_Instr_Fetch_delay <= Dbg_Stop_Instr_Fetch; end if; end if; end process Dbg_Stop_Instr_Fetch_DFF; IF_Hold_Incr_MMU_DFF: process (Clk) is variable ex_jump_occurred : boolean; variable ex_jump_occurred_already_tested : boolean; begin -- process IF_Hold_Incr_MMU_DFF if Clk'event and Clk = '1' then -- rising clock edge if reset_bool or C_USE_MMU < C_MMU_PROTECT then if_hold_incr_MMU_1 <= false; ex_jump_occurred := false; ex_jump_occurred_already_tested := false; if_valid_req_prev_i <= false; else if ex_jump and (not ex_jump_occurred_already_tested) then ex_jump_occurred := true; end if; if (ib_addr_strobe_i) and (IB_Addr_Strobe_MMU = '0') and (ex_jump or ex_jump_occurred) then -- Hold PC increment until MMU address strobe or exception if_hold_incr_MMU_1 <= true; ex_jump_occurred := false; ex_jump_occurred_already_tested := true; elsif IB_Addr_Strobe_MMU = '1' or IF_Instr_TLB_Miss_Excep = '1' or IF_Instr_Storage_Excep = '1' then -- Allow PC increment again if_hold_incr_MMU_1 <= false; ex_jump_occurred := false; end if; -- Do not allow new hold until next instruction if ex_PipeRun_i then ex_jump_occurred_already_tested := false; end if; -- Check for previous valid instruction cache request followed by a jump if_valid_req_prev_i <= ICACHE_Valid_Req and ex_jump and ib_addr_strobe_i and ib_vmode_i = '1'; end if; end if; end process IF_Hold_Incr_MMU_DFF; if_hold_incr_MMU <= if_hold_incr_MMU_1 or (if_valid_req_prev_i and not ICACHE_Valid_Req); IF_Valid_Req_Prev <= '1' when if_valid_req_prev_i else '0'; if_valid_fetch_i <= (if_valid_fetch_s = '1'); ---------------------------------------- -- IF_Missed_Fetch_DFF -- Keep track of missed IFetch due to delay slot or -- ongoing fetch ---------------------------------------- IF_Missed_Fetch_DFF : process (Clk) is begin if Clk'event and Clk = '1' then -- rising clock edge if reset_bool or (Dbg_Stop_Instr_Fetch = '1') then if_missed_fetch <= false; if_missed_fetch_already_tested <= false; else -- Can only be set on a branch if (ex_jump) then -- The branch target address fetch was missed due to ongoing -- instruction fetch if_missed_fetch <= (not if_missed_fetch_already_tested) and (not ib_addr_strobe_i); if_missed_fetch_already_tested <= true; end if; -- Clear the test signal when the branch instruction is leaving the ex_stage if (ex_PipeRun_i) then if_missed_fetch_already_tested <= false; end if; if if_missed_fetch then -- Missed fetch due to ongoing fetch -- If debug does a write to PC the fetch will not be executed since -- MB is under halt. For that missed_ifetch there will NOT be a ready -- signal bit rather another address strobe instead if_missed_fetch <= (ib_Ready_MMU = '0') and (not ib_addr_strobe_i); end if; end if; end if; end process IF_Missed_Fetch_DFF; if_valid <= not if_missed_fetch; -- Reset delay slot -- Clear the ex_jump_nodelay signal when the ignored instruction access -- is done. -- This is necessary for if_valid being dependent on ex_jump_nodelay if_jump_nodelay_rst <= not if_valid and (ib_Ready_MMU = '1'); --*************************************************************************** --*************************************************************************** -- Operand Fetch (OF) stage handling --*************************************************************************** --*************************************************************************** ----------------------------------------------------------------------------- -- Opcode ----------------------------------------------------------------------------- of_opcode <= of_instr(OPCODE_POS_TYPE); of_is_fpu_instr <= (of_instr(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (of_instr(DIVFPU_POS_TYPE) = DIVFPU_FPU_DEC) and (C_USE_FPU /= 0); of_is_div_instr <= (of_instr(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and -- bits are called DIVFPU but in this case are used for idiv (of_instr(DIVFPU_POS_TYPE) = DIVFPU_DIV_DEC) and C_USE_DIV; of_is_mul_instr <= ((of_opcode = MUL_DEC) or (of_opcode = MULI_DEC)) and C_USE_MUL_INSTR; ----------------------------------------------------------------------------- -- Generate register file OF stage read addresses ----------------------------------------------------------------------------- -- Ra of_op1_read_addr <= of_predecode(PreDecode_RD1_Addr); -- Type A instruction, Rb of_op2_read_addr <= of_predecode(PreDecode_RD2_Addr); OF_GPR_Op1_Rd_Addr <= of_instr(REG1_ADDR_POS_TYPE); OF_GPR_Op2_Rd_Addr <= of_instr(REG2_ADDR_POS_TYPE); OF_GPR_Op3_Rd_Addr <= of_gpr_write_addr; of_gpr_write_addr <= of_instr(WRITE_ADDR_POS_TYPE); of_use_imm <= (of_instr(IMMEDIATE_POS) = IMMEDIATE_DEC) or (of_opcode = MXS_DEC); of_is_branch <= (of_opcode = BRXX_BXX_DEC) or (of_opcode = RTX_DEC); of_use_op1 <= true; of_use_op2 <= not ((of_instr(IMMEDIATE_POS) = IMMEDIATE_DEC) or (of_opcode = SRX_DEC) or (of_opcode = MXS_DEC)); of_is_store <= (of_predecode(IS_STORE_INSTR_POS) = '1'); of_Take_Interrupt_i <= wb_intr_exception or of_Take_Interrupt_hold; OF_Take_Interrupt <= of_Take_Interrupt_i; of_Take_Interrupt_hold_DFF: process (Clk) is begin -- process of_Take_Interrupt_hold_DFF if Clk'event and Clk = '1' then -- rising clock edge if of_PipeRun_i then -- synchronous reset (active high) of_Take_Interrupt_hold <= false; elsif (of_Take_Interrupt_i) then of_Take_Interrupt_hold <= true; end if; end if; end process of_Take_Interrupt_hold_DFF; of_Take_Ext_BRK_i <= wb_hw_brk_exception or of_Take_Ext_BRK_hold; OF_Take_Ext_BRK <= of_Take_Ext_BRK_i; of_Take_Ext_BRK_hold_DFF: process (Clk) is begin -- process of_Take_Ext_BRK_hold_DFF if Clk'event and Clk = '1' then -- rising clock edge if of_PipeRun_i then -- synchronous reset (active high) of_Take_Ext_BRK_hold <= false; elsif (of_Take_Ext_BRK_i) then of_Take_Ext_BRK_hold <= true; end if; end if; end process of_Take_Ext_BRK_hold_DFF; OF_Take_Exception_i <= (wb_common_exception) or (of_Take_Exception_hold); OF_Take_Exception <= OF_Take_Exception_i; of_Take_Exception_hold_DFF: process (Clk) is begin -- process of_Take_Exception_hold_DFF if Clk'event and Clk = '1' then -- rising clock edge if of_PipeRun_i then -- synchronous reset (active high) of_Take_Exception_hold <= false; elsif (of_Take_Exception_i) then of_Take_Exception_hold <= true; end if; end if; end process of_Take_Exception_hold_DFF; of_Take_Intr_Exc_Brk <= of_Take_Interrupt_i or of_Take_Exception_i or of_Take_Ext_BRK_i; ----------------------------------------------------------------------------- -- Detect OF pipe stalls due to register conflicts and instruction stall ----------------------------------------------------------------------------- -- Register stall due to: -- 1) Load followed by use of the destination register -- 2) Multicycle instruction followed by use of the destination register -- -- Instruction stall due to: -- 1) FSL stall -- 2) Div stall -- 3) FPU stall -- 4) Debug exception -- 5) Waiting for external data -- 6) No instruction in prefetch buffer -- 7) MMU stall -- 8) Write cache stall for WDC or WIC -- Early arrival (FF or few logic levels). of_pipe_ctrl(1) <= '1' when ( (not ex_fsl_stall) and (not EX_MMU_Stall) and (not ex_write_cache_stall) ) else '0'; of_pipe_ctrl(2) <= '1' when ( not ex_Jump_stall ) else '0';-- ex_PipeRun_i <= (not mem_wait_on_ready) and (not MEM_Div_Stall) and (not MEM_FPU_Stall) and -- (not ex_Jump_Stall) and (not ex_fsl_stall) and (not EX_MMU_Stall) and-- (not ex_write_cache_stall); ex_PipeRun_i <= (of_PipeRun_carry(2) = '1'); EX_PipeRun <= ex_PipeRun_i; of_pipe_ctrl(3) <= '1' when ( of_valid and ((not wb_dbg_exception) and (not of_div_stall))) else '0'; -- Late arrival (2 or more logic levels). of_pipe_ctrl(4) <= '1' when not(of_read_ex_write_op1_conflict and of_use_op1 and ex_is_multi_or_load_instr) else '0'; of_pipe_ctrl(5) <= '1' when not(of_read_mem_write_op1_conflict and of_use_op1 and mem_is_multi_or_load_instr) else '0'; of_pipe_ctrl(6) <= '1' when not(of_read_ex_write_op2_conflict and of_use_op2 and ex_is_multi_or_load_instr) else '0'; of_pipe_ctrl(7) <= '1' when not(of_read_mem_write_op2_conflict and of_use_op2 and mem_is_multi_or_load_instr) else '0'; of_pipe_ctrl(8) <= '1' when not(of_read_ex_write_op3_conflict and of_is_store and ex_is_multi_or_load_instr) else '0'; of_pipe_ctrl(9) <= '1' when not(of_read_mem_write_op3_conflict and of_is_store and mem_is_multi_or_load_instr) else '0'; -- Extra step for load sharing. of_pipe_ctrl(10) <= '1'; -- Carry chain instantiation. Use_MuxCy: for I in 1 to of_pipe_ctrl'right generate begin OF_Piperun_Stage: carry_and generic map( C_TARGET => C_TARGET ) port map( Carry_IN => of_PipeRun_carry(I-1), -- [in std_logic] A => of_pipe_ctrl(I), -- [in std_logic] Carry_OUT => of_PipeRun_carry(I) -- [out std_logic] ); end generate Use_MuxCy; -- Start condition for evaluation. of_PipeRun_carry(0) <= mem_PipeRun_Stdl; -- Completely evaluated Pipe run condition. -- One for the load in the prefetch buffer (usually in the critical path) -- and one for the rest of the design. of_PipeRun_i <= of_PipeRun_Prefetch = '1'; of_PipeRun_Prefetch <= of_PipeRun_carry(of_PipeRun_carry'right-1); ----------------------------------------------------------------------------- -- Detect register conflicts in the pipeline ----------------------------------------------------------------------------- of_read_ex_write_op1_conflict <= ex_valid and ex_gpr_write and (ex_gpr_write_addr = of_op1_read_addr); of_read_ex_write_op2_conflict <= ex_valid and ex_gpr_write and (ex_gpr_write_addr = of_op2_read_addr); of_read_ex_write_op3_conflict <= ex_valid and ex_gpr_write and (ex_gpr_write_addr = of_gpr_write_addr) and of_is_store; of_read_mem_write_op1_conflict <= mem_valid and mem_gpr_write and (mem_gpr_write_addr = of_op1_read_addr); of_read_mem_write_op2_conflict <= mem_valid and mem_gpr_write and (mem_gpr_write_addr = of_op2_read_addr); of_read_mem_write_op3_conflict <= mem_valid and mem_gpr_write and (mem_gpr_write_addr = of_gpr_write_addr) and of_is_store; of_read_wb_write_op1_confl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -