Manchmal fällt es wirklich schwer einen passenden Betreff zu finden.:)
Es geht um folgendes:
Gegeben ist FPGA das mit VHDL "programmiert" wird.
Es gibt insgesamt 3 Processe.
Ein Reciever, Transmitter und Main.
WIe der Name sagt, Reciever empfäng die 12 Bit langen Befehl.
Sobald die Übertragung fertig ist, setzt Reciever INSTRFLG auf 1. Das
sagt den Main-Process, dass er jetzt diese 12 Bit in einen Befehl
decodieren soll.
Falls Bit 11 =1, werden diese 12 Bit an den Process "transmitter"
übergeben.(SET_REF='1')
Transmitter versendet insgesamt 16 bit seriell, und sobalt er fertig
ist soll er die Kommunikation unterbrechen.
Die Idee ist, dass Transmitter den INSTRFLG wierder auf 0 setzt
(RESET=0), und somit wird die Befehlausführung in MAIN beendet.
Jetzt habe ich folgende Meldung:
Error (12014): Net "INSTRFLG", which fans out to "SET_VREF", cannot be
assigned more than one value
Error (12015): Net is fed by "EXE:C1|FLG"
Error (12015): Net is fed by "TRANSMITTER:C2|RESET"
Auf INSTRFLG greift somit sowohl RECIEVER als auch TRANSMITTER, ich
denke da liegt das Problem.
Mir ist irgendwie nicht ganz klar, wieso der INSTRFLG nicht durch
Transmitter geändert werden kann, oder wie ich meine Idee richtig
realisieren kann.
Anbei der Quellcode, stark verkürzt für den besseren Übersicht...
>Ich weiss, das ist viel Code, ...
Deswegen soll langer Code auch als Anhang gepostet werden.
Steht bei jedem Anfang eines neuen Postings:
"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"
Und dann: Das schreibt sich "Receiver" auch wenn es sich "Reßiwer"
spricht.
Du kannst nicht ohne Weiteres von zwei Stellen aus ein Signal "ändern".
Das würde ja realisiert als eine "Leitung" die von zwei Treibern
angesteuert wird. Wenn ein Treiber ein High treibt, und der andere ein
Low...
Es gibt beim std_logic dafür die "schwachen" Zustände 'H' und 'L' (im
Gegensatz zu den starken '0' und '1') sowie den hochohmigen Zustand 'Z'.
Damit könntest du das realisieren.
Aber bevor du dich verkünstelst: Nimm doch einfach zwei Signale! Ein
'start' in die eine Richtung, ein 'done' in die andere.
Na, den START Signal muss ich ja trotzdem mit DONE auf Null setzen,
damit ich später wieder starten kann.
zB
If(DONE='1') THEN
START='0'
END IF;
Ist das dann nich das Gleiche?
Böser Kommunist schrieb:> Na, den START Signal muss ich ja trotzdem mit DONE auf Null setzen,> damit ich später wieder starten kann.>> zB> If(DONE='1') THEN> START='0'> END IF;>> Ist das dann nich das Gleiche?
Nee, weil du das in dem gleichen Prozess machst wie das setzen.
Christian R. schrieb:> Nee, weil du das in dem gleichen Prozess machst wie das setzen.
Nennt sich dann Handshake. Und der zeitliche Ablauf der nötigen 4
Schritte ist so:
1
a b c d
2
_____ ______
3
Start ___| ... |_______
4
___
5
Done _________...____| |_____
a Start wird signalisiert, das Senden beginnt
b Senden fertig wird mit Done signalisiert
c Start wird deaktiviert, wenn Done aktiv ist
c Done wird deaktiviert, wenn erkannt wird, dass Start inaktiv ist
Ich sag' jetzt mal nichts weiter zur speichernden(!) Variable INDEX, das
steht alles schon im Beitrag "Variable vs Signal". Aber
das mit der Sensitivliste muss ich doch sagen: FLAG und DA_SL sind
zuviel. Der Prozess ist nur auf CLK sensitiv...
Hier wäre ein Schieberegister evtl. die bessere Lösung gegenüber einem
Multiplexer. Besonders in einem FPGA...
1
TX<=(OTHERS=>DATA(INDEX));---SET BIT
Ein Tipp: sieh dir einfach an, wie das im Inneren eines Mikrocontrollers
gemacht wird. Das Datenblatt gibt das meist schon ausreichend viel
Informationen. Und uCs sind schon lang am Markt, da konnte die Evolution
schon einige Fehldesigns ausbügeln....
Danke für die Antworten. Handshake werde ich noch ausprobieren. Die
Sensitivliste ist noch veraltet, ich habe vorher dort was anderes
geschrieben.
Den Unterschied zwischen Variablen und Signale ist mir noch nicht ganz
klar, oder besser gesagt, wieso so viele gegen variablen sind. Ich
verwende die Variablen einfach für bessere Übersichtlichkeit: alle
processbezogene Sachen werden auch im Process deklariert.
Außerdem habe ich im Buch gelesen, dass Variablen sofort aktualisiert
werden, während Signale auf das Ende des Process warten müssen.
Im Buch stand übrigens nichts gegen Variablen an sich.
Böser Kommunist schrieb:> ist mir noch nicht ganz klar, oder besser gesagt, wieso so viele> gegen variablen sind.
Weil Variablen von Anfängern komplett falsch verwendet werden, weil sie
den Sinn und Nutzen dahinter (im Bezug auf die Synthese) nicht verstehen
und die fehlerhafte Nutzung zu massenhaften Problemen führt.
> Ich verwende die Variablen einfach für bessere Übersichtlichkeit:
Aus genau dem Grund verwende ich keine. 90% meiner VHDL-Codes kommen
vollständig ohne Variablen aus. Selbst in Testbenches brauche ich oft
keine.
> alle processbezogene Sachen werden auch im Process deklariert.
Was sind nach Deiner Vorstellung "prozessbezogene Sachen"?
> Außerdem habe ich im Buch gelesen, dass Variablen sofort aktualisiert> werden, während Signale auf das Ende des Process warten müssen.
Ohweh, Ich sehe sie schon vor dem geistigen Auge, die armen notleidenden
Signale, die auf die Barikaden gehen, weil sie immer bis zum Ende des
Prozesses dumm in der Ecke rumhängen und nicht aktualisiert werden,
während die offenkundig bevorzugten Variablen schon munter weiterrechen
dürfen. Wo bleibt die Gerechtigkeit beim VHDL?
Jetzt mal im Ernst: Du hast schon verstanden, dass das so sein muss,
dass Signale erst im nächsten Takt ihren Wert kriegen dürfen und man
innen drin immer die alten Werte hat? Erinnere Dich mal an die
Datenverarbeitungsvorlesung, erstes Semester, wo es um die Zustände
Z(t+1) = f(Z(t) ..) ging, das ist genau das. Variablen sind im
synthetisierbaren Code nur ein Hilfsmittel zum vereinfachten formulieren
von Zwischenergebnissen, sonst nix.
> Im Buch stand übrigens nichts gegen Variablen an sich.
Der Autor ist wahrscheinlich vom Förderverein zur Intensivierung der
Variablennutzung in HDL-Codes geschmiert worden. Jedenfalls ist der
Nachname des Autors schon mal nicht Miller. Das steht fest. :-)
Warte mal bis übernächstes Jahr: Dann kommt das vom EU-Ministerium für
Gleichstellungsfragen geförderte VHDL 2015. In dem müssen dann auch die
Signale sofort aktualisiert werden und dürfen nicht mehr benachteiligt
werden. Das wird schick!
> Was sind nach Deiner Vorstellung "prozessbezogene Sachen"?
z.B. interne Counter, Hilfsvariablen, etc. die nur für den Process
wichtig sind.
> Errinnere Dich mal an die Datenverarbeitungsvorlesung
Habe so eine Vorlesung nicht gehabt:)
Das Buch, das ich für den Anfang gelesen habe war "Circuit Design with
VHDL" Volnei A. Pedroni.
>weil sie
den Sinn und Nutzen dahinter (im Bezug auf die Synthese) nicht verstehen
Kannst du bitte kurz beschreiben wofür die Variablen gedacht sind, und
zu welchen Problemen diese führen können. Evtl. mit einem simplem
Beispiel?
> Kannst du bitte kurz beschreiben wofür die Variablen gedacht sind,
Für Zwischenergebnisse. Aber nicht zum Speichern. Variablen werden also
immer am Prozessanfang initialisiert.
> und zu welchen Problemen diese führen können.> Evtl. mit einem simplem Beispiel?
Ich hatte vier Posts weiter oben einen Link zum Thread Variable vs.
Signal eingefügt. Bitte jetzt Zutreffendes ankreuzen:
[ ] ich habe den Link zum Thread nicht gesehen
[ ] ich habe das, was im Thread beschrieben ist, nicht verstanden
[V] ich habe das, was im Thread beschrieben ist, nicht verstanden
So wie ich es verstanden habe, die Signalzuweisung ist sequenziel und
die Variabelnzuweisung parralel, sprich sofort.Etwa so...
Was ich nicht ganz verstehe, in deinem Bsp:
1
>process(din)
2
>variablevar:std_logic;
3
>begin
4
>res1<=var;
5
>var:=din;
6
>res2<=var;
7
>endprocess;
8
>
Ist das nicht selbsverständlich, dass res1 den alten Wert erhält, weil
die "var" aktualisierung erst danach erfolgt?
Obwohl, wenn Variablen parralel arbeiten, sollte das nicht passieren.
ehm...ich bin durcheinander.
Böser Kommunist schrieb:> in deinem Bsp: ....> Ist das nicht selbsverständlich, dass res1 den alten Wert erhält, weil> die "var" aktualisierung erst danach erfolgt?
Ich beantworte dir diese Frage nicht, weil sie rein akademisch ist.
Du musst dir eines klar machen: die Simulation arbeitet ausschließlich
mit der Sensitivliste, der Synthese ist die Sensitivliste schnurzegal.
Letztendlich darf dich aber nur die Synthese interessieren, denn nur mit
der Synthese kannst du ein Design in Hardware umsetzen. Du musst also
deinen VHDL-Code so schreiben, dass er das Verhalten deiner Harware
richtig simuliert. Mit diesem neuerworben Wissen siehst du dir diesen
Prozess nocheinmal an.
Und du erkennst, dass die (Verhaltens-)Simulation falsch sein muss,
weil der Simulator nur bei einer Änderung von din den Prozess neu
berechnet, (und so res1 ein von din abhängiges, speicherndes Verhalten
vorgaukelt), die Synthese aber erkennt, dass die Signale einfach
geradeaus durchverdrahtet werden.
Und du wirst diesen Prozess nie richtig simulieren können (also so, wie
sich die Hardware verhalten wird), weil die die Variable var nicht in
die Sensitivliste (zur Neuberechnung des Prozesses) aufnehmen kannst.
Böser Kommunist schrieb:> So wie ich es verstanden habe, die Signalzuweisung ist sequenziel und> die Variabelnzuweisung parralel, sprich sofort.Etwa so...
Keine Ahnung was auch immer da irgendwer mit sequentiell oder parallel
meint. Ich glaube, diese Begriffe dienen nur der Verwirrung von
Anfängern. In der Hardware ist letztlich alles parallel realisiert, also
immer da...
Nochmal kurz zum Mitschreiben:
Variablen sind dort sinnvoll und geeignet, wo eine komplizierte
Berechnung in kleine Schritte aufgeteilt werden soll/muss. Aber immer
steht am Anfang des Prozesses eine Zuweisung an die Variable:
http://www.lothar-miller.de/s9y/archives/78-Bubblesort.htmlhttp://www.lothar-miller.de/s9y/archives/84-Binaer-nach-BCD-mit-1-Takt-pro-Stelle.htmlhttp://www.lothar-miller.de/s9y/archives/67-Vektor-nach-BCD-kombinatorisch.htmlhttp://www.lothar-miller.de/s9y/archives/29-Division-in-VHDL.htmlhttp://www.lothar-miller.de/s9y/archives/73-Wurzel-in-VHDL.htmlhttp://www.lothar-miller.de/s9y/archives/68-Graycode-Umwandlung.html
Und so richtig austoben kann man sich mit Variablen, Schleifen und
sostwas in Testbenches, denn die müssen ja nicht synthetisierbar sein:
http://www.lothar-miller.de/s9y/archives/75-PS2-Tastatur.html
> in deinem Bsp: ....> Ist das nicht selbsverständlich, dass res1 den alten Wert erhält, weil> die "var" aktualisierung erst danach erfolgt?
Ganz klar NEIN, denn wie Du selber richtig geschrieben hast, bekommen
Signale erst am Ende des Prozesses ihre Werte. Beide res stehen dann auf
din.
mike schrieb:> Ganz klar NEIN, denn wie Du selber richtig geschrieben hast, bekommen> Signale erst am Ende des Prozesses ihre Werte.
Aber jetzt kommts: sie bekommen den letzten Wert, der ihnen /bis
dahin/ zugewiesen wurde. Probiers einfach mal aus...
> Beide res stehen dann auf din.
Das gilt nur für das Syntheseergebnis, aber nicht für die Simulation!
Zur Abkürzung ein Link auf die Lösung im
Beitrag "Re: Variable vs Signal"
Lothar Miller schrieb:>> So wie ich es verstanden habe, die Signalzuweisung ist sequenziel und>> die Variabelnzuweisung parralel, sprich sofort.Etwa so...> Keine Ahnung was auch immer da irgendwer mit sequentiell oder parallel> meint. Ich glaube, diese Begriffe dienen nur der Verwirrung von> Anfängern. In der Hardware ist letztlich alles parallel realisiert, also> immer da...
Ich würde mal stark annehmen, dass sich die Begriffe auf den zeitlichen
Ablauf des Prozesses beziehen. Die Variablenzuweisung wäre dann aber
sequenziell, weil die Zeitebene eine Rolle spielt, wärend die
Signalzuweisung parallel ist, weil die Zeitabhängigkeit nicht exisitert:
Alle Signale werden zur gleichen Zeit, nämlich beim Übergang in die
nächste Zeitscheibe geändert, egal, wie sie sequeniell angeordnet sind.
Dies ist quasi parallel, da es zwischen diesen Signalzuweisungen keine
Zeit vergeht. Die Darstellung an sich macht schon Sinn. Allerdings gibt
es anschaulichere Darstellungen des Sachverhaltes.
Das Beispiel oben zeigt aber wieder einmal dass genau hier der Hae im
Pfeffer liegt. Man muss sich bei der Nuzung von Variablen über die
Sequenz Gedanken machen, bei Signalen nicht - jedenfalls nicht innerhalb
einer Zeitebene.
Böser Kommunist schrieb:> Also Fazit ist: Nur Signale verwenden?
Soweit wie möglich.
Und wenn schon Variablen verwendet werden sollen, dann werden die vor
der Verwendung initialisiert und nur zum Ablegen von Zwischenergebnissen
verwendet. Ein paar sinnvolle Beispiele habe ich aufgezeigt und das hier
ist auch ein Musterbeispiel für die Verwendung von Variablen:
http://www.lothar-miller.de/s9y/archives/86-Einsen-im-Vektor-zaehlen.html
Aber eine speichernde Variable ist für mich von vorn herein suspekt.
Böser Kommunist schrieb:> WIe der Name sagt, Reciever empfäng die 12 Bit langen Befehl.> Sobald die Übertragung fertig ist, setzt Reciever INSTRFLG auf 1. Das> sagt den Main-Process, dass er jetzt diese 12 Bit in einen Befehl> decodieren soll.
Statt der vorgeschlagenen Handshakesache könntest Du auch Dein INSTRFLG
sofort wieder auf '0' setzten. Damit wird es zu einem
Instruction_enable.
Dein Main-Process und andere müssen dann nur aktiv werden, wenn das Bit
'1' ist. Damit das Konzept richtig funktioniert, dürfen die
Instructionen nicht schneller kommen, als sie verarbeitet werden können.
Jürgen Schuhmacher schrieb:> die armen notleidenden> Signale, die auf die Barikaden gehen
Du solltest öfters einen Clown frühstücken (bzw. zum Abendbrot
verspeisen) (+1 gefällt mir :-)
Duke