State Machine mit "Unterroutinen"
Hallo,
Ich versuche gerade mit einem FT245 Daten zu empfangen/senden via USB.
Das klappt auch soweit in der Simulation und auch auf dem Spartan 3 (via
WebIse 13.1).
Anbei ein Source in Verilog der eine State Machine implementiert (sieht
ggf. etwas komisch aus wegen Tabsize 2). Dieser erzeugt beim Implement
einige Warnings (siehe unten).
In dem Source verwende ich sowas wie State Unterroutinen (stateRead and
stateWrite) z.B. setze ich im stateIdle den stateRead um einen Wert vom
FT245 zu lesen.
Damit die State Machine weiss wo sie hinspringen soll wenn der read
durch ist setze ich auch ein stateReturn.
Beim Implement bekomme ich div. Warnings:
WARNING:Xst:1293 - FF/Latch <stateReturn_1> has a constant value of 0 in
block <usbController>. This FF/Latch will be trimmed during the
optimization process.
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch
<stateReturn_2> has a constant value of 0 in block <usbController>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch
<stateReturn_3> has a constant value of 0 in block <usbController>. This
FF/Latch will be trimmed during the optimization process.
/../
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch
<stateReturn_12> has a constant value of 0 in block <usbController>.
This FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch
<writeData_5> has a constant value of 0 in block <usbController>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch
<writeData_6> has a constant value of 0 in block <usbController>. This
FF/Latch will be trimmed during the optimization process.
WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch
<writeData_7> has a constant value of 0 in block <usbController>. This
FF/Latch will be trimmed during the optimization process.
In dem Source setze ich den stateReturn in der Next State Logic. Ein
Verschieben in die Output Logic erzeugt die gleichen Warnings.
Die Warnings versteh ich nicht so ganz. Ist sowas legal und kann man das
so machen? Oder hat das irgendwelche fiesen Nebenwirkungen?
Gruß egon
Solche Synthesewerkzeuge führen eine sehr radikale Optimierung durch,
d.h. auch auf Bitebene von Registern. Und wenn sich dabei herausstellt,
dass sich in einem Register ungenutzte Bits befinden, werden diese
entfernt und eine Warnung ausgegeben, denn vielfach deutet so etwas auf
einen Fehler hin. Wenn man aber z.B. einen Peripherieblock mit einem
externen Businterface baut, indem man einen Registerbereich mit 8/16/32
Bit anlegt, aber nicht in jedem Register jedes Bit verwendet, bekommt
man auch solch eine Warnung um die Ohren gehauen. Dies löse ich meist
so, dass ich alle beschreibbaren Register miteinander "verxodere" und
das Resultat über ein lesbares Register ausgebe.
Bei Deiner Beschreibung hast Du feste Vorgaben bezüglich der
FSM-Zustandswerte gemacht. Dies ist eine typische Vorgehensweise in der
Softwareentwicklung, aber bei programmierbarer Logik definiert man
lieber einen eigenen Datentyp für jede FSM und überlässt dem Werkzeug
die Implementierung. Dann ist es auch keine Warnung mehr wert, wenn
intern optimiert wird. Viel wichtiger ist dabei jedoch, dass das
Werkzeug sogar einen Fehler erzeugt, wenn man in der FSM einen Zustand
gar nicht verwendet. Man macht also durch die Typdefinition eine
Vorgabe, was die FSM machen soll und nicht wie sie es darstellen
soll. Das Werkzeug hat Defaulteinstellungen für die interne Darstellung
von FSMs (binär, Gray, one hot, usw.), die man aber durch Anweisungen
global oder für die einzelne FSM ändern kann. Und man bietet dem
Werkzeug die Möglichkeit, nach eigenem Gutdünken zu optimieren statt
sinnlosen strikten Vorgaben des Entwicklers zu folgen.
Da ich bisher noch nicht in Verilog, sondern nur in VHDL entwickelt
habe, gelten die obigen Ausführungen natürlich für VHDL. Ich gehe aber
sehr schwer davon aus, dass es bei Verilog genauso gehandhabt wird.
Hm.
Die Defitition der FSM-Zustandswerte ist aus den Language-Templates der
WebISE und auch im Buch "FPGA Prototyping By Verilog Examples" wird dies
so gemacht.
Gut bin kein Experte in Verilog aber ich vermute das geht nicht anders.
Vielleicht mit System Verilog das wird aber nicht von WebISE 13.1
unterstützt.
Ich habe mal zum Test One-Hot Encoding genommen, die States angepasst
und:
(* FSM_ENCODING="ONE-HOT", SAFE_IMPLEMENTATION="YES",
SAFE_RECOVERY_STATE="stateIdle" *) reg [14:0] state;
Probiert hat nichts geändert.
egon schrieb:> Die Defitition der FSM-Zustandswerte ist aus den Language-Templates> der WebISE und auch im Buch "FPGA Prototyping By Verilog Examples"> wird dies so gemacht.
Oha, ich habe mir auch gerade ein paar FSM-Beispieldefinitionen im
Internet angeschaut und bin entsetzt darüber, dass man in Verilog
offenbar wirklich so vorgehen muss. In VHDL würde ich schreiben:
1
TYPEt_stateis(IDLE,DO_THIS,DO_THAT);
2
3
SIGNALmy_state:t_state:=IDLE;
Vorteil und Nachteil gleichzeitig ist dabei, dass die dabei definierten
Werte nur Gültigkeit für die Verwendung mit Signalen/Variable des Typs
my_state besitzen. Würde man einen weiteren Datentyp definieren, dürfte
man die schon zuvor definierten Werte nochmals aufführen, und sie
besäßen dann auch nur in diesem neuen Datentyp ihre Gültigkeit.
Wenn man die Werte nach "außen" sichtbar machen möchte, benötigt man auf
jeden Fall eine explizite Abbildung auf entsprechende Bitmuster.
1
SIGNALmy_register:STD_LOGIC_VECTOR(2downto0);
2
3
...
4
5
withmy_stateselect
6
my_register<="001"whenIDLE,
7
"101"whenDO_THIS,
8
"110"whenDO_THAT,
9
"000"whenothers;
> WebISE 13.1
Was soll eigentlich WebISE sein? Ich kenne nur das Xilinx ISE Webpack.
Falls es sich um letzteres handeln sollte, wundere ich mich ziemlich
darüber, dass Du eine uralte Version statt der "aktuellen" Version 14.7
verwendest. Im Laufe der Zeit hat Xilinx immer mehr ursprünglich
kostenpflichtige Module (z.B. Microblaze, EDK, ILA) kostenfrei
beigelegt.
Andreas S. schrieb:> Dies löse ich meist so, dass ich alle beschreibbaren Register> miteinander "verxodere" und das Resultat über ein lesbares> Register ausgebe.
Das klingt nach ... ziemlich viel Umstand für einen Mangel im Tool (um
es nicht "pfuschen" zu nennen). Gibt es da keine bessere Lösung?
Mich stören an VHDL in erster Linie die vielen Warnungen, die mir Dinge
mitteilen, die (für mich) schlicht nicht relevant sind. Ist ja schön,
dass man meinen Prozess noch optimieren kann, aber davon gehe ich aus.
Übliche C-Compiler kriegen das gefühlt besser hin, mich auf die
wesentlichen Dinge hinzuweisen. ISE und Vivado ertränken mich lieber in
Rauschen.
Ja vielleicht muss ich irgendwann mal auf VHDL umsteigen. Als ich
angefangen hab war Verilog für mich einfacher zu lesen.
Der unterstütze Verilog Standard von der ISE ist von 2001 sprich uralt.
In SystemVerilog macht man die FSM-Zustandswertdefinition anscheinend
so:
enum {RED, GREEN, YELLOW} State, Next;
Sorry WebIse ist natürlich quatsch. Ich benutze Xilinx ISE WebPack.
Ich weiss die Version ist recht alt. Ich war froh das die Version dann
irgendwann endlich lief inkl. Impact und Modelsim.
Unter Windows 10 ist das doch recht fummelig (Ja gibt auch eine für W10
aber die kann kein Spartan 3 usw. usw.).
Bisher gabs es keinen Grund wechseln weil ich eh nur kleinere Sachen
mache.
egon schrieb:> Ja vielleicht muss ich irgendwann mal auf VHDL umsteigen. Als ich> angefangen hab war Verilog für mich einfacher zu lesen.
Ich habe mich ganz bewusst für VHDL statt Verilog entschieden, weil
Verilog sehr C-ähnlich aussieht. Wenn man gleichzeitig an der FPGA-Logik
und an der Firmware entwickelt, sorgt ein größerer sprachlicher
Unterschied dafür, dass der Wechsel zwischen den Welten besser gelingt.
> Der unterstütze Verilog Standard von der ISE ist von 2001 sprich uralt.
Xilinx bekleckert sich bezüglich der Sprachstandards nicht wirklich mit
Ruhm. Die Unterstützung für VHDL 2008 war in ISE sogar besser als in
Vivado, aber allmählich holt auch Vivado auf. Allerdings darf man kein
VHDL 2008 verwenden, wenn man daraus einen IP-Block generieren will.
Welch ein Murks... Ich weiß leider nicht, ob es bei Xilinx auch
entsprechende Einschränkungen bezüglich der verschiedenen
Verilog-Versionen gibt.
In dem folgenden Dokument werden ab Kapitel 5 die jeweils durch Vivado
2019.1 unterstützten Sprachelemente aufgeführt:
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_1/ug901-vivado-synthesis.pdf> In SystemVerilog macht man die FSM-Zustandswertdefinition anscheinend> so:>> enum {RED, GREEN, YELLOW} State, Next;
Aha, das ist natürlich gut.
> Sorry WebIse ist natürlich quatsch. Ich benutze Xilinx ISE WebPack.
OK.
> Ich weiss die Version ist recht alt. Ich war froh das die Version dann> irgendwann endlich lief inkl. Impact und Modelsim.> Unter Windows 10 ist das doch recht fummelig (Ja gibt auch eine für W10> aber die kann kein Spartan 3 usw. usw.).
Ja, ggf. muss man die spezielle W10-Version von ISE 14.7 installieren
und anschließend von einem anderen Rechner mit einer alten ISE 14.7 ein
paar Bibliotheken rüberkopieren. Hierzu findet man auch ein paar
Anleitungen im Netz.
> Bisher gabs es keinen Grund wechseln weil ich eh nur kleinere Sachen> mache.
Naja, es geht dabei nicht um die Größe der Projekte, sondern um die
genutzten Leistungsmerkmale.
Diese Art von Warnings kannst du meistens ignorieren. Sie zeigen nur,
dass die Synthese dein Design so optimiert hat, dass bestimmte FFs
wegfallen können, weil sie einen konstanten Wert haben. Soetwas
geschieht aber auch, wenn z.B. ein Eingang deines Moduls in einer
höheren Hierarchieebene auf eine Konstante gelegt wird. Das musst du
überprüfen. Wenn du ganz misstrauisch bist, kannst du auch eine
Post-Synthesis-Simulation machen, indem du die Netzliste als VHDL oder
Verilog rausschreibst und nochmal simulierst. Aber ich glaube, der
Aufwand lohnt sich nicht.
Ich bin nicht ganz sicher, ob man in Verilog Statemachines auf diese
Weise beschreiben muss. Es gibt auch in Verilog die Möglichkeit,
Aufzählungstypen zu definieren, soweit ich weiß.
Wie auch immer, wenn du bei der ISE bleiben willst, solltest du zu VHDL
wechseln. Im direkten Vergleich zwischen Verilog und VHDL ist letzeres
der klare Sieger. Falls es aber Verilog sein soll, würde ich zu Vivado
wechseln und Systemverilog verwenden. Vivado WebPack unterstüzt auch den
Synthese-Subset von SV. Wenn du nicht gerade objektorientierte
Verifikation machen willst, ist das völlig ausreichend.
Systemverilog ist eine massive Weiterentwicklung von Verilog und stellt
auch VHDL in den Schatten. Wobei VHDL-2018 auch schon wieder gut
aufgeholt hat. Das alte Verilog (ohne System-) ist jedenfalls ziemlich
off.
Andreas S. schrieb:> Ich habe mich ganz bewusst für VHDL statt Verilog entschieden, weil> Verilog sehr C-ähnlich aussieht. Wenn man gleichzeitig an der FPGA-Logik> und an der Firmware entwickelt, sorgt ein größerer sprachlicher> Unterschied dafür, dass der Wechsel zwischen den Welten besser gelingt.
So unterschiedlich sind die Geschmäcker. Ich bin immer froh, wenn ich
nicht dauernd zwischen zwei verschiedenen "Syntaxen" umschalten muss.
Abgesehen davon gibt es noch hinreichend genug Unterschiede zwischen SV
und C, um sie nicht verwechseln zu können.
Vancouver schrieb:> Wobei VHDL-2018 auch schon wieder gut aufgeholt hat.
Bevor VHDL-2018 in Vivado realisiert ist, friert die Hölle zu. Irgendwie
erinnert mich das an den C++-Compiler von Microsoft Visual Studio, der
häufig auch um viele Jahre hinter dem ANSI/ISO-Standard zurückgeblieben
ist; MS versucht aber offenbar, dadurch eigene, zum Standard
imkompatible Funktionen usw. durchzudrücken, so dass der Wechsel zu
einem anderen Compiler und womöglich Betriebssystem absichtlich
erschwert wird. Xilinx ist natürlich auch an Marktanteilen interessiert,
aber ich vermute, dass sie einfach mit dem dem riesigen Softwaremolloch
namens Vivado völlig überfordert sind. Dies sieht man z.B. daran, dass
zwar VHDL-2008 unterstützt wird, aber nicht für IP-Blöcke.
Das alte Verilog (ohne System-) ist jedenfalls ziemlich
> off.
Es gibt Unmengen an Verilog-Codebeständen, die man auch nicht so einfach
ersetzen kann. (Zumindest ältere) ARM-Prozessoren sind z.B. in Verilog
geschrieben. Somit wird Verilog noch ewig leben.
> Andreas S. schrieb:>> sorgt ein größerer sprachlicher>> Unterschied dafür, dass der Wechsel zwischen den Welten besser gelingt.>> So unterschiedlich sind die Geschmäcker. Ich bin immer froh, wenn ich> nicht dauernd zwischen zwei verschiedenen "Syntaxen" umschalten muss.
Oh, ich habe mich etwas ungünstig ausgedrückt. Wesentlich passender
wäre:
"... sorgt ein größerer sprachlicher Unterschied dafür, dass die
Unterscheidung zwischen den Welten besser gelingt."
@Vancouver
Ok @ignorieren. Auf dem Spartan 3 gehts ja auch.
Ich hab mir nur angewöhnt die Warnings ernst zu nehmen. Gerade wenn man
anfängt sind da doch mal ganz gute Hinweise auf mögliche Fehler.
@Aufzählungstypen die gibt es meines Wissens nur in SystemVerilog.
Als ich damals mit CPLD/FPGAs angefangen habe war mir das irgendwie too
much VHDL und dann noch in die Denke von programmierbarer Logik
reinzukommen. Zumal ich auch in unregemässigen Abständen etwas daran
gemacht habe teilweise mit einer Pause von Jahren.
Ich fand VHDL damals ziemlich geschwätzig und da lag mir Verilog einfach
mehr. Aber Geschmackssache ;)
Der Wechsel zwischen den Welten fand ich jetzt nicht so problematisch.
Aber mal schauen. Mittlerweile habe ich die programmierbare Logik-Denke
auch mehr verinnerlicht und vielleicht ist es Zeit für einen neuen VHDL
Anlauf.
Thx auf jeden Fall für die Antworten ;)
egon schrieb:> Ich fand VHDL damals ziemlich geschwätzig und da lag mir Verilog einfach> mehr. Aber Geschmackssache ;)
Ohne Emacs würde ich VHDL auch nicht schreiben wollen. Das wäre viel zu
viel Tipparbeit :-)
egon schrieb:> @Aufzählungstypen die gibt es meines Wissens nur in SystemVerilog.
Ja, du hast recht. Das Codefragment, das ich gefunden hatte, war SV. Man
muss also tatsächlich die Statecodierunug explizit machen in Verilog.
Das hat natürlich manchmal einen Vorteil. Einige Simulatoren geben für
Stateregister nicht den symbolischen Namen aus, sondern den codierten
Wert. Wenn man den nicht selbst festgelegt hat, kann man kaum
nachvollziehen, was dort passiert. Aber ist trotzdem ziemlich Oldschool.
VHDL ist deutlich geschwätziger als Verilog, und das macht z.B.
arithmetische Ausdrücke manchmal sehr lang und unleserlich. Andererseits
macht Verilog viele implizite Konvertierungen, die man kennen muss, um
die Gleichung richtig zu schreiben. Bei VHDL steht alles da, was gemacht
wird. Hat alles seine Vor- und Nachteile.
Ich persönlich versuche, in beiden Sprachen auf dem Laufenden zu
bleiben, auch deswegen, weil größere Designs häufig Mixed-Language sind.
Ich halte es für einen Fehler, sich eine Lieblingssprache zu erwählen
und den Rest zu ignorieren. Ist bei Software genauso. C/C++, Python,
Java und evtl Matlab sollte man schon halbwegs können (zumindest in
meinem Bereich), Perl wäre auch nicht verkehrt. Brainf*ck und Common
Lisp sind hingegen eher optional :-)