1
\$\begingroup\$

I have the following two files, and I'm trying to test the first file. The first file is a simple ALU which handles a variety of functions depending on the value of a selection input. I've played with it on my FPGA and it seems to work as intended (though I haven't checked Overflow's functionality yet). I obviously have not tested every possible output by hand. I intend the testbench to test 4 inputs for each of my ALU functions. The FOR loop in the testbench tries to accomplish this.

Unfortunately, the testbench gives me unknowns for my inputs, and I'm unsure why. This is my first time writing a VHDL testbench, so I'm trying to determine what the error is and why it occurs since I would like to see what my testbench outputs look like.

VHDL FILE

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity ALU is
    port (  S, A, B : in std_logic_vector(3 downto 0);
            Zero, Negative, Carry, Overflow : out std_logic;
            segments : out std_logic_vector(6 downto 0);
            disp_right, disp_left, disp_midright, disp_midleft : out std_logic
        );
end ALU;


architecture behavioral of ALU is

signal sum : std_logic_vector(5 downto 0);

begin
    with S select
        sum     <=  "00"&A when "0000",
                    "00"&(not A) when "0001",
                    "00"&(A and B) when "0010",
                    "00"&(not (A and B)) when "0011",
                    "00"&(A or B) when "0100",
                    "00"&(not (A or B)) when "0101",
                    "00"&(A xor B) when "0110",
                    "00"&(not (A xor B)) when "0111",
                    ("00"&A + B) when "1000",
                    ("00"&A - B) when "1001",
                    '0'&A(3 downto 0)&'0' when "1010",
                    "000"&A(3 downto 1) when "1011",
                    "00"&A(3)&A(3 downto 1) when "1100",
                    "111111" when others;       


        Zero        <=  '1' when (sum = "00000") else '0';
        Negative    <=  '1' when (sum(3) = '1') else '0';
        Carry       <=  '1' when (sum(4) = '1') else '0';
        Overflow    <=   ( A(3) and B(3) ) xnor sum(4);

    with sum(4 downto 0) select
        segments    <=  "0000001" when "00000",--0  
                        "1001111" when "00001",--1
                        "0010010" when "00010",--2
                        "0000110" when "00011",--3
                        "1001100" when "00100",--4
                        "0100100" when "00101",--5
                        "0100000" when "00110",--6
                        "0001111" when "00111",--7
                        "0000000" when "01000",--8
                        "0000100" when "01001",--9
                        "0000010" when "01010",--A
                        "1100000" when "01011",--B
                        "0110001" when "01100",--C
                        "1000010" when "01101",--D
                        "0110000" when "01110",--E
                        "0111000" when "01111",--F
                        "1111111" when others;--misc




    disp_left <= '1';       -- turn the seven-segment display off                   
    disp_midleft <= '1';    -- turn the seven-segment display off 
    disp_midright <= '1';   -- turn the seven-segment display off
    disp_right <= '0';      -- turn the seven-segment display on

end behavioral;

TESTBENCH FILE:

library ieee;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.std_logic_signed.all;
use ieee.std_logic_arith.all;

entity ALU_tb is
end ALU_tb;

architecture behavior of ALU_tb is
    component ALU is
        port (  S, A, B : in std_logic_vector(3 downto 0);
            Zero, Neg, Carry, Overflow : out std_logic;
            segments : out std_logic_vector(6 downto 0);
            disp_right, disp_left, disp_midright, disp_midleft : out std_logic);
    end component;

Signal A_tb, B_tb, S_tb : std_logic_vector(3 downto 0);
Signal Z_tb, N_tb, C_tb, O_tb : std_logic;
Signal seg_tb : std_logic_vector(6 downto 0);


begin

uut : ALU port map(
    A => A_tb, 
    B => B_tb, 
    S => S_tb,
    Zero => Z_tb, 
    Neg => N_tb, 
    Carry => C_tb, 
    Overflow => O_tb,--this is the letter "O" not a zero.
    segments => seg_tb
    );

    ALU_simulation : process
    begin
       --test loop checks 4 inputs for each select combination. There are 13 select combinations
       --not including the "when others" statement. 
       S_tb <= "0000";
       for i in 0 to 12 loop
           for j in 0 to 3 loop
               A_tb <= "0000";
               B_tb <= "0111";
               wait for 10 ns;
               A_tb <= A_tb + 1;
           end loop;
           wait for 10 ns;
           S_tb <= S_tb + 1;
       end loop;

    end process ALU_simulation;

end behavior;
\$\endgroup\$
  • \$\begingroup\$ Are you getting "U" (un-initialised) or "X" (unknown) and on which signals? (Also you probably don't want to re-init A_tb every inner loop iteration) \$\endgroup\$ – Brian Drummond Apr 24 at 19:32
3
\$\begingroup\$

I just copied your files and ran them is Xilinx ISE. They didn't compile:

Zero, Neg, Carry, Overflow : out std_logic;
Neg => N_tb, 

You have Neg instead of Negative in those lines. Correcting those lines resulted in: testbench

I'm rusty in VHDL and this IDE, but maybe thats the issue, and you tried to reload the simulation with an error or something?

You may have actually tried to run simulation on your 'uut' file, not on testbench file. That results in spawning a window with 'Uninitialised' inputs:

enter image description here

P.S.

Overflow => O_tb,--this is the letter "O" not a zero.
segments => seg_tb

Just don't use the O then, type something like ovf, like you did with seg ;)

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ Yes, I had the hierarchy set with the uut file as the top instead of the testbench. Switching it and restarting the simulation process resulted in the proper output. I also noticed a logical error with the code I used for looping. Assigning A_tb within the loop causes it to reset and not behave as desired, but that should be resolved by moving A_tb outside of the inner for loop. The same could be done for the B_tb assignment in the loop, since it doesn't change at all the way I've written it. \$\endgroup\$ – Luke Mathwalker Apr 24 at 20:08
  • \$\begingroup\$ I'm glad i helped \$\endgroup\$ – Marek Metelski Apr 24 at 20:28

Your Answer

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

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