📄 operand_select.vhd
字号:
else if (Res_Forward2) then reg2 := EX_Result; else reg2 := Reg2_Data; end if; end if; if (Take_Ext_BRK) then imm2 := EXT_BRK_ADDR; elsif (Take_Exception) then imm2 := EXC_ADDR; else if (Use_Imm_Reg) then imm2 := imm_Extend_Reg; else imm2 := Sign_Imm; end if; end if; if (OpSel2_Imm) then Op2_I <= imm2; Op2_C_I <= imm2; else Op2_I <= reg2; Op2_C_I <= reg2; end if; end process Op2_Handle; Op2_DFF : process (Clk) is begin -- process Op2_DFF if Clk'event and Clk = '1' then -- rising clock edge -- MSB bits must be able to select between 0 and -4. for I in 0 to C_DATA_SIZE-3 loop if (Store_PC_For_Intr_NoImm) then Op2(I) <= '0'; Op2_C(I) <= '0'; elsif (Store_PC_For_Intr) then Op2(I) <= '1'; Op2_C(I) <= '1'; elsif (OF_PipeRun) then Op2(I) <= Op2_I(I); Op2_C(I) <= Op2_C_I(I); end if; end loop; -- The two LSB bits are always zero. for I in C_DATA_SIZE-2 to C_DATA_SIZE-1 loop if (Store_PC_For_Intr) then Op2(I) <= '0'; Op2_C(I) <= '0'; elsif (OF_PipeRun) then Op2(I) <= Op2_I(I); Op2_C(I) <= Op2_C_I(I); end if; end loop; end if; end process Op2_DFF; end generate Using_RTL; ----------------------------------------------------------------------------- -- Store the Imm value for Imm Instructions ----------------------------------------------------------------------------- Size_4to16 : if (C_DATA_SIZE < 17) generate imm_Extend_Reg <= Imm_Value(16-C_DATA_SIZE to 15); end generate Size_4to16; Size_17to32 : if (C_DATA_SIZE > 16) and (C_DATA_SIZE < 33) generate signal imm_Reg : std_logic_vector(0 to C_DATA_SIZE-17); begin -- Build the Immediate value to be used if the Imm_Reg should be used imm_Extend_Reg(0 to C_DATA_SIZE-17) <= imm_Reg; imm_Extend_Reg(C_DATA_SIZE-16 to C_DATA_SIZE-1) <= Imm_Value; Imm_DFF : process (Clk) is begin -- process Imm_Reg if Clk'event and Clk = '1' then -- rising clock edge if Reset then Imm_Reg <= (others => '0'); else if Imm_Instr then Imm_Reg <= Imm_Value; end if; end if; end if; end process Imm_DFF; end generate Size_17to32; Size_33to64 : if (C_DATA_SIZE > 32) generate signal imm_Reg : std_logic_vector(0 to C_DATA_SIZE-17); begin -- Build the Immediate value to be used if the Imm_Reg should be used imm_Extend_Reg(0 to C_DATA_SIZE-17) <= imm_Reg; imm_Extend_Reg(C_DATA_SIZE-16 to C_DATA_SIZE-1) <= Imm_Value; Imm_DFF : process (Clk) is variable No : natural range 0 to 2; begin -- process Imm_Reg if Clk'event and Clk = '1' then -- rising clock edge if Reset then Imm_Reg <= (others => '0'); No := 0; else if (OF_PipeRun) then if (Imm_Instr) then if (No = 0) then Imm_Reg(0 to 31) <= (others => Imm_Value(0)); Imm_Reg(32 to 47) <= Imm_Value; elsif (No = 1) then Imm_Reg(0 to 15) <= (others => Imm_Value(0)); Imm_Reg(16 to 31) <= Imm_Value; else Imm_Reg(0 to 15) <= Imm_Value; end if; No := No + 1; else No := 0; end if; end if; end if; end if; end process Imm_DFF; end generate Size_33to64; ----------------------------------------------------------------------------- -- Exception handling ----------------------------------------------------------------------------- Use_Exceptions : if (C_USE_EXCEPTIONS) generate ----------------------------------------------------------------------------- -- To help unalignment detection ----------------------------------------------------------------------------- Unalignment_Decoding : process (Clk) is variable reg1 : std_logic_vector(30 to 31); variable reg2 : std_logic_vector(30 to 31); begin -- process Unalignment_Decoding if Clk'event and Clk = '1' then -- rising clock edge if Reset then -- synchronous reset (active high) word_r1_r2_unalignment <= '0'; word_r1_imm_unalignment <= '0'; halfword_unalignment <= '0'; else if (OF_PipeRun) then -- Correct word alignement when the two low operands are -- R1(30..31) R2(30..31) -- 00 00 -- 01 11 -- 10 10 -- 11 01 -- easier to code when it's not unalignment if (Res_Forward1) then reg1 := EX_Result(reg1'range); else reg1 := Reg1_Data(reg1'range); end if; if (Res_Forward2) then reg2 := EX_Result(reg2'range); else reg2 := Reg2_Data(reg2'range); end if; if (OpSel2_Imm) then word_r1_r2_unalignment <= not ((not(reg1(30)) and not(reg1(31)) and not (Imm_Value(14)) and not(Imm_Value(15))) or (not(reg1(30)) and reg1(31) and Imm_Value(14) and Imm_Value(15)) or (reg1(30) and not(reg1(31)) and Imm_Value(14) and not(Imm_Value(15))) or (reg1(30) and reg1(31) and not(Imm_Value(14)) and (Imm_Value(15)))); else word_r1_r2_unalignment <= not ((not(reg1(30)) and not(reg1(31)) and not (reg2(30)) and not(reg2(31))) or (not(reg1(30)) and reg1(31) and reg2(30) and reg2(31)) or (reg1(30) and not(reg1(31)) and reg2(30) and not(reg2(31))) or (reg1(30) and reg1(31) and not(reg2(30)) and (reg2(31))));-- word_r1_Imm_unalignment <= not ((not(reg1(30)) and not(reg1(31)) and not (Imm_Value(14)) and not(Imm_Value(15)))-- or-- (not(reg1(30)) and reg1(31) and Imm_Value(14) and Imm_Value(15))-- or-- (reg1(30) and not(reg1(31)) and Imm_Value(14) and not(Imm_Value(15)))-- or-- (reg1(30) and reg1(31) and not(Imm_Value(14)) and (Imm_Value(15)))); end if; -- For halfword unalignment we can decode both possibilites in one lut if (OpSel2_Imm) then halfword_unalignment <= reg1(31) xor Imm_Value(15); else halfword_unalignment <= reg1(31) xor reg2(31); end if; end if; end if; end if; end process Unalignment_Decoding; MFS_Reg_Selector : process (BTR, EAR, EDR, ESR, FSR, MFS_Reg_Sel, MSR) is begin -- process MFS_Reg_Selector if (not C_USE_FPU_bool) then case MFS_Reg_Sel is when EXT_SPR_MSR_DEC => -- Reading MSR spr_zero_extended <= (others => '0'); spr_zero_extended(MSR_CC_POS) <= MSR(MSR_C_POS); spr_zero_extended(C_DATA_SIZE-MSR'length to C_DATA_SIZE-1) <= MSR; Enable_SPR_I <= (others => '0'); Enable_SPR_I(MSR_CC_POS) <= '1'; Enable_SPR_I(C_DATA_SIZE-MSR'length to C_DATA_SIZE-1) <= (others => '1'); when EXT_SPR_EAR_DEC => -- Reading EAR Enable_SPR_I <= (others => '1'); spr_zero_extended <= EAR; when EXT_SPR_EDR_DEC => -- Reading EDR if( C_FSL_EXCEPTION ) then -- FSL exceptions are available. Enable_SPR_I <= (others => '1'); spr_zero_extended <= EDR; else -- Exceptions but not FSL -- => Treat as others case. Enable_SPR_I <= (others => '0'); Enable_SPR_I(BTR'range) <= (others => '1'); spr_zero_extended <= (others => '0'); spr_zero_extended(BTR'range) <= BTR; end if; when EXT_SPR_ESR_DEC => -- Reading ESR Enable_SPR_I <= (others => '0'); Enable_SPR_I(ESR'range) <= (others => '1'); spr_zero_extended <= (others => '0'); spr_zero_extended(ESR'range) <= ESR; when others => -- Reading BTR Enable_SPR_I <= (others => '0'); Enable_SPR_I(BTR'range) <= (others => '1'); spr_zero_extended <= (others => '0'); spr_zero_extended(BTR'range) <= BTR; end case; else case MFS_Reg_Sel is when EXT_SPR_MSR_DEC => -- Reading MSR spr_zero_extended <= (others => '0'); spr_zero_extended(MSR_CC_POS) <= MSR(MSR_C_POS); spr_zero_extended(C_DATA_SIZE-MSR'length to C_DATA_SIZE-1) <= MSR; Enable_SPR_I <= (others => '0'); Enable_SPR_I(MSR_CC_POS) <= '1'; Enable_SPR_I(C_DATA_SIZE-MSR'length to C_DATA_SIZE-1) <= (others => '1'); when EXT_SPR_EAR_DEC => -- Reading EAR Enable_SPR_I <= (others => '1'); spr_zero_extended <= EAR; when EXT_SPR_EDR_DEC => -- Reading EDR if( C_FSL_EXCEPTION ) then -- FSL exceptions are available. Enable_SPR_I <= (others => '1'); spr_zero_extended <= EDR; else -- Exceptions but not FSL -- => Treat as others case. Enable_SPR_I <= (others => '0'); Enable_SPR_I(C_DATA_SIZE-FSR'length to C_DATA_SIZE-1) <= (others => '1'); spr_zero_extended <= (others => '0'); spr_zero_extended(C_DATA_SIZE-FSR'length to C_DATA_SIZE-1) <= FSR; end if; when EXT_SPR_ESR_DEC => -- Reading ESR Enable_SPR_I <= (others => '0'); Enable_SPR_I(ESR'range) <= (others => '1'); spr_zero_extended <= (others => '0'); spr_zero_extended(ESR'range) <= ESR; when EXT_SPR_BTR_DEC => -- Reading BTR Enable_SPR_I <= (others => '0'); Enable_SPR_I(BTR'range) <= (others => '1'); spr_zero_extended <= (others => '0'); spr_zero_extended(BTR'range) <= BTR; when others => -- Reading FSR Enable_SPR_I <= (others => '0'); Enable_SPR_I(C_DATA_SIZE-FSR'length to C_DATA_SIZE-1) <= (others => '1'); spr_zero_extended <= (others => '0'); spr_zero_extended(C_DATA_SIZE-FSR'length to C_DATA_SIZE-1) <= FSR; end case; end if; end process MFS_Reg_Selector; end generate Use_Exceptions; No_Exceptions : if (not C_USE_EXCEPTIONS) generate signal spr_zero_extended_i : std_logic_vector(0 to C_DATA_SIZE-1); begin ----------------------------------------------------------------------------- -- Zero extend MSR register bit to full data size -- but replicate the carry bit to the msb bit for easy branches on carry -- adding the MUX for the FSR register ----------------------------------------------------------------------------- Zero_Extend_MSR : process (MSR, MFS_Reg_Sel, FSR) is begin -- process Zero_Extend_MSR if (C_USE_FPU_bool and MFS_Reg_Sel = EXT_SPR_FSR_DEC) then -- FSR spr_zero_extended_i <= (others => '0'); spr_zero_extended_i(C_DATA_SIZE-FSR'length to C_DATA_SIZE-1) <= FSR; else -- MSR spr_zero_extended_i <= (others => '0'); spr_zero_extended_i(MSR_CC_POS) <= MSR(MSR_C_POS); spr_zero_extended_i(C_DATA_SIZE-MSR'length to C_DATA_SIZE-1) <= MSR; end if; end process Zero_Extend_MSR; -- This must be done in a process Enable_SPR_Process : process (Reset) is constant NOT_USED_EXC_BITS : integer := 2; -- Number of exception bits not implemented begin Enable_SPR_I <= (others => '0'); -- Unused bits Enable_SPR_I(MSR_CC_POS) <= '1'; if (C_PVR /= C_PVR_NONE) then Enable_SPR_I(MSR_PVR_POS) <= '1'; end if; Enable_SPR_I(C_DATA_SIZE - MSR'length + NOT_USED_EXC_BITS to C_DATA_SIZE-1) <= (others => '1'); end process Enable_SPR_Process; word_r1_r2_unalignment <= '0'; word_r1_imm_unalignment <= '0'; halfword_unalignment <= '0'; spr_zero_extended <= spr_zero_extended_i; end generate No_Exceptions;end architecture IMP;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -