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

📄 alu_rtl.vhd

📁 Intel微处理器8088的VHDL实现
💻 VHD
📖 第 1 页 / 共 3 页
字号:
        end if;
        if ((alu_inbusa(7 downto 0) > X"9F") or (psrreg_s(0)='1')) then 
            setdaa_s(1) <= '1';     -- set CF
        else
            setdaa_s(1) <= '0';     -- clr CF
        end if;
        case setdaa_s is
            when "00"   => daabus_s <= alu_inbusa(7 downto 0);
            when "01"   => daabus_s <= alu_inbusa(7 downto 0) + X"06";
            when "10"   => daabus_s <= alu_inbusa(7 downto 0) + X"60";
            when others => daabus_s <= alu_inbusa(7 downto 0) + X"66";
        end case;
end process;

----------------------------------------------------------------------------
-- DAS Instruction  2F
----------------------------------------------------------------------------
-- if (((AL & 0x0F) > 9) || (AF == 1))
--      AL = AL - 6;
--      AF = 1;
-- else AF = 0;
-- if ((AL > 0x9F) || (CF == 1))
--      AL = AL - 0x60;
--      CF = 1;
-- else CF = 0;
----------------------------------------------------------------------------
process (alu_inbusa,psrreg_s,setdas_s)
    begin
        if ((alu_inbusa(3 downto 0) > X"9") or (psrreg_s(4)='1')) then  
            setdas_s(0) <= '1';     -- set AF
        else
            setdas_s(0) <= '0';     -- clr AF
        end if;
        if ((alu_inbusa(7 downto 0) > X"9F") or (psrreg_s(0)='1')) then 
            setdas_s(1) <= '1';     -- set CF
        else
            setdas_s(1) <= '0';     -- clr CF
        end if;
        case setdas_s is
            when "00"   => dasbus_s <= alu_inbusa(7 downto 0);
            when "01"   => dasbus_s <= alu_inbusa(7 downto 0) - X"06";
            when "10"   => dasbus_s <= alu_inbusa(7 downto 0) - X"60";
            when others => dasbus_s <= alu_inbusa(7 downto 0) - X"66";
        end case;
end process;

----------------------------------------------------------------------------
-- AAD Instruction  5D 0A
----------------------------------------------------------------------------
-- AL = (AH * 10) + AL;
-- AH = 0;
-- SF=1 if result is 0 or positive
-- SF=0 if result is negative
-- ZF=1 if result equal to 0
-- ZF=0 if result not equal to 0
-- PF=1 if low byte of result has even number of set bits
-- PF=0 otherwise
-- AF=?
----------------------------------------------------------------------------
process (alu_inbusa,aad1bus_s,aad2bus_s)
    begin
        aad1bus_s <= ("00" & alu_inbusa(15 downto 8) & '0') + (alu_inbusa(15 downto 8) & "000"); -- AH*2 + AH*8
        aad2bus_s <= aad1bus_s + ("000" & alu_inbusa(7 downto 0));   -- + AL
        aadbus_s<= "00000000" & aad2bus_s(7 downto 0);
end process;

----------------------------------------------------------------------------
-- ALU Operation
----------------------------------------------------------------------------
process (aluopr,abus_s,bbus_s,outbus_s,psrreg_s,alureg_s,aasbus_s,aaabus_s,daabus_s,sign16a_s,
         sign16b_s,sign32a_s,dasbus_s,product_s,divresult_s,alu_temp_s,aadbus_s,quotient_s,remainder_s) 
    begin
        case aluopr is
    
            when ALU_ADD | ALU_ADD_SE | ALU_INC | ALU_POP | ALU_SUB | ALU_SUB_SE | ALU_DEC | ALU_PUSH | ALU_CMP | ALU_CMP_SE | 
                 ALU_CMPS | ALU_ADC | ALU_ADC_SE | ALU_SBB | ALU_SBB_SE | ALU_SCAS | ALU_NEG | ALU_NOT
                            => alubus_s <= outbus_s;                
    
            when ALU_OR | ALU_OR_SE     
                            => alubus_s <= abus_s OR bbus_s;
            when ALU_AND | ALU_AND_SE | ALU_TEST0 | ALU_TEST1 | ALU_TEST2   
                            => alubus_s <= abus_s AND bbus_s;
            when ALU_XOR | ALU_XOR_SE   
                            => alubus_s <= abus_s XOR bbus_s;

            when ALU_LAHF   => alubus_s <= psrreg_s(15 downto 2)&'1'&psrreg_s(0);-- flags onto ALUBUS, note reserved bit1=1
                        
            when ALU_MUL | ALU_IMUL 
                            => alubus_s <= product_s(15 downto 0);  -- AX of Multiplier
            when ALU_MUL2| ALU_IMUL2
                            => alubus_s <= product_s(31 downto 16); -- DX of Multiplier
                        
            when ALU_DIV | ALU_IDIV                                 
                            => alubus_s <= divresult_s(15 downto 0);-- AX of Divider (quotient)   
            when ALU_DIV2| ALU_IDIV2
                            => alubus_s <= divresult_s(31 downto 16);-- DX of Divider (remainder) 
                                                                                
            when ALU_SEXT   => alubus_s <= sign16a_s;               -- Used for CBW Instruction
            when ALU_SEXTW  => alubus_s <= sign32a_s;               -- Used for CWD Instruction

            when ALU_AAS    => alubus_s <= aasbus_s;                -- Used for AAS Instruction
            when ALU_AAA    => alubus_s <= aaabus_s;                -- Used for AAA Instruction
            when ALU_DAA    => alubus_s <= abus_s(15 downto 8) & daabus_s;-- Used for DAA Instruction
            when ALU_DAS    => alubus_s <= abus_s(15 downto 8) & dasbus_s;-- Used for DAS Instruction
            when ALU_AAD    => alubus_s <= aadbus_s;                -- Used for AAD Instruction
            when ALU_AAM    => alubus_s <= quotient_s(7 downto 0) & remainder_s(7 downto 0); -- Used for AAM Instruction

            when ALU_ROL | ALU_ROL1 | ALU_ROR | ALU_ROR1 | ALU_RCL | ALU_RCL1 | ALU_RCR | ALU_RCR1 |    
                 ALU_SHL | ALU_SHL1 | ALU_SHR | ALU_SHR1 | ALU_SAR | ALU_SAR1 | ALU_REGL   
                            => alubus_s <= alureg_s(15 downto 0);   -- alu_inbusb to output

            when ALU_REGH  => alubus_s <= alureg_s(31 downto 16);  -- alu_inbusa to output

            when ALU_PASSA  => alubus_s <= abus_s;
            --when ALU_PASSB  => alubus_s <= bbus_s;

            when ALU_TEMP   => alubus_s <= alu_temp_s;              

            when others     => alubus_s <= DONTCARE(15 downto 0);           
        end case;
end process;
alubus <= alubus_s;                 -- Connect to entity

                  
----------------------------------------------------------------------------
-- Processor Status Register  (Flags)
-- bit   Flag
-- 15    Reserved
-- 14    Reserved
-- 13    Reserved               Set to 1?
-- 12    Reserved               Set to 1?
-- 11    Overflow Flag OF
-- 10    Direction Flag DF
-- 9     Interrupt Flag IF
-- 8     Trace Flag TF
-- 7     Sign Flag SF
-- 6     Zero Flag ZF
-- 5     Reserved
-- 4     Auxiliary Carry AF
-- 3     Reserved
-- 2     Parity Flag PF
-- 1     Reserved               Set to 1 ????
-- 0     Carry Flag
----------------------------------------------------------------------------
process (clk, reset)
    begin 
        if reset='1' then
            psrreg_s <= "0011000000000010";--(others => '0');   -- Change?
        elsif rising_edge(clk) then
            if (wrcc='1') then  
                case aluopr is
                    when ALU_ADD | ALU_ADD_SE | ALU_ADC | ALU_ADC_SE | ALU_INC  =>
                            OFLAG <= overflow_s; 
                            SFLAG <= signflag_s; 
                            ZFLAG <= zeroflag_s;
                            AFLAG <= bit4_s;
                            PFLAG <= parityflag_s;
                            CFLAG <= cout_s;    
                    when ALU_DEC => -- Same as for ALU_SUB exclusing the CFLAG :-(
                            OFLAG <= overflow_s; 
                            SFLAG <= signflag_s; 
                            ZFLAG <= zeroflag_s;
                            AFLAG <= not bit4_s;
                            PFLAG <= parityflag_s;
                    when ALU_SUB | ALU_SUB_SE | ALU_SBB | ALU_SBB_SE | ALU_CMP | 
                         ALU_CMP_SE | ALU_CMPS | ALU_SCAS | ALU_NEG =>
                            OFLAG <= overflow_s; 
                            SFLAG <= signflag_s; 
                            ZFLAG <= zeroflag_s;
                            AFLAG <= not bit4_s;
                            PFLAG <= parityflag_s;
                            CFLAG <= not cout_s;                                                                
                    when ALU_OR | ALU_OR_SE |  ALU_AND | ALU_AND_SE | ALU_XOR | ALU_XOR_SE | ALU_TEST0 | ALU_TEST1 | ALU_TEST2 =>
                            OFLAG <= '0'; 
                            SFLAG <= signflag_s;        
                            ZFLAG <= zeroflag_s;
                            AFLAG <= '0';           -- None defined, set to 0 to be compatible with debug
                            PFLAG <= parityflag_s;
                            CFLAG <= '0';
                    when ALU_SHL  | ALU_SHR  | ALU_SAR |
                         ALU_SHR1 | ALU_SAR1 | ALU_SHL1 => 
                            OFLAG <= overflow_s;
                            PFLAG <= parityflag_s;
                            SFLAG <= signflag_s;
                            ZFLAG <= zeroflag_s;
                            CFLAG <= alucout_s;                                                         
                                                                                    
                    when ALU_CLC =>
                            CFLAG <= '0';
                    when ALU_CMC =>
                            CFLAG <= not CFLAG;
                    when ALU_STC =>
                            CFLAG <= '1';
                    when ALU_CLD =>
                            DFLAG <= '0';
                    when ALU_STD =>
                            DFLAG <= '1';
                    when ALU_CLI =>
                            IFLAG <= '0';
                    when ALU_STI =>
                            IFLAG <= '1';
                    when ALU_POP =>                         -- Note only POPF executes a WRCC command, thus save for other pops
                            psrreg_s <= alu_inbusa; --or ABUS???-- Write memory operand (MDBUS) to CC register
                    when ALU_SAHF =>                            -- Write all AH bits (not compatible!)
                 --         psrreg_s(7 downto 0) <= alu_inbusa(7 downto 0);--alu_inbusa(15 downto 8); -- SAHF only writes bits 7,6,4,2,0
                            psrreg_s(7 downto 0) <= alu_inbusa(7 downto 6) & '0' & alu_inbusa(4) & '0' &
                                                    alu_inbusa(2) & '0' & alu_inbusa(0);-- SAHF only writes bits 7,6,4,2,0

                    when ALU_AAS  =>
                            AFLAG <= setaas_s;                  -- set or clear CF/AF flag
                            CFLAG <= setaas_s;
                            SFLAG <= '0';               -- **** Undefined, cleared to match debug output!!!!!! *****        
                    when ALU_AAA  =>
                            AFLAG <= setaaa_s;          -- set or clear CF/AF flag
                            CFLAG <= setaaa_s;
                    when ALU_DAA  =>
                            AFLAG <= setdaa_s(0);       -- set or clear CF/AF flag
                            CFLAG <= setdaa_s(1);
                            PFLAG <= parityflag_s;
                            SFLAG <= signflag_s; 
                            ZFLAG <= zeroflag_s;

                    when ALU_AAD  =>
                            SFLAG <= alubus_s(7); --signflag_s; 
                            PFLAG <= parityflag_s;
                            ZFLAG <= zeroflag_s;

                    when ALU_AAM  =>
                            SFLAG <= signflag_s;
                            PFLAG <= parityflag_s;
                            ZFLAG <= not(zflaglow_s);           -- signflag on AL only

                    when ALU_DAS  =>
                            AFLAG <= setdas_s(0);       -- set or clear CF/AF flag
                            CFLAG <= setdas_s(1);
                            PFLAG <= parityflag_s;
                            SFLAG <= signflag_s; 
                            ZFLAG <= zeroflag_s;
                                                        -- Shift Rotate Instructions
                    when ALU_ROL  | ALU_ROR  | ALU_RCL  | ALU_RCR | 
                         ALU_ROL1 | ALU_RCL1 | ALU_ROR1 | ALU_RCR1 =>
                            CFLAG <= alucout_s;
                            OFLAG <= overflow_s; 

                    when ALU_MUL | ALU_MUL2 | ALU_IMUL | ALU_IMUL2 =>  -- Multiply affects CF&OF only
                            CFLAG <= overflow_s;
                            OFLAG <= overflow_s; 

                    when ALU_CLRTIF  =>                 -- Clear TF and IF flag
                            IFLAG <= '0';              
                            TFLAG <= '0'; 

                    when others =>
                            psrreg_s <= psrreg_s;
                end case;
            end if; 
        end if; 
end process;  

ccbus <= psrreg_s;                                      -- Connect to entity

-- Latch Divide by 0 error flag & latched divresult.
-- Requires a MCP from all registers to these endpoint registers!
process (clk, reset)
    begin 
        if reset='1' then
            div_err  <= '0';
            divresult_s <= (others => '0');
        elsif rising_edge(clk) then
            if done_s='1' then              -- Latched pulse generated by serial divider  
                div_err  <= div_err_s;              -- Divide Overflow
                -- pragma synthesis_off
                assert div_err_s='0' report "**** Divide Overflow ***" severity failure;
                -- pragma synthesis_on

                if wl_s='1' then             -- Latched version required?????
                    divresult_s <= remainder_s & quotient_s; 
                else 
                    divresult_s <= remainder_s & remainder_s(7 downto 0) & quotient_s(7 downto 0);
                end if;
            else
                div_err <= '0';
            end if;
        end if; 
end process;  

end rtl;

⌨️ 快捷键说明

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