Lucy
Lucy

Reputation: 9

Undefined Initial Signals VHDL

I have to implement a mini-router in VHDL. The design requirements for this are:

design requirements

I've written the implementation, and a testbench. However, looking at the simulation waveform, some of my initial signals are undefined and I'm not sure why.

enter image description here

This is the source code:


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;

entity mini_router is
   port (
         clk       : in  std_logic; 
         reset     : in  std_logic; -- synchronous negative reset
         data1     : in  std_logic_vector(9 downto 0); 
         req1      : in  std_logic; 
         grant1    : out std_logic;
         data2     : in  std_logic_vector(9 downto 0); 
         req2      : in  std_logic; 
         grant2    : out std_logic;
         data_out  : out std_logic_vector(7 downto 0); 
         valid     : out std_logic
        );
  end entity;
  
  architecture arch of mini_router is  
  

  signal aux  : std_logic_vector(9 downto 0);
  signal aux1 : std_logic_vector(1 downto 0);
  signal aux2 : std_logic_vector(1 downto 0);
  signal aux_valid : std_logic;
  signal aux_grant1 : std_logic;
  signal aux_grant2 : std_logic;
  
  begin
  
  mini_router: process(clk)
  variable r : std_logic:= '1';
  
  begin
  -- conta le volte in cui c'è stato data conflict
  if rising_edge(clk) then -- chiuso
  
  if reset = '0' then
  aux    <= (others => '0');
  aux_valid  <= '0';
  aux_grant1 <= '0';
  aux_grant2 <= '0';
  
  elsif reset = '1' then 
 
  if (req1 xor req2) = '1' then --chiuso -- un solo req è alto
  if req1 ='1' then --chiuso
  aux    <= data1;
  aux_grant1 <= '1';
  aux_grant2 <= '0';
  aux_valid  <= '1';
  else 
  aux    <= data2;
  aux_grant1 <= '0';
  aux_grant2 <= '1';
  aux_valid  <= '1';
  end if;

  

 ----entrambi i req sono alti 
 elsif (req1 and req2) = '1'  then  -- chiuso

 if ((unsigned(aux1)) > (unsigned(aux2))) then
  aux    <= data1;
  aux_grant1 <= '1';
  aux_grant2 <= '0';
  aux_valid  <= '1';
            
 elsif ((unsigned(aux1)) < (unsigned(aux2))) then
  aux    <= data2;
  aux_grant2 <= '1';
  aux_grant1 <= '0';
  aux_valid  <= '1';
 
elsif ((unsigned(aux1)) = (unsigned(aux2))) then  -- stesso livello di priorità -- alternativa:(aux1 xnor aux2)="11" 

  if r = '1' then 
  aux    <= data1;
  aux_grant1<= '1';
  aux_grant2 <= '0';
  aux_valid  <= '1';
  r      := not (r);
  
  else 
   aux    <= data2;
   aux_grant2 <= '1';
   aux_grant1<= '0';
   aux_valid   <= '1';
   r      := not (r);

end if;
 
end if;


 elsif (req1 nor req2) = '1'  then
 aux_valid   <=  '0';
 aux    <= (others => '0');
 aux_grant1 <= '0';
 aux_grant2 <= '0';
 
 end if;
 end if; -- if del reset
 end if; -- if del clock
 end process;
  
data_out <= aux(9 downto 2);
aux1     <=  data1 (1 downto 0);
aux2     <=  data2 (1 downto 0);
valid    <=  aux_valid;
grant1   <= aux_grant1;
grant2   <= aux_grant2;

 end architecture;

This is the testbench:

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;

entity mini_router_tb is
end mini_router_tb;

architecture arc of mini_router_tb is

    constant T_CLK      : time := 10 ns; --- frequenza di clock: 125 MHz
     
    signal clk_tb      : std_logic := '1';
    signal reset_tb    : std_logic := '0';  -- reset attivo basso sincrono
    signal data1_tb    : std_logic_vector(9 downto 0) := (others => '0');
    signal req1_tb     : std_logic:= '0'; 
    signal grant1_tb   : std_logic;
    signal data2_tb    : std_logic_vector(9 downto 0) := (others => '0');
    signal req2_tb     : std_logic:= '0'; 
    signal grant2_tb   : std_logic;
    signal data_out_tb : std_logic_vector(7 downto 0);
    signal valid_tb    : std_logic;
         
    signal end_sim : std_logic := '1'; -- signal to use to stop the simulation when there is nothing else to test
    
component mini_router is
   port (
         clk       : in  std_logic; 
         reset     : in  std_logic; -- synchronous negative reset
         data1     : in  std_logic_vector(9 downto 0); 
         req1      : in  std_logic; 
         grant1    : out std_logic;
         data2     : in  std_logic_vector(9 downto 0); 
         req2      : in  std_logic; 
         grant2    : out  std_logic;
         data_out  : out std_logic_vector(7 downto 0); 
         valid     : out std_logic
        );
  end component;

    

begin

    clk_tb  <= (not(clk_tb)and(end_sim)) after T_CLK/2;

    

    DUT : mini_router
    port map ( 
        clk      => clk_tb,
        reset    => reset_tb,
        data1    => data1_tb,
        req1     => req1_tb,
        grant1   => grant1_tb,
        data2    => data2_tb,
        req2     => req2_tb,
        grant2   => grant2_tb,
        data_out => data_out_tb,
        valid    => valid_tb
             );

  -- process used to make the testbench signals change synchronously with the rising edge of the clock
   stimuli_process: process(clk_tb,reset_tb)

    variable t  : integer   := 0;  -- variabile che conta i cicli di clock
 begin  
    if (rising_edge(clk_tb)) then
            case (t) is
            
                when  1  =>  data1_tb  <= (9 downto 3 => '0') & "100"; -- data1= 4; data_out=0 per il reset
                             data2_tb  <= (9 downto 4 => '0') & "1101";-- data2= 13; 
                             req1_tb   <= '1' ; req2_tb<= '0';
                               
                when  2  =>  reset_tb  <= '1';  
                             data1_tb  <= (9 downto 3 => '0') & "100"; -- data1= 4; data_out=1
                             data2_tb  <= (9 downto 4 => '0') & "1101"; -- data2= 13; 
                             req1_tb   <= '1' ; req2_tb<= '0';
                             
                when  3  =>  data1_tb  <= (9 downto 3 => '0') & "100"; -- data1= 4; 
                             data2_tb  <= (9 downto 4 => '0') & "1101";-- data2= 13; data_out=3
                             req1_tb   <= '0' ; req2_tb<= '1';
                             
                when  4  =>  data1_tb  <= (9 downto 5 => '0') & "11100"; --data1=28
                             data2_tb  <= (9 downto 4 => '0') & "1101"; -- data2= 13; data_out=3 priorità maggiore
                             req1_tb   <= '1' ; req2_tb<= '1';
                
                when  5  =>  data1_tb  <= (9 downto 5 => '0') & "00111"; --data1=7; data_out=1 priorità maggiore
                             data2_tb  <= (9 downto 5 => '0') & "11101"; -- data2= 29; 
                             req1_tb   <= '1' ; req2_tb<= '1';
                
                when  6   => data1_tb  <= (9 downto 5 => '0') & "00111"; --data1=7; data_out=1
                             data2_tb  <= (9 downto 5 => '0') & "11111"; -- data2= 31; 
                             req1_tb   <= '1' ; req2_tb<= '1';
                
                when 7    => data1_tb  <= (9 downto 5 => '0') & "00111"; --data_out=0; 
                             data2_tb  <= (9 downto 5 => '0') & "11111"; 
                             req1_tb   <= '0' ; req2_tb<= '0';  
                            
                when 8    => data1_tb  <= (9 downto 5 => '0') & "10111"; --data1=7; data_out non assunto=5
                             data2_tb  <= (9 downto 5 => '0') & "11111"; -- data2= 31; data_out=7
                             req1_tb   <= '1' ; req2_tb<= '1';
                                
                                            
                when 9   => end_sim   <= '0'; -- stops the simulation when t = 10
                
                when others => null; -- non accade nulla negli altri casi
                         
            end case;

            t := t + 1;
        
          end if;           
     end process;
end architecture;

Upvotes: 1

Views: 712

Answers (2)

PlayDough
PlayDough

Reputation: 1138

The reason your signals are initially set to U or X is because the values of all signals, variables, etc. are initialized to the left hand side of the type definition.

From the IEEE 1076 code (see here):

  -------------------------------------------------------------------
  -- logic state system  (unresolved)
  -------------------------------------------------------------------
  type STD_ULOGIC is ( 'U',             -- Uninitialized
                       'X',             -- Forcing  Unknown
                       '0',             -- Forcing  0
                       '1',             -- Forcing  1
                       'Z',             -- High Impedance
                       'W',             -- Weak     Unknown
                       'L',             -- Weak     0
                       'H',             -- Weak     1
                       '-'              -- Don't care
                       );
  --------------------------------

And std_logic is just a resolved version of std_ulogic. So any signal of type std_logic will have its default value be U, unless set otherwise.

Consider the following code:

signal A : std_logic;
signal B : std_logic := '1';

Signal A would be U until set otherwise. Signal B will be 0 until set otherwise.

This is why you are seeing U in your simulation. (As for X you see in your waveform window, many simulators that collapse vectors into a single value in the waveform view treat collections with U as X. Expand that vector and I suspect you will see several U's.)

Upvotes: 0

the busybee
the busybee

Reputation: 12600

Your reset logic is synchronous, because the outmost condition is rising_edge(clk). Therefore the internal signals are undefined until the first raising edge of the clock.

Change to an asynchronous reset like this (excerpt):

    if reset = '0' then
        -- reset statements
    elsif rising_edge(clk) then
        -- work statements
    end if;

Please be aware that even with an asynchronous reset the signals will be undefined until reset is activated or the clock raises. This reflects the actual behavior of a real device.

Upvotes: 1

Related Questions