Forum: FPGA, VHDL & Co. Funktionen mehr fach benutzen


von Marco (Gast)


Lesenswert?

Ich habe eine Funktion der Form:

procedure Send( signal in :  in std_logic_vector(15 downto 0);
                signal clk : OUT std_logic;
                signal dat : OUT std_logic) is

...

die nach Aufruf aus dem input ein Taktschema ausgibt, was auch 
funktioniert. In der Sim wird damit ein Kanal bedient, der permanent 
sendet.

(warten auf Taktflanke)
14 ns Warten
pattern1<= x"1234";
Send (pattern1, clk1, dat1);

(warten auf Taktflanke)
14 ns Warten
pattern1<= x"1234";
Send (pattern1, clk1, dat1);

(warten auf Taktflanke)
14 ns Warten
pattern1<= x"1234";
Send (pattern1, clk1, dat1);
....................................


(Wie) kann ich diese Funktion noch für weitere Kanäle nutzen?

Kann ich eine Kopie der Funktion aufrufen oder stört sich das 
gegeneinander?

Ich brauche 16 Kanäle, die mit leichtem Versatz und etwas anderem Takt 
arbeiten, aber alle permanent senden:

(warten auf Taktflanke2)
18 ns Warten
pattern2<= x"1234";
Send (pattern2, clk2, dat2);

Natürlich sollen die Signal der anderen Kanäle bedient werden.

Ich habe es einfach nochmal aufgerufen und sehe, dass Chaos eintritt.

von P. K. (pek)


Lesenswert?

Soll das nur eine Simulation werden, oder willst Du das dereinst auch 
synthetisieren? Zweiteres kriegst Du mit diesem Ansatz vermutlich nicht 
sinnvoll hin.

Ich denke, dass Du hier allzusehr auf dem Software-Zug reitest. Lass mal 
Prozeduren für alles, was Du später synthetisieren willst, weg.

Dann packst Du Deinen "Send"-Block in eine separate Entity, und die 
kannst Du dann mehrfach "instantieren" und in der Port Map die jeweils 
benötigen "Drähte" anschliessen.

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


Lesenswert?

Peter K. schrieb:
> Soll das nur eine Simulation werden
Offenbar schon...
Marco schrieb:
> In der Sim wird damit ein Kanal bedient, der permanent sendet.

> (Wie) kann ich diese Funktion noch für weitere Kanäle nutzen?
Prinzipiell sind Funktionen unabhängig: auch rising_edge() ist eine 
Funktion und ich habe die zigmal in jedem Design.
Bleibt also die Frage: welche Funktion denn?
Soll heißen: wie sieht die innen aus?

> Ich habe es einfach nochmal aufgerufen und sehe, dass Chaos eintritt.
Wie sieht es aus, wenn du nicht gleicht 16 Stück gleichzeitig aufrufst, 
sondern mal nur 2 Stück einbaust und immmer nur 1 davon aktiv senden 
lässt?

von J. S. (engineer) Benutzerseite


Lesenswert?

Funktionen werden immer nacheinander aufgerufen, sowohl während der 
Simulation, als auch der Ausführungzeit, die hier die Compilezeit ist.

Ob das, was dabei rauskommt, gebaut werden kann, funktioniert und so 
funktioniert, wie Du es haben willst, hängt einzig davon ab, wie die 
Funktion innen ausschaut. Wenn dort Variablen und Signale beschrieben 
werden, die zu gleichen Zeitpunkt nirgendwo anders bedient werden, kann 
das klappen. Ansonsten findet die Synthese einen doppelten Treiber. Seit 
Neuestem meckert Xilinx z.B. sogar redundante Treiber an, wie ich 
letztens gesehen habe. In der Regel macht es keinen Sinn, Signale aus 
mehreren Ecken heraus zu treiben.

Da es angeblich alles unabhängig ist, dürfte es auch gebaut werden, 
sofern es grundsätzlich überhaupt baubar ist. Beim Compilerlauf werden 
die Funktionen nacheinander aufgerufen und die sich daraus ergebenden 
Syntheseanweisungen für alle Fälle druchgeführt, wodurch eine Vielzahl 
von Signalen entsteht. An der Stelle dürften redundante (unbedingte) 
Zuweisungen platzen, zumindest, wenn sie sich widersprechen.

Allerdings sieht mir das eher nach einer Stimulibescheibung aus. Für 
diese gilt aber dasselbe: Ob die arbeiten kann, hängt davon ab, ob es 
einen eindeutigen Ablauf gibt, den der Simulator erkennen und dem er 
folgen kann - dann machen mehrere Zugriffe auf dieselben Variablen und 
Signale erst einmal nichts aus - wobei ich wenige Fälle kenne, wo man so 
was Diffuses braucht. Meistens existieren solche Spielchen aus entweder 
Programmierersparnis / -faulheit oder infolge eines Denkfehlers.

Massgeblich bei den Abläufen sind die Sens-Listen. Da gibt es eine 
Vielzahl von Methoden wie man das nutzen kann und dementsprechend viele 
Fallen.

Ob Deine Simulation läuft - bzw wie gewünscht läuft, zeigt Dir doch 
direkt der Simulator. Oder nicht?

Falls das dennoch synthetisiert werden soll, sollte man die Logik nicht 
durch Funktionsaufrufe indirekt inferieren, sondern ausdrücklich 
instanziieren. Dafür gibt es den generate-Konstrukt. Wenn man sich damit 
ein wenig befasst, kann man die komplexesten Dinge beschreiben und es 
ist auch einfach verifizierbar, weil direkt die Struktur befohlen wird.

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.