Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17254 Discussions

design of a difficult VHDL Arithmetic and Logic Unit (ALU)

Altera_Forum
Honored Contributor II
5,395 Views

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!
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
3,502 Views

I think you're on the right approach. 

 

One thing, with numeric_std (good to see you're using it) std_logic_vectors are just collection of bits so it 

doesn't know how to 'add' them etc .... 

 

I'd declare reg1-3 as unsigned then .. 

 

op <= std_logic_vector(reg3); 

 

..to assign the result as a std_logic_vector. 

 

Can you get hold of modelsim and play about with different combinations of operation? It'll help you see what's 

going on. 

 

 

Nial.
0 Kudos
Altera_Forum
Honored Contributor II
3,502 Views

thanks for your quick response.  

 

- How can I'd declare reg1-3 as unsigned?  

- not sure if modelsim is available in uni - but I'll have a look tomorrow.
0 Kudos
Altera_Forum
Honored Contributor II
3,502 Views

 

--- Quote Start ---  

 

- How can I'd declare reg1-3 as unsigned?  

 

--- Quote End ---  

 

signal Reg1,Reg2,Reg3 : unsigned(7 downto 0);
0 Kudos
Altera_Forum
Honored Contributor II
3,502 Views

How is that diagram coming along?

0 Kudos
Altera_Forum
Honored Contributor II
3,502 Views

 

--- Quote Start ---  

How is that diagram coming along? 

--- Quote End ---  

 

 

like I said, Tricky****y, I've got it right in front of me; I'm not going to scan/upload it as I won't get more from you than another three words statement (no offence but it just hasn't been helpful at all).
0 Kudos
Altera_Forum
Honored Contributor II
3,502 Views

I think one of the main problems with your code and comments is that you have several unimplemented cases that say set Acc to something or increment Acc. Acc cannot be set to anything because it's an input. Either you have the comments wrong and you actually mean something else, or you're trying to do something that you cannot. 

 

You also have 3 signals misleadingly called "RegN", when only Reg3 is actually a register. Reg1 and Reg2 are just wires connected to Acc and Data_reg inputs, and all Reg3 does it connect directly to the output. So first thing is you probably want to make Reg1 and Reg2 actual registers, and maybe only load the output in specific cases?
0 Kudos
Reply