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

ALU in VHDL newbi having some major issues

Altera_Forum
Honored Contributor II
2,433 Views

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.
0 Kudos
13 Replies
Altera_Forum
Honored Contributor II
1,675 Views

Hey guys, let me try that again. I started from scratch. here is my code now. 

 

Now I have the full adder sitting up there, can someone please tell me how I correctly port map the variables under the condition for adding, and use the adder that is.  

 

I can not use the plus or minus operator like I did there, and it must be asynchronous.  

 

Thanks 

 

LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY fulladd IS PORT ( Cin, x, y : IN STD_LOGIC ; s, Cout : OUT STD_LOGIC ) ; END fulladd ; ARCHITECTURE LogicFunc OF fulladd IS BEGIN s <= x XOR y XOR Cin ; Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; END LogicFunc ; 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 -- you fill in what goes here!!! -- SIGNAL a1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; -- SIGNAL b1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; -- SIGNAL result1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; BEGIN PROCESS (op,a,b) BEGIN IF op="000" THEN result <= a AND b; ELSIF op="001" THEN result <= a OR b; ELSIF op="010" THEN result <= a + b; ELSIF op="110" THEN result <= a - b; ELSIF op="100" THEN --result <= a << 1; ELSIF op="101" THEN --result <= b >> 1; END IF; END PROCESS; END description;
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

like why doesn't this work? 

 

LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY fulladd IS PORT ( Cin, x, y : IN STD_LOGIC ; s, Cout : OUT STD_LOGIC ) ; END fulladd ; ARCHITECTURE LogicFunc OF fulladd IS BEGIN s <= x XOR y XOR Cin ; Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; END LogicFunc ; 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 -- you fill in what goes here!!! SIGNAL C : STD_LOGIC_VECTOR(0 TO 31) ; COMPONENT fulladd PORT ( Cin, x, y : IN STD_LOGIC ; s, Cout : OUT STD_LOGIC ) ; END COMPONENT ; -- SIGNAL a1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; -- SIGNAL b1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; -- SIGNAL result1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; BEGIN PROCESS (op,a,b) BEGIN IF op="000" THEN result <= a AND b; ELSIF op="001" THEN result <= a OR b; ELSIF op="010" THEN --result <= a + b; 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 ) ; ELSIF op="110" THEN result <= a - b; ELSIF op="100" THEN --result <= a << 1; ELSIF op="101" THEN --result <= b >> 1; END IF; END PROCESS; END description;
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

You cannot instantiate a component inside a process. A process decribes logic behaviour, and an entity instantiation is like placing a chip on a board. You wouldnt expect to place and remove chips on your board during runtime would you? Entities must be instantiated outside a process. 

 

Other notes: 

1. << and >> are not operators in VHDL. If you insist on using std_logic_vectors for numbers, you will have to do the shift manually: 

result <=a (30 downto 0) & '0'; 

 

But if you want to do things with correct types, ditch the non-standard std_logic_arith and std_logic_unsigned libraries, and use the VHDL library numeric_std instead. With this, you can declare a and b unsigned (or typecast the std_logic_vector to unsigned) then do a bit shift: 

 

result <= std_logic_vector( unsigned(a) sll 1 ); --shift left logical 

result <= std_logic_vector( unsigned(b) srl 1 ); --shift right logical
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

ok thanks again Tricky!!.. 

 

Now I'm getting some other error for the code below. There is something wrong with my port mapping loop. 

 

Error (10028): Can't resolve multiple constant drivers for net "result[31]" at alu.vhd(48) 

Error (10029): Constant driver at alu.vhd(52) 

Error (10028): Can't resolve multiple constant drivers for net "result[30]" at alu.vhd(48) 

Error (10028): Can't resolve multiple constant drivers for net "result[29]" at alu.vhd(48) 

Error (10028): Can't resolve multiple constant drivers for net "result[28]" at alu.vhd(48) 

Error (10028): Can't resolve multiple constant drivers for net "result[27]" at alu.vhd(48) 

Error (10028): Can't resolve multiple constant drivers for net "result[26]" at alu.vhd(48) 

Error (10028): Can't resolve multiple constant drivers for net "result[25]" at alu.vhd(48) 

 

 

LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY fulladd IS PORT ( Cin, x, y : IN STD_LOGIC ; s, Cout : OUT STD_LOGIC ) ; END fulladd ; ARCHITECTURE LogicFunc OF fulladd IS BEGIN s <= x XOR y XOR Cin ; Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; END LogicFunc ; 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); -- in place of result cout : OUT STD_LOGIC; zero : OUT STD_LOGIC); END alu; ARCHITECTURE description OF alu IS -- you fill in what goes here!!! COMPONENT fulladd PORT ( Cin, x, y : IN STD_LOGIC ; s, Cout : OUT STD_LOGIC ) ; END COMPONENT ; SIGNAL C : STD_LOGIC_VECTOR(0 TO 32) ; -- SIGNAL a1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; -- SIGNAL b1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; -- SIGNAL result1:STD_LOGIC_VECTOR (31 DOWNTO 0) ; BEGIN C(0) <= op(2) ; Generate_label: FOR i IN 0 TO 32-1 GENERATE stage: fulladd PORT MAP ( C(i), a(i), b(i), result(i), C(i+1)) ; END GENERATE; Cout <= C(32) ; PROCESS (op,a,b,C) BEGIN IF op="000" THEN result <= a AND b; ELSIF op="001" THEN result <= a OR b; ELSIF op="010" THEN --result <= a + b; ELSIF op="110" THEN result <= a - b; ELSIF op="100" THEN --result <= a << 1; ELSIF op="101" THEN --result <= b >> 1; END IF; END PROCESS; END description;  

 

Also, how the heck would I actually call the adder from the corresponding if statement?? 

 

Sorry my prof thinks we should know VHDL somehow, from our past lives I guess..
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

ok never mind I resolved the issue, but I still don't understand how to actually add.. like how do I call the adder from the if statement?? 

 

LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY fulladd IS PORT ( Cin, x, y : IN STD_LOGIC ; s, Cout : OUT STD_LOGIC ) ; END fulladd ; ARCHITECTURE LogicFunc OF fulladd IS BEGIN s <= x XOR y XOR Cin ; Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; END LogicFunc ; 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); -- in place of result cout : OUT STD_LOGIC; zero : OUT STD_LOGIC); END alu; ARCHITECTURE description OF alu IS -- you fill in what goes here!!! COMPONENT fulladd PORT ( Cin, x, y : IN STD_LOGIC ; s, Cout : OUT STD_LOGIC ) ; END COMPONENT ; SIGNAL C : STD_LOGIC_VECTOR(0 TO 32) ; SIGNAL sum : STD_LOGIC_VECTOR(31 DOWNTO 0); BEGIN C(0) <= op(2) ; Generate_label: FOR i IN 0 TO 31 GENERATE stage: fulladd PORT MAP ( C(i), a(i), b(i), result(i), C(i+1)) ; END GENERATE; Cout <= C(32) ; PROCESS (op,a,b) BEGIN IF op="000" THEN sum <= a AND b; ELSIF op="001" THEN sum <= a OR b; ELSIF op="010" THEN --sum <= a + b; ELSIF op="110" THEN --sum <= a - b; ELSIF op="100" THEN --sum <= a << 1; ELSIF op="101" THEN --sum <= b >> 1; END IF; END PROCESS; END description;  

 

 

since I don't know how to call the component I tried this, but don't work either! 

 

 

--LIBRARY ieee ; --USE ieee.std_logic_1164.all ; --ENTITY fulladd IS -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END fulladd ; --ARCHITECTURE LogicFunc OF fulladd IS --BEGIN -- s <= x XOR y XOR Cin ; -- Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; --END LogicFunc ; 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); -- in place of result cout : OUT STD_LOGIC; zero : OUT STD_LOGIC); END alu; ARCHITECTURE description OF alu IS -- you fill in what goes here!!! --COMPONENT fulladd -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END COMPONENT ; SIGNAL CIN : STD_LOGIC; SIGNAL X : STD_LOGIC; SIGNAL Y : STD_LOGIC; SIGNAL C_OUT: STD_LOGIC; SIGNAL C : STD_LOGIC_VECTOR(0 TO 32) ; SIGNAL sum : STD_LOGIC_VECTOR(31 DOWNTO 0); BEGIN --C(0) <= op(2) ; -- Generate_label: -- FOR i IN 0 TO 31 GENERATE -- stage: fulladd PORT MAP ( C(i), a(i), b(i), result(i), C(i+1)) ; -- END GENERATE; -- Cout <= C(32) ; PROCESS (op,a,b) BEGIN IF op="000" THEN sum <= a AND b; ELSIF op="001" THEN sum <= a OR b; ELSIF op="010" THEN --sum <= a + b; C(0) <= op(2) ; FOR i IN 0 DOWNTO 31 LOOP sum(i) <= a(i) XOR b(i) XOR C(i) ; C_OUT <= (a(i) AND b(i)) OR (C(i) AND a(i)) OR (C(i) AND b(i)) ; C(i+1)<=C_OUT; END LOOP; cout<=C(32); result<=sum; ELSIF op="110" THEN --sum <= a - b; ELSIF op="100" THEN --sum <= a << 1; ELSIF op="101" THEN --sum <= b >> 1; END IF; END PROCESS; END description;
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

In what way does it "not work"? the code looks fine to me - I think you just need to write a testbench and debug it.

0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

 

--- Quote Start ---  

In what way does it "not work"? the code looks fine to me - I think you just need to write a testbench and debug it. 

--- Quote End ---  

 

 

 

Hey Trick, well it doesn't add is the problem. there seems to be something with the loop.. I can't figure it out. I did test it, using wave forms, or test bench as you call it, modelsim whatever. check out the waveform,, some other operations seem to work ok but the damn thing won't add. Also how do I shift right using a vector??  

 

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

 

the 010 op corresponds to add 

 

 

--LIBRARY ieee ; --USE ieee.std_logic_1164.all ; --ENTITY fulladd IS -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END fulladd ; --ARCHITECTURE LogicFunc OF fulladd IS --BEGIN -- s <= x XOR y XOR Cin ; -- Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; --END LogicFunc ; 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); -- in place of result cout : OUT STD_LOGIC; zero : OUT STD_LOGIC); END alu; ARCHITECTURE description OF alu IS -- you fill in what goes here!!! --COMPONENT fulladd -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END COMPONENT ; SIGNAL CIN : STD_LOGIC; SIGNAL X : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL Y : STD_LOGIC; SIGNAL C_OUT: STD_LOGIC; SIGNAL C : STD_LOGIC_VECTOR(0 TO 32) ; SIGNAL sum : STD_LOGIC_VECTOR(31 DOWNTO 0); BEGIN --C(0) <= op(2) ; -- Generate_label: -- FOR i IN 0 TO 31 GENERATE -- stage: fulladd PORT MAP ( C(i), a(i), b(i), result(i), C(i+1)) ; -- END GENERATE; -- Cout <= C(32) ; PROCESS (op,a,b) BEGIN CASE op IS WHEN "000" => result <= a AND b; WHEN "001" => result <= a OR b; WHEN "010" => --sum <= a + b; C(0) <= '0'; --op(2) ; FOR i IN 0 DOWNTO 31 LOOP sum(i) <= a(i) XOR b(i) XOR C(i) ; C_OUT <= (a(i) AND b(i)) OR (C(i) AND a(i)) OR (C(i) AND b(i)) ; C(i+1)<=C_OUT; END LOOP; cout<=C(32); result<=sum; WHEN "110" => --sum <= a - b; --C(0) <= op(2) ; --if carry in is one wont it mess up the operation? X <= ((NOT b) + 1); C(0) <= '0'; FOR i IN 0 DOWNTO 31 LOOP sum(i) <= a(i) XOR X(i) XOR C(i) ; C_OUT <= (a(i) AND X(i)) OR (C(i) AND a(i)) OR (C(i) AND X(i)) ; C(i+1)<=C_OUT; END LOOP; cout<=C(32); --result<=sum(31 DOWNTO 0); result<=sum; WHEN "100" => --sum <= a << 1; result <=a (30 DOWNTO 0) & '0'; WHEN "101" => --sum <= a >> 1; HOW DO I SHIFT RIGHT?? --result <=a (0 TO 31) & '0'; -- ahh no. WHEN OTHERS => END CASE; END PROCESS; END description;
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

The problem is because you forgot to put C in the sensitivity list. Another problem is due to the behaviour of VHDL. Signals are only assign when a process finishes, so C_out will only be assigned from when i = 31. And so all the values of C = C_OUT at i = 31. To do what you want you need to make C_Out a variable, not a signal.  

 

Also, that is not modelsim, thats the quartus integrated simulator that is quite lacking. A testbench is a peice of VHDL code that instantiates your design under test and provides stimulus for the UUT inputs. 

 

Have a think about how to shift right. You cannot change the direction an array is declared. So using 0 to 31 will cause an error before you start. you need to use downto.
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

 

--- Quote Start ---  

The problem is because you forgot to put C in the sensitivity list. Another problem is due to the behaviour of VHDL. Signals are only assign when a process finishes, so C_out will only be assigned from when i = 31. And so all the values of C = C_OUT at i = 31. To do what you want you need to make C_Out a variable, not a signal.  

 

Also, that is not modelsim, thats the quartus integrated simulator that is quite lacking. A testbench is a peice of VHDL code that instantiates your design under test and provides stimulus for the UUT inputs. 

 

Have a think about how to shift right. You cannot change the direction an array is declared. So using 0 to 31 will cause an error before you start. you need to use downto. 

--- Quote End ---  

 

 

 

Thanks again Trick, but this thing wont add, it will never add! lol hate my life ... 

 

--LIBRARY ieee ; --USE ieee.std_logic_1164.all ; --ENTITY fulladd IS -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END fulladd ; --ARCHITECTURE LogicFunc OF fulladd IS --BEGIN -- s <= x XOR y XOR Cin ; -- Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; --END LogicFunc ; 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); -- in place of result cout : OUT STD_LOGIC; zero : OUT STD_LOGIC); END alu; ARCHITECTURE description OF alu IS -- you fill in what goes here!!! --COMPONENT fulladd -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END COMPONENT ; SIGNAL CIN : STD_LOGIC; SIGNAL X : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL Y : STD_LOGIC; --SIGNAL C : STD_LOGIC_VECTOR(0 TO 32) ; SIGNAL sum : STD_LOGIC_VECTOR(31 DOWNTO 0); --variable cnt : integer := -1; BEGIN --C(0) <= op(2) ; -- Generate_label: -- FOR i IN 0 TO 31 GENERATE -- stage: fulladd PORT MAP ( C(i), a(i), b(i), result(i), C(i+1)) ; -- END GENERATE; -- Cout <= C(32) ; PROCESS (op,a,b) VARIABLE C : STD_LOGIC_VECTOR(0 TO 32) ; VARIABLE C_OUT: STD_LOGIC; BEGIN CASE op IS WHEN "000" => result <= a AND b; WHEN "001" => result <= a OR b; WHEN "010" => --sum <= a + b; C(0) := '0'; --op(2) ; FOR i IN 0 DOWNTO 31 LOOP sum(i) <= a(i) XOR b(i) XOR C(i) ; C_OUT := (a(i) AND b(i)) OR (C(i) AND a(i)) OR (C(i) AND b(i)) ; C(i+1):= C_OUT; END LOOP; cout<=C(32); result<=sum; WHEN "110" => --sum <= a - b; --C(0) <= op(2) ; --if carry in is one wont it mess up the operation? X <= ((NOT b) + 1); C(0) := '0'; FOR i IN 0 DOWNTO 31 LOOP sum(i) <= a(i) XOR X(i) XOR C(i) ; C_OUT := (a(i) AND X(i)) OR (C(i) AND a(i)) OR (C(i) AND X(i)) ; C(i+1):=C_OUT; END LOOP; cout<=C(32); --result<=sum(31 DOWNTO 0); result<=sum; WHEN "100" => --sum <= a << 1; result <=a (30 DOWNTO 0) & '0'; WHEN "101" => --sum <= a >> 1; HOW DO I SHIFT RIGHT?? --result <=a (0 TO 31) & '0'; -- ahh no. WHEN OTHERS => END CASE; END PROCESS; END description;
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

I don't get this, this code should add, I have one just like it for the adder alone and it adds, but mine does not, vhdl is definitely the worst langue ever.  

 

code that works: 

 

library IEEE; use IEEE.STD_LOGIC_1164.all; entity adder_4 is port( a : in STD_LOGIC_VECTOR(3 downto 0); b : in STD_LOGIC_VECTOR(3 downto 0); sum : out STD_LOGIC_VECTOR(4 downto 0) ); end adder_4; architecture adder4_arc of adder_4 is begin adder4 : process (a,b) is variable s : std_logic_vector (4 downto 0); begin s(0) := '0'; for i in 0 to 3 loop sum(i) <= a(i) xor b(i) xor s(i) ; s(i+1) := (a(i) and b(i)) or (b(i) and s(i)) or (s(i) and a(i)); end loop; sum(4) <= s(4); end process; end adder4_arc;  

 

 

my code using the exact same logic, don't work : ( 

--LIBRARY ieee ; --USE ieee.std_logic_1164.all ; --ENTITY fulladd IS -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END fulladd ; --ARCHITECTURE LogicFunc OF fulladd IS --BEGIN -- s <= x XOR y XOR Cin ; -- Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ; --END LogicFunc ; 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 -- you fill in what goes here!!! --COMPONENT fulladd -- PORT ( Cin, x, y : IN STD_LOGIC ; -- s, Cout : OUT STD_LOGIC ) ; --END COMPONENT ; SIGNAL CIN : STD_LOGIC; SIGNAL X : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL Y : STD_LOGIC; --SIGNAL C : STD_LOGIC_VECTOR(0 TO 32) ; SIGNAL sum : STD_LOGIC_VECTOR(31 DOWNTO 0); --variable cnt : integer := -1; BEGIN --C(0) <= op(2) ; -- Generate_label: -- FOR i IN 0 TO 31 GENERATE -- stage: fulladd PORT MAP ( C(i), a(i), b(i), result(i), C(i+1)) ; -- END GENERATE; -- Cout <= C(32) ; PROCESS (op,a,b,X,CIN,sum) VARIABLE C : STD_LOGIC_VECTOR(32 DOWNTO 0) ; VARIABLE C_OUT: STD_LOGIC; BEGIN CASE op IS WHEN "000" => result <= a AND b; WHEN "001" => result <= a OR b; WHEN "010" => --sum <= a + b; C(0) := '0'; --op(2) ; FOR i IN 0 DOWNTO 31 LOOP --sum(i) <= a(i) XOR b(i) XOR C(i) ; result(i) <= a(i) XOR b(i) XOR C(i) ; C(i+1) := (a(i) AND b(i)) OR (C(i) AND a(i)) OR (C(i) AND b(i)) ; --C(i+1):= C_OUT; END LOOP; cout<=C(32); --result<=sum; WHEN "110" => --sum <= a - b; --C(0) <= op(2) ; --if carry in is one wont it mess up the operation? X <= ((NOT b) + 1); C(0) := '0'; FOR i IN 0 DOWNTO 31 LOOP sum(i) <= a(i) XOR X(i) XOR C(i) ; C(i+1) := (a(i) AND X(i)) OR (C(i) AND a(i)) OR (C(i) AND X(i)) ; --C_OUT := (a(i) AND X(i)) OR (C(i) AND a(i)) OR (C(i) AND X(i)) ; --C(i+1):=C_OUT; END LOOP; cout<=C(32); --result<=sum(31 DOWNTO 0); result<=sum; WHEN "100" => --sum <= a << 1; result <=a (30 DOWNTO 0) & '0'; WHEN "101" => --sum <= a >> 1; HOW DO I SHIFT RIGHT?? --result <=a (0 TO 31) & '0'; -- ahh no. WHEN OTHERS => END CASE; END PROCESS; END description;
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

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.
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

 

--- 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.
0 Kudos
Altera_Forum
Honored Contributor II
1,675 Views

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.

0 Kudos
Reply