Forum Discussion
Fmax Improvment
I'm trying to improve Fmax in our design. See the archived quartus II proejct file in the attachment. The source files are also attached.
In my currrent design, after compilation, Fmax can reach only 141Mhz. But my target is to reach 300mhz. Do you know how to optimize it to achieve 300mhz? The device I'm using is Arria V 5AGXBA3D4F31C4.22 Replies
- Altera_Forum
Honored Contributor
Thank you. flz47655.
One more question: What's the difference of Fmax and Restricted Fmax? I used timequest to report the Fmax. And find there is a big differnece between Fmax and Restricted Fmax. See attached picture. https://www.alteraforum.com/forum/attachment.php?attachmentid=10599 - Altera_Forum
Honored Contributor
Physical pins have limits, you should go with differential signals for higher frequencies
- Altera_Forum
Honored Contributor
--- Quote Start --- What this code shows is how verbose it can become when you start using innapropriate types. Why is setting_pixel not an unsigned already? instead of shift_right function, why not do /2^n? so a 1 bit shift is /2, 2 = /2 etc. so instead of the massive long lines you already have, you could just use:
--- Quote End --- That's a good idea. Do you think "/" operation will lead to lower Fmax than "shift_right"?elsif Setting_Pixel < ( Setting_TotPixel/2 + Setting_TotPixel/8 ) then - Altera_Forum
Honored Contributor
--- Quote Start --- Thank you. flz47655. One more question: What's the difference of Fmax and Restricted Fmax? I used timequest to report the Fmax. And find there is a big differnece between Fmax and Restricted Fmax. See attached picture. https://www.alteraforum.com/forum/attachment.php?attachmentid=10599 --- Quote End --- FMax is a theoretical max frequency if there are no restrictions Restricted FMax is when there are restrictions ( timing specs provided by engineer, limitations of the part you are using etc). --- Quote Start --- That's a good idea. Do you think "/" operation will lead to lower Fmax than "shift_right"? --- Quote End --- There is no different between shift_right and /2^n. They are the same operation. But using the / operator can make the code more readible. Be aware that dividing by some other value (that is not 2^n) will instantiate a divider, and that will have a terrrible fmax). - Altera_Forum
Honored Contributor
Thank you. Tricky and flz476555. I already change my code with "unsigned" to make it more readable as below.
In my code, there is a long "if" + "elsif" chain which has lower Fmax very much. Do you have any idea to optimize the code if adding pipeline is not an option?signal Setting_TotPixel : unsigned(15 downto 0) := (others=>'0'); signal Setting_Pixel : unsigned(15 downto 0) := (others=>'0'); -- Gray bar(16 gray bars) HelperGrayBar <= "1111"; -- gray level 15 if Setting_Pixel < (Setting_TotPixel/16) then HelperGrayBar <= "0000"; -- black elsif Setting_Pixel < (Setting_TotPixel/8) then HelperGrayBar <= "0001"; -- gray level 1 elsif Setting_Pixel < ((Setting_TotPixel/8) + (Setting_TotPixel/16)) then HelperGrayBar <= "0010"; -- gray level 2 elsif Setting_Pixel < (Setting_TotPixel/4) then HelperGrayBar <= "0011"; -- gray level 3 elsif Setting_Pixel < ((Setting_TotPixel/4)) + ((Setting_TotPixel/16)) then HelperGrayBar <= "0100"; -- gray level 4 elsif Setting_Pixel < ((Setting_TotPixel/4)) + ((Setting_TotPixel/8)) then HelperGrayBar <= "0101"; -- gray level 5 elsif Setting_Pixel < ((Setting_TotPixel/2) - (Setting_TotPixel/16)) then HelperGrayBar <= "0110"; -- gray level 6 elsif Setting_Pixel < (Setting_TotPixel/2) then HelperGrayBar <= "0111"; -- gray level 7 elsif Setting_Pixel < ((Setting_TotPixel/2) + (Setting_TotPixel/16)) then HelperGrayBar <= "1000"; -- gray level 8 elsif Setting_Pixel < ((Setting_TotPixel/2) + (Setting_TotPixel/8)) then HelperGrayBar <= "1001"; -- gray level 9 elsif Setting_Pixel < ((Setting_TotPixel/2) + (Setting_TotPixel/8) + (Setting_TotPixel/16)) then HelperGrayBar <= "1010"; -- gray level 10 elsif Setting_Pixel < ((Setting_TotPixel/2) + (Setting_TotPixel/4)) then HelperGrayBar <= "1011"; -- gray level 11 elsif Setting_Pixel < ((Setting_TotPixel/2) + (Setting_TotPixel/4) + (Setting_TotPixel/16)) then HelperGrayBar <= "1100"; -- gray level 12 elsif Setting_Pixel < ((Setting_TotPixel/2) + (Setting_TotPixel/4) + (Setting_TotPixel/8)) then HelperGrayBar <= "1101"; -- gray level 13 elsif Setting_Pixel < (Setting_TotPixel - (Setting_TotPixel/16)) then HelperGrayBar <= "1110"; -- gray level 14 end if; - Altera_Forum
Honored Contributor
You could probably setup all of the compare values on the previous clock cycle, and then setup some signal so that a case statement is viable instead of the if/elseif chain. if/elsif will create a priority mux if the cases are not mutually exclusive, which is slower than a normal mux (that you get from a case statement).
- Altera_Forum
Honored Contributor
Hello Tricky, don't understand very well on your idea. Could you be more specific?
If setup all of the compare values on the previous cycle, is it just moving the long chain "if-elsif" to the previous cycle? - Altera_Forum
Honored Contributor
Hello Tricky, thanks a lot for your idea. I think I already got your point and already implemented it into my code as below. It did improve Fmax a lot(60mhz).
HelperGrayBar <= (others=>'0'); if Setting_Pixel_un < (Setting_TotPixel_un/16) then HelperGrayBar(0) <= '1'; end if; if Setting_Pixel_un < (Setting_TotPixel_un/8) then HelperGrayBar(1) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/8) + (Setting_TotPixel_un/16)) then HelperGrayBar(2) <= '1'; end if; if Setting_Pixel_un < (Setting_TotPixel_un/4) then HelperGrayBar(3) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/4)) + ((Setting_TotPixel_un/16)) then HelperGrayBar(4) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/4)) + ((Setting_TotPixel_un/8)) then HelperGrayBar(5) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/2) - (Setting_TotPixel_un/16)) then HelperGrayBar(6) <= '1'; end if; if Setting_Pixel_un < (Setting_TotPixel_un/2) then HelperGrayBar(7) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/2) + (Setting_TotPixel_un/16)) then HelperGrayBar(8) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/2) + (Setting_TotPixel_un/8)) then HelperGrayBar(9) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/2) + (Setting_TotPixel_un/8) + (Setting_TotPixel_un/16)) then HelperGrayBar(10) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/2) + (Setting_TotPixel_un/4)) then HelperGrayBar(11) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/2) + (Setting_TotPixel_un/4) + (Setting_TotPixel_un/16)) then HelperGrayBar(12) <= '1'; end if; if Setting_Pixel_un < ((Setting_TotPixel_un/2) + (Setting_TotPixel_un/4) + (Setting_TotPixel_un/8)) then HelperGrayBar(13) <= '1'; end if; if Setting_Pixel_un < (Setting_TotPixel_un - (Setting_TotPixel_un/16)) then HelperGrayBar(14) <= '1'; end if; if HelperGrayBar(0) = '1' then --black Out_Data <= GrayColor; end if; if HelperGrayBar(1 downto 0) = "10" then --gray level 1 Out_Data <= GrayColor + x"100100100"; end if; if HelperGrayBar(2 downto 1) = "10" then --gray level 2 Out_Data <= GrayColor + x"200200200"; end if; if HelperGrayBar(3 downto 2) = "10" then --gray level 3 Out_Data <= GrayColor + x"300300300"; end if; if HelperGrayBar(4 downto 3) = "10" then --gray level 4 Out_Data <= GrayColor + x"400400400"; end if; if HelperGrayBar(5 downto 4) = "10" then --gray level 5 Out_Data <= GrayColor + x"500500500"; end if; if HelperGrayBar(6 downto 5) = "10" then --gray level 6 Out_Data <= GrayColor + x"600600600"; end if; if HelperGrayBar(7 downto 6) = "10" then --gray level 7 Out_Data <= GrayColor + x"700700700"; end if; if HelperGrayBar(8 downto 7) = "10" then --gray level 8 Out_Data <= GrayColor + x"800800800"; end if; if HelperGrayBar(9 downto 8) = "10" then --gray level 9 Out_Data <= GrayColor + x"900900900"; end if; if HelperGrayBar(10 downto 9) = "10" then --gray level 10 Out_Data <= GrayColor + x"A00A00A00"; end if; if HelperGrayBar(11 downto 10) = "10" then --gray level 11 Out_Data <= GrayColor + x"B00B00B00"; end if; if HelperGrayBar(12 downto 11) = "10" then --gray level 12 Out_Data <= GrayColor + x"C00C00C00"; end if; if HelperGrayBar(13 downto 12) = "10" then --gray level 13 Out_Data <= GrayColor + x"D00D00D00"; end if; if HelperGrayBar(14 downto 13) = "10" then --gray level 14 Out_Data <= GrayColor + x"E00E00E00"; end if; if HelperGrayBar(14) = '0' then --gray level 15 Out_Data <= GrayColor + x"F00F00F00"; end if; - Altera_Forum
Honored Contributor
This still builds a priority encoder, as in VHDL the last assignment always takes priority.
And if you're only getting an FMax of 60MHz, there are still probably some long logic paths. You should use Timequest to find the worst paths, and then try and reduce the logic. - Altera_Forum
Honored Contributor
--- Quote Start --- This still builds a priority encoder, as in VHDL the last assignment always takes priority. And if you're only getting an FMax of 60MHz, there are still probably some long logic paths. You should use Timequest to find the worst paths, and then try and reduce the logic. --- Quote End --- Hello Tricky, Thanks for your help. Is it possible you can show me some code to explain your idea?