Altera_Forum
Honored Contributor
12 years agodesign of a difficult VHDL Arithmetic and Logic Unit (ALU)
Hey guys, I was wondering if someone could give me a hand with designing a specific ALU.
Here are the main bits which I would like to implement: - sequentlial unit with 2 registers (e.g. Acc and Data_Reg) - immediate Read and Write Access to Acc - 4 funtion bits (S01 - S03) to select an OpCode (see table below) - ALU should flag for Acc = 0 (CPZ), for overflow (OVR) and for Acc = Data_Reg (AED) S01...S02..S03..S04.. 0......0......0......0......RES RESET Acc to 00000000 (Arith) 0......0......0......1......INC Acc = Acc + 1 (Arith) 0......0......1......0......ADD Acc = Acc + Data_Reg (Arith) 0......0......1......1......SUB Acc = Acc - Data_Reg (Arith) 0......1......0......0......MUL Acc = Acc x Data_Reg (Arith) 0......1......0......1......SHL Acc = Acc shifted left (up) by Data_Reg bits 0......1......1......0......SHR Acc = Acc shifted right (down) by Data_Reg bits 0......1......1......1......AND Acc <= Acc NAND Data_Reg (Logic) 1......0......0......0......XOR Acc <= Acc EXOR Data_Reg (Logic) 1......0......0......1......SET SET Acc to 11111111 (Arith) 1......0......1......0......LDA Load Acc from Data RAM (Cntrl) 1......0......1......1......LDD Load Data_Reg from Data RAM (Cntrl) 1......1......0......0......STA Store Acc to Data RAM (Cntrl) 1......1......0......1......STE Store External Data to Data RAM (Cntrl) 1......1......1......0......INZ Increment PC if ZFL = '1' (Cntrl) 1......1......1......1......JMP Jump to P(x)C if ZFL = '1' (Cntrl) here is what I've done so far (I basically strugle with everything which is not implemented):
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity simple_alu is
port( Clk : in std_logic; --clock signal
Acc, Data_Reg : in std_logic_vector (7 downto 0); --input operands
Op : in std_logic_vector(3 downto 0); --Operation to be performed
R : out std_logic_vector(7 downto 0) --output of ALU
);
end simple_alu;
architecture Behavioral of simple_alu is
--temporary signal declaration.
signal Reg1,Reg2,Reg3 : std_logic_vector(7 downto 0) := (others => '0');
begin
Reg1 <= Acc;
Reg2 <= Data_Reg;
R <= Reg3;
process(Clk)
begin
if(rising_edge(Clk)) then --Do the calculation at the positive edge of clock cycle.
case Op is
when "0000" => Reg3 <= '00000000' --0 RES RESET Acc to 00000000 (Arith)
when "0001" => Reg3 <= --1 INC Acc = Acc + 1 (Arith)
when "0010" => Reg3 <= Reg1 + Reg2; --2 ADD Acc = Acc + Data_Reg (Arith)
when "0011" => Reg3 <= Reg1 - Reg2; --3 SUB Acc = Acc - Data_Reg (Arith)
when "0100" => Reg3 <= --4 MUL Acc = Acc x Data_Reg (Arith)
when "0101" => Reg3 <= --5 SHL Acc = Acc shifted left (up) by Data_Reg bits
when "0110" => Reg3 <= --6 SHR Acc = Acc shifted right (down) by Data_Reg bits
when "0111" => Reg3 <= Reg1 nand Reg2; --7 Acc <= Acc NAND Data_Reg (Logic)
when "1000" => Reg3 <= Reg1 xor Reg2; --8 Acc <= Acc EXOR Data_Reg (Logic)
when "1001" => Reg3 <= --9 SET Acc to 11111111 (Arith)
when "1010" => Reg3 <= --A Load Acc from Data RAM (Cntrl)
when "1011" => Reg3 <= --B Load Data_Reg from Data RAM (Cntrl)
when "1100" => Reg3 <= --C Store Acc to Data RAM (Cntrl)
when "1101" => Reg3 <= --D Store External Data to Data RAM (Cntrl)
when "1110" => Reg3 <= --E Increment PC if ZFL = '1' (Cntrl)
when "1111" => Reg3 <= --F Jump to P(x)C if ZFL = '1' (Cntrl)
when others => Reg3 <= (others => '0');
end case;
end if;
end process;
end Behavioral;
all this code might be nonsense / not useful at all. I don't want anyone to solve this "task" but I would appreciate if you could let me know if I am on the right way?! I would also appreciate if you could post code examples as I am quite new to VHDL and generally better in understanding when I look at actual code. thanks in advance for any help you are able to provide. Cheers!