cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
jmcano
Visitor
Visitor
4,205 Views
Registered: ‎06-05-2013

Post-synthesis timing simulation - what's happening?

Jump to solution

Hi, 

 

I have been struggling for some time with this. I have finally reach a fix, but I would like an expert to tell me the difference between the wrong and the correct solution. I am using Vivado 2013.1 as a tool with a Kintex evaluation board (system clock is 200MHz)

 

This is a piece of code to allow a button to start and stop a device correcting debouncing (I just write the process - port and signals are declared correctly - I hope - and are not the core of my question): 

 

process (CLK)
begin
   if (rising_edge(CLK)) then
      if SW_S='1' and q_tff='0' and enable='1' then      --- SW_S is the button signal and q_tff is the past state of SW_S
         enable <= '0';
         START <= not START;                                           --- Starts or stops the device alternatively if the button is pressed
      elsif enable='0' then
         cuenta <= cuenta+1;
         if cuenta = to_unsigned(2000000,21) then       --- debouncing inhibition until 10ms after the last press of the button 
         cuenta <= to_unsigned(0,21);
         enable <= '1';
         end if;
      else
         START <= START;
         enable <= enable;
      end if;
      q_tff <= SW_S;
end if;
end process;

 

Now, the problem is that all work fine during RTL analysis and synthesis. Both 'Behavioural simulation' and "Post-synthesis funcional simulation" lead to the desired design....BUT, when running the "Post-synthesis timing simulation", START do not activate after activating the switch (SW_S). ¿?

 

I solved it (after testing millions of possibilities), by removing the line in red, and putting it inside of the IF. This is how it looks now: 

 

process (CLK)
begin
   if (rising_edge(CLK)) then
      if SW_S='1' and q_tff='0' and enable='1' then
         enable <= '0';
         START <= not START;

         q_tff <= SW_S;
      elsif enable='0' then
         cuenta <= cuenta+1;
         if cuenta = to_unsigned(2000000,21) then 
         cuenta <= to_unsigned(0,21);
         enable <= '1';
         end if;

         q_tff <= SW_S;
      else 
         START <= START; 
         enable <= enable;

         q_tff <= SW_S;
      end if;
end if;
end process;

 

This works with the three types of simulations in Vivado. My problem is that I do not see any difference between these to versions. Could somebody help me?

 

Thanks in advance. 

 

Jose M. Cano

 

0 Kudos
1 Solution

Accepted Solutions
bassman59
Historian
Historian
5,295 Views
Registered: ‎02-25-2008

@jmcano wrote:

Hi, 

 

I have been struggling for some time with this. I have finally reach a fix, but I would like an expert to tell me the difference between the wrong and the correct solution. I am using Vivado 2013.1 as a tool with a Kintex evaluation board (system clock is 200MHz)

 

This is a piece of code to allow a button to start and stop a device correcting debouncing (I just write the process - port and signals are declared correctly - I hope - and are not the core of my question): 

 

process (CLK)
begin
   if (rising_edge(CLK)) then
      if SW_S='1' and q_tff='0' and enable='1' then
         enable <= '0';
         START <= not START;  
      elsif enable='0' then
         cuenta <= cuenta+1;
         if cuenta = to_unsigned(2000000,21) then  
             cuenta <= to_unsigned(0,21);
             enable <= '1';
         end if;
      else
         START <= START;
         enable <= enable;
      end if;
      q_tff <= SW_S;
end if;
end process;

 

I solved it (after testing millions of possibilities), by removing the line in red, and putting it inside of the IF. This is how it looks now: 

 

process (CLK)
begin
   if (rising_edge(CLK)) then
      if SW_S='1' and q_tff='0' and enable='1' then
         enable <= '0';
         START <= not START;

         q_tff <= SW_S;
      elsif enable='0' then
         cuenta <= cuenta+1;
         if cuenta = to_unsigned(2000000,21) then 
         cuenta <= to_unsigned(0,21);
         enable <= '1';
         end if;

         q_tff <= SW_S;
      else 
         START <= START; 
         enable <= enable;

         q_tff <= SW_S;
      end if;
end if;
end process;

 

 


That looks like a bug. The assignment to your delay flop q_tff should occur on every rising edge of the clock, and as such putting it outside of the big if statement (and as you do, inside of the clock edge if statement) is correct.

 

(also, the final else clause, where you just assign START to itself and enable to itself, is entirely redundant.)

----------------------------Yes, I do this for a living.

View solution in original post

4 Replies
austin
Scholar
Scholar
4,202 Views
Registered: ‎02-27-2008

Jose,

 

Think hardware:  wires, gates, DFF.

 

Look at the resulting edif or xdf (what actually went into the FPGA as a result of synthesis).

 

I agree it is a subtle difference, but as you have discovered, it makes a big difference.


Remember that in RTL, EVERYTHING is "executed" all at the same time (the order of the statements is irrelevant).

 

But, the position of the statment in the block, does imply where the hardware goes.

 

 

Austin Lesea
Principal Engineer
Xilinx San Jose
0 Kudos
bassman59
Historian
Historian
5,296 Views
Registered: ‎02-25-2008

@jmcano wrote:

Hi, 

 

I have been struggling for some time with this. I have finally reach a fix, but I would like an expert to tell me the difference between the wrong and the correct solution. I am using Vivado 2013.1 as a tool with a Kintex evaluation board (system clock is 200MHz)

 

This is a piece of code to allow a button to start and stop a device correcting debouncing (I just write the process - port and signals are declared correctly - I hope - and are not the core of my question): 

 

process (CLK)
begin
   if (rising_edge(CLK)) then
      if SW_S='1' and q_tff='0' and enable='1' then
         enable <= '0';
         START <= not START;  
      elsif enable='0' then
         cuenta <= cuenta+1;
         if cuenta = to_unsigned(2000000,21) then  
             cuenta <= to_unsigned(0,21);
             enable <= '1';
         end if;
      else
         START <= START;
         enable <= enable;
      end if;
      q_tff <= SW_S;
end if;
end process;

 

I solved it (after testing millions of possibilities), by removing the line in red, and putting it inside of the IF. This is how it looks now: 

 

process (CLK)
begin
   if (rising_edge(CLK)) then
      if SW_S='1' and q_tff='0' and enable='1' then
         enable <= '0';
         START <= not START;

         q_tff <= SW_S;
      elsif enable='0' then
         cuenta <= cuenta+1;
         if cuenta = to_unsigned(2000000,21) then 
         cuenta <= to_unsigned(0,21);
         enable <= '1';
         end if;

         q_tff <= SW_S;
      else 
         START <= START; 
         enable <= enable;

         q_tff <= SW_S;
      end if;
end if;
end process;

 

 


That looks like a bug. The assignment to your delay flop q_tff should occur on every rising edge of the clock, and as such putting it outside of the big if statement (and as you do, inside of the clock edge if statement) is correct.

 

(also, the final else clause, where you just assign START to itself and enable to itself, is entirely redundant.)

----------------------------Yes, I do this for a living.

View solution in original post

jmcano
Visitor
Visitor
4,176 Views
Registered: ‎06-05-2013

Hi Bassman59, 

 

Yes, I think that there is same kind of bug there. I just wanted to test with an expert that my believe is correct: both codes should lead to the same circuit. 

 

Thank you for your kind attention. 

 

Jose M. Cano

0 Kudos
austin
Scholar
Scholar
4,165 Views
Registered: ‎02-27-2008

j,

 

I don't think it is  bug....

 

Did you compare the .xdf, or the .edif?

 

Until you do that, you are guessing.

 

Austin Lesea
Principal Engineer
Xilinx San Jose
0 Kudos