library IEEE; use IEEE.STD_LOGIC_1164.all; library ieee; use ieee.std_logic_arith.all; library ieee; use ieee.STD_LOGIC_UNSIGNED.all; entity PICALU is port ( -- Operation will depend on the PIC Instruction opcode. Op : in STD_LOGIC_VECTOR(3 downto 0); -- Main 8-bit inputs and output A : in STD_LOGIC_VECTOR(7 downto 0); B : in STD_LOGIC_VECTOR(7 downto 0); Q : out STD_LOGIC_VECTOR(7 downto 0); -- Carries and zero out CIN : in STD_LOGIC; COUT : out STD_LOGIC; ZERO : out STD_LOGIC); end PICALU; architecture first of PICALU is constant ALUOP_ADD : STD_LOGIC_VECTOR (3 downto 0) := "0000"; constant ALUOP_SUB : STD_LOGIC_VECTOR (3 downto 0) := "0001"; constant ALUOP_AND : STD_LOGIC_VECTOR (3 downto 0) := "0010"; constant ALUOP_OR : STD_LOGIC_VECTOR (3 downto 0) := "0011"; constant ALUOP_XOR : STD_LOGIC_VECTOR (3 downto 0) := "0100"; constant ALUOP_COM : STD_LOGIC_VECTOR (3 downto 0) := "0101"; constant ALUOP_ROR : STD_LOGIC_VECTOR (3 downto 0) := "0110"; constant ALUOP_ROL : STD_LOGIC_VECTOR (3 downto 0) := "0111"; constant ALUOP_SWAP : STD_LOGIC_VECTOR (3 downto 0) := "1000"; constant ALUOP_BITCLR : STD_LOGIC_VECTOR (3 downto 0) := "1001"; constant ALUOP_BITSET : STD_LOGIC_VECTOR (3 downto 0) := "1010"; constant ALUOP_BITTESTCLR : STD_LOGIC_VECTOR (3 downto 0) := "1011"; constant ALUOP_BITTESTSET : STD_LOGIC_VECTOR (3 downto 0) := "1100"; -- This will help us decide when to raise the Z flag. constant ZEROBYTE : STD_LOGIC_VECTOR (7 downto 0) := "00000000"; -- B_2SC is the 2s Complement (i.e. negative) of B. We'll use this -- for our SUB operation, rather than use the sub2c built-in, which -- didn't work quite right... -- signal B_2SC : STD_LOGIC_VECTOR (8 downto 0); -- LONGQ is simply the 8-bit Q output with the additional carry out MSB that -- results from Adds and Subtracts, as well as rotates. -- Typically, just think of LONGQ(8) as being the carryout signal -- signal LONGQ : STD_LOGIC_VECTOR (8 downto 0); -- The BITDECODER simply decodes out the encoded B field in many PIC instructions. -- This decoded vector is then used for masking and such. -- signal BITDECODER : STD_LOGIC_VECTOR (7 downto 0); signal BITTEST : STD_LOGIC_VECTOR (7 downto 0); begin -- Q output is the 8-bit output without the carry out -- Q <= LONGQ(7 downto 0); -- Now.. The Z flag will also represent how the BIT Testing operations -- turn out. For the bit testing ops, the ZERO won't ultimately -- affect the STATUS register. -- ZERO <= '1' When LONGQ(7 downto 0) = ZEROBYTE else '1' When (BITTEST /= ZEROBYTE) AND (Op = ALUOP_BITTESTSET) else '1' When (BITTEST = ZEROBYTE) AND (Op = ALUOP_BITTESTCLR) else '0'; -- Eg. Negative B -- B_2SC <= CONV_STD_LOGIC_VECTOR( (CONV_INTEGER(NOT B) + 1 ) , 9); -- Carry out is the MSB of the Long Q vector. -- COUT <= LONGQ(8); -- Here's the main ALU datapath. -- LONGQ <= CONV_STD_LOGIC_VECTOR( (CONV_INTEGER(A) + CONV_INTEGER(B)) , 9 ) When Op = ALUOP_ADD Else CONV_STD_LOGIC_VECTOR( (CONV_INTEGER(A) + CONV_INTEGER(B_2SC)) , 9 ) When Op = ALUOP_SUB Else "0" & (A AND B) When Op = ALUOP_AND Else "0" & (A OR B) When Op = ALUOP_OR Else "0" & (A XOR B) When Op = ALUOP_XOR Else "0" & (NOT A) When Op = ALUOP_COM Else A(0)& CIN & A(7 downto 1) When Op = ALUOP_ROR Else A & CIN When Op = ALUOP_ROL Else "0" & A(3 downto 0) & A(7 downto 4) When Op = ALUOP_SWAP Else "0" & ((NOT BITDECODER) AND A) When Op = ALUOP_BITCLR Else "0" & (BITDECODER OR A) When Op = ALUOP_BITSET Else "0" & A; -- This is where we expand (eg. decode) the PIC Instruction "b" field. -- The decoded value becomes the mask used for the logical comparison. -- BITDECODER <= "00000001" When CONV_INTEGER(B(7 downto 5)) = 0 Else "00000010" When CONV_INTEGER(B(7 downto 5)) = 1 Else "00000100" When CONV_INTEGER(B(7 downto 5)) = 2 Else "00001000" When CONV_INTEGER(B(7 downto 5)) = 3 Else "00010000" When CONV_INTEGER(B(7 downto 5)) = 4 Else "00100000" When CONV_INTEGER(B(7 downto 5)) = 5 Else "01000000" When CONV_INTEGER(B(7 downto 5)) = 6 Else "10000000" When CONV_INTEGER(B(7 downto 5)) = 7 Else "00000000"; -- Used for the BITTESTSET and BITTESTCLR operations. -- BITTEST <= BITDECODER AND A; end first;