1
\$\begingroup\$

I am facing a very strange situation:

I have one VHDL entity and two associated architecture. When I test the entity with one single architecture the output is right and clear. But when I add the second architecture (creating two instances) all the first one output shows U. I am two days on it, and still can not solve it. If you think adding the code is helpful let me know and I will attach the code, but I am sure the code is right.

Update:

I hoped it is a common glitch and there is a quick fix, but seems I am wrong and have to include code:

I am using Vivado v2015.4 and trying to perform the behavioral simulation.

FullAdder.vhd:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;            -- Provides : STD_LOGIC, STD_LOGIC_VECTOR

entity fullAdder is
    Port ( Cin : in  STD_LOGIC;
           x : in  STD_LOGIC;
           y : in  STD_LOGIC;
           s : out  STD_LOGIC;
           Cout : out  STD_LOGIC);
end fullAdder;

architecture GateLevel of fullAdder is
begin
       s <= x XOR y XOR Cin ;
       Cout <= (x AND y) OR (Cin AND x) OR (Cin AND y) ;
end GateLevel;

Adder.vhd:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;            -- Provides : STD_LOGIC, STD_LOGIC_VECTOR
USE IEEE.numeric_std.all;

entity adder is
    generic (N: integer := 16);
   Port ( Cin : in  STD_LOGIC;
          X : in  std_logic_vector (N - 1 downto 0);
          Y : in  std_logic_vector (N - 1 downto 0);
          S : out  std_logic_vector (N - 1 downto 0);
          Cout : out  STD_LOGIC);
end adder;

architecture CarryLookAheadAdder of adder is
    signal c : std_logic_vector (N - 1 downto 1);
    signal g : std_logic_vector (N - 1 downto 0);
    signal p : std_logic_vector (N - 1 downto 0);
    signal carryOut : STD_LOGIC;
begin

-- Carry Look-Ahead Circuit
g(0) <= x(0) and y(0);
p(0) <= x(0) or y(0);
c(1) <= g(0) or (p(0) and Cin);

-- generate the carry bits in the middle
gen_carry_bits: for I in 1 to (N - 2) generate
    carry_bitX:
    g(I) <= x(I) and y(I);
    p(I) <= x(I) or y(I);
    c(I + 1) <= g(I) or (p(I) and c(I));
end generate gen_carry_bits;    

-- generate the last carry
g(N - 1) <= x(N - 1) and y(N - 1);
p(N - 1) <= x(N - 1) or y(N - 1);
Cout <= c(N - 1);

--  First sum bit
S(0) <= x(0) xor y(0) xor Cin;

-- generate the bit sums in between
gen_sums: for I in 1 to N - 2 generate
    S(I) <= x(I) xor y(I) xor c(I);
end generate gen_sums;

-- LAst sum bit
S(N - 1) <= x(N - 1) xor y(N - 1) xor c(N - 1);

end CarryLookAheadAdder;

architecture RippleCarryAdder of adder is
    component fullAdder    
        Port ( Cin : in  STD_LOGIC;
           x : in  STD_LOGIC;
           y : in  STD_LOGIC;
           s : out  STD_LOGIC;
           Cout : out  STD_LOGIC);
  end component;   
  SIGNAL C : std_logic_vector(1 TO N - 1) ;      
  --for all: fullAdder use entity fullAdder(GateLevel);
begin

-- First stage gets the carry in
stage0: fullAdder PORT MAP (Cin, X(0), Y(0), S(0), C(1));

-- Middle stages follow the same pattern
gen_stage:
    for I in 1 to N - 2 generate
    stageX: fullAdder PORT MAP (C(I), X(I), Y(I), S(I), C(I + 1));
    end generate gen_stage;

-- Last stage spits the carry out
stageN_1: fullAdder PORT MAP (C(N - 1), X(N - 1), Y(N - 1), S(N - 1), Cout);

end RippleCarryAdder;

compare_adders.vhd:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;            -- Provides : STD_LOGIC, STD_LOGIC_VECTOR
USE IEEE.numeric_std.all;
use work.all;

entity compare_adders is
    generic (N: integer := 16);
    Port ( Cin : in  STD_LOGIC;
           X : in  std_logic_vector (N - 1 downto 0);
           Y : in  std_logic_vector (N - 1 downto 0);
           S1 : out  std_logic_vector (N - 1 downto 0);
           Cout1 : out  STD_LOGIC;
           S2 : out  std_logic_vector (N - 1 downto 0);
           Cout2 : out  STD_LOGIC
           );
end compare_adders;

architecture Structure of compare_adders is
    component adder
         generic (N : integer);
         Port ( Cin : in  STD_LOGIC;
           X : in  std_logic_vector (N - 1 downto 0);
           Y : in  std_logic_vector (N - 1 downto 0);
           S : out  std_logic_vector (N - 1 downto 0);
           Cout : out  STD_LOGIC);
    end component;

    for AdderNormal: adder use entity work.adder(RippleCarryAdder);
    for AdderLookAHead: adder use entity work.adder(CarryLookAheadAdder);

begin
    AdderNormal: adder generic map (N => 16) port map (Cin , X, Y, S1, Cout1);
    AdderLookAHead: adder generic map (N => 16) port map (Cin , X, Y, S2, Cout2);
end Structure;

compare_adders_test.vhd

LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

ENTITY compare_adders_test_vhd IS
END compare_adders_test_vhd;

ARCHITECTURE behavior OF compare_adders_test_vhd IS 

    -- Component Declaration for the Unit Under Test (UUT)
    COMPONENT compare_adders
    PORT(
        Cin : IN std_logic;
        X : IN std_logic_vector(15 downto 0);
        Y : IN std_logic_vector(15 downto 0);          
        S1 : OUT std_logic_vector(15 downto 0);
        Cout1 : OUT std_logic;
        S2 : OUT std_logic_vector(15 downto 0);
        Cout2 : OUT std_logic
        );
    END COMPONENT;

    --Inputs
    SIGNAL Cin :  std_logic := '0';
    SIGNAL X :  std_logic_vector(15 downto 0) := (others=>'0');
    SIGNAL Y :  std_logic_vector(15 downto 0) := (others=>'0');

    --Outputs
    SIGNAL S1 :  std_logic_vector(15 downto 0);
    SIGNAL Cout1 :  std_logic;
    SIGNAL S2 :  std_logic_vector(15 downto 0);
    SIGNAL Cout2 :  std_logic;

    --internal
    signal X_t : unsigned (15 downto 0) := (others=>'0');
    signal Y_t : unsigned (15 downto 0) := (others=>'0');

BEGIN

    -- Instantiate the Unit Under Test (UUT)
    uut: compare_adders PORT MAP(
        Cin => Cin,
        X => X,
        Y => Y,
        S1 => S1,
        Cout1 => Cout1,
        S2 => S2,
        Cout2 => Cout2
    );

    tb : PROCESS
    BEGIN

        -- Wait 100 ns for global reset to finish
        wait for 100 ns;

        report "Testing 16-bit adder is started.";

        -- Place stimulus here
        Cin <= '0';
        X <= B"0000_0000_0000_0000";
        Y <= B"0000_0000_0000_0000";
        X_t <= B"0000_0000_0000_0000";
        Y_t <= B"0000_0000_0000_0000";
        wait for 500 ns;

        for J in 0 to 3 loop
            for I in 0 to 65535 loop
                wait for 1000 ns;
                assert (unsigned(S1) = unsigned(X) + unsigned(Y)) report "Error, expected sum of " &
                    integer'image(to_integer(unsigned(X) + unsigned(Y))) & " for x = " &
                    integer'image(to_integer(unsigned(X))) & " and y = " &
                    integer'image(to_integer(unsigned(Y))) & " but result S1 is " &
                    integer'image(to_integer(unsigned(S1))) severity error ;
                assert (unsigned(S2) = unsigned(X) + unsigned(Y)) report "Error, expected sum of " &
                    integer'image(to_integer(unsigned(X) + unsigned(Y))) & " for x = " &
                    integer'image(to_integer(unsigned(X))) & " and y = " &
                    integer'image(to_integer(unsigned(Y))) & " but result S2 is " &
                    integer'image(to_integer(unsigned(S2))) severity error ;
                --assert (S1 = S2) report "S1 does not match S2" severity error;
                --assert (Cout1 = Cout2) report "S1 does not match S2" severity error;

                X_t <= X_t + B"0000_0000_0000_0001";    
                X <= std_logic_vector(X_t);
            end loop;
            Y_t <= Y_t + B"0000_0000_0000_0001";    
            Y <= std_logic_vector(Y_t);
        end loop;

        report "test completed";

        wait; -- will wait forever
    END PROCESS;

END;

UPDATE 2:

I just managed to compile and simulate the above code in GHDL and GTKWave showing 100% success. Therefore the problem is with Xilinx Vivado.

\$\endgroup\$
  • \$\begingroup\$ You should start by telling us which simulator you're using. \$\endgroup\$ – Dave Tweed Sep 8 '16 at 10:39
  • 1
    \$\begingroup\$ If the code was 100% correct, you would not be seeing errors! It's always worth including some relevant code. \$\endgroup\$ – scary_jeff Sep 8 '16 at 10:41
  • \$\begingroup\$ Also tell us if this is behavioural or post-synthesis simulation. (If it's post-synth, don't add the netlist code to the question, only the sources, but it would be helpful to dropbox or link to it) \$\endgroup\$ – Brian Drummond Sep 8 '16 at 10:45
  • \$\begingroup\$ ok I added all the codes. \$\endgroup\$ – Ehsan Sep 8 '16 at 10:55
  • 1
    \$\begingroup\$ If you have a channel to Xilinx Support, report this with testcase to Xilinx and push them to get a change request. \$\endgroup\$ – Brian Drummond Sep 8 '16 at 13:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.