Hallo -
folgende inputs:
datain<15:0>
a1<15:0>
a2<15:0>
b1<15:0>
b2<15:0>
bei jedem Takt kommen neue Daten an datain, sowie an a1, a2 und b1, b2
folgende Berechnung:
c = b1 * b2
d = datain - a1 - b2
e = d * a1
y = c + e
kann man eine FSM beschreiben, die sich in mehreren states befindet ?
oder wie beschreibt man pipalined prozesse am besten?
grüße,
linus
Ich denke es kommt darauf an, wie man "pipeline" auffasst. Eine Pipeline
kann meiner Auffassung nach in einer FSM mit Zuständen implementiert
werden. Ist sicherlich bei Prozessoren üblich. Muss aber nicht, wenn man
eine stufenweise Verarbeitung als Pipeline betrachtet. Da man ja die
Wahl hat, ob man Zwischenresultate weiterverwendet oder nicht ist beides
möglich.
In beiden Fällen ergibt sich aber die "Pipeline" ganz natürlich aus
Deiner Beschreibung:
Zustand 0:
c = b1 * b2
d = datain - a1 - b2
Zustand 1:
e = d * a1
Zustand 2:
y = c + e
Oder (als Datenpipeline betrachtet):
c = b1 * b2
d = datain - a1 - b2
e = d * a1
y = c + e
Oder (als zeitlich aufgelöster Prozess)
c = b1 * b2
d = datain - a1 - b2
e = d_t-1 * a1
y = c_t-2 + e_t-2
Hallo -
Danke für die Antwort.
Dennoch: wenn als FSM, wird ja mit jedem Takt zum Folgezustand
gewechselt. Somit kann man doch in einer FSM nicht in einem anderen
Zustand sein, und im selben Takt neue Daten einlesen.. oder verstehe ich
das was nicht richtig?
>Dennoch: wenn als FSM, wird ja mit jedem Takt zum Folgezustand>gewechselt. Somit kann man doch in einer FSM nicht in einem anderen>Zustand sein, und im selben Takt neue Daten einlesen.. oder verstehe ich>das was nicht richtig?
Kann auch sein, das ich Deine Frage nicht richtig verstehe oder was
nicht ganz korrekt dargestellt habe.
>somit kann man doch in einer FSM nicht in einem anderen>Zustand sein
In einem anderen Zustand als welchem?
Eine mögliche Implementierung wäre, das die FSM in jedem Takt neue
Daten einliest und in jedem Zustand die jeweiligen Berechnungsschritte
ausführt, also jeweils mit den Daten und Zwischenergebnissen, die sie
schon hat. Die Zustände dienen dann zur Unterscheidung welche Parameter
die jeweiligen Berechnungsschritte erhalten.
Eine andere wäre, das in jedem Zustand nur eine der Berechnungen
ausgeführt wird. Dann dienen die Zustände dafür, die Berechnungen zu
unterscheiden und es wird nur im Startzustand ein neuer Wert eingelesen.
Eigentlich bräuchte man dafür keine FSM.
Ergänzung:
Eine andere wäre, das in jedem Zustand nur eine der Berechnungen
ausgeführt wird. Dann dienen die Zustände dafür, die Berechnungen zu
unterscheiden und es wird nur im Startzustand ein neuer Wert eingelesen.
Eigentlich bräuchte man dafür keine FSM, aber die Zustände würden auch
dazu dienen die Parameter zu explizit zu machen, so das es ein wenig
einfacher geistig zu erfassen wird.
Was bei VHDL immer zu beachten ist, ist das Zwischenwerte, wenn sie
weiterverwendet werden sollen, entweder zwischengespeichert werden
müssen oder der Quelltext so gestaltet werden muss, das klar ist, das
die Ausgabe von diesen Zwischenwerten abhängt.
Stichwort: Variablen
Sorry, Ich komme da jetzt selbst ein bisschen ins schwimmen, was VHDL
betrifft.
Genauer, wenn Du in einem VHDL-prozess sowas hast:
x = y + z
k = a + x
dann wird bei der Berechnung von k der alte Wert von x genommen, bevor
er nach der ersten Formel neu berechnet wird.
Wenn Du das nicht willst, musst Du (glaube ich) Variablen verwenden. In
einer FSM wäre halt definitiv klar, das im zweiten Zustand x schon neu
gesetzt ist.
Hmmm. wo ist Lothar Miller?
Moin,
du schreibst das der Einfachheit halber mal als 3 Prozesse hin, im
ersten werden c und d berechnet, im zweiten e, und im dritten y. Nach 3
clk-Zyklen hast du dann dein erstes Ergebnis, danach in jedem Zyklus
ein neues, d.h. du solltest auch ein valid-Flag durch die Pipeline (die
3 rozesse) schieben.
PS: Da du fuer d einen 3-Port-Adder brauchst, solltest du noch einen
weiteren Prozess (als allerersten) haben, in dem wird c einfach
durchgeschleust und der erste Teilausdruck von d berechnet. Waere dann
also eine 4-stufige Pipeline.
Hallo Linus,
was ich noch nicht ganz verstehe ist die Sache weshalb Du überhaupt eine
FSM verwenden willst? Hat es damit zu tun, dass für c und e der selben
Multiplizierer verwendent werden soll, so wie bei einer CPU-ALU?
Dann dient ja die FSM so als Steuerwerk, welche diese "ALU" mit Daten
versorgt ... was dazu führt, dass Deine FSM gut fünf mal schneller
laufen muss, wie die Daten über datain und Co. reinkommen.
Sinnvoller halte ich jedoch den Aufbau einer Pipeline-Struktur, da
Du die Flexibilität einer ALU nicht zu brauchen scheinst. Die Struktur
hätte dann 3 Stufen:
Stufe 1:
c = b1 * b2
d = datain - a1 - b2
Stufe 2:
e = d * a1
Stufe 3:
y = c + e
Aber 'ne FSM braucht man dafür dann nicht ... oder irre ich mich?
Gruß Tuffke
Nach drei Takten hast du das erste gültige Ergebnis, ab da wird in jedem
Takt ein Ergebnis ausgegeben.
Ich bin mal davon ausgegangen das als ergebnis wieder 16bit rauskommen
sollen und Überläufe ignoriert werden können.
Synthese sagt dazu auf Spartan 3A:
Nein es gibt keinen besonderen Grund. Dachte mit der übersichthalber.
Ausserdem hat es mich interessiert, ob es denn in vhdl möglich ist eine
FSM zu schreiben, die in mehreren stages gleichzeitig ist..
Dies scheint nicht möglich zu sein, oder?
Linus
Kommt immer drauf an wie du das definierst... Du kannst natürlich in
einem Zustand wieder ne FSM einabuen die dann einen Unterzustand hat,
oder die FSM einfach mehrfach instantziieren aber ich wüßte jezt nicht
wo das Vorteile bringen sollte.
Linus schrieb:
> Nein es gibt keinen besonderen Grund. Dachte mit der übersichthalber.> Ausserdem hat es mich interessiert, ob es denn in vhdl möglich ist eine> FSM zu schreiben, die in mehreren stages gleichzeitig ist..>> Dies scheint nicht möglich zu sein, oder?
Hmm. Das ist von (Pipeline-)Stages unabhängig. Was Du meinst ist wohl,
kann eine FSM an zwei stellen Steuerungen übernehmen. Prinzipiell ja.
Aber der Zustandsraum der FSM explodiert dann. Stell Dir vor, Du hast
zwei unabhängige FSMs mit einmal zwei und einmal drei Zuständen. Würdest
man diese zu einer FSM vereinen, dann hätte diese 2*3 = 6 Zustände.
Klingt bei diesem Beispiel noch nicht so sehr beeindruckend, aber FSMs
haben mit unter deutlich mehr Zustände.
Ansonsten gibt es da wohl noch sowas wie kontextabhängige FSMs. Die
können quasi parallel arbeiten und in mehreren Zuständen "gleichzeitig
sein".
Aber keine Ahnung wie das genau funzt - vermutlich bringt jeder "Thread"
seinen aktuellen Zustand mit und die FSM berechnet einen neuen Zustand,
der dann abermals wieder als Eingangssignal zugeführt wird. Wie dort der
Zustandsraum aussieht weiß ich aber nicht so recht ...
Gruß und schönen Sonntag
Tuffke
Eine Variable taucht dann ENTWEDER oben, ODER unten auf und wird nur aus
Variablen gepeist, die einen um 1 kleineren Index haben. Variablen, die
später nicht mehr benötigt werden, kann man weglassen, oder laesst sie
die Synthese eliminieren.
So kann man auch die Verzögerungen der RAMs und externen Quellen im
Bezug auf den FPGA-Zeitpunkt NULL (pipe start) gut einbringen.
extern_dsp_data_t2 z.B. sind die Daten aus einem DSP, der 2 Takte später
antwortet.
Man kann dann auch etwas herumspielen, indem man die fortschreibenden
Konstrukte testweise aus dem getakteten Prozess heraus nimmt.
> Was ist Nachteil wenn ich im vergleich zu pipeline so mache?
In einem synchronen Design muß alles in 1 Takt fertig sein (abgesehen
von Multi-Cycles), und für die obige Berechnung ist eine elendig lange
Durchlaufzeit nötig.
Denn da steht ja, dass e_tmp erst nach d_tmp berechnet werden darf. Und
dann könntest du gleich ganz ohne Prozess so schreiben:
danke für eure schnelle Antwort:-)
Lothar Miller schrieb:
> und für die obige Berechnung ist eine elendig lange> Durchlaufzeit nötig.
du meinst, wenn ich als process oder
1
y<=(b1*b2)+(datain-a1-b2)*a1;
schreibe, dann Logik delay ist groß, deswegen mit pipeline werden quasi
FFs inzwischen hinzugefügt, damit logik path geringerer ist?
Klaus Falser schrieb:
> Ganz abgesehen davon, dass man mit std_logic_vector nicht rechnen soll.> Du solltest dringend die Datentypen signed oder unsigned verwenden.
stimmt, danke
zekoo schrieb:
> du meinst, wenn ich als process oder> y <= (b1 * b2) + (datain - a1 - b2) * a1;> schreibe, dann Logik delay ist groß, deswegen mit pipeline werden quasi> FFs inzwischen hinzugefügt, damit logik path geringerer ist?
Richtig.
Du könntest aber auch einen Trick anwenden und den Tools das Einfügen
von FFs an den passenden Stellen erlauben. Dazu mußt du nur den Ausgang
über eine weitere Registerstufe führen und den Syntheseparameter "Xilinx
Specific Options" --> "Register Balancing" aktivieren, dann werden FFs
automatisch an passenden Stellen eingefügt:
1
y1<=(b1*b2)+(datain-a1-b2)*a1;
2
y2<=y1whenrsing_edge(clk);
3
y<=y2whenrsing_edge(clk);
Allerdings ist das dann kein Pipelining, sonden einfach das Einfügen von
zusätzliche Latency-Takten.
Lothar Miller schrieb:
> Du könntest aber auch einen Trick anwenden und den Tools das Einfügen> von FFs an den passenden Stellen erlauben. Dazu mußt du nur den Ausgang> über eine weitere Registerstufe führen und den Syntheseparameter "Xilinx> Specific Options" --> "Register Balancing" aktivieren, dann werden FFs> automatisch an passenden Stellen eingefügt: y1 <= (b1 * b2) + (datain - a1 -
b2) * a1;
> y2 <= y1 when rsing_edge(clk);> y <= y2 when rsing_edge(clk);> Allerdings ist das dann kein Pipelining, sonden einfach das Einfügen von> zusätzliche Latency-Takten.
danke Lothar:)
werde heute ausprobieren, die in konkurenz vorhandenen berechnungen in
pipeline sowie in mode "register balancing" umzusetzen.
melde mich nochmals wenn prolemm gibts:-)
Läubi .. schrieb:
> Nach drei Takten hast du das erste gültige Ergebnis, ab da wird in jedem> Takt ein Ergebnis ausgegeben.
Die Ergebnisse sind dann nicht die aktuelle, oder? ich meine, man kreigt
alte werte, vor 3 takten. Dann ist die weitere rechnungen nicht mehr
korekt!?
GastausHannover schrieb:
> Läubi .. schrieb:>> Nach drei Takten hast du das erste gültige Ergebnis, ab da wird in jedem>> Takt ein Ergebnis ausgegeben.>> Die Ergebnisse sind dann nicht die aktuelle, oder? ich meine, man kreigt> alte werte, vor 3 takten. Dann ist die weitere rechnungen nicht mehr> korekt!?
Nein, stell dir einfach folgendes vor:
Du hast 3 Leute welche nebeneinander an einem Tisch sitzen:
Von Links gibt jetzt jemand alle X Sekunden einen Zettel auf dem die
Eingabezahlen stehen.
Person 1 rechnet jetzt den ersten Schritt aus, schreibt ihn auf einen
Zettel und gibt ihn nach rechts weiter, Person 2 rechnet nun ihren Teil
und gibt das Ergebnis weiter an Person 3 weiter, welche ihrerseits das
Endergebnis berechnet und an die "Ausabeperson" übergibt.
Sobald einmal zum Zeitpunkt 0 das ganze begonnen hat kommt nach 3*X das
erste Ergebnis an, von da an alle X Sekunden und jeder rechnet mit den
korrekten Zahlen.
Läubi .. schrieb:
> Du hast 3 Leute welche nebeneinander an einem Tisch sitzen:> Von Links gibt jetzt jemand alle X Sekunden einen Zettel auf dem die> Eingabezahlen stehen.> Person 1 rechnet jetzt den ersten Schritt aus, schreibt ihn auf einen> Zettel und gibt ihn nach rechts weiter, Person 2 rechnet nun ihren Teil> und gibt das Ergebnis weiter an Person 3 weiter, welche ihrerseits das> Endergebnis berechnet und an die "Ausabeperson" übergibt.>> Sobald einmal zum Zeitpunkt 0 das ganze begonnen hat kommt nach 3*X das> erste Ergebnis an, von da an alle X Sekunden und jeder rechnet mit den> korrekten Zahlen.
danke für deine erklärung:)
ich hab grad ein Testbench gemacht, und also wie du sagst.
Ich gehe davon aus, dass die clk hier ist nur für synchronisierung
gedacht. Die Eingangdaten sind asynchron relativ mit clk, oder?
Meine Frage ist nun, wann, wo sollte man pipeline machen?
Mein Algorithmus ist, alle jede 50ms (20Khhz) werden neue Daten kommen.
Die ganze berechnungen sollten innerhalb von 50ms/2 = 25ms
fertig sein,damit nächste Periode (50ms) die neuen Ergebnisse
aktuallisiert werden. Also es geht hier um eine
2-level-Umrichter-PWM-signalerzeugung.
Ich hab bis jetzt den Algorithmus in einzeln Process verteilt.
Die Sensitiv-Liste von Process2 sind dann die Ausgangssignals von
process1 und so weiter.
In jedem process benutze ich nur variable, damit ich wie nomale
software-programmierung (C, matlab..) behandeln kann.
Damit bekomme ich meiner Meinung nach reine Kombinatorik-Schaltung,
diese Kombinatorik-Schaltung kann vielleicht
nachher timing-problem machen, oder?
Ich warte noch auf treiberboard, mit dem ich meinen algorithmus
testen kann.Mit Testbench scheinen die ganzen Berechnungen zu gehen.
ALso noch ohne timing constraint:(.
Bis dahin versuche ich als 2.Altenativ die einzelnen processe mit
pipeline zu realisieren.
Mit pipeline stelle ich mir vor:
mit zb. 50Mhz-clk werden alle berechnungen (sequentiell) durchgeführt,
dann ist die maximal
pipeline-stage = 25ms/20ns = 1250 000. Dafür brauche ich ein
ready-signal, das am Anfange der Periode
aktiv sein sollte, damit ganze Berechnungen beginnen, wenn es fertig
ist, geht das ready-signal
wieder inaktiv und warte bis nächste Periode und so weiter.
Ist das Vorgehen richtig?
vielen dank!
Dein Vorgehen mit den Variablen ist schonmal Unsinn.
Je nachdem wie immens die Berechnungen sind landest du bei einem Design
das irgentwo bei wenigen mhz läuft und unmöglich viel Logik verbraucht.
Hardware ist nunmal nicht software und insbesondere nicht vergleichbar
was das codezeilen/leistungsbedarf-verhältnis angeht.
Zumal vieles auch gar nicht möglich ist, etwa schleifen(z.b. for) aus
der software direkt zu übernehmen.
iulius schrieb:
> Dein Vorgehen mit den Variablen ist schonmal Unsinn.>> Je nachdem wie immens die Berechnungen sind landest du bei einem Design> das irgentwo bei wenigen mhz läuft und unmöglich viel Logik verbraucht.>> Hardware ist nunmal nicht software und insbesondere nicht vergleichbar> was das codezeilen/leistungsbedarf-verhältnis angeht.>> Zumal vieles auch gar nicht möglich ist, etwa schleifen(z.b. for) aus> der software direkt zu übernehmen.
vielen dank für deine anwort!
Ich hab jetzt versucht, einzeln process mit signal zu realiseren. Hier
ist mein "PWM-Erzeugen"-process. Es macht: 14-bit counter UP-Down( also
dreiecksignal), und counter vergleicht mit dem compare-wert für
PWM-Erzeugung. Der Comparewert wird bei counter = 0 aktualisiert.
Nur für diese process, kriege ich die detailed synthesis report
(anhang), er sagt ich kann nur bis Maximum Frequency: 134.844MHz!
ereichen!
Simulation läuft, und jetzt ist meine frage:
Was kann man noch verbessern damit die frequenz größer sein kann, zb.
bis 250Mhz?