2
\$\begingroup\$

I'm creating an ALU for a simple calculator. I have made the addition, subtraction, and multiplication part of the ALU and with them I didn't have to initialize anything.

I am attempting to create the division part but my inputs and outputs will not initialize. I have tried setting the ports to 0 but still they remain uninitialized (it reports "UUUU" or "UUUUUUUU").

The problem seems to be in this line:

 X <=std_logic_vector(to_unsigned(to_integer(unsigned(A))/to_integer(unsigned(B)),32));

Source:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;


entity DIV is
    port(
        A: in std_logic_vector(15 downto 0);
        B: in std_logic_vector(15 downto 0);
        X: out std_logic_vector(31 downto 0)
    );
end DIV;

architecture Behavioral of DIV is


begin

       X <=std_logic_vector(to_unsigned(to_integer(unsigned(A))/to_integer(unsigned(B)),32));
      
 
end Behavioral;

Testbench:

library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;

entity DIV_tb is
end;

architecture bench of DIV_tb is

  component DIV
      port(
          A: in std_logic_vector(15 downto 0);
          B: in std_logic_vector(15 downto 0);
          X: out std_logic_vector(31 downto 0)
      );
  end component;

  signal A: std_logic_vector(15 downto 0);
  signal B: std_logic_vector(15 downto 0);
  signal X: std_logic_vector(31 downto 0);

begin

  uut: DIV port map ( A => A,
                      B => B,
                      X => X );

  stimulus: process
  begin
  
    A<= std_logic_vector(to_unsigned(integer(12), 16));
    B<= std_logic_vector(to_unsigned(integer(6), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(2), 32)) then report "PASS for division    of A = 12, B = 6";
    else report "FAIL for division    of A = 12, B = 6";
    end if;

    A<= std_logic_vector(to_unsigned(integer(300), 16));
    B<= std_logic_vector(to_unsigned(integer(7), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(42), 32)) then report "PASS for division    of A = 300, B = 7";
    else report "FAIL for division    of A = 300, B = 7";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(500), 16));
    B<= std_logic_vector(to_unsigned(integer(6), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(83), 32)) then report "PASS for division    of A = 500, B = 6";
    else report "FAIL for division    of A = 500, B = 6";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(755), 16));
    B<= std_logic_vector(to_unsigned(integer(7), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(107), 32)) then report "PASS for division    of A = 755, B = 7";
    else report "FAIL for division    of A = 755, B = 7";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(500), 16));
    B<= std_logic_vector(to_unsigned(integer(14), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(35), 32)) then report "PASS for division    of A = 500, B = 14";
    else report "FAIL for division    of A = 500, B = 14";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(222), 16));
    B<= std_logic_vector(to_unsigned(integer(11), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(20), 32)) then report "PASS for division    of A = 222, B = 11";
    else report "FAIL for division    of A = 222, B = 11";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(18), 16));
    B<= std_logic_vector(to_unsigned(integer(6), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(3), 32)) then report "PASS for division    of A = 18, B = 6";
    else report "FAIL for division    of A = 18, B = 6";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(999), 16));
    B<= std_logic_vector(to_unsigned(integer(8), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(124), 32)) then report "PASS for division    of A = 999, B = 8";
    else report "FAIL for division    of A = 999, B = 8";
    end if;
    
  end process;


end;

This an image of the wave forms:

enter image description here

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Looks like you actually have to run the simulation. Try and find a "run" command or button. \$\endgroup\$
    – user16324
    Commented Jan 4, 2021 at 16:07

2 Answers 2

2
\$\begingroup\$

You must initialize the signals in the testbench to a value that is greater than 0.

library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;

entity DIV_tb is
end;

architecture bench of DIV_tb is

  component DIV
      port(
          A: in std_logic_vector(15 downto 0);
          B: in std_logic_vector(15 downto 0);
          X: out std_logic_vector(31 downto 0)
      );
  end component;

  signal A: std_logic_vector(15 downto 0):="0000000000000001";
  signal B: std_logic_vector(15 downto 0):="0000000000000001";
  signal X: std_logic_vector(31 downto 0);

begin

  uut: DIV port map ( A => A,
                      B => B,
                      X => X );

  stimulus: process
  begin
  
    A<= std_logic_vector(to_unsigned(integer(12), 16));
    B<= std_logic_vector(to_unsigned(integer(6), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(2), 32)) then report "PASS for division   of A = 12, B = 6";
    else report "FAIL for division   of A = 12, B = 6";
    end if;

    A<= std_logic_vector(to_unsigned(integer(300), 16));
    B<= std_logic_vector(to_unsigned(integer(7), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(42), 32)) then report "PASS for division   of A = 300, B = 7";
    else report "FAIL for division   of A = 300, B = 7";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(500), 16));
    B<= std_logic_vector(to_unsigned(integer(6), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(83), 32)) then report "PASS for division   of A = 500, B = 6";
    else report "FAIL for division   of A = 500, B = 6";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(755), 16));
    B<= std_logic_vector(to_unsigned(integer(7), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(107), 32)) then report "PASS for division   of A = 755, B = 7";
    else report "FAIL for division   of A = 755, B = 7";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(500), 16));
    B<= std_logic_vector(to_unsigned(integer(14), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(35), 32)) then report "PASS for division   of A = 500, B = 14";
    else report "FAIL for division   of A = 500, B = 14";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(222), 16));
    B<= std_logic_vector(to_unsigned(integer(11), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(20), 32)) then report "PASS for division   of A = 222, B = 11";
    else report "FAIL for division   of A = 222, B = 11";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(18), 16));
    B<= std_logic_vector(to_unsigned(integer(6), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(3), 32)) then report "PASS for division   of A = 18, B = 6";
    else report "FAIL for division   of A = 18, B = 6";
    end if;
    
    A<= std_logic_vector(to_unsigned(integer(999), 16));
    B<= std_logic_vector(to_unsigned(integer(8), 16));
    wait for 1ns;
    if X =std_logic_vector(to_unsigned(integer(124), 32)) then report "PASS for division   of A = 999, B = 8";
    else report "FAIL for division   of A = 999, B = 8";
    end if;
    
  end process;

end;
\$\endgroup\$
7
  • 2
    \$\begingroup\$ Specifically, you need to set B to a non-zero value, because dividing by zero doesn't work. \$\endgroup\$ Commented Dec 5, 2022 at 7:00
  • \$\begingroup\$ since this is a testbench, you can simplify it greatly by using VHDL-2008 and understand VHDL's overloading. The unsigned(X) = 2 type checks could be simplified to X = 2 if you used either unsigned ports or package numeric_std_unsigned in the testbench. \$\endgroup\$
    – Jim Lewis
    Commented Jan 28 at 18:20
  • 1
    \$\begingroup\$ Hey, lets not change the answer since it could invalidate the code. Stick to the version that the OP is using. Thanks \$\endgroup\$
    – Voltage Spike
    Commented Jan 29 at 16:35
  • \$\begingroup\$ @JimLewis - FYI, you may wish to (re)submit your edit as an answer, due to the rollback. \$\endgroup\$ Commented Jan 29 at 19:38
  • 1
    \$\begingroup\$ I know you are bringing the code up to speed, but we would prefer if you post your own answer instead of taking someone else's answer out of context. That's what worked for the OP. \$\endgroup\$
    – Voltage Spike
    Commented Jan 30 at 21:04
2
\$\begingroup\$

This is the same solution as @kenneth except I have replaced the extensive verbosity in the form of conversions with VHDL-2008 code.

Also since this is a testbench and since the OP used std_logic_vector ports, where perhaps unsigned should have been used, I also added the package numeric_std_unsigned (from VHDL-2008) to simplify the results checking.

library IEEE;
use IEEE.Std_logic_1164.all;
use IEEE.Numeric_Std.all;
use IEEE.Numeric_Std_unsigned.all;

entity DIV_tb is
end;

architecture bench of DIV_tb is

  component DIV
      port(
          A: in std_logic_vector(15 downto 0);
          B: in std_logic_vector(15 downto 0);
          X: out std_logic_vector(31 downto 0)
      );
  end component;

  signal A: std_logic_vector(15 downto 0):="0000000000000001";
  signal B: std_logic_vector(15 downto 0):="0000000000000001";
  signal X: std_logic_vector(31 downto 0);

begin

  uut: DIV port map ( A => A,
                      B => B,
                      X => X );

  stimulus: process
  begin
  
    A<= 16UD"12" ; -- VHDL-2008
    B<= 16UD"6";
    wait for 1ns;
    if X = 2 then report "PASS for division   of A = 12, B = 6";
    else report "FAIL for division   of A = 12, B = 6";
    end if;

    A<= 16UD"300" ; -- VHDL-2008
    B<= 16UD"7";
    wait for 1ns;
    if X = 42 then report "PASS for division   of A = 300, B = 7";
    else report "FAIL for division   of A = 300, B = 7";
    end if;
    
    A<= 16UD"500" ; -- VHDL-2008
    B<= 16UD"6";
    wait for 1ns;
    if X = 83 then report "PASS for division   of A = 500, B = 6";
    else report "FAIL for division   of A = 500, B = 6";
    end if;
    
    A<= 16UD"755" ; -- VHDL-2008
    B<= 16UD"7";
    wait for 1ns;
    if X = 107 then report "PASS for division   of A = 755, B = 7";
    else report "FAIL for division   of A = 755, B = 7";
    end if;
    
    A<= 16UD"500" ; -- VHDL-2008
    B<= 16UD"14";
    wait for 1ns;
    if X = 35 then report "PASS for division   of A = 500, B = 14";
    else report "FAIL for division   of A = 500, B = 14";
    end if;
    
    A<= 16UD"222" ; -- VHDL-2008
    B<= 16UD"11";
    wait for 1ns;
    if X = 20 then report "PASS for division   of A = 222, B = 11";
    else report "FAIL for division   of A = 222, B = 11";
    end if;
    
    A<= 16UD"18" ; -- VHDL-2008
    B<= 16UD"6";
    wait for 1ns;
    if X = 3 then report "PASS for division   of A = 18, B = 6";
    else report "FAIL for division   of A = 18, B = 6";
    end if;
    
    A<= 16UD"999" ; -- VHDL-2008
    B<= 16UD"8";
    wait for 1ns;
    if X = 124 then report "PASS for division   of A = 999, B = 8";
    else report "FAIL for division   of A = 999, B = 8";
    end if;
    
  end process;

end;
\$\endgroup\$
0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.