114 lines
4.2 KiB
VHDL
114 lines
4.2 KiB
VHDL
|
ARCHITECTURE RTL OF alu IS
|
||
|
|
||
|
signal aluCodeInt: unsigned(aluCode'range);
|
||
|
signal aArith: signed(opA'high+1 downto 0);
|
||
|
signal bArith: signed(opA'high+1 downto 0);
|
||
|
signal cInArith: signed(1 downto 0);
|
||
|
signal cInShift: std_ulogic;
|
||
|
signal yArith: signed(aluOut'high+1 downto 0);
|
||
|
signal aluOutInt: signed(aluOut'range);
|
||
|
|
||
|
BEGIN
|
||
|
------------------------------------------------------------------------------
|
||
|
-- clear aluCode don't care LSB for shifts
|
||
|
aluCodeInt(aluCode'high downto 1) <= unsigned(aluCode(aluCode'high downto 1));
|
||
|
|
||
|
cleanupLsb: process(aluCode)
|
||
|
begin
|
||
|
if aluCode(aluCode'high) = '1' then
|
||
|
aluCodeInt(0) <= '0';
|
||
|
else
|
||
|
aluCodeInt(0) <= aluCode(0);
|
||
|
end if;
|
||
|
end process cleanupLsb;
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
-- values for arithmetic operations
|
||
|
aArith <= signed(resize(unsigned(opA), aArith'length));
|
||
|
bArith <= signed(resize(unsigned(opB), bArith'length));
|
||
|
cInArith <= (0 => cIn, others => '0');
|
||
|
|
||
|
process(aluCode, cIn, opA)
|
||
|
begin
|
||
|
case aluCode(2 downto 1) is
|
||
|
when "00" => cInShift <= cIn;
|
||
|
when "01" => cInShift <= opA(opA'high);
|
||
|
when "10" => cInShift <= opA(opA'low);
|
||
|
when "11" => cInShift <= aluCode(0);
|
||
|
when others => cInShift <= '-';
|
||
|
end case;
|
||
|
end process;
|
||
|
|
||
|
------------------------------------------------------------------------------
|
||
|
-- alu operations
|
||
|
aluOperation: process(
|
||
|
aluCodeInt,
|
||
|
opA, opB,
|
||
|
aArith, bArith, cInArith,
|
||
|
cInShift,
|
||
|
yArith, aluOutInt
|
||
|
)
|
||
|
variable xorAcc: std_ulogic;
|
||
|
begin
|
||
|
yArith <= (others => '-');
|
||
|
cOut <= '-';
|
||
|
aluOutInt <= (others => '-');
|
||
|
case to_integer(aluCodeInt) is
|
||
|
when 0 => -- LOAD sX, kk
|
||
|
aluOutInt <= opB;
|
||
|
when 2 => -- INPUT sX, pp
|
||
|
aluOutInt <= opB;
|
||
|
when 3 => -- FETCH sX, ss
|
||
|
aluOutInt <= opB;
|
||
|
when 5 => -- AND sX, kk
|
||
|
aluOutInt <= opA and opB;
|
||
|
cOut <= '0';
|
||
|
when 6 => -- OR sX, kk
|
||
|
aluOutInt <= opA or opB;
|
||
|
cOut <= '0';
|
||
|
when 7 => -- XOR sX, kk
|
||
|
aluOutInt <= opA xor opB;
|
||
|
cOut <= '0';
|
||
|
when 9 => -- TEST sX, kk
|
||
|
aluOutInt <= opA and opB;
|
||
|
xorAcc := '0';
|
||
|
for index in aluOutInt'range loop
|
||
|
xorAcc := xorAcc xor aluOutInt(index);
|
||
|
end loop;
|
||
|
cOut <= xorAcc;
|
||
|
when 10 => -- COMPARE sX, kk
|
||
|
yArith <= aArith - bArith;
|
||
|
aluOutInt <= yArith(aluOut'range);
|
||
|
cOut <= yArith(yArith'high);
|
||
|
when 12 => -- ADD sX, kk
|
||
|
yArith <= aArith + bArith;
|
||
|
aluOutInt <= yArith(aluOut'range);
|
||
|
cOut <= yArith(yArith'high);
|
||
|
when 13 => -- ADDCY sX, kk
|
||
|
yArith <= (aArith + bArith) + cInArith;
|
||
|
aluOutInt <= yArith(aluOut'range);
|
||
|
cOut <= yArith(yArith'high);
|
||
|
when 14 => -- SUB sX, kk
|
||
|
yArith <= aArith - bArith;
|
||
|
aluOutInt <= yArith(aluOut'range);
|
||
|
cOut <= yArith(yArith'high);
|
||
|
when 15 => -- SUBCY sX, kk
|
||
|
yArith <= (aArith - bArith) - cInArith;
|
||
|
aluOutInt <= yArith(aluOut'range);
|
||
|
cOut <= yArith(yArith'high);
|
||
|
when 16 to 23 => -- SL sX
|
||
|
aluOutInt <= opA(opA'high-1 downto 0) & cInShift;
|
||
|
cOut <= opA(opA'high);
|
||
|
when 24 to 31 => -- SR sX
|
||
|
aluOutInt <= cInShift & opA(opA'high downto 1);
|
||
|
cOut <= opA(0);
|
||
|
when others =>
|
||
|
aluOutInt <= (others => '-');
|
||
|
end case;
|
||
|
end process aluOperation;
|
||
|
|
||
|
aluOut <= aluOutInt;
|
||
|
zero <= '1' when aluOutInt = 0 else '0';
|
||
|
|
||
|
END ARCHITECTURE RTL;
|