1
0
SEm-Labos/Libs/NanoBlaze/hdl/alu_RTL.vhd

114 lines
4.2 KiB
VHDL
Raw Normal View History

2024-02-23 13:01:05 +00:00
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;