URL
https://opencores.org/ocsvn/ax8/ax8/trunk
Subversion Repositories ax8
[/] [ax8/] [trunk/] [rtl/] [vhdl/] [AX_ALU.vhd] - Rev 6
Go to most recent revision | Compare with Previous | Blame | View Log
-- -- AT90Sxxxx compatible microcontroller core -- -- Version : 0146 -- -- Copyright (c) 2001-2002 Daniel Wallner (jesus@opencores.org) -- -- All rights reserved -- -- Redistribution and use in source and synthezised forms, with or without -- modification, are permitted provided that the following conditions are met: -- -- Redistributions of source code must retain the above copyright notice, -- this list of conditions and the following disclaimer. -- -- Redistributions in synthesized form must reproduce the above copyright -- notice, this list of conditions and the following disclaimer in the -- documentation and/or other materials provided with the distribution. -- -- Neither the name of the author nor the names of other contributors may -- be used to endorse or promote products derived from this software without -- specific prior written permission. -- -- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, -- THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -- PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE -- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -- -- Please report bugs to the author, but before you do so, please -- make sure that this is not a derivative work and that -- you have the latest version of this file. -- -- The latest version of this file can be found at: -- http://www.opencores.org/cvsweb.shtml/t51/ -- -- Limitations : -- -- File history : -- library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; use work.AX_Pack.all; entity AX_ALU is port ( Clk : in std_logic; ROM_Data : in std_logic_vector(15 downto 0); A : in std_logic_vector(7 downto 0); B : in std_logic_vector(7 downto 0); Q : inout std_logic_vector(8 downto 0); SREG : in std_logic_vector(7 downto 0); PassB : in std_logic; Skip : in std_logic; Do_Other : out std_logic; Z_Skip : out std_logic; Status_D : out std_logic_vector(6 downto 1); Status_Wr : out std_logic_vector(6 downto 0) -- T,H,S,V,N,Z,C ); end AX_ALU; architecture rtl of AX_ALU is signal Do_NEG : std_logic; signal Do_ADD : std_logic; signal Do_SUB : std_logic; signal Do_DEC : std_logic; signal Do_INC : std_logic; signal Do_AND : std_logic; signal Do_OR : std_logic; signal Do_XOR : std_logic; signal Do_COM : std_logic; signal Do_SWAP : std_logic; signal Do_BLD : std_logic; signal Do_BST : std_logic; signal Do_ROR : std_logic; signal Do_ASR : std_logic; signal Do_LSR : std_logic; signal Do_PASSB : std_logic; signal Do_SBRC : std_logic; signal Do_SBRS : std_logic; signal Use_Carry : std_logic; signal Bit_Pattern : std_logic_vector(7 downto 0); signal Bit_Test : std_logic_vector(7 downto 0); -- AddSub intermediate signals signal Carry7_v : std_logic; signal Overflow_v : std_logic; signal Overflow_t : std_logic; signal HalfCarry_v : std_logic; signal Carry_v : std_logic; signal Q_v : std_logic_vector(7 downto 0); signal AAS : std_logic_vector(7 downto 0); signal BAS : std_logic_vector(7 downto 0); begin Do_Other <= Do_PASSB; process (Clk) begin if Clk'event and Clk = '1' then Do_SUB <= '0'; Do_ADD <= '0'; Use_Carry <= '0'; Do_AND <= '0'; Do_XOR <= '0'; Do_OR <= '0'; Do_SWAP <= '0'; Do_ASR <= '0'; Do_LSR <= '0'; Do_ROR <= '0'; Do_INC <= '0'; Do_DEC <= '0'; Do_COM <= '0'; Do_NEG <= '0'; Do_BLD <= '0'; Do_BST <= '0'; Do_PASSB <= '0'; Do_SBRC <= '0'; Do_SBRS <= '0'; if PassB = '0' then if Skip = '0' then if ROM_Data(15 downto 10) = "000101" or ROM_Data(15 downto 12) = "0011" or ROM_Data(15 downto 10) = "000110" or ROM_Data(15 downto 12) = "0101" or ROM_Data(15 downto 12) = "0100" or ROM_Data(15 downto 10) = "000001" or ROM_Data(15 downto 10) = "000010" or (ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0001") or (ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "1010") then -- CP, CPI, SUB, SUBI, SBCI, CPC, SBC, NEG, DEC Do_SUB <= '1'; end if; if ROM_Data(15 downto 10) = "000011" or ROM_Data(15 downto 10) = "000111" or (ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0011") then -- ADD, ADC, INC Do_ADD <= '1'; end if; if ROM_Data(15 downto 12) = "0100" or ROM_Data(15 downto 10) = "000001" or ROM_Data(15 downto 10) = "000010" or ROM_Data(15 downto 10) = "000111" then -- SBCI, CPC, SBC, ADC Use_Carry <= '1'; end if; if ROM_Data(15 downto 10) = "001000" or ROM_Data(15 downto 12) = "0111" then -- AND, ANDI Do_AND <= '1'; end if; if ROM_Data(15 downto 10) = "001001" then -- EOR Do_XOR <= '1'; end if if ROM_Data(15 downto 10) = "001010" or ROM_Data(15 downto 12) = "0110" then -- OR, ORI Do_OR <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0010" then -- SWAP Do_SWAP <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0101" then -- ASR Do_ASR <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0110" then -- LSR Do_LSR <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0111" then -- ROR Do_ROR <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0011" then -- INC Do_INC <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "1010" then -- DEC Do_DEC <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0000" then -- COM Do_COM <= '1'; end if; if ROM_Data(15 downto 9) = "1001010" and ROM_Data(3 downto 0) = "0001" then -- NEG Do_NEG <= '1'; end if; if ROM_Data(15 downto 9) = "1111100" then -- BLD Do_BLD <= '1'; end if; if ROM_Data(15 downto 9) = "1111101" then -- BST Do_BST <= '1'; end if; if ROM_Data(15 downto 10) = "001011" or ROM_Data(15 downto 12) = "1011" or ROM_Data(15 downto 12) = "1110" then -- MOV, DidPause, IN, OUT, LDI Do_PASSB <= '1'; end if; if ROM_Data(15 downto 9) = "1111110" then -- SBRC Do_SBRC <= '1'; else Do_SBRC <= '0'; end if; if ROM_Data(15 downto 9) = "1111111" then -- SBRS Do_SBRS <= '1'; else Do_SBRS <= '0'; end if; end if; else Do_PASSB <= '1'; end if; case ROM_Data(2 downto 0) is when "000" => Bit_Pattern <= "00000001"; when "001" => Bit_Pattern <= "00000010"; when "010" => Bit_Pattern <= "00000100"; when "011" => Bit_Pattern <= "00001000"; when "100" => Bit_Pattern <= "00010000"; when "101" => Bit_Pattern <= "00100000"; when "110" => Bit_Pattern <= "01000000"; when others => Bit_Pattern <= "10000000"; end case; end if; end process; Bit_Test <= Bit_Pattern and A; Z_Skip <= '1' when ((Bit_Test /= "00000000") and (Do_SBRS = '1')) or ((Bit_Test = "00000000") and (Do_SBRC = '1')) else '0'; AAS <= "00000000" when Do_NEG = '1' else A; BAS <= A when Do_NEG = '1' else "00000001" when Do_DEC = '1' or Do_INC = '1' else B; AddSub(AAS(3 downto 0), BAS(3 downto 0), Do_SUB, Do_SUB xor (Use_Carry and SREG(0)), Q_v(3 downto 0), HalfCarry_v); AddSub(AAS(6 downto 4), BAS(6 downto 4), Do_SUB, HalfCarry_v, Q_v(6 downto 4), Carry7_v); AddSub(AAS(7 downto 7), BAS(7 downto 7), Do_SUB, Carry7_v, Q_v(7 downto 7), Carry_v); OverFlow_v <= Carry_v xor Carry7_v; Status_D(5) <= HalfCarry_v xor Do_SUB; -- H Q(7 downto 0) <= Q_v when Do_ADD = '1' or Do_SUB = '1' else "ZZZZZZZZ"; Q(8) <= Carry_v xor Do_SUB when Do_ADD = '1' or Do_SUB = '1' else 'Z'; Q(7 downto 0) <= (A and B) when Do_AND = '1' else (A or B) when Do_OR = '1' else (A xor B) when Do_XOR = '1' else "ZZZZZZZZ"; Q <= '1' & (not A) when Do_COM = '1' else "ZZZZZZZZZ"; Q(7 downto 0) <= A(3 downto 0) & A(7 downto 4) when Do_SWAP = '1' else "ZZZZZZZZ"; Q <= A(0) & A(7) & A(7 downto 1) when Do_ASR = '1' else "ZZZZZZZZZ"; Q <= A(0) & "0" & A(7 downto 1) when Do_LSR = '1' else "ZZZZZZZZZ"; Q <= A(0) & SREG(0) & A(7 downto 1) when Do_ROR = '1' else "ZZZZZZZZZ"; Q(7 downto 0) <= ((not Bit_Pattern) and A) when Do_BLD = '1' and SREG(6) = '0' else (Bit_Pattern or A) when Do_BLD = '1' and SREG(6) = '1' else "ZZZZZZZZ"; Status_D(6) <= '1' when (Bit_Pattern and A) /= "00000000" else '0'; Overflow_t <= Overflow_v when Do_SUB = '1' or Do_ADD = '1' else Q(7) xor Q(8) when (Do_ASR or Do_LSR or Do_ROR) = '1' else '0'; -- V Status_D(3) <= Overflow_t; Status_D(2) <= Q(7); -- N Status_D(4) <= Overflow_t xor Q(7); -- SREG(3) xor SREG(2); -- S Status_D(1) <= '1' when Q(7 downto 0) = "00000000" and (Do_SUB = '0' or Use_Carry = '0') else SREG(1) when Q(7 downto 0) = "00000000" and Do_SUB = '1' and Use_Carry = '1' else '0'; -- Z process (Do_SUB, Do_ADD, Do_COM, Do_ASR, Do_LSR, Do_ROR, Do_AND, Do_XOR, Do_OR, Do_INC, Do_DEC, Do_BST) begin Status_Wr <= "0000000"; if (Do_COM or Do_ASR or Do_LSR or Do_ROR) = '1' then Status_Wr <= "0011111"; -- Z,C,N,V ,S end if; if (Do_AND or Do_XOR or Do_OR or Do_INC or Do_DEC) = '1' then Status_Wr <= "0011110"; -- Z,N,V ,S elsif (Do_SUB or Do_ADD) = '1' then Status_Wr <= "0111111"; -- Z,C,N,V,H ,S end if; if Do_BST = '1' then Status_Wr <= "1000000"; -- T end if; end process; end;
Go to most recent revision | Compare with Previous | Blame | View Log