- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I was told the multiplier "*" in the code blow will dramatically slow down the operating speed(Fmax) of FPGA. But i don't konw why. Could somebody give me some hints on it? Any idea to optimize it?
-- Color bar(V) (White,Yellow,Cyan,Green,Magenta,Red,Blue,Black)p_main: process(Clk)
begin
if rising_edge(Clk) then
HelperColorBars <= "000"; -- black
if unsigned(Setting_Pixel) < shift_right(unsigned(Setting_TotPixel),3) then
HelperColorBars <= "111"; -- white
elsif unsigned(Setting_Pixel) < shift_right(unsigned(Setting_TotPixel),2) then
HelperColorBars <= "011"; -- yellow
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*3) then
HelperColorBars <= "110"; --Cyan
elsif unsigned(Setting_Pixel) < shift_right(unsigned(Setting_TotPixel),1) then
HelperColorBars <= "010"; --Green
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*5) then
HelperColorBars <= "101"; --Magenta
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*6) then
HelperColorBars <= "001"; --red
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*7) then
HelperColorBars <= "100"; --blue
end if;
end process;
See below for the complete code. library ieee;use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use ieee.math_real.log2;
use ieee.math_real.ceil;
entity IPG1_FIP_worker_testpattern is
generic(
Intended_device_family : string := "Default";
Intended_compiler : string := "Default";
BurstLength : integer := 64;
IPG1_Max_combine_nr : integer := 8
);
port (
-- General
Clk : in std_logic;
Reset : in std_logic;
-- Instruction interface
Setting_TotPixel : in std_logic_vector(15 downto 0) := (others => '0'); -- T -1
Setting_TotLine : in std_logic_vector(15 downto 0) := (others => '0'); -- T -1
Setting_Pixel : in std_logic_vector(15 downto 0) := (others => '0'); -- T -1
Setting_Line : in std_logic_vector(15 downto 0) := (others => '0'); -- T -1
Setting_Field : in std_logic_vector( 3 downto 0) := (others => '0'); -- T -1
Setting_R : in std_logic_vector(11 downto 0) := (others => '0'); -- T -1
Setting_G : in std_logic_vector(11 downto 0) := (others => '0'); -- T -1
Setting_B : in std_logic_vector(11 downto 0) := (others => '0'); -- T -1
Setting_Pattern : in std_logic_vector( 3 downto 0) := (others => '0'); -- T -1
Setting_Disables : in std_logic_vector( 2 downto 0) := (others => '0'); -- T 0
-- Input
In_Start : in std_logic := '0'; -- T 0
In_DE : in std_logic := '0'; -- T 0
In_Data : in std_logic_vector(35 downto 0) := (others => '0'); -- T 0
-- Output
Out_Start : out std_logic := '0'; -- T 1
Out_DE : out std_logic := '0'; -- T 1
Out_Data : out std_logic_vector(35 downto 0) := (others => '0') -- T 1
);
end IPG1_FIP_worker_testpattern;
architecture RTL of IPG1_FIP_worker_testpattern is
-- Defined test patterns
constant c_NoPattern : integer := 0;
constant c_Geometry : integer := 1;
constant c_Colorbars : integer := 2;
constant c_Graybars : integer := 3;
constant c_GrayRamp : integer := 4;
constant c_Purity : integer := 5;
-- Define helpers
constant c_Outline : integer := 0; -- Is pixel on outline
constant c_Centerline : integer := 1; -- Is pixel on centerline
constant c_Hatch32 : integer := 2; -- Is pixel on 32 hatch
constant c_Hatch32Moving : integer := 3; -- Is pixel on moving 32 hatch
constant c_NrOfHelpers : integer := 4; -- Total amount of helpers
-- Helpers
signal Helper : std_logic_vector(c_NrOfHelpers-1 downto 0) := (others => '0');
signal HelperColorBars : unsigned(2 downto 0) := (others => '0');
-- Software defined color
signal Color : std_logic_vector(35 downto 0) := (others => '0');
-- Half intensity content
signal Data2 : std_logic_vector(35 downto 0) := (others => '0');
-- Half intensity Software defined color
signal Color2 : std_logic_vector(35 downto 0) := (others => '0');
-- Gray color value 64 (on 256 scale)
signal Gray64 : std_logic_vector(35 downto 0) := (10 => '1', 22 => '1', 34 => '1', others => '0');
begin
-- Color delivered by settings
Color <= Setting_B & Setting_G & Setting_R;
-- Half intensity
Data2 <= '0' & In_Data(35 downto 25) & '0' & In_Data(23 downto 13) & '0' & In_Data(11 downto 1);
Color2 <= '0' & Setting_B(11 downto 1) & '0' & Setting_G(11 downto 1) & '0' & Setting_R(11 downto 1);
p_main: process(Clk)
begin
if rising_edge(Clk) then
-- Time -1 ----------------------------------------------------------------------------------------------------------
-- Helpers default
Helper <= (others => '0');
-- Outline
if Setting_Pixel = 0 or Setting_Pixel = Setting_TotPixel or Setting_Line = 0 or Setting_Line = Setting_TotLine then
Helper(c_Outline) <= '1';
end if;
-- Center line
if unsigned(Setting_Pixel) = shift_right(unsigned(Setting_TotPixel),1) or unsigned(Setting_Line) = shift_right(unsigned(Setting_TotLine),1) then
Helper(c_Centerline) <= '1';
end if;
-- Hatch 32x32
if Setting_Pixel(4 downto 0) = "00000" or Setting_Line(4 downto 0) = "00000" then
Helper(c_Hatch32) <= '1';
end if;
-- Hatch 32x32 Moving
if Setting_Pixel(4 downto 0) = Setting_Field & '0' or Setting_Line(4 downto 0) = Setting_Field & '0' then
Helper(c_Hatch32Moving) <= '1';
end if;
-- Color bar(V) (White,Yellow,Cyan,Green,Magenta,Red,Blue,Black)
HelperColorBars <= "000"; -- black
if unsigned(Setting_Pixel) < shift_right(unsigned(Setting_TotPixel),3) then
HelperColorBars <= "111"; -- white
elsif unsigned(Setting_Pixel) < shift_right(unsigned(Setting_TotPixel),2) then
HelperColorBars <= "011"; -- yellow
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*3) then
HelperColorBars <= "110"; --Cyan
elsif unsigned(Setting_Pixel) < shift_right(unsigned(Setting_TotPixel),1) then
HelperColorBars <= "010"; --Green
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*5) then
HelperColorBars <= "101"; --Magenta
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*6) then
HelperColorBars <= "001"; --red
elsif unsigned(Setting_Pixel) < ((shift_right(unsigned(Setting_TotPixel),3))*7) then
HelperColorBars <= "100"; --blue
end if;
-- Time 0 ----------------------------------------------------------------------------------------------------------
-- default value
Out_Data <= In_Data;
case to_integer(unsigned(Setting_Pattern)) is
when c_Geometry =>
Out_Data <= Gray64;
if Helper(c_Hatch32) = '1' then
Out_Data <= Color2;
end if;
if Helper(c_Outline) = '1' or Helper(c_Centerline) = '1' then
Out_Data <= Color;
end if;
when c_Purity =>
Out_Data <= Color;
when c_Colorbars =>
Out_Data <= (others => '0');
for i in 0 to 2 loop
if HelperColorBars(i) = '1' then
Out_Data(11+i*12 downto i*12) <= (others => '1');
end if;
end loop;
-- when =>
when c_NoPattern =>
when others =>
Out_Data <= In_Data;
end case;
-- Disable a color
for i in 0 to 2 loop
if Setting_Disables(i) = '1' then
Out_Data(11+i*12 downto i*12) <= (others => '0');
end if;
end loop;
-- Delay the control signals
Out_Start <= In_Start;
Out_DE <= In_DE;
-- Reset ------------------------------------------------------------------------------------------------------------
if Reset = '1' then
-- Only reset control stuff that is realy needed not the data path!
end if;
end if;
end process;
end RTL;
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
My understanding is that the compiler inserts a multiplier for each inference occurrence in a construct.
you can keep the construct but remove mult inference, use one mult and use the constrcut as switch for multiplier input- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Because you're expecting a non trivial multiply (ie non power of 2 which is simply a bit shift) and a compare to be done in a single clock cycle. Longer logic chains = slower clock speed. This is on top of the priority encode you build with all of those elseifs.
You'd be much better off trying to pipeline it all somehow (not much I can say, as you are using inputs directly). On a side note - why are all your setting_* signals std_logic_vectors? why not just make them unsigned in the port map, and you'll save yourself a load of RSI.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
alternatively, to multiply x by 2,3,4,5,6,7
use adders or shift 2*x (shift as you done it); 3*x (add above to x) 4*x (shift) 5*x(add 2*x to 3*x) 6*x(add 3*x,3*x) 7*x (add x to 6*x)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That is just an open coded multiply, to multiply x by y (y 0..7):
(y & 1 ? x : 0) + (y & 2 ? 2 * x : 0) + (y & 4 ? 4 * x : 0)- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Because you're expecting a non trivial multiply (ie non power of 2 which is simply a bit shift) and a compare to be done in a single clock cycle. Longer logic chains = slower clock speed. This is on top of the priority encode you build with all of those elseifs. You'd be much better off trying to pipeline it all somehow (not much I can say, as you are using inputs directly). On a side note - why are all your setting_* signals std_logic_vectors? why not just make them unsigned in the port map, and you'll save yourself a load of RSI. --- Quote End --- What is RSI? Could explain more on the diffence of using "std_logic_vector" and "unsinged"?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Rsi = repetative strain injury
The std_ logic_vector type is meant to represent a collection of bits, while the unsigned type represents an unsigned integer. The numeric_std library defines functions for arithmatic with unsigned and signed types. There are no standard libraries for arithmatic with std_logic_vector, because it is not meant to represent anything.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you!
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page