www.mikrocontroller.net

Forum: FPGA, VHDL & Co. FPGA/VHDL Timing


Autor: Florian Rems (flo0815)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo beisammen,

zunächst vorneweg: bin ein FPGA und VHDL Newcomer, es könnten also 
einige blöde Fragen folgen :-).

Ich habe gerade folgendes Verständnisproblem. In einer entity habe ich 
eine component eingebunden. Diese (selbstgebastelte) component besteht 
aus einem process, der zwei Binärzahlen dividiert. Da das leider eine 
recht sequenzielle Angelegenheit ist, gehe ich mal davon aus, dass das 
mit einem Takt nicht getan ist.
Wenn ich jetzt in der entity dem divider auf die Eingänge Werte gebe, 
wie kann ich dann sichergehen, dass der Ausgang, den ich auslese auch zu 
den Eingabewerten gehört und nicht zu denen davor? Muss ich warten, bis 
sich der Ausgang ändert bzw. ein trigger signal mit einbauen?
Wenn ja, wo ist dann der Unterschied zur Verwendung einer function oder 
procedure? Dann müsste die hardware quasi so synthetisiert werden, dass 
automatisch gewartet wird?
Ach ja: Wie ist das dann, wenn ich "vorgefertigte" Komponenten, wie z.B. 
einen hardware multiplier (Spartan3E) einbinde. Muss/kann ich da warten?

Hinter diese Timing-Sache steig ich noch nicht so ganz. Die sequenzielle 
Art zu Denken ist nur schwer zu verdrängen...

Vielen Dank für jede Hilfe und jeden Hinweis.

Gruß
flo0815

Autor: Niklas Gürtler (erlkoenig)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Da das leider eine
> recht sequenzielle Angelegenheit ist, gehe ich mal davon aus, dass das
> mit einem Takt nicht getan ist.
Ich hoffe, du meinst damit: Du hast eine komplizierte ("tiefe") 
kombinatorische Logik beschrieben - also einen Haufen LUT's - deren 
Ausgänge direkt das Ergebnis in Abhängigkeit von den Eingängen ausgeben?
Weil sequentiell kann ein FPGA nicht - diese LUT's, auch wenn davon 
viele hintereinander geschaltet sind, arbeiten ja im Prinzip alle 
parallel.
>Wenn ich jetzt in der entity dem divider auf die Eingänge Werte gebe,
>wie kann ich dann sichergehen, dass der Ausgang, den ich auslese auch zu
>den Eingabewerten gehört und nicht zu denen davor?
Vermutlich gibst du mit einer Taktflanke die Eingabedaten auf die 
Eingänge, und liest bei der nächsten Taktflanke das Ergebnis aus 
(jeweils mittels FlipFlops)? Dann macht die Toolchain das automatisch, 
vorausgesetzt, sie weiß, wie schnell der Takt ist, was in der UCF-Datei 
angegeben werden kann. Wenn deine kombinatorische Logik länger braucht 
um die Eingabe zu verarbeiten als ein Takt dauert, gibts Timing Errors 
am Ende des Place&Route bzw. in der Ausgabe der maximal möglichen 
Frequenz wird eine niedrigere angegeben.
>Ach ja: Wie ist das dann, wenn ich "vorgefertigte" Komponenten, wie z.B.
>einen hardware multiplier (Spartan3E) einbinde. Muss/kann ich da warten?
Die Dinger sind sehr schnell, wie schnell steht im Datenblatt. Wenn du 
die inferierst - also einfach "c <= a * b;" schreibst, wird der 
Hardware-Block ja automagisch verwendet, und die Toolchain errechnet 
genau wie bei normaler Logik ob er schnell genug ist.

Zur Division guggst du da:
http://www.lothar-miller.de/s9y/categories/24-Division

Autor: Florian Rems (flo0815)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für die schnelle Antwort!


>Ich hoffe, du meinst damit: Du hast eine komplizierte ("tiefe")
>kombinatorische Logik beschrieben - also einen Haufen LUT's - deren
>Ausgänge direkt das Ergebnis in Abhängigkeit von den Eingängen ausgeben?

Das hoffe ich auch:
entity DIVIDER is
--------------------------------------------------------------------
    Port ( Divisor_DIV  : in  STD_LOGIC_VECTOR(17 downto 0);
           Dividend_DIV : in STD_LOGIC_VECTOR(17 downto 0);
        Quotient_DIV : out STD_LOGIC_VECTOR(17 downto 0);
           Start_DIV   : in  STD_LOGIC;
        Finished_DIV : out STD_LOGIC);
end DIVIDER;
--------------------------------------------------------------------
--------------------------------------------------------------------
architecture Behavioral of DIVIDER is

begin

  Pdiv: process(Start_DIV)
  
  variable topbit   : INTEGER RANGE -1 TO 17;
  variable temp    : STD_LOGIC_VECTOR (18 downto 0);
  variable quot     : STD_LOGIC_VECTOR (17 downto 0):=(others => '0');
  
  begin
  
    Finished_Div <= '0';
  
    if Start_DIV='1' and Start_DIV'event then
    
      if Divisor_DIV > Dividend_DIV then
      
        Quotient_DIV <= (others => '0');
      
      else
        
        if divisor_DIV = "000000000000000000" then
        
          quotient_DIV <= "111111111111111111";
          
        else
        
          -- Find leftmost non-zero digit of divisor and save in variable topbit
          topbit := -1;
          for i in 17 downto 0 loop
            if divisor_DIV(i) = '1' then 
              topbit := i;
              exit;
            end if;      
          end loop;
          
          -- Do division algorithm.
          temp := "0"&dividend_DIV;
          for i in 18-(topbit+1) downto 0 loop
            if temp(topbit+i+1 downto i) >= "0"&divisor_DIV(topbit downto 0) then
              temp(topbit+i+1 downto i) := (temp(topbit+i+1 downto i))-("0"&divisor_DIV(topbit downto 0));
              quot(i):='1';
            end if;
           end loop;
           
           quotient_DIV <= quot;
          
        end if;
          
      end if;
    
    end if;
    
    Finished_DIV <= '1';
    
  end process;

end Behavioral;

>Vermutlich gibst du mit einer Taktflanke die Eingabedaten auf die
>Eingänge, und liest bei der nächsten Taktflanke das Ergebnis aus
>(jeweils mittels FlipFlops)?

Keine Ahnung, mach ich das? Ich setze die Signale Divisor_DIV und 
Dividend_DIV, danach setze ich Start_DIV<='1' und warte auf eine 
steigende Flanke auf Finished_DIV. Meine Frage ist, ob ich dieses 
triggern und warten auf Bestätigung immer machen muss, wenn ich auch 
tatsächlich das aktuelle Ergebnis und nicht das des letzten Durchgangs 
haben will.

Danke übrigens für den Link. Werde mir das mal genauer anschauen.

Gruß
Flo

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein Tipp an einen Anfänger: du brauchst keine for-Schleife.
Sie macht etwas ganz anderes, als du erwartest...  :-o

>> Vermutlich gibst du mit einer Taktflanke die Eingabedaten ...
> Keine Ahnung, mach ich das?
Nein, schlimmer: du hast gar keinen Takt, sondern einen Dividierer 
kombinatorisch beschreiben... :-/
Geh einfach mal davon aus, dass du mit deiner Beschreibung einen 
riesengroßen kombinatorischen Multiplexer gebaut hast:
          for i in 18-(topbit+1) downto 0 loop  
            if temp(topbit+i+1 downto i) >= "0"&divisor_DIV(topbit downto 0) then     
               -- das ist ein Mega-Multiplexer
              temp(topbit+i+1 downto i) := (temp(topbit+i+1 downto i))-("0"&divisor_DIV(topbit downto 0));    
              quot(i):='1';
            end if;
           end loop; 

Das wird sich nicht in Hardware abbilden lassen:
          for i in 18-(topbit+1) downto 0 loop  ...
Denn du kannst für die Synthese nur einen statischen Bereich für die 
for-Schleife angeben...
Du wirst diesen Dividierer also bestenfalls simulieren können. Manchen 
reicht das  ;-)

> Muss ich warten,...
Ja, das Ding ist unglaublich kompilziert (wenn du es mal übersetzt 
bekommst), und die Synthese wird dir dafür dann eine recht lange 
Laufzeit bescheinigen. Die mußt du abwarten.
Und: auf dein
Finished_DIV <= '0';
:
Finished_DIV <= '1';
kannst du dich nicht verlassen. Die Synthese wird dieses Signal einfach 
fest auf '1' legen, weil die letzte Zuweisung im Prozess gewinnt (ein 
Prozess wird in der theoretischen Zeit 0 abgearbeitet).

Autor: Florian Rems (flo0815)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also, danke für die umfangreiche Antwort. Hast mir gerade mehr 
brauchbare Hinweise und v.a. Verständnishilfen gegeben, als ich in 
diversen Tutorials gefunden habe. Das mit der For-Schleife hab ich schon 
befürchtet.

Ich war so frei, und habe nun den Divisions-Algorithmus von deiner 
Homepage benutzt. Das ist für eine Semesterarbeit. Wäre das für dich in 
Ordnung, wenn ich den Algorithmus benutze - selbstverständlich 
wissenschaftlich korrekt mit Quellen/Autorenangabe?

Ich denke das mit dem Takt habe ich jetzt zumindest grob verstanden. Ein 
anderes Modul habe ich jetzt als FSM geschrieben. Da kann ich sauber auf 
den Dividierer warten und kann halbwegs nachvollziehen was passiert 
(oder nicht passiert :-)).

Noch eine Frage: Gibt es empfehlenswerte Literatur, die eben auf die 
Synthetisierbarkeit eingeht? Über VHDL gibt es ja zeugs wie Sand am 
Meer, aber ich habe praktisch nichts mit praktischen Hinweisen für die 
Synthese gefunden.

Nochmal vielen Dank.

Gruß
Flo

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Ich war so frei, und habe nun den Divisions-Algorithmus von deiner
> Homepage benutzt. Das ist für eine Semesterarbeit. Wäre das für dich in
> Ordnung, wenn ich den Algorithmus benutze - selbstverständlich
> wissenschaftlich korrekt mit Quellen/Autorenangabe?
Wie üblich eben... ;-)

> Noch eine Frage: Gibt es empfehlenswerte Literatur, die eben auf die
> Synthetisierbarkeit eingeht?
VHDL-Synthese von Reichardt&Schwarz

Autor: Florian Rems (flo0815)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sehr gut. Danke!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.