Hallo,
erstmal sorry für den dürftigen Threadnamen, nur mir viel nix besseres
dazu ein. Ich habe folgendes Problem, ich muss eine PLL mit 24 Bit
initialisieren und dazu CLK, DATA und STROBE entsprechend ansteuern,
also immer DATA anlegen, t_setup warten, CLK hochziehen, t_hold warten,
CLK runter und wieder von vorne, anschließend nach der letzten CLK noch
STROBE für eine entsprechende Zeit hochziehen um die Daten zu
übernehmen.
Ich war schon wieder dabei eine FSM dafür zu bauen als ich mir überlegt
habe ob es nicht auch einfacher (ohne Unmengen an Text zu schreiben)
geht. Dann hatte ich die Idee das Ganze mit einem getakteten Prozess
(Statements hintereinander mit wait until rising_edge; leider auch viel
Geschreibsel) oder einen Counter (wo ich auf das Setzen bestimmter
Bitmuster reagiere) zu machen.
Darum meine Frage, wie würdet Ihr das machen, oder eventuell noch ne
Idee die ich übersehen hab und einfacher ist?
Tim T. schrieb:> Dann hatte ich die Idee das Ganze mit einem getakteten Prozess> (Statements hintereinander mit wait until rising_edge; leider auch viel> Geschreibsel)
Mehrere wait until rising_edge in einem Prozess wird dein Sythesizer
nicht unterstützen.
Tim T. schrieb:> oder einen Counter (wo ich auf das Setzen bestimmter> Bitmuster reagiere) zu machen.
Das ist auch eine FSM, nur mit Zählerwerten als Zustandsnamen.
Tim T. schrieb:> wie würdet Ihr das machen
FSM. Wieviel "Geschreibsel" das ist, hängt davon ab, was deine FSM macht
bzw. wie geschickt du es implementierst.
VHDL hotline schrieb im Beitrag #6138587:
> Mehrere wait until rising_edge in einem Prozess wird dein Sythesizer> nicht unterstützen.
Kommt auf den Synthesizer und die Aufgabe an. Im Prinzip ging das mit
ISE schon vor 10 Jahren:
http://www.lothar-miller.de/s9y/archives/47-wait-im-Prozess.htmlTim T. schrieb:> oder einen Counter (wo ich auf das Setzen bestimmter Bitmuster reagiere)> zu machen.
Dein "Counter (wo du auf das Setzen bestimmter Bitmuster wartest)" ist
im Prinzip auch nur eine längere Schreibweise für "FSM". Also kannst du
es auch gleich mit einer FSM machen, die die nötigen Zustände und
Pegelwechsel so abhandelt, dass es auch nach einem halben Jahr noch
jeder versteht.
Sieh dir mal die SPI-Schnitte als Grundlage an:
http://www.lothar-miller.de/s9y/categories/45-SPI-Master
Das Modell dort so abgespeckt, dass nur dein "Modus" abgehandelt wird,
und du bist fertig.
Lothar M. schrieb:> VHDL hotline schrieb im Beitrag #6138587:>> Mehrere wait until rising_edge in einem Prozess wird dein Sythesizer>> nicht unterstützen.> Kommt auf den Synthesizer und die Aufgabe an. Im Prinzip ging das mit> ISE schon vor 10 Jahren:> http://www.lothar-miller.de/s9y/archives/47-wait-im-Prozess.html
Stimmt, die Seite hab ich irgendwann schon mal gesehen^^
> Tim T. schrieb:>> oder einen Counter (wo ich auf das Setzen bestimmter Bitmuster reagiere)>> zu machen.> Dein "Counter (wo du auf das Setzen bestimmter Bitmuster wartest)" ist> im Prinzip auch nur eine längere Schreibweise für "FSM". Also kannst du
Das es alles irgendeine Art FSM ist, ist mir schon klar, dachte nur als
Counter wäre es weniger zu Texten.
> es auch gleich mit einer FSM machen, die die nötigen Zustände und> Pegelwechsel so abhandelt, dass es auch nach einem halben Jahr noch> jeder versteht.
Glaube dass ist das Killerargument, ich hab oft schon am nächsten Morgen
Probleme mit sowas...
> Sieh dir mal die SPI-Schnitte als Grundlage an:> http://www.lothar-miller.de/s9y/categories/45-SPI-Master> Das Modell dort so abgespeckt, dass nur dein "Modus" abgehandelt wird,> und du bist fertig.
Habs jetzt erstmal so gelöst, muss mir nur noch was für den Reset
überlegen:
Tim T. schrieb:> CLK, DATA und STROBE entsprechend ansteuern,> also immer DATA anlegen, t_setup warten, CLK hochziehen, t_hold warten,> CLK runter und wieder von vorne, anschließend nach der letzten CLK noch> STROBE für eine entsprechende Zeit hochziehen um die Daten zu> übernehmen.
Das kling für mich sehr nach einem einfachen Schieberegister mit
zusätzlichem Latch wie das SN74HC595.
Ich hänge hier mal Code ran der 8 Bits überträgt und dann einen Puls für
das Latch ausgibt. Das kannst du sehr wahrscheinlich einfach anpassen.
Gustl B. schrieb:> Tim T. schrieb:>> CLK, DATA und STROBE entsprechend ansteuern,>> also immer DATA anlegen, t_setup warten, CLK hochziehen, t_hold warten,>> CLK runter und wieder von vorne, anschließend nach der letzten CLK noch>> STROBE für eine entsprechende Zeit hochziehen um die Daten zu>> übernehmen.>> Das kling für mich sehr nach einem einfachen Schieberegister mit> zusätzlichem Latch wie das SN74HC595.
Jop, dürften 3 Schieberegister hintereinander mit Latch sein.
> Ich hänge hier mal Code ran der 8 Bits überträgt und dann einen Puls für> das Latch ausgibt. Das kannst du sehr wahrscheinlich einfach anpassen.
Genau sowas ging mir als Counter Variante durch den Kopf, aber stimmt
schon die Lesbarkeit leidet da etwas...
VHDL hotline schrieb im Beitrag #6138587:
> Tim T. schrieb:>> wie würdet Ihr das machen>> FSM. Wieviel "Geschreibsel" das ist, hängt davon ab, was deine FSM macht> bzw. wie geschickt du es implementierst.
Einen Editor benutzen, der einem beim Schreiben von VHDL unterstützt,
damit das meiste von diesem "Geschreibsel" der Editor einfügt und nicht
von dir getippt werden muss.
Mein persönlicher Favorit ist immer noch der VHDL Modus von Emacs, aber
es gibt noch andere Editoren, die einem anständig unterstützen können
(Die Editoren die mit den EDA Tools mitkommen sind alle schlecht, wohl
weil kein Entwickler bei diesen Firmen diese nutzen würden).
Tim T. schrieb:> Habs jetzt erstmal so gelöst, muss mir nur noch was für den Reset> überlegen:
Wow, das war jetzt ja echt viel Geschreibsel... ;-) .
Falls du einen Xilinx-FPGA verwendest und die FSM nur einmal beim
FPGA-Start laufen soll, kannst du den Resetzustand der FSM gleich in die
Signaldeklaration schreiben, also
1
signalstate:t_state:=start;
Deine strobe-Zustände am Ende kannst du sinnvollerweise auch mit einem
Zähler zusammenfassen, wie vorher beim hold.
VHDL hotline schrieb im Beitrag #6138733:
> Tim T. schrieb:>> Habs jetzt erstmal so gelöst, muss mir nur noch was für den Reset>> überlegen:>> Wow, das war jetzt ja echt viel Geschreibsel... ;-) .
Ging mir allgemein darum wie man das am besten angeht, zugegeben hier
wars diesmal nicht so schwer wobei ich mir immernoch was für einen
sinnvollen Reset überlegen muss.
>> Falls du einen Xilinx-FPGA verwendest und die FSM nur einmal beim> FPGA-Start laufen soll, kannst du den Resetzustand der FSM gleich in die> Signaldeklaration schreiben, also>>
1
>signalstate:t_state:=start;
2
>
Ist bekannt und auch so im Source, aber ganz so einfach ist es hierbei
nicht, wollte schon zwischendurch einen Reset auslösen können.
>> Deine strobe-Zustände am Ende kannst du sinnvollerweise auch mit einem> Zähler zusammenfassen, wie vorher beim hold.
Da es nur 4 Clocks waren, fand ich es so einfacher, aber sonst ja.
Was soll der Reset denn überhaupt machen? Ich könnte mir vorstellen,
dass der Reset einen definierten Defaultwert ausgibt und in die PLL
schreibt.
Aber dazu braucht man doch keinen Reset in dieser Komponente sondern
übergibt ihr einfach den auszugebenden Defaultwert. Ich sehe da keinen
Grund für einen Reset.
VHDL hotline schrieb im Beitrag #6138766:
> Tim T. schrieb:>> wobei ich mir immernoch was für einen>> sinnvollen Reset überlegen muss.>> Tim T. schrieb:>>
1
>>whendone=>idt_strobe<='0';
2
>>state<=done;
3
>if(reset=1)then
4
>state<=start;
5
>endif;
6
>
>> Vielleicht so? Wobei Gustl B. ja schon geschrieben hat, dass die> Resetfunktion nicht so richtig klar ist.
Wenn ich mich darauf beschränke das der Reset nur ausgelöst werden darf
wenn die Initialisierung druch ist, dann ja, einsynchronisiert ist der
Reset eh, aber was mache ich wenn es einen Grund für einen Reset gibt
bevor das Ding fertig initialisiert ist?
Das Zweite ist, wie reagiert die PLL darauf wenn während der
Initialiserung einfach nochmal von vorne angefangen wird, leider
schweigt sich das Datenblatt dazu aus, ich gehe aber einfach mal von
einem 24 Bit Schieberegister aus, wo die Bits des ersten
Teilinitialisierung einfach hinten Rausfallen und dann die neuen Daten
gelatcht werden. Ein gezieltes Reset über einen dedizierten Pin ist
leider nicht möglich, der entsprechende Pin der PLL ist nicht zum FPGA
geführt.
Tim T. schrieb:> wollte schon zwischendurch einen Reset auslösen können.
Was soll der Reset bewirken? Woher kommt der Reset? Was passiert sonst
noch bei dem Reset? Kannst du statt eines Resets nicht einfach das FPGA
neu laden?
Tim T. schrieb:> leider schweigt sich das Datenblatt dazu aus
Leider wissen wir nicht, welches Datenblatt du meinst. Ausser, dass es
wahrscheinlich eine PLL von IDT ist...
Lothar M. schrieb:> Tim T. schrieb:>> wollte schon zwischendurch einen Reset auslösen können.> Was soll der Reset bewirken? Woher kommt der Reset? Was passiert sonst> noch bei dem Reset? Kannst du statt eines Resets nicht einfach das FPGA> neu laden?
Hauptgrund (eigentlich der Einzige) für einen Reset könnte ein Fehler
auf einer der Versorgungsspannungen sein, die werden kontinuierlich
getestet und melden das dem FPGA, der daraufhin eine entsprechende
Behandlung ausführt.
Im Zweifelsfall wird auch der FPGA neu geladen, ja aber nicht unbedingt
bei allen Fehlern, nur wenn die FPGA Versorgung betroffen ist, aber dann
ist es eh egal.
Lothar M. schrieb:> Tim T. schrieb:>> leider schweigt sich das Datenblatt dazu aus> Leider wissen wir nicht, welches Datenblatt du meinst. Ausser, dass es> wahrscheinlich eine PLL von IDT ist...
ICS307M-02LF von IDT
https://www.idt.com/document/dst/307-02-datasheet
OK, in dem Datenblatt steht auch der entscheidende Satz: "The ICS307 can
be reprogrammed at any time during operation."
Gustl B. schrieb:> Über #PDTS könntest du den Chip selbst doch auch resetten wenn ich das> richtig sehe?!
Das ist eine Gute Frage, egal wie oft ich den 2. Satz über den Powerdown
auch lese, ich komme einfach nicht dahinter was er eigentlich sagen
will...
Satz 1:
"When the PDTS pin is pulled low, the chip will enter the power-down
mode, where the output clocks are tri-stated and the rest of the chip is
powered down."
Satz 2:
"The chip can be programmed during power-down mode, however, if the chip
is programmed during operation and enters power-down mode, the registers
will return to their settings and not reset when exiting power-down mode
(PDTS pin is pulled high)."
Wobei ich mittlerweile eine Tendenz dazu hab, das der Chip nach dem
Powerdown wieder die vorherigen Werte annimmt und nicht resettet wird,
aber sicher bin ich mir da nicht.
Aber unabhängig davon ist der PDTS auch nicht am FPGA, also eigentlich
auch egal.
Tim T. schrieb:> ich gehe aber einfach mal von einem 24 Bit Schieberegister aus, wo die> Bits des ersten Teilinitialisierung einfach hinten Rausfallen und dann> die neuen Daten gelatcht werden.
Es werden die zuletzt eingeschobenen 24 Bit gelatcht. Die "Note" im
"Programming Example" zeigt das dann auch an:
1
As show in Figure 2, after these 24 bits are clocked into the ICS307-02, taking STROBE high will send this data to the internal latch and the CLK output will lock within 10 ms.
2
3
Note: If STROBE is in the high state and SCLK is pulsed, DATA is clocked directly to the internal latch...
Es gibt ein SCLK-taktgesteuertes Schieberegister und ein pegelabhängiges
STROBE-Latch. Im Schieberegister werden einfach die Daten
durchgeschoben. Wenn STROBE während des Schiebens aktiv ist, ist das
Latch transparent und jedes Bit bringt neue Überraschungen.
Lothar M. schrieb:> Tim T. schrieb:>> ich gehe aber einfach mal von einem 24 Bit Schieberegister aus, wo die>> Bits des ersten Teilinitialisierung einfach hinten Rausfallen und dann>> die neuen Daten gelatcht werden.> Es werden die zuletzt eingeschobenen 24 Bit gelatcht. Die "Note" im> "Programming Example" zeigt das dann auch an:>
1
> As show in Figure 2, after these 24 bits are clocked into the ICS307-02,
2
> taking STROBE high will send this data to the internal latch and the CLK
3
> output will lock within 10 ms.
4
>
5
> Note: If STROBE is in the high state and SCLK is pulsed, DATA is clocked
6
> directly to the internal latch...
7
>
> Es gibt ein SCLK-taktgesteuertes Schieberegister und ein pegelabhängiges> STROBE-Latch. Im Schieberegister werden einfach die Daten> durchgeschoben. Wenn STROBE während des Schiebens aktiv ist, ist das> Latch transparent und jedes Bit bringt neue Überraschungen.
Ja, den Teil hatte ich auch gesehen (und das Bild vom Block Diagram),
daher auch die Idee das einfach immer die letzten 24 Bit vor dem Strobe
übernommen werden könnten. Manchmal gehen die Amerikaner mir mit ihrer
unpräzisen Ausdrucksweise schon auf den Wecker... Hätten ja auch einfach
schreiben können das die letzten 24 in den Chip getakteten Bits beim
Strobe übernommen werden, evtl. mit dem Hinweis das wenn weniger als 24
Bits in den Chip getaktet wurden die fehlenden Bitstellen im
Schieberegister mit undefiniertem Müll gefüllt sind.
Also werde ich jetzt in jeden State wohl einfach ne Reset Abfrage machen
und dann jeweils zum Start State verzweigen, wobei das natürlich wieder
genau die Art vom stupidem rumtexten ist, die ich gerne vermeiden würde.
Oder hat jemand dazu noch ne elegantere Idee?
Tim T. schrieb:> Also werde ich jetzt in jeden State wohl einfach ne Reset Abfrage machen
Ich würde das Verhalten von Signalen in Prozessen vorteilhaft anwenden
und es basierend auf deinem Code einfach so machen:
Oh man, klar wieder total das Brett vorm Kopf gehabt. Danke Dir
Und im übrigen auch den Anderen hier im Thread, insbesondere auch die
Lösung mit dem Zähler von Gustl B. werde ich mir bei Gelegenheit mal
genauer anschauen.
Die Idee mit dem Zähler ist Folgende:
Der Zähler(n-1 downto 0) ist n Bits lang. Und zählt nach oben.
Jetzt werden die obersten Zähler(n-1 downto n-X) Bits als Adresse für
das auszugebende Bit, und das Bit Zählers(n-X-1) als "Takt" verwendet.
Die Bits Zähler(n-X-2 downto 0) sind dann noch übrig und dienen als
Taktteiler. Dann kann man den Zähler schön bequem mit Systemtakt
betreiben und bekommt trotzdem einen deutlich niedrigeren Takt für das
Schieberegister.
Beispiel:
Du willst 24 Bits ausgeben. Das sind also schon 5 Bits für die Adresse.
Dann das eine Bit für den Takt.
Und dann haben wir jetzt als Beispiel 100 MHz Systemtakt und wollen aber
nur maximal 8 MHz Takt für das Schieberegister. Das bedeutet wir teilen
die 100 durch 8, bekommen 12,5 und nehmen die nächste Zweierpotenz, 16,
das sind 4 Bits. Das 4. Bit vom LSB aus ist also der neue Takt (das sind
dann 6,25 MHz) und die 3 niederwertigsten Bits sind die Taktteiler.
Der Zähler muss insgesamt mindestens 5+4=9 Bits lang sein.
Es bietet sich an einen Alias für die Adresse zu verwenden und intern
ein Register das bei einem Startsignal den Inhalt überreicht bekommt. Da
der Zähler bei mir nach oben zählt, aber das MSB zuerst ausgegeben
werden soll, habe ich intern das TX_Reg als ein 0 to 23 beschrieben.
Zusätzlich gibt es noch ein Ready als Ausgang der sagt wann
fertiggeschoben ist.
Das gibt es jetzt hier als Anhang, es wird nach 200 ns für einen Takt
lang Start auf '1' gesetzt und die Daten x"ABCDEF" übergeben. Danach
wird herausgeschoben und am Ende einmal das Latch gepulst.
Damit man auch beobachten kann was passiert gibt es mehrere Bausteine:
1. Die Komponente die die Daten bekommt mit dem Startsignal und die dann
herausschiebt. Ich habe sie SR_24Bit genannt.
2. Den IC Baustein, also das Schieberegister in das hineingeschoben
wird, das ist quasi dein PLL Baustein, hier SR_24Bit_IC genannt.
3. Die SR_24Bit_bench, das ist die Testbench die die Komponente im FPGA
mit dem IC verbindet und der Komponente einmal die 24 Datenbits
überreicht.
Die ZIP Datei enthält das schön als Xilinx Vivado Projekt.