Forum: FPGA, VHDL & Co. Komponenten parametrisieren und Werte zurückgeben


von thpo (Gast)


Lesenswert?

Hallo zusammen,

vielleicht weiß jemand etwas zur geschickten Parametrisierung von VHDL 
Instanzen. Und zwar habe ich ein Top-Level Modul welches eine relativ 
aufwändige Pipeline realisiert. Dies geschieht mit mehreren 
Untermodulen, embedded DSPs und auch IP cores die alle ein bestimmtes 
Delay haben. Das Top-Level Modul ist parametrierbar bzgl. der 
Eingangsbitbreiten und hat auch noch ein paar andere Abhängigkeiten 
(z.B. Reduktionsprimzahl und Konstanten) die als generic übergeben 
werden.

Für wechselnde generics werden dann in den Untermodulen mit if generate 
die passenden Blöcke, wie z.B. schon vorgefertigte IP Cores für die 
Multiplikation (wegen Abhängigkeit von der Breite der Eingänge, und da 
für Cores ja leider keine support für VHDL generics besteht) oder ein 
modularer Reduzierer (speziell auf die gewählte Reduktionsprimzahl 
zugeschnitten) ausgewählt.

Jetzt geht es darum, dass eine Oberkomponente wissen muss, wie viele 
Takte delay ihre instantiierten Unterkomponenten haben um selber zu 
wissen, wann gültige Werte am Ausgang der Pipeline anliegen. Diese 
Oberkomponente hat auch wieder eine Oberoberkomponente, die wiederum das 
Delay wissen muss. Delays können sich z.B. ändern, wenn ich an einigen 
Stellen noch Register einfügen muss, um das Timing einhalten zu können 
oder eine Optimierung finde, die Register überflüssig macht.

Jetzt hatte ich gedacht, ich könnte einfach den delay einer Komponente A 
als "quasi-konstanten" out port in der Entity declaration angeben. Wenn 
die Komponente B die Komponente A instantiiert hätte sie diesen Wert und 
wüsste über das Delay Bescheid. Leider funktioniert das so nicht, da der 
output port in der instantiierenden Komponente B nicht als konstant 
markiert wird. Dies ist wichtig, da abhängig vom delay in A z.b. 
Schieberegister einer bestimmten Länge von B instantiiert werden.

Was ich also suche, sind umgekehrte generics, d.h. ich will Konstanten 
(oder noch besser Werte die zur Synthesezeit abhänig von generics 
ausgerechnet wurden) an die instantiierende Oberkomponente (zurück) 
übergeben.

Eine relative „einfache“ Möglichkeit dies teilweise zu realisieren wäre 
ein Package zu deklarieren, in dem ich für jedes Modul das delay als 
constant eintrage. Problem ist allerdings, dass ich dann natürlich auch 
bei jeder Änderung im Code der Komponente die Einfluss auf das delay 
hat, auch den Eintrag in der Packagedefinition ändern muss 
(fehleranfällig). Zusätzlich würde ich das delay gerne auch von den 
tatsächlich über if generate instantiierten Komponenten abhängig machen 
und komme dann mit der Package Lösung nicht weiter.

Prinzipiell realisierbar sollte das alles sein, da alles zur 
Synthesezeit ablaufen soll, die Frage ist nur wie man so etwas schön mit 
VHDL Bordmitteln realisiert. Vielleicht hat ja wer eine gute Idee oder 
kennt eventuell Compiler Optionen die „quasi-konstante“ out Ports 
erlauben oder andere obskure VHDL Features mit denen dies möglich ist.

Achja, ich arbeite mit Xilinx ISE 13 und würde auch gerne den normalen 
graphischen „Klick auf Knopf“ Designflow beibehalten und keinen 
Präprozessor einbauen.

Vielen Dank im Voraus

von Ralf (Gast)


Lesenswert?

Woraus bestimmen sich die Delays?

Meistens ist es ja so, dass von oben her so parametriert wird, dass eine 
Schaltung genauer und damit bitbreiter wird, was sich dann nicht mehr 
mit demselben delay machen lässt. Dann synthetisiere ich FFs und erhöhe 
IN dem Modul die Latenz indem ich einen Takt zurückmelde. Ist einfach 
ein Schieberegister. Die Ergebnisse werden dann dynamisch gelatched.

Wenn die Sache von oben her ausgeechnet wird, dann müsste das anhand der 
Strategie natürlich auch schon oben berechenbar sein, wie sich das Delay 
entwickelt. Damit würde beides von oben her ins Modul hineingetrieben.

Man müsste wissen, welche Schaltungen Du benutzt,um  einen Tipp geben zu 
können, wie es laufn müsste.

Ich designe alle pipelines aus Papier und Excel und lasse mir die delays 
ausrechnen.

In Deinem Fall ist es aber wohl besser, Du dynamisierst die gesamte 
Schaltung, sodass die Delays nicht bekannt sein müssen. Also 
"Endemeldung" von  PRozessen wie oben und synch über FiFos wie in der 
reinen SW-Landschaft.

von Duke Scarring (Gast)


Lesenswert?

Ich sehe hier zwei Ansätze:

1. Du könntest eine Funktion in das package legen, die Dir Dein Delay 
berechnet:
1
package calc_stuff is
2
3
    function get_calc_delay( bit_width: positive; ...) return positive is
4
        variable result : positive;
5
    begin
6
        ...
7
        return result;
8
    end function get_calc_delay;
9
10
end package calc_stuff;
11
12
...
13
14
begin
15
   
16
   instance0: calc
17
       generic map (
18
           delay      => get_calc_delay( calc_width, ...),
19
           data_width => calc_width
20
       )
21
       port map (
22
           ....


2. So wie Ralf das auch vorgeschlagen hat: Du kannst zum Ende der 
Berechnung ein ready oder data vaild mit ausgeben. Dann weiß die 
nachfolgende Komponente, wann sie loszulegen hat.

Duke

von thpo (Gast)


Lesenswert?

Ich hab das jetzt mit der Funktion gelöst. Vielen Dank für die Hilfe.

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.