- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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−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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page