cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
pgigliotti_usac
Explorer
Explorer
465 Views
Registered: ‎10-22-2020

Vivado 2020.1 Simulator incorrect - values not initializing correctly

Jump to solution

I had created an array, and some constants, and then used concurrent assignment statements to set some of the array elements.  When running the simulation, these elements are evaluating to unknow.  So I modified the code as shown below.  Basically I created a clocked process with a synchronous reset and always set the array elements to the desired values, but at reset and on every clock edge.  Furthermore, I put a report statement at the end of the clocked assignments.  I place a breakpoint on the report and run.  I continually stop at the break point, but it always shows the values as unknown.  I am baffled.

pgigliotti_usac_0-1619997693045.png

 

 

type Array_11_slv32 is array (0 to 10) of std_logic_vector(31 downto 0);

 

constant LABEL_230_SLV32 : std_logic_vector(31 downto 0):= x"0CF83898";
constant LABEL_231_SLV32 : std_logic_vector(31 downto 0):= x"8C36B099";
constant LABEL_232_SLV32 : std_logic_vector(31 downto 0):= x"8C38B19A";
constant LABEL_233_SLV32 : std_logic_vector(31 downto 0):= x"8C36B09B";
constant LABEL_234_SLV32 : std_logic_vector(31 downto 0):= x"8C30209C";
constant LABEL_235_SLV32 : std_logic_vector(31 downto 0):= x"8DF8329D";
constant LABEL_236_SLV32 : std_logic_vector(31 downto 0):= x"0E7BED9E";
constant LABEL_237_SLV32 : std_logic_vector(31 downto 0):= x"0C38209F";

 

signal Info_Labels_int : Array_11_slv32;

 

pSInfo_lables : process(clk)
begin
     if(rising_edge(clk)) then
          if(reset = '1') then
                 Info_Labels_int(0) <= LABEL_230_SLV32;
                 Info_Labels_int(1) <= LABEL_231_SLV32;
                 Info_Labels_int(2) <= LABEL_232_SLV32;
                 Info_Labels_int(3) <= LABEL_233_SLV32;
                 Info_Labels_int(4) <= LABEL_234_SLV32;
                 Info_Labels_int(5) <= LABEL_235_SLV32;
                 Info_Labels_int(6) <= LABEL_236_SLV32;
                 Info_Labels_int(7) <= LABEL_237_SLV32;
       else
                 Info_Labels_int(0) <= LABEL_230_SLV32;
                 Info_Labels_int(1) <= LABEL_231_SLV32;
                 Info_Labels_int(2) <= LABEL_232_SLV32;
                 Info_Labels_int(3) <= LABEL_233_SLV32;
                 Info_Labels_int(4) <= LABEL_234_SLV32;
                 Info_Labels_int(5) <= LABEL_235_SLV32;
                 Info_Labels_int(6) <= LABEL_236_SLV32;
                 Info_Labels_int(7) <= LABEL_237_SLV32;
                 report("set labels");
            end if;
     end if;
end process pSInfo_lables;

0 Kudos
1 Solution

Accepted Solutions
pgigliotti_usac
Explorer
Explorer
445 Views
Registered: ‎10-22-2020

OK, So in another process in the code, I had the other vectors in the array being initialized on reset, and modified when appropriate, as follows:

if(rising_edge(clk)) then
       if(reset ='1') then

   Info_Labels_int(8) <= LABEL_240_SLV32;
   Info_Labels_int(9) <= LABEL_241_SLV32;
   Info_Labels_int(10) <= LABEL_242_SLV32;

 

else

if(phase =0) then --send read command
    phase := phase + 1;

elsif(phase =1) then --parse data to array
   phase := phase + 1;

elsif(phase = 2) then --create labels
    phase := phase + 1;
    for i in 0 to 2 loop
       Info_Labels_int(8 + i)(29 downto 23) <= Serial_number(8-(i*3))(6 downto 0);
       Info_Labels_int(8 + i)(22 downto 16) <= Serial_number(7-(i*3))(6 downto 0);
       Info_Labels_int(8 + i)(15 downto 9) <= Serial_number(6-(i*3))(6 downto 0);
   end loop;
else
     phase := 0;
     for i in 8 to 10 loop
             Info_Labels_int(i)(31) <= parity_gen32(Info_Labels_int(i)(30 downto 0));
    end loop;
    FRAM_state <= Idle;

end if;

 

I modified the code as follows, and now it works!

 

if(rising_edge(clk)) then
       if(reset ='1') then

 Info_Labels_int(0) <= LABEL_230_SLV32;
Info_Labels_int(1) <= LABEL_231_SLV32;
Info_Labels_int(2) <= LABEL_232_SLV32;
Info_Labels_int(3) <= LABEL_233_SLV32;
Info_Labels_int(4) <= LABEL_234_SLV32;
Info_Labels_int(5) <= LABEL_235_SLV32;
Info_Labels_int(6) <= LABEL_236_SLV32;
Info_Labels_int(7) <= LABEL_237_SLV32;
Info_Labels_int(8) <= LABEL_240_SLV32;
Info_Labels_int(9) <= LABEL_241_SLV32;
Info_Labels_int(10) <= LABEL_242_SLV32;

 

else

View solution in original post

9 Replies
pgigliotti_usac
Explorer
Explorer
457 Views
Registered: ‎10-22-2020

 

When opening the elaborated design, it looks correct

pgigliotti_usac_0-1619998811461.png

 

0 Kudos
pgigliotti_usac
Explorer
Explorer
446 Views
Registered: ‎10-22-2020

OK, So in another process in the code, I had the other vectors in the array being initialized on reset, and modified when appropriate, as follows:

if(rising_edge(clk)) then
       if(reset ='1') then

   Info_Labels_int(8) <= LABEL_240_SLV32;
   Info_Labels_int(9) <= LABEL_241_SLV32;
   Info_Labels_int(10) <= LABEL_242_SLV32;

 

else

if(phase =0) then --send read command
    phase := phase + 1;

elsif(phase =1) then --parse data to array
   phase := phase + 1;

elsif(phase = 2) then --create labels
    phase := phase + 1;
    for i in 0 to 2 loop
       Info_Labels_int(8 + i)(29 downto 23) <= Serial_number(8-(i*3))(6 downto 0);
       Info_Labels_int(8 + i)(22 downto 16) <= Serial_number(7-(i*3))(6 downto 0);
       Info_Labels_int(8 + i)(15 downto 9) <= Serial_number(6-(i*3))(6 downto 0);
   end loop;
else
     phase := 0;
     for i in 8 to 10 loop
             Info_Labels_int(i)(31) <= parity_gen32(Info_Labels_int(i)(30 downto 0));
    end loop;
    FRAM_state <= Idle;

end if;

 

I modified the code as follows, and now it works!

 

if(rising_edge(clk)) then
       if(reset ='1') then

 Info_Labels_int(0) <= LABEL_230_SLV32;
Info_Labels_int(1) <= LABEL_231_SLV32;
Info_Labels_int(2) <= LABEL_232_SLV32;
Info_Labels_int(3) <= LABEL_233_SLV32;
Info_Labels_int(4) <= LABEL_234_SLV32;
Info_Labels_int(5) <= LABEL_235_SLV32;
Info_Labels_int(6) <= LABEL_236_SLV32;
Info_Labels_int(7) <= LABEL_237_SLV32;
Info_Labels_int(8) <= LABEL_240_SLV32;
Info_Labels_int(9) <= LABEL_241_SLV32;
Info_Labels_int(10) <= LABEL_242_SLV32;

 

else

View solution in original post

pgigliotti_usac
Explorer
Explorer
367 Views
Registered: ‎10-22-2020

I believe this is a bug with the simulator. As mentioned, in the original design, several elements in the array were assigned with concurrent statements.  Other elements in the array where being assigned in a clocked process.  When viewing the elaborated design, everything looks correct.  The simulation is incorrect, in that the array elements that are being concurrently assigned do not get assigned.  There is no overlap between the elements.  Elements 0 through 7 are static, and items 8 through 10 are clocked.  The only linkage between these vectors is that they are grouped as an array.  I do not believe this violates VHDL standard.  Again, it implements and correctly and works in hardware!

0 Kudos
maps-mpls
Mentor
Mentor
362 Views
Registered: ‎06-20-2017

Initializing and reseting are two different things, but your problem, and your solution, seem to conflate the two concepts.

*** Destination: Rapid design and development cycles *** Unappreciated answers get deleted, unappreciative OPs get put on ignored list ***
0 Kudos
richardhead
Scholar
Scholar
345 Views
Registered: ‎08-01-2012

There is nothing that "violates" VHDL standard here. If that was the case, it wouldnt compile or you would get a runtime error. an Unknown value during simulation is likely the result of user error.

It is perfectly fine to assign different elements of an array in multiple processes.

UNLESS

a for loop is involved, whhich you appear to have done. The problem with a loop is the static elaboration cannot work out which elements of an array are driven, and hence it creates a driver for ALL elements of the array. So while having different elements of an array in different processes is noormally fine, it causes multiple drivers if you use a loop. Because std_logic(_vector) is a resolved type, you get 'X' in simulation.

You never actually posted the actual code, only out of context snippets, so we cannot confirm if this was actuallu your problem.

pgigliotti_usac
Explorer
Explorer
331 Views
Registered: ‎10-22-2020

Here is the original code that exhibited the problem. I am surprised that the loop would be the issue as it only touches array elements 8, 9 and 10, whereas elements 0-7 are set concurrently

In packages

type Array_11_slv32 is array (0 to 10) of std_logic_vector(31 downto 0);

constant LABEL_230_SLV32 : std_logic_vector(31 downto 0):= x"0CF83898";
constant LABEL_231_SLV32 : std_logic_vector(31 downto 0):= x"8C36B099";
constant LABEL_232_SLV32 : std_logic_vector(31 downto 0):= x"8C38B19A";
constant LABEL_233_SLV32 : std_logic_vector(31 downto 0):= x"8C36B09B";
constant LABEL_234_SLV32 : std_logic_vector(31 downto 0):= x"8C30209C";
constant LABEL_235_SLV32 : std_logic_vector(31 downto 0):= x"8DF8329D";
constant LABEL_236_SLV32 : std_logic_vector(31 downto 0):= x"0E7BED9E";
constant LABEL_237_SLV32 : std_logic_vector(31 downto 0):= x"0C38209F";
constant LABEL_240_SLV32 : std_logic_vector(31 downto 0):= x"000000A0"; --serial number 0
constant LABEL_241_SLV32 : std_logic_vector(31 downto 0):= x"800000A1"; --serial number 1
constant LABEL_242_SLV32 : std_logic_vector(31 downto 0):= x"000000A2"; --serial number 2

Signals

signal Info_Labels_int : Array_11_slv32;

 

Concurrent statements

Info_Labels_int(0) <= LABEL_230_SLV32;
Info_Labels_int(1) <= LABEL_231_SLV32;
Info_Labels_int(2) <= LABEL_232_SLV32;
Info_Labels_int(3) <= LABEL_233_SLV32;
Info_Labels_int(4) <= LABEL_234_SLV32;
Info_Labels_int(5) <= LABEL_235_SLV32;
Info_Labels_int(6) <= LABEL_236_SLV32;
Info_Labels_int(7) <= LABEL_237_SLV32;

 

Sequential statements

process(clk)

begin

if(rising_edge(clk)) then
       if(reset ='1') then

   Info_Labels_int(8) <= LABEL_240_SLV32;
   Info_Labels_int(9) <= LABEL_241_SLV32;
   Info_Labels_int(10) <= LABEL_242_SLV32;

 

else

if(phase =0) then --send read command
    phase := phase + 1;

elsif(phase =1) then --parse data to array
   phase := phase + 1;

elsif(phase = 2) then --create labels
    phase := phase + 1;
    for i in 0 to 2 loop
       Info_Labels_int(8 + i)(29 downto 23) <= Serial_number(8-(i*3))(6 downto 0);
       Info_Labels_int(8 + i)(22 downto 16) <= Serial_number(7-(i*3))(6 downto 0);
       Info_Labels_int(8 + i)(15 downto 9) <= Serial_number(6-(i*3))(6 downto 0);
   end loop;
else
     phase := 0;
     for i in 8 to 10 loop
             Info_Labels_int(i)(31) <= parity_gen32(Info_Labels_int(i)(30 downto 0));
    end loop;
    FRAM_state <= Idle;

end if;

0 Kudos
richardhead
Scholar
Scholar
313 Views
Registered: ‎08-01-2012

"I am surprised that the loop would be the issue as it only touches array elements 8, 9 and 10, whereas elements 0-7 are set concurrently"

You know this, but the compiler doesnt. A for looop is a runtime item and the static analysis does not look at runtime elements. Hence it assumes everything is driven, causing multiple drivers on elements 0-7.

0 Kudos
pgigliotti_usac
Explorer
Explorer
286 Views
Registered: ‎10-22-2020

Ok.  Elaborated design does not show multiple drivers.  Also, comes up as unknown, not X's.  I will have to look closely at the messages, as there were some warnings about statically defined items, that I was aware of that we not an issue. I may have overlooked these. 

Still not sure why it was confused when some of the elements of the array were assigned values in one process, and other elements were assigned values in another process, being that they were different elements.

0 Kudos
richardhead
Scholar
Scholar
268 Views
Registered: ‎08-01-2012

'X' is Unknown. 'U' is uninitialised. In the case of multiple drivers, 'U' will always override everything.