UPGRADE YOUR BROWSER

We have detected your current browser version is not the latest one. Xilinx.com uses the latest web technologies to bring you the best online experience possible. Please upgrade to a Xilinx.com supported browser:Chrome, Firefox, Internet Explorer 11, Safari. Thank you!

cancel
Showing results for 
Search instead for 
Did you mean: 
Adventurer
Adventurer
2,521 Views
Registered: ‎11-18-2013

Vivado Synthesis Issue (2014.2)

Hello,

     I am using Vivado 2014.2 but I think the version shouldn't matter here. 

The problem is as follows:

intRd is a trigger sent by a serial port state machine whenever it is ready to read the next Byte. The values to be sent are 16bits and so the high and low bytes are sent in an alternate manner. A intrd_div_clk is generated in order to mux the high and low bytes. 

proc_intRead_div_counter : process(intRead)
begin
if(rising_edge(intRead)) then
intRead_div_counter <= std_logic_vector(unsigned(intRead_div_counter) + 1);
end if;
if(rising_edge(intRead)) then
if(unsigned(intRead_div_counter) = INTREAD_DIV_VAL - 1) then  --INTREAD_DIV_VAL = 2;
intRead_div_counter <= (others => '0');
intRead_div_clk <= '1';
else
intRead_div_clk <= '0';
end if;
end if;
end process

 

And the following is the mux:

 

proc_data_mux : process(intRead, intRead_div_counter)
begin
if(rising_edge(intRead)) then
if(intRead_div_counter = "00") then
intRdData <= daq_mem_out_data(15 downto 8);
elsif(intRead_div_counter = "01") then
intRdData <= daq_mem_out_data(7 downto 0);
elsif(intRead_div_counter = "10") then
intRdData <= x"AB";
elsif(intRead_div_counter = "11") then
intRdData <= x"CD";
else
intRdData <= x"EF";
end if;
end if;

 

The problem is as follows: intRead_div_counter is reaching the value "10" when it actually shouldn't (the counter should simply be "00", "01" and back to "00". 

This code was verified using ISim in ISE. 

The project however is being run on a K7160T and hence being implemented in Vivado 2014.2. However when actually implemented in hardware, the counter is reaching "10" and x"AB" is being received. 

Please advise on what could be the issue? This is very basic and so I am a bit surprised to see it behave like this. Is this related to false path settings? 

Thank you for helping me out,

Regards,

 

 

0 Kudos
3 Replies
Contributor
Contributor
2,486 Views
Registered: ‎07-04-2016

Re: Vivado Synthesis Issue (2014.2)

@shashankm

can you show a code for serial port state machine? 

and also can you check what happens if you do this?

 

 

proc_intRead_div_counter : process(intRead)
begin
  if(rising_edge(intRead)) then
    if(unsigned(intRead_div_counter) = INTREAD_DIV_VAL - 1) then  --INTREAD_DIV_VAL = 2;
      intRead_div_counter <= (others => '0');
      intRead_div_clk <= '1';
    else
      intRead_div_counter <= std_logic_vector(unsigned(intRead_div_counter) + 1); --added increment here
      intRead_div_clk <= '0';
    end if;
  end if;
end process

And the following is the mux:

proc_data_mux : process(intRead, intRead_div_counter)
begin
if(rising_edge(intRead)) then
  if(intRead_div_counter = "00") then
    intRdData <= daq_mem_out_data(15 downto 8);
  elsif(intRead_div_counter = "01") then
    intRdData <= daq_mem_out_data(7 downto 0);
  elsif(intRead_div_counter = "10") then
    intRdData <= x"AB";
  elsif(intRead_div_counter = "11") then
    intRdData <= x"CD"; 
  else
    intRdData <= x"EF";
  end if;
end if;
0 Kudos
Adventurer
Adventurer
2,456 Views
Registered: ‎11-18-2013

Re: Vivado Synthesis Issue (2014.2)

Hello 

          Thank you for your suggestion. 

I tried your idea but this changes the ordering in the received bytes but the problem persists. 

intRead is derived from a master system clock and I modified the code as follows and the results are more consistent. It hasn't solved the problem completely (still facing the issue of missing data). The uart code being is used from uart2bus which is available on opencores. Send me your email address and I can also mail you the complete project. The change observed because of the following code modification seems to indicate that Vivado interprets things differently. It would be really great if some one could:

1) Highlight the issue with the previous code

2) Can it be avoided by some constraint

3) Why doesn't it show up in simulations?

 

proc_intRead_div_counter : process(clk,intRead)
begin
if(rising_edge(clk)) then
if(intRead = '1') then
if(unsigned(intRead_div_counter) = INTREAD_DIV_VAL - 1) then
intRead_div_counter <= (others => '0');
intRead_div_clk <= '1';
else
intRead_div_clk <= '0';
intRead_div_counter <= std_logic_vector(unsigned(intRead_div_counter) + 1);
intRead_div_counter2 <= not(intRead_div_counter2);
end if;
end if;

 

Thank you once again in helping me out,

 

0 Kudos
Contributor
Contributor
2,440 Views
Registered: ‎07-04-2016

Re: Vivado Synthesis Issue (2014.2)

@shashankm 

glad to help you a little.

 

1) Highlight the issue with the previous code

- i think it should written exclusively what is going to happen exactly. it should either increment or clear. because now, there is a condition when two assignments happen at the same time, check the third answer for details.

 

 

3) Why doesn't it show up in simulations?

 

In simulation, at the clock cycle, when counter is already "1", this happens :

- the increment condition is true and it tries to assign the value "2"

- the clear condition is true and it tries to set this counter to value "0" 

 

 

So this two assignments are taking place at the same "delta cycle" and since it is simulated, the assignment that is physically written last - takes place. 

 

for example, you can change the order of those assignments, like this and you should be able to see "2" in your simulation (p.s. have not simulated, and will be funny if it won't work )) ) : 

 

proc_intRead_div_counter : process(intRead)
begin

  if(rising_edge(intRead)) then
    if(unsigned(intRead_div_counter) = 1) then 
      intRead_div_counter <= (others => '0');
      intRead_div_clk <= '1';
    else
      intRead_div_clk <= '0';
    end if;
  end if;

  
  if(rising_edge(intRead)) then
    intRead_div_counter <= std_logic_vector(unsigned(intRead_div_counter) + 1);
  end if;
  
end process

 

for more details look at the second answer with its example: 

https://stackoverflow.com/questions/19209773/is-the-concurrent-signal-assignment-within-a-process-statement-sequential-or-c

 

 

2) Can it be avoided by some constraint

-don't know anything else.

 

 

thats all with your questions, but now we know that your code simulated that way but the synthesis was different. I don't know why it was different or why it should not be. 

 

it would be cool if you could synthesize(and simulate before) this code also, and then change the order of assignments and synthesize(and simulate before) again.

 

proc_intRead_div_counter : process(intRead)
begin
  if rising_edge(intRead)
  
    --first assignment. in synthesis that was the result, but I don't know why
      intRead_div_counter <= 2; 

    --second assignment. in simulation this must be the result.
      intRead_div_counter <= 0; 
      
  end if;
end process