⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pps_di.vhd

📁 这是一个基于mips-I结构的处理器,32bit,冯诺依曼结构
💻 VHD
📖 第 1 页 / 共 2 页
字号:
        variable rt : bus5;        variable rd : bus5;        variable shamt : bus5;        variable imm : bus16;        variable address : bus26;    begin        -- Selection of the instruction codop and its mode        case EI_instr(31 downto 26) is            when "000000" => -- special mode                 op_mode := OP_SPECIAL;                op_code := EI_instr(5 downto 0);            when "000001" => -- regimm mode                op_mode := OP_REGIMM;                op_code := '0' & EI_instr(20 downto 16);            when "010000" => -- cop0 mode                op_mode := OP_COP0;                op_code := '0' & EI_instr(25 downto 21);            when others   => -- normal mode                op_mode := OP_NORMAL;                op_code := EI_instr(31 downto 26);        end case;        -- Search the current instruction in the micro-code table        flag := false;        instr := 0;        for i in micro_code'range loop            if micro_code(i).op_mode=op_mode and micro_code(i).op_code=op_code then                flag := true;           -- The instruction exists                instr := i;             -- Index memorisation            end if;        end loop;        -- Read the instruction field        rs      := EI_instr(25 downto 21);        rt      := EI_instr(20 downto 16);        rd      := EI_instr(15 downto 11);        shamt   := EI_instr(10 downto  6);        imm     := EI_instr(15 downto  0);        address := EI_instr(25 downto  0);        if not flag then -- Unknown instruction            -- Synchronous output preparation            PRE_bra          <= '0';              -- Branch operation            PRE_link         <= '0';              -- Branch with link            PRE_op1          <= (others => '0');  -- operand 1 of the ual            PRE_op2          <= (others => '0');  -- operand 2 of the ual            PRE_code_ual     <= OP_OUI;           -- Alu operation            PRE_offset       <= (others => '0');  -- Address offset for calculation            PRE_adr_reg_dest <= (others => '0');  -- Destination register adress for result            PRE_ecr_reg      <= '0';              -- Writing of result in the bank register            PRE_mode         <= '0';              -- Address calculation with current pc            PRE_op_mem       <= '0';              -- Memory access operation instruction             PRE_r_w          <= '0';              -- Read/write selection in memory            PRE_exc_cause    <= IT_ERINS;         -- Potential exception cause            PRE_level        <= LVL_DI;           -- Result availability stage for bypass            -- Set asynchronous outputs            adr_reg1 <= (others => '0');    -- First operand register            adr_reg2 <= (others => '0');    -- Second operand register            bra_detect <= '0';              -- Detection of a branch in current instruction            use1 <= '0';                    -- Effective use of operand 1            use2 <= '0';                    -- Effective use of operand 2        else -- Valid instruction            -- Offset signal preparation            case micro_code(instr).off_sel is                when OFS_PCRL => -- PC(31..28) & Adresse & 00                    PRE_offset <= EI_adr(31 downto 28) & address & "00";                when OFS_NULL => -- 0                    PRE_offset <= (others => '0');                when OFS_SESH => -- sgn_ext(Imm) & 00                    if imm(15)='1' then                        PRE_offset <= "11111111111111" & imm & "00";                    else                        PRE_offset <= "00000000000000" & imm & "00";                    end if;                when OFS_SEXT => -- sgn_ext(Imm)                    if imm(15)='1' then                        PRE_offset <= "1111111111111111" & imm;                    else                        PRE_offset <= "0000000000000000" & imm;                    end if;            end case;            -- Alu operand preparation            if micro_code(instr).cs_imm1='0' then                -- Datas from register banks                PRE_op1 <= data1;            else                -- Immediate datas                if micro_code(instr).imm1_sel='0' then                    PRE_op1 <= (others => '0');             -- Immediate operand = 0                else                    PRE_op1 <= X"000000" & "000" & shamt;   -- Immediate operand = shamt                end if;            end if;            if micro_code(instr).cs_imm2='0' then                -- Datas from register banks                PRE_op2 <= data2;            else                -- Immediate datas                if micro_code(instr).imm2_sel='0' then                    PRE_op2 <= X"0000" & imm;               -- Immediate operand = imm                else                    if imm(15)='1' then                     -- Immediate operand = sgn_ext(imm)                        PRE_op2 <= X"FFFF" & imm;                    else                        PRE_op2 <= X"0000" & imm;                    end if;                end if;            end if;            -- Selection of destination register address            case micro_code(instr).des_sel is                when D_RT => PRE_adr_reg_dest <= micro_code(instr).bank_des & rt;                when D_RD => PRE_adr_reg_dest <= micro_code(instr).bank_des & rd;                when D_31 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "11111";                when D_00 => PRE_adr_reg_dest <= micro_code(instr).bank_des & "00000";            end case;            -- Command signal affectation            PRE_bra       <= micro_code(instr).bra;        -- Branch operation            PRE_link      <= micro_code(instr).link;       -- Branch with link            PRE_code_ual  <= micro_code(instr).code_ual;   -- Alu operation            PRE_ecr_reg   <= micro_code(instr).ecr_reg;    -- Writing the result in a bank register            PRE_mode      <= micro_code(instr).mode;       -- Type of calculation for the address with current pc            PRE_op_mem    <= micro_code(instr).op_mem;     -- Memory operation needed            PRE_r_w       <= micro_code(instr).r_w;        -- Read/Write in memory selection            PRE_exc_cause <= micro_code(instr).exc_cause;  -- Potential cause exception            PRE_level     <= micro_code(instr).level;            -- Set asynchronous outputs            adr_reg1 <= micro_code(instr).cop_org1 & rs; -- First operand register address            adr_reg2 <= micro_code(instr).cop_org2 & rt; -- Second operand register address            bra_detect <= micro_code(instr).bra;         -- Branch detection in current instruction            use1 <= not micro_code(instr).cs_imm1;       -- Effective use of operande 1            use2 <= not micro_code(instr).cs_imm2;       -- Effective use of operande 2        end if;    end process;    -- Set the synchronous outputs    process (clock)    begin        if clock='1' and clock'event then            if reset='1' then                DI_bra <= '0';                DI_link <= '0';                DI_op1 <= (others => '0');                DI_op2 <= (others => '0');                DI_code_ual <= OP_OUI;                DI_offset <= (others => '0');                DI_adr_reg_dest <= (others => '0');                DI_ecr_reg <= '0';                DI_mode <= '0';                DI_op_mem <= '0';                DI_r_w <= '0';                DI_adr <= (others => '0');                DI_exc_cause <= IT_NOEXC;                DI_level <= LVL_DI;                DI_it_ok <= '0';            elsif stop_all='0' then                if clear='1' or stop_di='1' then                    -- Nop instruction                    DI_bra <= '0';                    DI_link <= '0';                    DI_op1 <= (others => '0');                    DI_op2 <= (others => '0');                    DI_code_ual <= OP_OUI;                    DI_offset <= (others => '0');                    DI_adr_reg_dest <= (others => '0');                    DI_ecr_reg <= '0';                    DI_mode <= '0';                    DI_op_mem <= '0';                    DI_r_w <= '0';                    DI_adr <= EI_adr;                    DI_exc_cause <= IT_NOEXC;                    DI_level <= LVL_DI;                    if clear='1' then                      DI_it_ok <= '0';                    else                      DI_it_ok <= EI_it_ok;                    end if;                else -- Noraml step                    DI_bra <= PRE_bra;                    DI_link <= PRE_link;                    DI_op1 <= PRE_op1;                    DI_op2 <= PRE_op2;                    DI_code_ual <= PRE_code_ual;                    DI_offset <= PRE_offset;                    DI_adr_reg_dest <= PRE_adr_reg_dest;                    DI_ecr_reg <= PRE_ecr_reg;                    DI_mode <= PRE_mode;                    DI_op_mem <= PRE_op_mem;                    DI_r_w <= PRE_r_w;                    DI_adr <= EI_adr;                    DI_exc_cause <= PRE_exc_cause;                    DI_level <= PRE_level;                    DI_it_ok <= EI_it_ok;                end if;            end if;        end if;    end process;end rtl;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -