Forum: FPGA, VHDL & Co. Summe, Index und Multiplikation von Std_Logic_Vectoren


von hans (Gast)


Lesenswert?

Guten Morgen liebes Forum,

ich bin gerade dabei, ein Desgin zu entwerfen, welches die Summe aus n 
Elementen (12 Bit Std_logic_Vector) berechnet, wobei jedes n-te Element 
mit dem Indexfaktor n multipliziert wird.

Formeltechnisch sieht das ganze so aus:


Die reine Addition, bzw. die Gesamtsumme aller Vektoren steht soweit. 
Dies habe ich folgendermaßen realisiert:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use ieee.numeric_std.all; 
4
5
6
entity summ is
7
    Port ( data_a : in  STD_LOGIC_VECTOR (11 downto 0);
8
           data_b : in  STD_LOGIC_VECTOR (11 downto 0);
9
           clk : in  STD_LOGIC;           
10
           sum_sub : out  STD_LOGIC_VECTOR (23 downto 0)
11
          );
12
13
end summ;
14
15
architecture Behavioral of summe_index is
16
signal sum :  unsigned (23 downto 0):= (others => '0');      
17
signal count: unsigned (11 downto 0) := (others => '0');      
18
signal temp : unsigned (11 downto 0):= (others => '0');  
19
20
21
begin
22
23
process(clk)
24
begin
25
if rising_edge(clk) then    
26
  temp <= unsigned(data_a) + unsigned(data_b);
27
  sum_sub <= std_logic_vector(sum);
28
end if;
29
30
if falling_edge(clk) then
31
  sum <= sum + temp;
32
end if;
33
34
end process;
35
end Behavioral;

Dazu habe ich mir eine Testbench geschrieben, die  data_a und data_b 
eine gewissen Anzahl von Signalen in Abhängigkeit des Taktes zuweisen. 
Das Ergebnis geht auf.

Um nun jedes Element mit einem Faktor zu belegen, habe ich mir erst 
einmal Zähler gebaut:
1
process(clk)
2
begin
3
  if rising_edge(clk) then    
4
    count <= count + 1;    
5
  end if;
6
end process;


Nun wollte ich das Ganze so lösen:
1
process(clk)
2
begin
3
if rising_edge(clk) then    
4
  temp <= unsigned(data_a) * unsigned(count sll 1) + unsigned(data_b) * unsiged ((count sll 1) + 1);
5
  sum_sub <= std_logic_vector(sum);
6
end if;
7
8
if falling_edge(clk) then
9
  sum <= sum + temp;
10
end if;
11
12
end process;
13
end Behavioral;

Nun muss ich natürlich den Wertebereich meiner sum und sum_sub 
erweitern, ich meine es waren dann 36 Bit. Dieses Vorhaben geht jedoch 
leider nicht mehr auf. Es wird zwar ohne Fehler synthetisiert, jedoch 
sehe ich im ISIM nur UNITIALIZED bei sum_sub. Kann es sein, dass es mit 
den Takten nicht ganz hin haut, da ich in der aufsteigender Flanke 
addieren UND multiplizieren möchte?

Wäre über jeden Rat sehr dankbar, wie ich das Problem lösen kann.



Schönen Sonntag,

Hans

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

1
process(clk) begin
2
 if rising_edge(clk) then    
3
   ...
4
 end if;
5
6
 if falling_edge(clk) then
7
  ...
8
 end if;
9
end process;
Was versprichst du dir von dieser "Aufteilung" der Arbeit in fallende 
und steigende Flanken?

Abgesehen von vielen zusätzlichen Registern und einer Halbierung der 
Laufzeiten (mit allen Nachteilen) kommt dabei nichts heraus...

> Kann es sein, dass es mit den Takten nicht ganz hin haut, da ich in
> der aufsteigender Flanke addieren UND multiplizieren möchte?
Nein, trotzdem ist es Murks.

Das Ganze wird problemlos etwa auf diese Art funktionieren:
1
process(clk) begin
2
  if rising_edge(clk) then    
3
    sum <= sum + unsigned(data_a) * unsigned(count sll 1) + unsigned(data_b) * unsiged ((count sll 1) + 1);
4
    count <= count+1;
5
  end if;
6
end process;
Denn mehr Aufgaben hast du nicht:
1. Rechnen und Summieren
2. Index hochzählen

> sehe ich im ISIM nur UNITIALIZED bei sum_sub.
Bei allen Elementen des Vektors, oder nur bei einigen?
Passen die Vektorbreiten zusammen?
Was für Infos und Warnings spuckt die Synthese aus?

von hans (Gast)


Lesenswert?

Super, danke Lothar. Es funktioniert.

Lothar Miller schrieb:
> Was versprichst du dir von dieser "Aufteilung" der Arbeit in fallende
> und steigende Flanken?

Ich weiß auch nicht so recht, irgendwie hatte ich gedacht, dass sum <= 
sum + x nicht synthesefähig wäre. Ich hatte es am Anfang mal in dieser 
Richtung ausprobiert, hatte eine Fehlermeldung bekommen mit dem Hinweis, 
dass ich ein Signal zur gleichen Zeit mehrfach beanspruche oder in der 
Art. Ich weiß es nicht mehr so genau.

Lothar Miller schrieb:
> Abgesehen von vielen zusätzlichen Registern und einer Halbierung der
> Laufzeiten (mit allen Nachteilen) kommt dabei nichts heraus...

Zu welchen Nachteilen kann es alles kommen?


Und das Ganze funktioniert mit dem use ieee.numeric_std.all Package auch 
auf einem FPGA? Ich könnte mit den Operatoren + , - , * und / rechnen?


Vielen Dank für die super Hilfe,

Hans

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

hans schrieb:
> Zu welchen Nachteilen kann es alles kommen?
Du hast nur die halbe Zeit für die Rechnung zur Verfügung, weil temp 
mit der steigenden Flanke berechnet, aber mit der fallenden Flanke schon 
gespeichert wird (oder andersrum). Wie gesagt: dein Design muss deshalb 
doppelt so schnell sein...
> Und das Ganze funktioniert mit dem use ieee.numeric_std.all Package auch
> auf einem FPGA?
Ja, tadellos.
> Ich könnte mit den Operatoren + , - , * und / rechnen?
Ja, ja, ja, und jein.
Zum Thema "Division in der Synthese" gibts aktuell deinen 
Beitrag "Division von STD_LOGIC_VECTOR"
Und: Divisionen durch Zweierpotenzen (2,4,8,16...) werden im FPGA durch 
einfaches Umverdrahten erledigt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.