Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16596 Discussions

timing requirement not met

Altera_Forum
Honored Contributor II
1,733 Views

Hello  

 

I'm kind of new in the world of FPGA and puzzled with a timing warning message sent by quartus.  

 

This fonction extract ratio info of an arbitrary PWM signal every period and send the ratio over a 14 bits bus to another function. 

the code is as follow :  

entity formfactor is Port ( PWM : in STD_LOGIC; rst : in STD_LOGIC; clk : in STD_LOGIC; FF2 : out integer range 0 to 10020 ); end formfactor; architecture behaviour of formfactor is signal buf_ton1, buf_ton2,buf_T1, buf_T2, compteur1, compteur2: integer range 0 to 12000; type etats is (s0,s1,s2,s3); --type of state machine. signal s: etats; signal flag: std_logic_vector (1 downto 0); type atats is (a0,a1,a2,a3); signal a : atats; begin DUREE:process (clk, rst) begin if rst = '0' then compteur1 <= 0; compteur2 <= 0; flag <= "00"; elsif (clk'EVENT and clk ='1') then case s is when s0 => compteur2 <= compteur2 + 1; if (PWM ='1' AND compteur2 > (buf_ton2 + 10) ) then buf_T2 <= compteur2; s <= s1; flag <= "10"; else s <= s0; end if; when s1 => compteur1 <= compteur1 + 1; if(PWM = '0' AND compteur1 > 10 ) then buf_ton1 <= compteur1; compteur2 <= 0; s <= s2 ; else s <= s1; end if; when s2 => compteur1 <= compteur1 + 1; if (PWM ='1' AND compteur1 > (buf_ton1 + 10)) then buf_T1 <= compteur1; s <= s3; flag <= "01"; else s <= s2; end if; when s3 => compteur2 <= compteur2 + 1; if (PWM ='0' AND compteur2 > 10 ) then buf_ton2 <= compteur2; compteur1 <= 0; s <= s0; else s <= s3; end if; end case; end if; end process DUREE; DIVIDE: process (clk) BEGIN if (clk'EVENT and clk ='1') then case a is when a0 => if(flag = "10") then a <= a1; else a <= a0; end if; when a1 => FF2 <= 100000000 /((buf_T1 * 10000) / buf_ton1); a <= a2; when a2 => if(flag = "01") then a <= a3; else a <= a2; end if; when a3 => FF2 <= 100000000 /((buf_T2 * 10000) / buf_ton2); a <= a0; end case; end if; end process DIVIDE; end behaviour; 

 

Clock is 100Mhz 

Timequest gives me a negative slack of -127 in the worst case between bufTx / buf_tonx and FF2  

ex : -127.307 formfactor:inst10|buf_T2[0] formfactor:inst10|FF2[0] inst1|altpll_component|auto_generated|pll1|clk[0] 

The problem is obviously in my process DIVIDE but I can not manage to find it. 

Can someone give me a hint ? It would be much appreciated. 

Thanks
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
546 Views

when a3 => FF2 <= 100000000 /((buf_T2 * 10000) / buf_ton2); a <= a0; 

 

It is ultimately saying that the logic can not run at the speed you would like it to. The line above starting with "FF2" is a bit much to expect to run at 100MHz. You will probably want to pipeline your math to make this a bit easier on the compiler to have your design meet timing. 

 

I might suggest keeping your * and / operations isolated by registers.
0 Kudos
Altera_Forum
Honored Contributor II
546 Views

TO_BE_DONE

0 Kudos
Altera_Forum
Honored Contributor II
546 Views

The division operation is *VERY* slow and complex to implement in actual logic. 

The usual solution is to avoid it. 

A common strategy is to have a table of reciprocals and replace division by multiplication by the reciprocal.
0 Kudos
Altera_Forum
Honored Contributor II
546 Views

at least simplify the massive term 100000000 /((buf_T1 * 10000) / buf_ton1) to:  

 

10000 *buf_ton1 / buf_T1 and remember not to call them twice but once otherwise the tool creates two instants of * & / as it may not be that kind. 

 

Incidentally, your figures helped me find out that: 

10000 = 8192+1024+512+256+16 

hence you can shift add if you wish to trade 1 mult for adders.
0 Kudos
Reply