Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
12 years ago

ALU in VHDL newbi having some major issues

Hi guys, I need to serious help over here. I need to code an ALU that can perform different function base on the op code, add, subtract, logical shift left and right.

namely these:

https://www.alteraforum.com/forum/attachment.php?attachmentid=8404

Now my main problem right now is.. i have no clue how to implement the condition statements correctly so that I can pick and choose what operation I need to perform. I think i managed to code an full adder/subtract r.. but I dont know how to implement it under a condition .. keep getting compile time errors if i try anything... I want to keep everything in one file.. i dont want to use packages.. Can some one please help me!? this is what I have so far.. it compiles as is, but the comments will tell you my struggles..


LIBRARY ieee ;
USE ieee.std_logic_1164.all ;
ENTITY fulladd IS
    PORT ( a, b, cin : IN STD_LOGIC ;
            s, cout : OUT STD_LOGIC ) ;
END fulladd ;
ARCHITECTURE LogicFunc OF fulladd IS
BEGIN
    s <= a XOR b XOR cin ;
    Cout <= (a AND b) OR (cin AND a) OR (cin AND b) ;
END LogicFunc ;
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
USE ieee.std_logic_unsigned.ALL;
--USE work.fulladd package.all ;
ENTITY alu IS
--GENERIC ( n : INTEGER := 32 );
PORT(
    a         : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
    b         : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
    cin   : IN  STD_LOGIC;
    S     : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); --sum
    cout     : OUT STD_LOGIC;
    op     : IN  STD_LOGIC_VECTOR( 2 DOWNTO 0);
    zero     : OUT STD_LOGIC);
END ENTITY alu;    
--ARCHITECTURE description OF alu IS BEGIN
-- You fill in what goes here!!!! END description;
--process(all)
--begin    
         
               architecture LogicFunc of alu is
                        signal c : std_logic_vector(0 to 30); -- internal carry signals
                        begin  
                        a0: entity WORK.fulladd port map(a(0), b(0), cin, S(0), c(0));
                        stage: for I in 1 to 30 generate
                            as: entity WORK.fulladd port map(a(I), b(I), c(I-1) , S(I), c(I));
                        end generate stage;
                        a31: entity WORK.fulladd port map(a(31), b(31), c(30) , S(31), cout);
                    end architecture LogicFunc;  
       
         --       architecture LogicFunc of alu is
            --            signal c : std_logic_vector(0 to 30); -- internal carry signals
            --            begin  
            --            a0: entity WORK.fulladd port map(a(0), b(0), cin, S(0), c(0));
            --            stage: for I in 1 to 30 generate
            --                as: entity WORK.fulladd port map(a(I), b(I), c(I-1) , S(I), c(I));
            --            end generate stage;
            --            a31: entity WORK.fulladd port map(a(31), b(31), c(30) , S(31), cout);
            --        end architecture LogicFunc;   
                 
  
    
--end process;    
                            
                                
--END description;                                
                            
                            
--ARCHITECTURE Structure OF alu IS
--    SIGNAL C : STD_LOGIC_VECTOR(0 TO n) ;
--    COMPONENT fulladd
--        PORT ( Cin, x, y : IN  STD_LOGIC ; 
--                    s, Cout : OUT STD_LOGIC ) ;
--    END COMPONENT ;
--BEGIN
--    C(0) <= Cin ;
--    Generate_label:
--    FOR i IN 0 TO n&#8722;1 GENERATE
--        stage: fulladd PORT MAP ( C(i), a(i), b(i), result(i), C(i+1)) ;
--    END GENERATE;
--    Cout <= C(32) ;
--END Structure;
--stage0: fulladd PORT MAP ( Cin, a(0), b(0), S(0), C(1) ) ;
--stage1: fulladd PORT MAP ( C(1), a(1), b(1), S(1), C(2) ) ;
--stage3: fulladd PORT MAP ( C(2), a(2), b(2), S(2), C(3) ) ;
--stage4: fulladd PORT MAP ( C(3), a(3), b(3), S(3), C(4) ) ;
--stage5: fulladd PORT MAP ( C(4), a(4), b(4), S(4), C(5) ) ;
--stage6: fulladd PORT MAP ( C(5), a(5), b(5), S(5), C(6) ) ;
--stage7: fulladd PORT MAP ( C(6), a(6), b(6), S(6), C(7) ) ;
--stage8: fulladd PORT MAP ( C(7), a(7), b(7), S(7), C(8) ) ;
--stage9: fulladd PORT MAP ( C(8), a(8), b(8), S(8), C(9) ) ;
--stage10: fulladd PORT MAP ( C(9), a(9), b(9), S(9), C(10) ) ;
--stage11: fulladd PORT MAP ( C(10), a(10), b(10), S(10), C(11) ) ;
--stage12: fulladd PORT MAP ( C(11), a(11), b(11), S(11), C(12) ) ;
--stage13: fulladd PORT MAP ( C(12), a(12), b(12), S(12), C(13) ) ;
--stage14: fulladd PORT MAP ( C(13), a(13), b(13), S(13), C(14) ) ;
--stage15: fulladd PORT MAP ( C(14), a(14), b(14), S(14), C(15) ) ;
--stage16: fulladd PORT MAP ( C(15), a(15), b(15), S(15), C(16) ) ;
--stage17: fulladd PORT MAP ( C(16), a(16), b(16), S(16), C(17) ) ;
--stage18: fulladd PORT MAP ( C(17), a(17), b(17), S(17), C(18) ) ;
--stage19: fulladd PORT MAP ( C(18), a(18), b(18), S(18), C(19) ) ;
--stage20: fulladd PORT MAP ( C(19), a(19), b(19), S(19), C(20) ) ;
--stage21: fulladd PORT MAP ( C(20), a(20), b(20), S(20), C(21) ) ;
--stage22: fulladd PORT MAP ( C(21), a(21), b(21), S(21), C(22) ) ;
--stage23: fulladd PORT MAP ( C(22), a(22), b(22), S(22), C(23) ) ;
--stage24: fulladd PORT MAP ( C(23), a(23), b(23), S(23), C(24) ) ;
--stage25: fulladd PORT MAP ( C(24), a(24), b(24), S(24), C(25) ) ;
--stage26: fulladd PORT MAP ( C(25), a(25), b(25), S(25), C(26) ) ;
--stage27: fulladd PORT MAP ( C(26), a(26), b(26), S(26), C(27) ) ;
--stage28: fulladd PORT MAP ( C(27), a(27), b(27), S(27), C(28) ) ;
--stage29: fulladd PORT MAP ( C(28), a(28), b(28), S(28), C(29) ) ;
--stage30: fulladd PORT MAP ( C(29), a(29), b(29), S(29), C(30) ) ;
--stage31: fulladd PORT MAP ( C(30), a(30), b(30), S(30), C(31) ) ;
--stage32: fulladd PORT MAP ( C(31), a(31), b(31), S(31), cout ) ;
--END Structure ;

please help me!

oh and I can't use add or subtract operator, must be using logic gates.

13 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    VHDL only does what you tell it:

    for i in 0 DOWNTO 31 loop

    will loop a grand total of 0 times.

    for i in 31 DOWNTO 0 loop

    will loop a grand total of 32 times

    Hence why the top code works, and bottom code doesnt.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    VHDL only does what you tell it:

    for i in 0 DOWNTO 31 loop

    will loop a grand total of 0 times.

    for i in 31 DOWNTO 0 loop

    will loop a grand total of 32 times

    Hence why the top code works, and bottom code doesnt.

    --- Quote End ---

    Yes, you are absolutely right. Thank you so much for all your wonderful help Tricky! I started from scratch and build one part at a time according to you suggestions and it actually worked out pretty well. I am not sure if my subtraction work right but I am out of time for this one. I figure out how to shift right base on your hint also, thanks for that. here is what I have including some sims.. functional and timing. The propagation on the add subtract are crazy...

    sims: (most cased shown)

    https://www.alteraforum.com/forum/attachment.php?attachmentid=8410

    sims: (emphasis on add and subtract)

    https://www.alteraforum.com/forum/attachment.php?attachmentid=8411

    
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.std_logic_arith.ALL;
    USE ieee.std_logic_unsigned.ALL;
    ENTITY alu IS
    PORT(
    	a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
    	b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
    	op : IN STD_LOGIC_VECTOR( 2 DOWNTO 0);
    	result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
    	cout : OUT STD_LOGIC;
    	zero : OUT STD_LOGIC);
    END alu;
    ARCHITECTURE description OF alu IS
    BEGIN
    		PROCESS (op,a,b)
    		VARIABLE carry:STD_LOGIC;
    		VARIABLE X:STD_LOGIC_VECTOR(31 DOWNTO 0);
    		VARIABLE sum:STD_LOGIC_VECTOR(31 DOWNTO 0);
    		BEGIN
    			zero<='0';
    			cout<='0';
    			CASE op IS
    				WHEN "000" =>
    					sum:= a AND b;
    					result<=sum;
    				WHEN "001" =>
    					result <= a OR b;
    				WHEN "010" =>
    					--sum <= a + b;
    					carry:='0';
    					FOR i IN 0 TO 31 LOOP
    						sum(i):=a(i) XOR b(i) XOR carry;
    						carry:=(a(i) AND b(i))OR(b(i) AND carry)OR(carry AND a(i));
    					END LOOP;
    					result<=sum;
    					cout<=carry;
    				WHEN "110" =>
    					--sum <= a - b;  
    					carry:='0';
    						X:=((NOT b) + 1);
    						FOR i IN 0 TO 31 LOOP
    							sum(i):=a(i) XOR X(i) XOR carry;
    							carry:=(a(i) AND X(i))OR(X(i) AND carry)OR(carry AND a(i));
    						END LOOP;
    						--sum:=((NOT sum)+1);
    						result<=sum;
    						cout<=carry;
    				WHEN "100" =>
    					--sum <= a << 1;
    					sum:=a(30 DOWNTO 0) & '0';
    					result<=sum;
    				WHEN "101" =>
    					--sum <= a >> 1;
    					sum:='0' & b (31 DOWNTO 1);
    					result<=sum;
    				WHEN  OTHERS =>
    			END CASE;
    				IF sum = "00000000000000000000000000000000" THEN zero<='1';
    				END IF;
    		END PROCESS;
    		
    END description;
    

    if you have any advice on the subtract part of the code it would be most welcome : ) more specifically I'm not sure if 5-6 works correctly.. its gives me FFFFFF it should be one with overflow set?? if I take twos compliment of that I will get it, but no overflow ofcourse... but when I tried that my add got messed up for some reason, so I just left it. yeahh.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    the propogation is becaus you are creating an asynchronous circuit. if it was synchronous you wouldnt see all the transitions. What you see is all the bits changing one by one.