- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear my friends
I checked an adder, multiplier and a divider. All of them used LPM library. This is my code of Adder:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_arith.all;
USE IEEE.std_logic_signed.all;
LIBRARY lpm;
USE lpm.LPM_COMPONENTS.ALL;
ENTITY Add IS
port (CLK,CLK_40n : IN STD_LOGIC;
X1 : IN STD_LOGIC_VECTOR(15 downto 0);
A1 : IN STD_LOGIC_VECTOR(15 downto 0);
Y : OUT STD_LOGIC_VECTOR(15 downto 0)
);
END Add;
ARCHITECTURE Add_arch OF Add IS
SIGNAL adda,addb,addr,addrs :STD_LOGIC_VECTOR(15 downto 0):=(others =>'0');
SIGNAL CNT :STD_LOGIC_VECTOR(7 downto 0):=(others =>'0');
SIGNAL overflow, cout : STD_LOGIC:='0';
BEGIN
adder1: lpm_add_sub
generic map(lpm_width=>16,LPM_REPRESENTATION=>"SIGNED",lpm_pipeline=>1)
port map(dataa=>adda,datab=>addb,clock=> clk,overflow=>overflow,
cout=>cout,result=>addr);
GEN:block
BEGIN
PROCESS(CLK_40n)
BEGIN
IF CLK_40n'EVENT and CLK_40n='1' THEN
CNT<=CNT+1;
IF CNT=X"00" THEN
adda<=A1;
addb<=X1;
ELSIF CNT=X"01" THEN
Y<=addr(15 downto 0);
CNT <=X"00";
END IF;
END IF;
END PROCESS;
END BLOCK GEN;
END Add_arch;
And this is the code of Multiplier:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_arith.all;
USE IEEE.std_logic_signed.all;
LIBRARY lpm;
USE lpm.LPM_COMPONENTS.ALL;
ENTITY Mult IS
port (CLK,CLK_40n : IN STD_LOGIC;
X1 : IN STD_LOGIC_VECTOR(15 downto 0);
A1 : IN STD_LOGIC_VECTOR(15 downto 0);
Y : OUT STD_LOGIC_VECTOR(15 downto 0)
);
END Mult;
ARCHITECTURE Mult_arch OF Mult IS
SIGNAL mula,mulb :STD_LOGIC_VECTOR(15 downto 0):=(others =>'0');
SIGNAL mulr :STD_LOGIC_VECTOR(31 downto 0):=(others =>'0');
SIGNAL CNT :STD_LOGIC_VECTOR(7 downto 0):=(others =>'0');
BEGIN
mull: lpm_mult
generic map(LPM_WIDTHA=>16,LPM_WIDTHB=>16,LPM_WIDTHS=>16,LPM_WIDTHP=>32,
LPM_REPRESENTATION=>"SIGNED",LPM_PIPELINE=>1)
port map(dataa=> mula,datab=>mulb,clock=> clk,result=> mulr);
GEN:block
BEGIN
PROCESS(CLK_40n)
BEGIN
IF CLK_40n'EVENT and CLK_40n='1' THEN
CNT<=CNT+1;
IF CNT=X"00" THEN
mula<=A1;
mulb<=X1;
ELSIF CNT=X"01" THEN
Y<=mulr(15 downto 0);
CNT <=X"00";
END IF;
END IF;
END PROCESS;
END BLOCK GEN;
END Mult_arch;
And this is the code of Divider:
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
LIBRARY lpm;
USE lpm.LPM_COMPONENTS.ALL;
USE IEEE.std_logic_arith.all;
USE IEEE.std_logic_signed.all;
entity divide2 is
port(clk,clk_80n : in STD_LOGIC;
X1 : in STD_LOGIC_VECTOR(15 downto 0);
A1 : in STD_LOGIC_VECTOR(15 downto 0);
Y : Out STD_LOGIC_VECTOR(15 downto 0)
);
end divide2 ;
architecture divide2_ARCH of divide2 is
signal A,sat : STD_LOGIC_VECTOR(15 downto 0);
signal B : STD_LOGIC_VECTOR(15 downto 0);
signal cnt : STD_LOGIC_VECTOR(15 downto 0);
begin
m1: lpm_divide
GENERIC
MAP (LPM_WIDTHN=>16, LPM_WIDTHD=>16, LPM_PIPELINE=>1,
LPM_NREPRESENTATION=>"SIGNED", LPM_DREPRESENTATION=>"SIGNED")
port map (numer=>A,denom=>B,clock =>clk,quotient=>sat);
-----------------------------------------------------------------------------------
RC_TIME:block
begin
process(clk,clk_80n)
begin
if clk_80n'event and clk_80n='1' then
cnt <= cnt + 1;
if cnt= X"0000" then
A <= A1;
B <= X1;
elsif cnt= X"0001" then
Y <= sat;
cnt <= x"0000";
end if;
end if;
end process;
end block RC_TIME;
end divide2_ARCH;
The resource consumption: Adder is 77 logic elements. Multiplier is 61 logic elements. Divider is 410 logic elements. I don't know why the adder has the number of LEs more larger than Multiplier. Is it this code wrong? Thanks in advance
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The multiplier is probably using hardware DSP slices.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I also notice you're using a different clock for the LPM modules and your external input selector. Why? Are these two clocks related?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- I also notice you're using a different clock for the LPM modules and your external input selector. Why? Are these two clocks related? --- Quote End --- Thank you very much for your quickly answer. I used two clock because in my code, i programmed it with FSM (Finite State Machine). For example: With Adder: First clock (clk_40n): I send value of X1 and A1 to input of lpm_add_sub (adda and addb). Second clock (clk_40n): I get the result from lpm_add_sub. The time between first clock and second clock, lpm_add_sub will do his job (It must finish before second clock of clk_40n transfer from low to high. with clk = 20ns and clk_40 = 40 ns.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[advice
You should avoid [s]USE IEEE.std_logic_arith.all; USE IEEE.std_logic_signed.all;[/s] instead, use ieee.numeric_std.all [/advice]- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- [advice You should avoid [s]USE IEEE.std_logic_arith.all; USE IEEE.std_logic_signed.all;[/s] instead, use ieee.numeric_std.all [/advice] --- Quote End --- Dear mmTsuchi When I used "USE ieee.numeric_std.all" to replace for "USE IEEE.std_logic_arith.all" and "USE IEEE.std_logic_signed.all". It shown an error with this code
CNT<=CNT+1;
Error (10327): VHDL error at Add.vhd(48): can't determine definition of operator ""+"" -- found 0 possible definitions They don't understand with operator "+"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thats because you need to declare cnt as unsinged, not std_logic_vector.
With your clocks - how do you create the 40ns clock? Is it related to the 20ns clock? If they are unrelated (ie. you did NOT use a PLL) you will have problems with your design.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Thats because you need to declare cnt as unsinged, not std_logic_vector. With your clocks - how do you create the 40ns clock? Is it related to the 20ns clock? If they are unrelated (ie. you did NOT use a PLL) you will have problems with your design. --- Quote End --- With my original program ("USE IEEE.std_logic_arith.all" and "USE IEEE.std_logic_signed.all"), It ran ok. I already tested with a lots of cases. I just don't understand why the LEs of Adder larger than the LEs of Multiplier. Sorry, Can you explain clearly for me. Thx Best regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Most FPGAs have Built in multipliers that dont use any LEs, they use the dedicated multiplier circuit.
You didnt answer the question about your clocks.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Most FPGAs have Built in multipliers that dont use any LEs, they use the dedicated multiplier circuit. You didnt answer the question about your clocks. --- Quote End --- Sorry. I forgot. Now I just simulation by Vector wave form of Quartus. The wave form, I captured and attached in this message. If FPGAs don't use any LEs for multiplier, why in my adder and multiplier have the same data bit, same input/output, it was just different with LPM library. Why the LEs of them was difference?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Look in the RTL viewer (or Technology map viewer) in Quartus, you will see implantation of your design.
Quartus synthetize your "adder" with Logic Elements. So many Logic Elements will be used. Quartus synthetize your "mult" with inside DSP and a (very) few Logic Elements. You should see that in ressources report. For information for newbies, DSP is Digital Signal Processing that is especially optimized to multiply and add. About your "divider": Dividing is complex to synthetize, except those /2, /4, /8, /16 ... Be aware of timing requirements, you may need to use "pipeline" generic- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Look in the RTL viewer (or Technology map viewer) in Quartus, you will see implantation of your design. Quartus synthetize your "adder" with Logic Elements. So many Logic Elements will be used. Quartus synthetize your "mult" with inside DSP and a (very) few Logic Elements. You should see that in ressources report. For information for newbies, DSP is Digital Signal Processing that is especially optimized to multiply and add. About your "divider": Dividing is complex to synthetize, except those /2, /4, /8, /16 ... Be aware of timing requirements, you may need to use "pipeline" generic --- Quote End --- Dear mmTsuchi I already saw the LTI viewer of my disign. But in this viewer has some symbol I don't understand. Can you explain some information for me. Or do you have any documents discuss about that information, can you share for me. I attached LTI viewer of adder in this message. Thanks in advance Best regards
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The adder is the square block in the middle. The surrounding logic comes from your input selections to the adder from your origional code. It shows comparitors, muxes and registers.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I already checked the LTI viewer.
With Adder and Multiplier, It just has only one difference in LPM_ADD_SUB:adder1 (for Adder function) and LPM_MULT:mull (for Multiplier function). The other block don't have any difference. (attached pictures) In my opinion, => the difference between adder and multiplier (using LPM library) just inside of LPM function. The multiplier function is more complex than adder function, but I don't know why the LEs of adder are larger than multiplier.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Like we said - the FPGA has built in multiplier that the adder cannot use. The built in multiplier uses zero LEs.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Like we said - the FPGA has built in multiplier that the adder cannot use. The built in multiplier uses zero LEs. --- Quote End --- I known that. But why the other block of Adder and Multiplier has no difference but the total LEs is difference? It's too difficult to explain. Or you mean, The multiplier used zero LEs, Adder used LEs. So the total LEs has difference?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes.
Your external logic probably uses the 40 or so LEs thats reported, and its the same logic for each of your blocks (with the same clocking problems I tried to highlight to you). If you go to the fitter report, you can see the LE usage by entity.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- Quote Start --- Yes. If you go to the fitter report, you can see the LE usage by entity. --- Quote End --- Thank you very much. What you mean? Where I can find fitter report? I use Quartus 9.1, but I can't find fitter report function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you need to do a full compilation.
In the compilation report, fitter is one of the options. Under that, there is a sub report - resource usage by entity.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page