📄 decode.vhd
字号:
if_fsl_atomic <= '0'; if (Instr_I(OPCODE_POS_TYPE) = FSL_STAT_DEC) then if_fsl_atomic <= Instr_I(FSL_STAT_ATOMIC_POS); elsif( Instr_I(OPCODE_POS_TYPE) = FSL_DYN_DEC ) then if_fsl_atomic <= Instr_I(FSL_DYN_ATOMIC_POS); end if; end process IF_FSL_Decode; of_fsl_atomic <= instr_OF(C_PREFETCH_ATOMIC_FSL_POS); end generate Using_Atomic_FSL; No_Atomic_FSL: if (C_FSL_ATOMIC = 0) generate begin Instr_II <= Instr_I; of_fsl_atomic <= '0'; end generate No_Atomic_FSL; Prefetch_Reset <= Reset or (Stop_CPU = '1'); PreFetch_Buffer_I : PreFetch_Buffer generic map ( C_TARGET => C_TARGET, -- [TARGET_FAMILY_TYPE] C_FSL_ATOMIC => C_FSL_ATOMIC, -- [integer] C_IEXT_BUS_EXCEPTION => C_IEXT_BUS_EXCEPTION ) port map ( Clk => Clk, -- [in std_logic] Reset => Prefetch_Reset, -- [in boolean] IReady => clean_iReady, -- [in std_logic] OF_PipeRun => of_PipeRun_s_I, -- [in std_logic] Jump => jump_i, -- [in boolean] Instr_Data => Instr_II, -- [in STD_LOGIC_VECTOR(0 TO 31)] Valid_Fetch => Valid_Fetch, OF_Valid => of_Valid, -- [out boolean] Buffer_Full => buffer_Full, -- [out boolean] Instr_OF => instr_OF, -- [out STD_LOGIC_VECTOR(0 TO 31)] Buffer_Addr => Buffer_Addr); -- [out std_logic_vector(0 to 3)] EX_Valid_SM : process (Clk) is begin -- process EX_Valid_SM if Clk'event and Clk = '1' then -- rising clock edge if Reset then ex_Valid <= false; else if of_PipeRun_I then -- Valid instruction in EX stage when -- and (no jumping with delay-slot inhibit) if (take_Intr_Now) then ex_Valid <= not(inHibit_EX and jump_I); else ex_Valid <= not(inHibit_EX and jump_I) and not Illegal_Opcode and not IExt_Exception; end if; elsif (Dbg_Inhibit_EX = '0') then -- Multi-cycle instruction handling -- Load Store instructions are valid until DReady is true -- Mul instructions are valid as long as they are executing if (Exc_Blocking = '1') then ex_Valid <= false; else ex_Valid <= (load_Store and (DReady = '0')) or mul_Executing or ((jump_Carry2 = '1') and jump2_I and (of_Valid_S = '0')); end if; end if; end if; end if; end process EX_Valid_SM; IFetch_Bus_SM : process (Clk) is begin -- process IFetch_Bus_SM if Clk'event and Clk = '1' then -- rising clock edge if Reset then iFetch_In_Progress <= false; else if i_AS_I then iFetch_In_Progress <= true; elsif iFetch_In_Progress and (IReady = '1') then iFetch_In_Progress <= false; end if; end if; end if; end process IFetch_Bus_SM; Load_Store_Decode : process (Clk) is begin -- process Load_Store_Decode if Clk'event and Clk = '1' then -- rising clock edge if Reset then load_Store_I <= false; else if of_PipeRun_I then load_Store_I <= (instr_OF(RESULT_SEL_POS_TYPE) = LOAD_STORE_DEC) and not take_Intr_Now and not(inHibit_EX and jump_I) and not Illegal_Opcode and not IExt_Exception; elsif load_Store and DReady = '1' then load_Store_I <= false; end if; end if; end if; end process Load_Store_Decode; load_Store <= load_Store_I and (Dbg_Inhibit_EX = '0'); -- and ex_Valid; load_Store_without_dbg <= not unalignment_1 when load_Store_I and (Dbg_Inhibit_EX = '0') else '0'; Mem_Strobe <= (not Dbg_Inhibit_EX) when (ex_Valid and load_Store_I and (unalignment = '0')) else '0'; Mul_Handling : process (Clk) is variable mul_first : boolean := false; variable mul_second : boolean := false; variable div_first : boolean := false; variable fpu_first : boolean := false; variable bs_first : boolean := false; variable fsl_first : boolean := false; variable pvr_first : boolean := false; variable wic_first : boolean := false; variable wdc_first : boolean := false; begin -- process Mul_Handling if Clk'event and Clk = '1' then -- rising clock edge if Reset then mul_Executing <= false; mul_first := false; mul_second := false; bs_first := false; fsl_first := false; div_first := false; fpu_first := false; pvr_first := false; wic_first := false; wdc_first := false; else if (Dbg_Inhibit_EX = '0') then if (C_USE_MUL_INSTR) then mul_second := mul_first; mul_first := false; end if; if (C_USE_DIV = 1) then div_first := div_first and (Div_Done = '0'); end if; if (C_USE_FPU > 0) then fpu_first := fpu_first and (FPU_Done = '0'); end if; if (C_USE_BARREL = 1) then bs_first := false; end if; if (C_FSL_LINKS > 0) then fsl_first := false; end if; if (C_PVR > 0) then pvr_first := false; end if; if (C_USE_ICACHE_WR) then wic_first := wic_first and (not ICache_Read_Idle); end if; if (C_USE_DCACHE_WR) then wdc_first := wdc_first and (not DCache_Read_Idle); end if; else mul_first := false; mul_second := false; bs_first := false; fsl_first := false; div_first := false; fpu_first := false; pvr_first := false; wic_first := false; wdc_first := false; end if; if of_PipeRun_I and not take_Intr_Now and not (inHibit_EX and jump_I) then if (C_USE_MUL_INSTR) then mul_first := (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(4 to 5) = "00"); end if; if (C_USE_BARREL = 1) then bs_first := (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(4 to 5) = "01"); end if; if (C_FSL_LINKS > 0) then fsl_first := (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(4 to 5) = "11"); end if; if (C_USE_DIV = 1) then div_first := (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(DIVFPU_POS_TYPE) = DIVFPU_DIV_DEC); end if; if (C_USE_FPU > 0) then fpu_first := (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(DIVFPU_POS_TYPE) = DIVFPU_FPU_DEC); end if; if (C_PVR > 0) then pvr_first := (instr_OF(OPCODE_POS_TYPE) = MXS_DEC) and (instr_OF(MSRxxx_POS) = EXT_MXS_DEC) -- MXS or MSRxxx and (instr_OF(MXS_POS) = MFS_DEC) -- MFS or MTS and (instr_OF(PVR_POS) = PVR_DEC); -- PVR end if; if (C_USE_ICACHE_WR) then wic_first := (instr_OF(OPCODE_POS_TYPE) = SRX_DEC) and (instr_OF(SRX_POS_TYPE) = SEXT_DEC) and (instr_OF(WIC_POS_TYPE) = WIC_DEC); end if; if (C_USE_DCACHE_WR) then wdc_first := (instr_OF(OPCODE_POS_TYPE) = SRX_DEC) and (instr_OF(SRX_POS_TYPE) = SEXT_DEC) and (instr_OF(WDC_POS_TYPE) = WDC_DEC); end if; end if; if take_Exc then mul_first := false; mul_second := false; bs_first := false; fsl_first := false; div_first := false; fpu_first := false; pvr_first := false; wic_first := false; wdc_first := false; end if; if (C_FSL_LINKS = 0) then mul_Executing <= mul_first or mul_second or div_first or fpu_first or bs_first or pvr_first or wic_first or wdc_first; else -- FSL stall must be prolonged if it has been decided it shall be breaken. -- Even if the data becomes available at the last cycle, it will be dealt with -- at the return from the ISR. mul_Executing <= mul_first or fpu_first or bs_first or fsl_first or mul_second or div_first or pvr_first or wic_first or wdc_first or FSL_Stall = '1' or FSL_Will_Break = '1'; end if; end if; end if; end process Mul_Handling; ----------------------------------------------------------------------------- -- Decode Read Addresses to Register File ----------------------------------------------------------------------------- -- Ra Reg1_Addr <= instr_OF(REG1_ADDR_POS_TYPE); -- Type A instruction, Rb Reg2_Addr <= instr_OF(REG2_ADDR_POS_TYPE); Wr_Addr_DFF : process (Clk) is begin -- process Wr_Addr_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then write_Addr_I <= (others => '0'); else if of_PipeRun_I then -- Rd write_Addr_I <= instr_OF(WRITE_ADDR_POS_TYPE); if take_Intr_Now then if (Take_Exc) then write_Addr_I <= EXC_REG_ADDR; -- Register 17 elsif (take_Break) then write_Addr_I <= BRK_REG_ADDR; -- Register 16 else write_Addr_I <= INT_REG_ADDR; -- Register 14 end if; end if; elsif( FSL_Will_Break_No_Dbg = '1' ) then -- Return address shall be written to registerfile. if (take_Break) then write_Addr_I <= BRK_REG_ADDR; -- Register 16 else write_Addr_I <= INT_REG_ADDR; -- Register 14 end if; end if; end if; end if; end process Wr_Addr_DFF; Write_Addr <= write_Addr_I; Write_Reg_Decode : process (Clk) is begin -- process Write_Reg_Decode if Clk'event and Clk = '1' then -- rising clock edge if Reset then write_Reg <= false; else if of_PipeRun_I then write_Reg <= true; -- Do not write for MTS, Bxx, Load, Store, RTI, RTS and IMM. -- The results from load are handled with the write_load_result signal instead. if ((instr_OF(OPCODE_POS_TYPE) = MXS_DEC) and (instr_OF(MxS_POS) = MTS_Dec)) or --MTS (instr_OF(OPCODE_POS_TYPE) = BXX_DEC) or (instr_OF(OPCODE_POS_TYPE) = BXXI_DEC) or (instr_OF(RESULT_SEL_POS_TYPE) = LOAD_STORE_DEC ) or (instr_OF(OPCODE_POS_TYPE) = RTX_DEC) or (instr_OF(OPCODE_POS_TYPE) = IMM_DEC) then write_Reg <= false; end if; -- Do not write for BRxx and BRxx with no LINK if (instr_OF(OPCODE_POS_TYPE) = BRXX_DEC) or (instr_OF(OPCODE_POS_TYPE) = BRXXI_DEC) then write_Reg <= (instr_OF(BRXX_LINK_POS) = BRXX_LINK_DEC); -- Save PC end if; if (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(DIVFPU_POS_TYPE) = DIVFPU_FPU_DEC) and (C_USE_FPU /= 0) then write_Reg <= false; end if; if (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(DIVFPU_POS_TYPE) = DIVFPU_DIV_DEC) and (C_USE_DIV = 1) then write_Reg <= false; end if; -- Do not write FSL directly when exceptions are available. if( FSL_EXCEPTION_ON ) then -- Only extended FSL functionality can take interrupts. if( (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(RESULT_SUB_SEL_POS_TYPE) = MULTI_FSL_INSTR_DEC) ) then write_Reg <= false; end if; end if; if take_Intr_2nd_Phase then write_Reg <= false; elsif take_Intr_Now then write_Reg <= true; end if; elsif( FSL_Will_Break_No_Dbg = '1' ) then write_Reg <= true; elsif( FSL_Will_Break = '1' ) then write_Reg <= false; end if; end if; end if; end process Write_Reg_Decode; -- Only write to the register file when there is an valid instruction in the -- EX stage and when the register write address is NOT register0 -- All new register values shall be written to debug, only the the registerfile shall -- ignore write to register 0. -- The result from an external data load access shall only be written to the register file -- when bus exceptions are selected (with generics) and enabled and no exception occurs. -- All writes except load. other_Write <= ( write_Reg or Write_FPU_result or Write_DIV_result or Write_FSL_result ) and (stop_mem_access = '0'); -- Determine if this is a valid register to write to. write_Valid_Reg <= (write_Addr_I /= NULL_REG_ADDR);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -