Fråga om VHDL (Xilinx FPGA)

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Godagens!

Nu när jag är sjuk så tänkte jag friska upp mina VHDL kunskaper.
Så tog och gjorde ett projekt in ISE WebPack och tänkte börja enkelt med en 16 bitars multiplikator för komplexa tal som start på en enkel FFT implementation.

Jag och gjort så blev koden såhär:

Kod: Markera allt

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

-- Complex multiplication: (a + bi) * (c + di) = (ac - bd) + (ad + bc)i
entity cmul_16to32 is
	port (
		ar: in signed (15 downto 0);  -- Real input a of the first term
		bi: in signed (15 downto 0);  -- Imaginary input b of the first term
		cr: in signed (15 downto 0);  -- Real input c of the second term
		di: in signed (15 downto 0);  -- Imaginary input d of the second term
		yr: out signed (31 downto 0); -- Real output
		yi: out signed (31 downto 0)  -- Imaginary output
	);
end cmul_16to32;

architecture Behavioral of cmul_16to32 is
	signal res_ac : signed (31 downto 0);
	signal res_bd : signed (31 downto 0);
	signal res_ad : signed (31 downto 0);
	signal res_bc : signed (31 downto 0);
begin
	res_ac <= ar * cr;
	res_bd <= bi * di;
	res_ad <= ar * di;
	res_bc <= bi * cr;
	
	yr <= res_ac - res_bd;
	yi <= res_ad + res_bc;

end Behavioral;
Men när jag mappar detta till hårdvara (Spartan 3E minsta modellen) får jag errorn: "WARNING:Xst:1336 - (*) More than 100% of Device resources are used"
Den är ganska självsägande så jag använder mer av FPGAn än det finns, så jag kollar i rapporten vad som jag har för lite av för detta.
Då säger den såhär: "Number of bonded IOBs: 128 of 83 - 153% OVERMAPPED", så jag använder för många IOBs.

Första frågan, kan någon förklara lite varför min design drar så många IOBs?
Andra frågan, gör jag något med en vektorbredd på 32 bitar så får jag samma error - så hur mappar vektorbredd till IOBs?

Hjälp en FPGA nybörjare i hårdvaruvärlden! :)
Användarvisningsbild
Andax
Inlägg: 4373
Blev medlem: 4 juli 2005, 23:27:38
Ort: Jönköping

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Andax »

Det beror på vad du menar att du mappar till hårdvaran. Ditt block har 128 I/O. Av någon anledning har du knytet upp dessa mot fysiska IOB (IO block).
Hur ser topp-nivån ut?
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Eller hur, detta är mycket konstigt. Tror jag har någon inställning fel ju mer jag läser på det.
Jag tror det är för att jag inte har definierat vart de ska kopplas in så den bara tar hur mycket den vill (kopplar alla oanvända signaler till något).

Borde fixa så det blir en mer komplett miljö som läser från minne.
Eller finns det något sätt att testa "sythesize" moduler utan att koppla in dom bara för att se hur mycket de drar?
Användarvisningsbild
abcabc
Inlägg: 188
Blev medlem: 13 september 2014, 21:59:16

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av abcabc »

Du har säker provat att skala ner till 8 eller 4 bitar, vad gav det för resultat? Fungerade det? Vissa saker är ju inte syntetiserbara, som oftast exponent (**), men felmeddelandet tyder ju på att kompilatorn försöker syntetisera.

Det verkar lite förvånande att även den minsta FPGA skulle ta slut av detta ganska begränsade uträkning, men det kanske blir så, multiplikation kan nog dra mycket grindar, det blir nog en något mer än kvadratisk utveckling beroende på bitar, om man kollar på hur multiplikation brukar implementeras.

I och att det är specificerat att multiplikationer skall ske parallellt så kommer ju också grindantalet att bli 4 gånger jämfört med bara en multiplikation, du kräver ju 4 grindnät för 16-bitars multiplikation, när man funderar på det så är det nog en hel del grindar. 16*16*4*någon faktor och en del supportgrindar runt det.

Kanske skulle du utföra multiplikationerna i en process istället, för att om möjligt få det sekventiellt? Ibland måste man prova sig fram, jag vet inte riktigt om en process skulle spara grindar, men kanske.

Om det är så att det drar för mycket grindar så är alltid en lösning att tvinga det sekventiellt med en multiplikationsprocess, en klocka och en statemaskin, som en CPU.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Jag har luskat ut vad detta detta är nu! :)
Det va som vi trodde, det är så att den kopplar alla signaler till något bara för att de inte ska optimeras bort vid "kompileringen".

Så bara man har ett block som genererar signaler till mina block jag testar så funkar det som de ska. Dock så är de svårt att veta hur mycket HW en modul drar.
Men den kanske är så smart att den blandar ihop allt för att optimera?
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av stekern »

Som du märkte så kopplar ISE dina portar på din modul till IO, varför ISE gör sådant när man inte explicit ber den om det har irriterat mig ett antal gånger.
Men för att kunna få ett mått på ungefär hur mycket en modul drar måste man ändå koppla det till något verkligt för att få vettiga siffror.
Om du kopplar portarna till signaler som i slutändan inte används kommer funktionalitet att optimiseras bort.
Ofta får man även titta på designen som helhet för att få en uppfattning av vad en modul tar för yta,
verktygen kan ibland optimisera över flera moduler och flytta register/logic mellan dem.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Jag har en ny fråga angående VHDL.
Jag testade att skriva en "complex magnitude"-estimerare och det va inga direkta problem, men vill att den ska vara pipeline-ad.
Så grävde fram mina kursböcker och kollade lite tutorials och såhär blev resultatet:

Kod: Markera allt

library ieee;
use ieee.std_logic_1164.all;        
use ieee.numeric_std.all;

entity magnitude_est is
	generic (N:positive := 16);
	port (
		clk : in std_logic;
		rst : in std_logic;
		A   : in signed (N-1 downto 0);
		B   : in signed (N-1 downto 0);
		mag : out signed (N-1 downto 0)
	);
end magnitude_est;

architecture Behavioral of magnitude_est is
	-- Absulute value signals
	signal after_abs_A : signed (N-1 downto 0);
	signal after_abs_B : signed (N-1 downto 0);

	-- Max/min signals
	signal maxmin_tmp : signed (N-1 downto 0);
	signal after_minmax_max : signed (N-1 downto 0);
	signal after_minmax_min : signed (N-1 downto 0);
	
	-- Scaling signals
	signal after_scale_max : signed (N-1 downto 0);
	signal after_scale_min : signed (N-1 downto 0);
	
	-- Summation signals
	signal after_sum_M : signed (N-1 downto 0);

begin -- Implementation starts here!

	process (clk, rst) begin
		if rising_edge(clk) then
			if rst = '1' then
				-- Reset all signals to zero state
				after_abs_A      <= (others => '0');
				after_abs_B      <= (others => '0');
				maxmin_tmp       <= (others => '0');
				after_minmax_max <= (others => '0');
				after_minmax_min <= (others => '0');
				after_scale_max  <= (others => '0');
				after_scale_min  <= (others => '0');
				after_sum_M      <= (others => '0');
			else
				-- ------------------------
				-- Stage 1
				-- ---
				-- Absulute value part
				-- ------------------------
				after_abs_A <= abs(A);
				after_abs_B <= abs(B);
				
				-- ------------------------
				-- Stage 2
				-- ---
				-- Max/min part
				-- ------------------------
				maxmin_tmp <= after_abs_A - after_abs_B;
				
				if maxmin_tmp > 0 then -- abs(A) is largest
					after_minmax_max <= after_abs_A;
					after_minmax_min <= after_abs_B;
				else -- abs(B) is largest
					after_minmax_max <= after_abs_B;
					after_minmax_min <= after_abs_A;
				end if;
				
				-- ------------------------
				-- Stage 3
				-- ---
				-- Scaling part
				-- alpha = 0.948 ~ x - x/16
				-- beta = 0.392 ~ x/2 - x/8 + x/32 
				-- ------------------------
				after_scale_max <= after_minmax_max - after_minmax_max / 16;
				after_scale_min <= after_minmax_min / 2 - after_minmax_min / 8 + after_minmax_min / 32;
				
				-- ------------------------
				-- Stage 4
				-- ---
				-- Summation part
				-- ------------------------
				after_sum_M <= after_scale_max + after_scale_min;
				
			end if;
		end if;
	end process;

	-- ------------------------
	-- Connect output
	-- ------------------------
	mag <= after_sum_M;

end Behavioral;
Det jag då funderar på är, hur vet man att det kommer bli pipeline-ad design? :humm:
Det känns som att syntetiseringen borde kunna optimera bort mina signaler och tvinga en kombinatorisk design.
Är detta rätt design metod? Eller finns det andra/bättre sätt att göra det på?
Användarvisningsbild
Andax
Inlägg: 4373
Blev medlem: 4 juli 2005, 23:27:38
Ort: Jönköping

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Andax »

Har du en klockad tilldelning så kan verktyget inte optimera bort det (givet att resultatet används någonstans). Pipeline får du ju enklast om du använder signaler som är klockat tilldelat i samma process och tilldelar nästa del i pipen.
Har inte satt mig in i din kod, men jag tror du använder värden från olika pipeline steg. T.ex. beräknar du ett tmp-värde av skillnaden mellan after_abs_a och after_abs_b som kommer vara fördröjt en klockcyckel eftersom du har en signal-tilldelning när du sedan gör jämförelsen med >0.

Ibland är det enklare att använda variable istället för signal i sådana situationer.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Ahh, så det är så den tänker. Då hänger jag med! :tumupp:
Men du har helt klart rätt max/mix steget måste delas upp, annars blir det spännande. :)
Märkte det också när jag började pumpa data genom den i simulering att resultatet blev fel.

Just typen "variable" har jag aldrig använt, har du något bra exempel med denna?
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Glömde den fixade koden om nån vill testa. :) Syntetiseringen säger att den ska klara av 177 MHz på en Spartan 6.
Bygger på den här approximationen: http://www.dspguru.com/book/export/html/62

Kod: Markera allt

library ieee;
use ieee.std_logic_1164.all;        
use ieee.numeric_std.all;

entity magnitude_est is
	generic (N:positive := 16);
	port (
		clk : in std_logic;
		rst : in std_logic;
		A   : in signed (N-1 downto 0);
		B   : in signed (N-1 downto 0);
		mag : out unsigned (N-1 downto 0)
	);
end magnitude_est;

architecture Behavioral of magnitude_est is
	-- Absulute value signals
	signal after_abs_A : unsigned (N-1 downto 0);
	signal after_abs_B : unsigned (N-1 downto 0);

	-- Max/min part
	signal after_minmax_max : unsigned (N-2 downto 0);
	signal after_minmax_min : unsigned (N-2 downto 0);
	
	-- Scaling part
	signal after_scale_max : unsigned (N-2 downto 0);
	signal after_scale_min : unsigned (N-2 downto 0);
	
	-- Summation part
	signal after_sum_M : unsigned (N-1 downto 0);
begin

	process (clk) begin
		if rising_edge(clk) then
			if rst = '1' then
				-- Reset all signals to zero state
				after_abs_A      <= (others => '0');
				after_abs_B      <= (others => '0');
				after_minmax_max <= (others => '0');
				after_minmax_min <= (others => '0');
				after_scale_max  <= (others => '0');
				after_scale_min  <= (others => '0');
				after_sum_M      <= (others => '0');
			else
				-- ------------------------
				-- Stage 1
				-- ---
				-- Absulute value part
				-- ------------------------
				after_abs_A <= unsigned(abs(A));
				after_abs_B <= unsigned(abs(B));
				
				-- ------------------------
				-- Stage 2
				-- ---
				-- Max/min part
				-- ------------------------
				if after_abs_A > after_abs_B then -- abs(A) is largest
					after_minmax_max <= after_abs_A(N-2 downto 0);
					after_minmax_min <= after_abs_B(N-2 downto 0);
				else -- abs(B) is largest
					after_minmax_max <= after_abs_B(N-2 downto 0);
					after_minmax_min <= after_abs_A(N-2 downto 0);
				end if;
				
				-- ------------------------
				-- Stage 3
				-- ---
				-- Scaling part
				-- alpha = 0.948 * x ~~ x - x/16 + x/128
				--  beta = 0.392 * x ~~ x/2 - x/8 + x/64 
				-- ------------------------
				after_scale_max <= after_minmax_max - (after_minmax_max / 16) + (after_minmax_max / 128);
				after_scale_min <= (after_minmax_min / 2) - (after_minmax_min / 8) + (after_minmax_min / 64);
				
				-- ------------------------
				-- Stage 4
				-- ---
				-- Summation part
				-- ------------------------
				after_sum_M <= ('0' & after_scale_max) + ('0' & after_scale_min);
				
			end if;
		end if;
	end process;

	-- ------------------------
	-- Connect output
	-- ------------------------
	mag <= after_sum_M;

end Behavioral;
Senast redigerad av Korken 29 september 2014, 10:06:08, redigerad totalt 7 gånger.
qx5
Inlägg: 1678
Blev medlem: 14 augusti 2014, 04:23:04

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av qx5 »

Vad blir det för hastighet i MHz på en Spartan-3E ..?
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Spartan 3E (500): 82.713 MHz med -4 speed grade.
Tar 160 slices (291 LUTs).
Användarvisningsbild
Andax
Inlägg: 4373
Blev medlem: 4 juli 2005, 23:27:38
Ort: Jönköping

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Andax »

Här kan du läsa lite om variables:
http://www.gmvhdl.com/variable.htm

Vill man pipelina så är det inte applicerbart men kan vara mycket användbart i vissa sammanhang.
Användarvisningsbild
Korken
Inlägg: 2230
Blev medlem: 3 februari 2006, 19:19:36
Ort: Luleå, Porsön

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av Korken »

Tackar! :tumupp:
Användarvisningsbild
stekern
Inlägg: 453
Blev medlem: 2 november 2008, 08:24:18
Ort: Esbo, Finland

Re: Fråga om VHDL (Xilinx FPGA)

Inlägg av stekern »

En minimal inflikning, det är lite missvisande att säga att variables inte är applicerbara vid pipelining, det går alldeles utmärkt att använda de vid detta.
Exempelvis så här:

Kod: Markera allt

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity test is
  port(
    clk         : in std_logic;
    a           : in std_logic;
    b           : out std_logic
  );
end;

architecture rtl of test is
begin
  process(clk)
    variable var1 : std_logic;
    variable var2 : std_logic;
    variable var3 : std_logic;
  begin
    if rising_edge(clk) then
      b <= var3;
      var3 := var2;
      var2 := var1;
      var1 := a;
    end if;
  end process;
end rtl;
Anledningen till att jag vill poängtera detta, är att nyttan med variabler är inte bara att hålla temporära mellanvärden,
utan en annan fördel är att de endast blir deklarerade i scopet för processen.
Skriv svar