Welcome Notice

Register Log in

Newbee in VHDL ... why is this not working?...

C

Christoph Linden

Guest
Hi all,
I am getting into VHDL right now and doing the first implementation of some architecutres. For me to learn I follow nand2tetris, that uses its own HDL and translating that for my learning into VHDL.

I am at the point of createing a 4bit adder with carry look ahead.

I have defined two entities CLA4 and Add4LAC.

CLA4 is supposed to calculate the look ahead carry

Add4LAC is a 4bit adder with carry that uses CLA4 to calculate the carries of every bit.

I also have written a testbench to check it with ModelSim. The result is weird and I do not understand it at all.

I have defined in my simulator the following signals:

a,b (3 downto 0) --operands
cin --carry in
sum (3 downto 0) -- output of the sum
carry -- carry output.

for testing purposes i also added the expected results as

csum and ccarry (compare sum and compare carry).

If I now run it, with the following input:
a <= \"0000\";
b <= \"0000\";
cin <= \'0\';
csum <= \"0000\";
ccarry <= \'0\';

The result is not as in csum and ccarry, but instead:
# a b cin sum coutcsum ccout
# 0000 0000 0 UUUU 0 0000 0
# ** Note: Result Mismatch!
# Time: 10 ns Iteration: 0 Instance: /add4lactb
# 1111 1111 0 UU00 0 1110 1
# ** Note: Result Mismatch!
# Time: 20 ns Iteration: 0 Instance: /add4lactb

Can someone please help me to understand what is wrong? I am getting undefined output ... ???
I must have made a generic mistake and have no idea what it is. Even stepping through the code with ModelSim does not give any hint.

Here is the code:
-- Full 16 bit adder for Hack Computer with look ahead carry
-- From the book nand2tetris, translated to vhdl
-- by Christoph Linden


-- Look ahead carry calculation for 4 bits.
-- length to be defined as constant c_WordWidth

library ieee;
use ieee.std_logic_1164.all;

entity CLA4 is

port(
-- inputs
i_g : in std_logic_vector (3 downto 0);
i_p : in std_logic_vector (3 downto 0);
i_cin : in std_logic;

-- outputs
o_cout : out std_logic_vector (3 downto 0) );

end entity;

architecture cal4 of CLA4 is

signal cp0 : std_logic;
signal cp0p1 : std_logic;
signal cp0p1p2 : std_logic;
signal cp0p1p2p3 : std_logic;
signal g0p1 : std_logic;
signal g0p1p2 : std_logic;
signal g0p1p2p3 : std_logic;
signal g1p2 : std_logic;
signal g1p2p3 : std_logic;
signal g2p3 : std_logic;

begin

process (i_p, i_g, i_cin) is

begin
-- caculate bit 1 preproduct and carry out 0
-- And(a=p[0],b=cin,out=p0c);
-- Or(a=p0c,b=g[0],out=cout[0]);

cp0 <= i_p(0) and i_cin;
o_cout(0) <= cp0 or i_g(0);


-- calculate bit 2 preproduct and carry out 1
-- And3Way(a=cin, b=p[0], c=p[1], out=cp0p1);
-- And(a=g[0],b=p[1],out=g0p1);
-- Or3Way(a=cp0p1,b=g0p1,c=g[1],out=cout[1]);

cp0p1 <= i_cin and i_p(0) and i_p(1);
g0p1 <= i_g(0) and i_p(1);
o_cout(1) <= cp0p1 or g0p1 or i_g(1);

--calculate bit 3 preproducts and carry out 2
-- And4Way(a=cin, b=p[0], c=p[1], d=p[2], out=cp0p1p2);
-- And3Way(a=g[0],b=p[1],c=p[2],out=g0p1p2);
-- And(a=g[1],b=p[2],out=g1p2);
-- Or4Way(a=cp0p1p2,b=g0p1p2,c=g1p2,d=g[2],out=cout[2]);

cp0p1p2 <= i_cin and i_p(0) and i_p(1) and i_p(2);
g0p1p2 <= i_g(0) and i_p(1) and i_p(2);
g1p2 <= i_g(1) and i_p(2);
o_cout(2) <= cp0p1p2 or g0p1p2 or g1p2 or i_g(2);

--calculate bit 4 preproducts and carry out 4
-- And5Way(a=cin, b=p[0], c=p[1], d=p[2], e=p[3], out=cp0p1p2p3);
-- And4Way(a=g[0], b=p[1], c=p[2], d=p[3], out=g0p1p2p3);
-- And3Way(a=g[1],b=p[2],c=p[3],out=g1p2p3);
-- And(a=g[2],b=p[3],out=g2p3);
-- Or5Way(a=cp0p1p2p3,b=g0p1p2p3,c=g1p2p3,d=g2p3, e=g[3],out=cout[3]);

cp0p1p2p3 <= i_cin and i_p(0) and i_p(1) and i_p(2) and i_p(3);
g0p1p2p3 <= i_g(0) and i_p(1) and i_p(2) and i_p(3);
g1p2p3 <= i_g(1) and i_p(2) and i_p(3);
g2p3 <= i_g(2) and i_p(3);
o_cout(3) <= cp0p1p2p3 and g0p1p2p3 and g1p2p3 and g2p3;

end process;

end architecture;


-- a 4 bit carry look ahead adder.
library ieee;
use ieee.std_logic_1164.all;

entity Add4LAC is

port(
-- inputs
i_a : in std_logic_vector (3 downto 0);
i_b : in std_logic_vector (3 downto 0);
i_cin : in std_logic;

-- outputs
o_sum : out std_logic_vector (3 downto 0);
o_carry : out std_logic );

end entity;

architecture add4lac of Add4LAC is

component CLA4
port(
-- inputs
i_g : in std_logic_vector (3 downto 0);
i_p : in std_logic_vector (3 downto 0);
i_cin : in std_logic := \'L\';

-- outputs
o_cout : out std_logic_vector (3 downto 0) );
end component;

signal g0,g1,g2,g3 : std_logic;
signal p0,p1,p2,p3 : std_logic;
signal c0,c1,c2 : std_logic;

begin

u1: CLA4
port map(
i_g(0) => g0,
i_g(1) => g1,
i_g(2) => g2,
i_g(3) => g3,
i_p(0) => p0,
i_p(1) => p1,
i_p(2) => p2,
i_p(3) => p3,
o_cout(0) => c0,
o_cout(1) => c1,
o_cout(2) => c2,
o_cout(3) => o_carry );

process (i_a,i_b,i_cin) is
begin
-- Bit 0
g0 <= i_a(0) and i_b(0);
p0 <= i_a(0) xor i_b(0);
o_sum(0) <= p0 xor i_cin;


-- Bit 1
g1 <= i_a(1) and i_b(1);
p1 <= i_a(1) xor i_b(1);
o_sum(1) <= p1 xor c0;


-- Bit 2
g2 <= i_a(2) and i_b(2);
p2 <= i_a(2) xor i_b(2);
o_sum(2) <= p2 xor c1;


-- Bit 3
g3 <= i_a(3) and i_b(3);
p3 <= i_a(3) xor i_b(3);
o_sum(3) <= p3 xor c2;


end process;
end architecture;


Here is the tb code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;

entity Add4LACTB is
end entity;

architecture sim of Add4LACTB is

signal a,b,sum,csum : std_logic_vector (3 downto 0);
signal cin,carry,ccarry : std_logic;

component Add4LAC

port(
-- inputs
i_a : in std_logic_vector (3 downto 0);
i_b : in std_logic_vector (3 downto 0);
i_cin : in std_logic;

-- outputs
o_sum : out std_logic_vector (3 downto 0);
o_carry : out std_logic );
end component;

begin
Adder1: Add4LAC

port map(
i_a => a,
i_b => b,
i_cin => cin,
o_sum => sum,
o_carry => carry );

process is
variable v_myline : line;


begin
write(v_myline, string\'(\" a\"), left, 5);
write(v_myline, string\'(\" b\"), left, 5);
write(v_myline, string\'(\" cin\"), left, 5);
write(v_myline, string\'(\" sum\"), left, 5);
write(v_myline, string\'(\" cout\"), left, 5);
write(v_myline, string\'(\"csum\"), left, 5);
write(v_myline, string\'(\"ccout\"), left, 5);
writeline(output, v_myline);

-- testscenarios
--set a %B0000000000000000,
--set b %B0000000000000000,
--set a %B0000000000000000,
--set b %B1111111111111111,
--set a %B1111111111111111,
--set b %B1111111111111111,
--set a %B1010101010101010,
--set b %B0101010101010101,
--set a %B0011110011000011,
--set b %B0000111111110000,
--set a %B0001001000110100,
--set b %B1001100001110110,

a <= \"0000\";
b <= \"0000\";
cin <= \'0\';
csum <= \"0000\";
ccarry <= \'0\';


wait for 10 ns;
write(v_myline, a, left, 5);
write(v_myline, b, left, 5);
write(v_myline, cin, left, 5);
write(v_myline, sum, left, 5);
write(v_myline, carry, left, 5);
write(v_myline, csum, left, 5);
write(v_myline, ccarry, left, 5);
writeline(output, v_myline);
if sum /= csum or carry /= ccarry then
report \"Result Mismatch!\";
-- wait ;
end if;

a <= \"1111\";
b <= \"1111\";
cin <= \'0\';
csum <= \"1110\";
ccarry <= \'1\';



wait for 10 ns;
write(v_myline, a, left, 5);
write(v_myline, b, left, 5);
write(v_myline, cin, left, 5);
write(v_myline, sum, left, 5);
write(v_myline, carry, left, 5);
write(v_myline, csum, left, 5);
write(v_myline, ccarry, left, 5);
writeline(output, v_myline);
if sum /= csum or carry /= ccarry then
report \"Result Mismatch!\";
wait ;
end if;

wait;
end process;

end architecture;
 
Toggle Sidebar

Welcome to EDABoard.com

Sponsor

Top