📄 decode.vhd
字号:
-- Determine when it is valid to store the load data. dready_Valid <= ( not writing ) and (stop_mem_access = '0')and not( Exceptions_Enabled and D_Exception = '1' and ( C_DOPB_BUS_EXCEPTION /= 0 or C_DPLB_BUS_EXCEPTION /= 0 ) ); -- Join normal writes with the uninterrupt load or data.-- write_Reg_I <= ( ( ( DReady = '1' ) and ( dready_Valid ) ) or ( other_Write ) ) and-- ( write_Valid_Reg ) ; dready_Valid_S <= '1' when dready_Valid else '0'; other_Write_S <= '1' when other_Write else '0'; write_Valid_Reg_S <= '1' when write_Valid_Reg else '0'; write_Reg_I_LUT: LUT4 generic map ( INIT => X"F800") -- [bit_vector] port map ( O => write_Reg_I_S, -- [out std_logic] I0 => DReady, -- [in std_logic] I1 => dready_Valid_S, -- [in std_logic] I2 => other_Write_S, -- [in std_logic] I3 => write_Valid_Reg_S); -- [in std_logic] write_Reg_I <= ( write_Reg_I_S = '1' ); -- Write to register file depending on source. write_mem_valid_in_ex <= write_Valid_Reg and ex_Valid and (Dbg_Inhibit_EX = '0'); write_other_valid_in_ex <= other_Write and write_Valid_Reg and ex_Valid and (Dbg_Inhibit_EX = '0'); -- Merge to one write signal while fitting inside an LUT4. -- Rewrite of equation below to simplify for tool to insert late arriving signals with few logic levels. -- Reg_Write <= write_Reg_I and ex_Valid and (Dbg_Inhibit_EX = '0'); Reg_Write <= ( ( DReady = '1' ) and dready_Valid and write_mem_valid_in_ex ) or write_other_valid_in_ex; -- Write to debug logic. Reg_Write_Dbg <= ( ( ( DReady = '1' ) and ( DReady_Valid ) ) or ( other_Write ) ) and ( ex_Valid and (Dbg_Inhibit_EX = '0') ); ----------------------------------------------------------------------------- -- Decode Immediate values ----------------------------------------------------------------------------- Imm_Value <= instr_OF(IMMEDIATE_VALUE_POS_TYPE); ----------------------------------------------------------------------------- -- Decoding for carry handling ----------------------------------------------------------------------------- Carry_Decode : process (Clk) is begin -- process Carry_Decode if Clk'event and Clk = '1' then -- rising clock edge if Reset then write_Carry_I <= false; -- Don't write select_ALU_Carry <= false; else if of_PipeRun_I then write_Carry_I <= false; select_ALU_Carry <= (instr_OF(instr_OF'left) = '0'); if instr_OF(RESULT_SEL_POS_TYPE) = ARITH_INSTR_DEC then -- Arithmetic instructions write_Carry_I <= (instr_OF(CARRY_UPDATE_POS) = UPDATE_CARRY); end if; if (instr_OF(OPCODE_POS_TYPE) = SRX_DEC) and (instr_OF(SRX_POS_TYPE) /= SEXT_DEC) then -- Shift operations write_Carry_I <= true; end if; if (take_Intr_Now) then write_Carry_I <= false; select_ALU_Carry <= false; end if; end if; end if; end if; end process Carry_Decode; ----------------------------------------------------------------------------- -- Decode for the Result Multiplexor ----------------------------------------------------------------------------- -- Result_Sel = 00 => Select ALU result -- Result_Sel = 01 => Select Multiplier result or PVR -- Result_Sel = 10 => Select Shift -- Result_Sel = 11 => Select External Data Result_Mux_Decode : process (Clk) is begin -- process Result_Mux_Decode if Clk'event and Clk = '1' then -- rising clock edge if Reset then Result_Sel <= (others => '0'); else if of_PipeRun_I then Result_Sel <= instr_OF(RESULT_SEL_POS_TYPE); if (C_PVR > 0) and (instr_OF(OPCODE_POS_TYPE) = MXS_DEC) and (instr_OF(MSRxxx_POS) = EXT_MXS_DEC) and -- MXS or MSRxxx (instr_OF(MXS_POS) = MFS_DEC) and -- MFS or MTS (instr_OF(PVR_POS) = PVR_DEC) then -- PVR Result_Sel <= MULTI_INSTR_DEC; -- Select PVR end if; if take_Intr_Now then Result_Sel <= ARITH_INSTR_DEC; -- PC to store is coming from ALU end if; elsif( FSL_Will_Break_No_Dbg = '1' ) then -- FSL interrupted, store the previously calculated return PC. Result_Sel <= ARITH_INSTR_DEC; end if; end if; end if; end process Result_Mux_Decode; ----------------------------------------------------------------------------- -- Decode for Multiplier ----------------------------------------------------------------------------- Using_Mul_Instr: if (C_USE_MUL_INSTR) generate --------------------------------------------------------------------------- -- Multiplier -- EX_Not_Mul_Op is used so that the multiplier result is zero -- when the divider or FPU is selected --------------------------------------------------------------------------- EX_Not_Mul_Op_Decode : process (Clk) is begin if Clk'event and Clk = '1' then -- rising clock edge if Reset then ex_not_mul_op_i <= false; elsif of_PipeRun_i then ex_not_mul_op_i <= (instr_OF(5) or instr_OF(4)) = '1'; end if; end if; -- Clk end process EX_Not_Mul_op_Decode; end generate Using_Mul_Instr; No_Mul_Instr: if (not C_USE_MUL_INSTR) generate ex_not_mul_op_i <= true; end generate No_Mul_Instr; Using_Mul64: if (C_USE_MUL_INSTR and C_USE_MUL64) generate --------------------------------------------------------------------------- -- Multiplier -- EX_Mulh_Instr is used so that the multiplier knows that it should -- do a MULH instruction --------------------------------------------------------------------------- EX_Mulh_Instr_Decode : process (Clk) is begin if Clk'event and Clk = '1' then -- rising clock edge if Reset then ex_mulh_instr_i <= false; elsif of_PipeRun_I then ex_mulh_instr_i <= instr_OF(0 to 5) = "010000" and instr_OF(30 to 31) = "01"; end if; end if; -- Clk end process EX_Mulh_Instr_Decode; --------------------------------------------------------------------------- -- Multiplier -- EX_Mulhu_Instr is used so that the multiplier knows that it should -- do a MULHU instruction --------------------------------------------------------------------------- EX_Mulhu_Instr_Decode : process (Clk) is begin if Clk'event and Clk = '1' then -- rising clock edge if Reset then ex_mulhu_instr_i <= false; elsif of_PipeRun_I then ex_mulhu_instr_i <= instr_OF(0 to 5) = "010000" and instr_OF(30 to 31) = "11"; end if; end if; -- Clk end process EX_Mulhu_Instr_Decode; --------------------------------------------------------------------------- -- Multiplier -- EX_Mulhsu_Instr is used so that the multiplier knows that it should -- do a MULHSU instruction --------------------------------------------------------------------------- EX_Mulhsu_Instr_Decode : process (Clk) is begin if Clk'event and Clk = '1' then -- rising clock edge if Reset then ex_mulhsu_instr_i <= false; elsif of_PipeRun_I then ex_mulhsu_instr_i <= instr_OF(0 to 5) = "010000" and instr_OF(30 to 31) = "10"; end if; end if; -- Clk end process EX_Mulhsu_Instr_Decode; end generate Using_Mul64; No_Mul64 : if (not C_USE_MUL_INSTR or not C_USE_MUL64) generate ex_mulh_instr_i <= false; ex_mulhu_instr_i <= false; ex_mulhsu_instr_i <= false; end generate No_Mul64; EX_Not_Mul_Op <= ex_not_mul_op_i; EX_Mulh_Instr <= ex_mulh_instr_i; EX_Mulhu_Instr <= ex_mulhu_instr_i; EX_Mulhsu_Instr <= ex_mulhsu_instr_i; ----------------------------------------------------------------------------- -- Decoding Data strobes ----------------------------------------------------------------------------- Load_Store_Handler : process (Clk) is begin -- process Load_Store_Handler if Clk'event and Clk = '1' then -- rising clock edge if Reset then writing <= false; byte_i <= false; doublet_i <= false; quadlet_i <= false; doublet_Read_i <= false; quadlet_Read_i <= false; else if of_PipeRun_I then doublet_Read_i <= true; quadlet_Read_i <= true; writing <= false; byte_i <= false; doublet_i <= false; quadlet_i <= false; -- Specially decode the store instructions if (instr_OF(RESULT_SEL_POS_TYPE) = LOAD_STORE_DEC) and not take_Intr_Now then -- Load/Store doublet_Read_i <= (instr_OF(SIZE_POS_TYPE) /= BYTE_DEC); -- Not Byte quadlet_Read_i <= (instr_OF(SIZE_POS_TYPE) = QUADLET_DEC); -- Quadlet access byte_i <= instr_OF(SIZE_POS_TYPE) = BYTE_DEC; doublet_i <= instr_OF(SIZE_POS_TYPE) = DOUBLET_DEC; quadlet_i <= instr_OF(SIZE_POS_TYPE) = QUADLET_DEC; writing <= instr_OF(Store_POS) = STORE_DEC; end if; end if; end if; end if; end process Load_Store_Handler; Byte <= byte_i; Doublet <= doublet_i; Doublet_Read <= doublet_Read_i; Quadlet_Read <= quadlet_Read_i; ----------------------------------------------------------------------------- -- Handling PC ----------------------------------------------------------------------------- PC_Write <= ((i_AS_I) or (jump_I)); PC_Incr <= not missed_IFetch and not buffer_Full; of_Valid_S <= '1' when of_Valid else '0'; Missed_IFetch_DFF : process (Clk) is begin -- process Missed_IFetch_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then missed_IFetch <= false; nonvalid_IFetch_n <= '1'; else if (jump_I and not i_AS_I) then -- Missed fetch due to ongoing fetch missed_IFetch <= true; -- The missed IFetch should be ignored if -- There is no delay slot or -- If there is a delay slot but it's already fetched if (inHibit_EX) then nonvalid_IFetch_n <= '0'; else nonvalid_IFetch_n <= not of_Valid_s; end if; end if; if (missed_IFetch) then missed_IFetch <= (IReady = '0'); -- Back on track again end if; if (nonvalid_IFetch_n = '0') then nonvalid_IFetch_n <= IReady; end if; end if; end if; end process Missed_IFetch_DFF; -- Added since ISA tests needs this if_valid <= not missed_IFetch; Div_Decode : process (Clk) is begin -- process Div_Decode if Clk'event and Clk = '1' then -- rising clock edge if Reset then Start_Div_i <= '0'; Not_Div_Op <= '1'; else if (OF_PipeRun_I) then Start_Div_i <= '0'; Not_Div_Op <= instr_OF(5) or not(instr_OF(4)) or instr_OF(3); if (instr_OF(RESULT_SEL_POS_TYPE) = MULTI_INSTR_DEC) and (instr_OF(DIVFPU_POS_TYPE) = DIVFPU_DIV_DEC) then Start_Div_i <= '1'; end if; if (take_Intr_Now) then Start_Div_i <= '0'; end if; end if; end if; end if; end process Div_Decode; Div_Decode2 : process (Clk) is begin -- process Div_Decode2 if Clk'event and Clk = '1' then -- rising clock edge if (OF_PipeRun_I) then div_started <= '0'; elsif (Dbg_Inhibit_EX = '0') then div_started <= Start_Div_i; end if; end if; end process Div_Decode2; Start_Div <= Start_Div_i and not div_started when ex_Valid and (Dbg_Inhibit_EX = '0') else '0'; Write_DIV_Result_DFF: process (Clk) is begin -- process Write_DIV_Result_DFF if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) Write_DIV_Result <= false; else if (C_DIV_ZERO_EXCEPTION /= 0) then if (Exceptions_Enabled) then Write_DIV_Result <= (Div_Done = '1') and (Div_By_Zero = '0'); else Write_DIV_result <= (Div_Done = '1'); end if; else Write_DIV_result <= (Div_Done = '1'); end if; end if; end if; end process Write_DIV_Result_DFF; FPU_Decode : process (Clk) is begin -- process FPU_Decode if Clk'event and Clk = '1' then -- rising clock edge if Res
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -