📄 decode.vhd
字号:
No_Div_Exception : if (C_DIV_ZERO_EXCEPTION = 0) generate Div_Exception <= '0'; end generate No_Div_Exception; Using_FSL_Exception: if (FSL_EXCEPTION_ON) generate signal FSL_Exception_occurred : std_logic; signal FSL_Exception_hold : std_logic; begin FSL_Exception_occurred <= ( EX_FSL_Control_Error and FSL_Exceptionable ) when Exceptions_Enabled else '0'; FSL_Exception_hold_DFF : process (Clk) is begin -- process FSL_Exception_hold_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) FSL_Exception_hold <= '0'; else if (of_PipeRun_I) then FSL_Exception_hold <= '0'; else FSL_Exception_hold <= FSL_Exception_hold or FSL_Exception_occurred; end if; end if; end if; end process FSL_Exception_hold_DFF; FSL_Exception_I <= FSL_Exception_occurred or FSL_Exception_hold; -- The result is only written when there is no exception. Write_FSL_result_DFF: process (Clk) is begin -- process Write_FSL_Result_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) Write_FSL_Result <= false; else Write_FSL_result <= (FSL_Get_Succesful = '1') and (FSL_Exception_I = '0'); end if; end if; end process Write_FSL_result_DFF; end generate Using_FSL_Exception; No_FSL_Exception: if not(FSL_EXCEPTION_ON) generate FSL_Exception_I <= '0'; Write_FSL_result <= false; end generate No_FSL_Exception; FSL_Exception <= FSL_Exception_I; Detect_Illegal_Major_Opcodes : if (C_ILL_OPCODE_EXCEPTION /= 0) generate Illegal_Opcode_Detect : process (Exceptions_Enabled, instr_OF) is variable error : boolean; constant opcode_0x0 : DATA_TYPE := (others => '0'); begin -- process Illegal_Opcode_Detect -- Always illegal error := (instr_OF(OPCODE_POS_TYPE) = "011010") or -- FreeI #1 (instr_OF(OPCODE_POS_TYPE) = "010100") or -- Free #3 (instr_OF(OPCODE_POS_TYPE) = "011100") or -- FreeI #3 (instr_OF(OPCODE_POS_TYPE) = "010101") or -- Free #4 (instr_OF(OPCODE_POS_TYPE) = "011101") or -- FreeI #4 (instr_OF(OPCODE_POS_TYPE) = "011110") or -- FreeI #6 (instr_OF(OPCODE_POS_TYPE) = "010111") or -- Free #7 (if used, change decoding for fsl to use all bits) (instr_OF(OPCODE_POS_TYPE) = "011111") or -- FreeI #7 (if used, change decoding for fsl to use all bits) (instr_OF(OPCODE_POS_TYPE) = "110011") or -- Unused Load (instr_OF(OPCODE_POS_TYPE) = "110111") or -- Unused Store (instr_OF(OPCODE_POS_TYPE) = "111011") or -- Unused LoadI (instr_OF(OPCODE_POS_TYPE) = "111111"); -- Unused StoreI if (C_USE_FPU = 0) then error := error or (instr_OF(OPCODE_POS_TYPE) = "010110"); end if; if (C_USE_DIV = 0) then error := error or (instr_OF(OPCODE_POS_TYPE) = "010010"); end if; if (C_USE_BARREL = 0) then error := error or (instr_OF(OPCODE_POS_TYPE) = "010001") or(instr_OF(OPCODE_POS_TYPE) = "011001"); end if; if (C_FSL_LINKS = 0) then error := error or (instr_OF(OPCODE_POS_TYPE) = FSL_STAT_DEC); end if; if (C_USE_EXTENDED_FSL_INSTR = 0 or C_FSL_LINKS = 0) then error := error or (instr_OF(OPCODE_POS_TYPE) = FSL_DYN_DEC); end if; if (not C_USE_MUL_INSTR) then error := error or (instr_OF(OPCODE_POS_TYPE) = "010000") or (instr_OF(OPCODE_POS_TYPE) = "011000"); end if; if (C_DETECT_OPCODE_0x0) then error := error or (instr_OF(opcode_0x0'range) = opcode_0x0); end if; if (Exceptions_Enabled) then Illegal_Opcode <= error; else Illegal_Opcode <= false; end if; end process Illegal_Opcode_Detect; Illegal_Opcode_DFF : process (Clk) is begin -- process Illegal_Opcode_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) Illegal_Opcode_EX <= '0'; else if (of_PipeRun_I) then -- Only generate exception for instructions that are -- executed, avoiding false exceptions for instuctions -- not executed in delay slots. if (Illegal_Opcode and not(inHibit_EX and jump_I) ) then Illegal_Opcode_EX <= '1'; else Illegal_Opcode_EX <= '0'; end if; end if; end if; end if; end process Illegal_Opcode_DFF; end generate Detect_Illegal_Major_Opcodes; No_Illegal_Opcodes : if (C_ILL_OPCODE_EXCEPTION = 0) generate Illegal_Opcode <= false; Illegal_Opcode_EX <= '0'; end generate No_Illegal_Opcodes; Detect_Unaligned_Mem_Accesses : if (C_UNALIGNED_EXCEPTIONS /= 0) generate signal word_unalignment : std_logic; signal halfword_unalignment_i : std_logic; begin halfword_unalignment_i <= halfword_unalignment when doublet_i else '0'; word_unalignment <= word_r1_r2_unalignment when quadlet_i else '0'; unalignment <= (halfword_unalignment_i or word_unalignment) when Exceptions_Enabled else '0'; unalignment_exc <= unalignment when load_Store_i else '0'; stop_mem_access <= unalignment_exc; Unalignment_DFF : process (Clk) is begin -- process Unalignment_DFF if Clk'event and Clk = '1' then -- rising clock edge if (Reset) then unalignment_1 <= '0'; else unalignment_1 <= unalignment_exc; end if; end if; end process Unalignment_DFF; end generate Detect_Unaligned_Mem_Accesses; No_unaligned_exceptions : if (C_UNALIGNED_EXCEPTIONS = 0) generate unalignment <= '0'; unalignment_1 <= '0'; unalignment_exc <= '0'; stop_mem_access <= '0'; end generate No_unaligned_exceptions; Illegal_Opcode_I <= '1' when Illegal_Opcode else '0'; Using_Exceptions : if C_EXCEPTIONS generate signal RTED_Instr : boolean; signal Valid_RTED : boolean; begin Stall_Pipe_DFF: process (Clk) is begin -- process Stall_Pipe_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) Stall_Pipe_i <= '0'; else if (of_PipeRun_I and (IExt_Exception or Illegal_Opcode)) then Stall_Pipe_i <= '1'; else Stall_Pipe_i <= '0'; end if; end if; end if; end process Stall_Pipe_DFF; Take_Exc_Process : process (Clk) variable do_Exception : boolean; begin -- process Brk_Or_Intr if Clk'event and Clk = '1' then -- rising clock edge if Reset then Take_Exc <= false; else do_exception := (exception = '1'); take_exc <= do_exception and not ((take_exc and of_PipeRun_I) or Take_Exc_2nd_cycle); end if; end if; end process Take_Exc_Process; exception <= unalignment_exc or Illegal_Opcode_EX or IExt_Exception_EX or DExt_Exception or Div_Exception or FPU_Exception_i or FSL_Exception_I when Exceptions_Enabled else '0'; Exc_Blocking <= exception; -- Information bits for the ESR Load_EAR <= (exception = '1'); Load_EDR <= (exception = '1'); Load_ESR <= (exception = '1'); Disable_Exceptions <= (exception = '1') and of_PipeRun_I; Set_EIP <= (exception = '1'); SW_Instr <= '1' when writing and load_Store_I else '0'; Word_Access <= '1' when quadlet_i and load_Store_I else '0'; Unaligned_Exception <= stop_mem_access; Illegal_Opcode_Exception <= Illegal_Opcode_EX; IExt_Bus_Exception <= IExt_Exception_EX; DExt_Bus_Exception <= DExt_Exception; Div_Zero_Exception <= Div_Exception; RTE_Decode : process (Clk) is begin -- process RTI_Decode if Clk'event and Clk = '1' then -- rising clock edge if Reset then RTED_Instr <= false; else if of_PipeRun_I then RTED_Instr <= false; if not take_Intr_Now then if (instr_OF(OPCODE_POS_TYPE) = RTX_DEC) then RTED_Instr <= (instr_OF(RTE_POS) = RTE_DEC); end if; end if; end if; end if; end if; end process RTE_Decode; Valid_RTED <= RTED_Instr and ex_valid and (Dbg_Inhibit_EX = '0'); Clr_ESR <= Valid_RTED; Enable_Exceptions <= Valid_RTED; Reset_EIP <= Valid_RTED; end generate Using_Exceptions; No_Exceptions : if not C_EXCEPTIONS generate Stall_Pipe_i <= '0'; Take_Exc <= false; exception <= '0'; Load_EAR <= false; Load_EDR <= false; Load_ESR <= false; Disable_Exceptions <= false; Set_EIP <= false; Clr_ESR <= false; SW_Instr <= '0'; Word_Access <= '0'; Unaligned_Exception <= '0'; Unalignment <= '0'; Unalignment_1 <= '0'; Exc_Blocking <= '0'; Illegal_Opcode_Exception <= '0'; IExt_Bus_Exception <= '0'; DExt_Bus_Exception <= '0'; Div_Zero_Exception <= '0'; Enable_Exceptions <= false; Reset_EIP <= false; end generate No_Exceptions; Detect_DOPB_Exceptions : if (C_DOPB_BUS_EXCEPTION = 1 or C_DPLB_BUS_EXCEPTION = 1) generate signal D_Exception_hold : std_logic; begin -- Must ensure that DExt_Exception is kept active if the pipeline does not -- move at the same time as D_Exception is active. Executing from a slow memory D_Exception_hold_DFF : process (Clk) is begin -- process D_Exception_hold_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) D_Exception_hold <= '0'; else if (of_PipeRun_I) then D_Exception_hold <= '0'; else D_Exception_hold <= D_Exception_hold or D_Exception; end if; end if; end if; end process D_Exception_hold_DFF; DExt_Exception <= D_Exception or D_Exception_hold when Exceptions_Enabled else '0'; end generate Detect_DOPB_Exceptions; No_DOPB_Exceptions : if (C_DOPB_BUS_EXCEPTION = 0 and C_DPLB_BUS_EXCEPTION = 0) generate DExt_Exception <= '0'; end generate No_DOPB_Exceptions; Detect_IExt_Exceptions : if (C_IOPB_BUS_EXCEPTION = 1 or C_IPLB_BUS_EXCEPTION = 1) generate Instr_I <= Instr & I_Exception; IExt_Exception <= (instr_OF(IOPB_EXC_POS) = IOPB_EXC_DEC) and Exceptions_Enabled; IExt_Exception_DFF : process (Clk) is begin -- process IExt_Exception_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active true) IExt_Exception_EX <= '0'; else if (of_PipeRun_I) then -- Only generate exception for instructions that are -- executed, avoiding false exceptions for instuctions -- not executed in delay slots. if (IExt_Exception and not(inHibit_EX and jump_I) ) then IExt_Exception_EX <= '1'; else IExt_Exception_EX <= '0'; end if; end if; end if; end if; end process IExt_Exception_DFF; end generate Detect_IExt_Exceptions; No_IExt_Exceptions : if (C_IOPB_BUS_EXCEPTION = 0 and C_IPLB_BUS_EXCEPTION = 0) generate Instr_I <= Instr; IExt_Exception <= false; IExt_Exception_EX <= '0'; end generate No_IExt_Exceptions; Using_Atomic_FSL: if (C_FSL_ATOMIC /= 0) generate begin Instr_II <= Instr_I & if_fsl_atomic; -- IF Decode IF_FSL_Decode: process (Instr_I) is begin -- process IF_FSL_Decode
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -