📄 pps_di.vhd
字号:
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 + -