Meine Frage zuerst: Braucht ein Altera Max2 CPLD einen Takt der ein Minimum nicht unterschreiten darf? Hintergrund: Ich habe mir in Qartus eine Uhr gemalt. Darin sind ein paar 4017 Dekadenzähler, die ich aus dem Datenblatt abgemalt habe. Auf meinem China Max2 board ist ein 50MHz Oszillator. Einen ca 1s Takt für die Uhr erzeuge ich mit einem 32bit Zähler wo ich das 24. Bit als Eingang für die 4017 nehme. Als Ausgabe habe ich ein kleines board mit 4x 10 LEDs gemacht. Wenn ich nun den Takt vom 50MHz Oszillator der an Pin_12 ist verwende, funzt alles wunderbar. Die ersten Leds zählen so jede Sekunde eins höher und dann die 10er Sekunden usw. Wie bei einer Uhr. Das Max2 board hat an PIN_62 einen Eingang. Wenn ich dort nun einen Takt von 2Hz anlege, und das 2. Bit vom Zähler nehme, clk auf PIN_62 ändere, zählen meine 4017 aber nicht. Wie gesagt, es zählt wunderbar wenn ich den 50MHz Oszillator an pin12 nehme und den Vorteiler benutze. Warum funzt es nicht wenn ich einen 2Hz Takt anlege? Ich habe ins Datenblatt geguckt (nein die 300 Seiten habe ich nicht alle gelesen) und diesen thread gefunden Beitrag "Takt zwingend notwendig für einen CPLD" Leider bin ich zu blöd darin die Information zu finden die ich brauche.
Thomas G. schrieb: > Braucht ein Altera Max2 CPLD einen Takt der ein Minimum nicht > unterschreiten darf? Nein. Thomas G. schrieb: > Warum funzt es nicht wenn ich einen 2Hz Takt anlege? Was "funzt nicht"? Was erwartet du und was passiert stattdessen?
:
Bearbeitet durch Moderator
Nö, beim Tackt gibt es kein Minimum. Es befindet sich ja kein DRAM oder ähnliches in den CPLDs, die einen internen Refresh benötigen. Wenn Du rein kombinatorische Sachen machst, d.h. auf Flipflops komplett verzichtest brauchst Du sogar gar keinen Takt. Dann benimmt sich der CPLD halt so wie ein Logic Gate.
Den 2 Hz Takt generiere ich mit einem Arduino der bei 3.3V an derselben Versorgung hängt. Sieht auf dem Oszi auch ok aus. 40kHz habe ich ebenso getestet. Bei 2Hz, und Vorteiler 2 durch den Zähler, erwarte ich, daß der erste 4017 zähler langsam höher zählt, also wie ein 4017 immer ein Ausgang auf high ist und dann der 2. Zähler nach Überlauf von 0 auf 1 zählt. Außerdem erwarte ich, daß beim Einschalten meines Konstruktes alle Zähler auf 0 stehen und die 0 LED jeweils an ist, weil die pins für preset auf weak pullup gesetzt sind. Dem ist aber nicht so, beim ersten Zähler ist irgend eine Stelle an, z.B. 8. Beim 2. Zähler keine, obwohl bei einem 4017 immer eine Stelle an sein müßte. Dann zählt der erste Zähler irgendwie, aber nicht 1, 2, 3... sondern 8, 2, 6... Ich habe mittlerweile den Vorteiler auf counter0 gestellt, so daß eigentlich jeder Taktimpuls durchgereicht werden müßte. Ich nehme stark an, daß das Problem vor dem Computer sitzt, habe aber im Moment keine Strategie was ich zuerst überprüfen sollte. Wie gesagt, bei 50MHz Takt und runtergeteiltem ca 1s Takt für die 4017 geht alles wie oben beschrieben.
Thomas G. schrieb: > Sieht auf dem Oszi auch ok aus. Hast du dir die Flanke des Signals direkt am CPLD Eingang auch schon mal hochaufgelöst angeschaut (als im ns-Bereich, nicht im s-Bereich) Ist der PIN_62 deines boards ein dedizierter CLK-Eingang? Ist der IO-Pegel für diesen Eingang auf 3,3V eingestellt?
@Achim S. 62 und 64 sowie 12 und 14 sind CLK beim Max2 mit 100 pins. Nein, so stark habe ich nicht reingezoomt, da ich annahm, daß der Arduino anständige Pegel liefert. Werde das aber morgen nachholen. edit: I/O war auf 2.5V, habe die Eingänge jetzt auf 3.3V LCMOS gestellt. Vorher hatte ich das an einem Pendel was per 74hc123 Monoflop einen 75ms langen Puls schickt, die machen eigentlich anständige Pulse. Hier kommen noch 2 Bilder wie ich den 4017 gemalt habe. Dafür habe ich die Vorlage von NXP für einen 74hc4017 genommen, die CMOS Varianten sind geringfügig anders, mit NAND am Ausgang statt NOR. Bei meinem Konstrukt, habe ich die D-flipflops aus Quartus genommen, die haben keinen negierten Q Ausgang. Daher das NOT am Q. Außerdem haben die einen Reset active low, im Unterschied zum "original". Deshalb habe ich da einen NOT davor gesetzt. Ich hänge die Bilder hier an.
:
Bearbeitet durch User
Thomas G. schrieb: > Braucht ein Altera Max2 CPLD einen Takt der ein Minimum nicht > unterschreiten darf? > Ich habe ins Datenblatt geguckt (nein die 300 Seiten habe ich nicht alle > gelesen) Nein, die timings umfassen nur 28 Seiten und auf Seite 20 findet sich eine klare Angabe zur maximalen Periode wiedergegeben als "Global clock high time" resp. "Global clock low time" - jeweils die Max-Spalte.
C. A. Rotwang schrieb: > Nein, die timings umfassen nur 28 Seiten und auf Seite 20 findet sich > eine klare Angabe zur maximalen Periode wiedergegeben als "Global clock > high time" resp. "Global clock low time" - jeweils die Max-Spalte. Sorry, link auf die 28 pages hiermit nachgereicht: https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/hb/max2/max2_mii51005.pdf
Es könnte sein das dein Problem auch hier liegt: Thomas G. schrieb: > Einen ca 1s Takt für die Uhr erzeuge ich mit einem 32bit Zähler wo ich > das 24. Bit als Eingang für die 4017 nehme. Du teilst anscheinend einen Takt mit einem Zähler herunter und nimmst das Signal nun als Takt für deinen 4016 Nachbau her - Kann er das so machen im CPLD? im FPGA sicher nicht! Hier ein Artikel dazu, siehe auch "clock enable" https://www.mikrocontroller.net/articles/Taktung_FPGA/CPLD
:
Bearbeitet durch User
Damit wäre die Frage von C. A. Rotwang beantwortet und auch bewiesen, minimum clock braucht es, maximum nicht, also kann man es so langsam clocken wie man will. Für alle die, die wie ich, seit Jahrzehnten Probleme mit Lesen und Schreiben haben, hänge ich das Bild von Seite 20 hier an. @Bernhard K. Ja, der Teiler war ein Behelf, weil ich erstmal das Pendel oder externe clk weglassen wollte. Es funzt so auf cyclone4 und max2 mit onboard Oszillator bei 50MHz. Es ist auch keine clock in dem Sinne, sondern nur Impulse die gezählt werden, diese gehen nur an einen Einzigen Eingang des Konstruktes.
:
Bearbeitet durch User
Thomas G. schrieb: > Damit wäre die Frage von C. A. Rotwang beantwortet Die Frage wurde schon deutlich vorher beantwortet. Du wolltest es (wie dein biblischer Namenskollege) nur nicht glauben... ;-) > und auch bewiesen Um es kurz zu fassen: wenn da keine Taktmanger beteiligt sind, dann hast du prinzipiell kein Problem mit einem langsamen Takt. Das hilft dir jetzt aber trotzdem nicht, weil deine Schaltung ja auch mit der (fehlenden) Datenblattangabe nicht funktioniert. Du musst zudem sowieso noch anschauen, ob du einen der globalen Takteingänge als Taktquelle verwendest oder einen stinknormalen IO-Pin, dessen Standard (und auch das Verhalten mit/ohne Schmitttrigger) noch eingestellt werden muss. https://www.altera.com/content/dam/altera-www/global/en_US/pdfs/literature/an/an428.pdf Thomas G. schrieb: > Es ist auch keine clock in dem Sinne, sondern nur Impulse die gezählt > werden, diese gehen nur an einen Einzigen Eingang des Konstruktes. Und wenn dann noch mehr damit gemacht werden soll, stellt sich die Frage, ob du nicht besser auf ein synchrones Design umsteigen solltest... Thomas G. schrieb: > Leider bin ich zu blöd darin die Information zu finden die ich brauche. Da steht auch nach längerem Suchen eine Information nicht drin, die ich zumindest interessant fände: die Mindest-Flankensteilheit. Denn so wie ich das Datenblatt lese, kann ich den Baustein auch mit einem Sinus takten. Thomas G. schrieb: > Vorher hatte ich das an einem Pendel was per 74hc123 Monoflop einen 75ms > langen Puls schickt, die machen eigentlich anständige Pulse. Und wie lange ist die Zuleitung zu diesem Takt? Letztlich gilt als Takt nur das, was der Takteingang sieht. Und wenn das "Taktsignal" wegen ungünstiger Leitungsführung klingelt wie eine Fahrradglocke, dann sieht dein Flipflop gleich ein paar Takte pro Flanke. Deshalb meine Frage, was denn da "nicht funktioniert"...
Der externe Taktgenerator ist an einem der globalen clk pins dran, es ist ein Arduino auf 3.3V mit 5cm Strippen die gesteckt sind. Alternativ habe ich einen 74hc123 monoflop der auch an 5cm Strippen dran war. Ich werde heute abend folgendes testen und dann berichten: 1. den 4017 block einzeln mit diesem externen Signal, nicht das ganze Zählkonstrukt wovon ich hier noch ein Bild anhänge. Wenn Ihr noch andere Ideen habt, laßt es mich bitte wissen.
Thomas G. schrieb: > es ist ein Arduino auf 3.3V mit 5cm Strippen die gesteckt sind Mal dumm gefragt: Die Masse hast Du mit angeschlossen?
Die Frage war nicht dumm, das ist mir schon manchmal passiert mit der Masse, hier aber nicht. Zum Beweis hänge ich ein Photo an. Die Masse kommt vom Max2 board, ebenso 3.3V für den Arduino der auf der weißen Platine rechts ist. Im Vordergrund die LEDs die an den 4017 hängen. Ich habe jetzt den 4017 nochmal ganz neu in ein neues Projekt gesteckt, allerdings nur einen einzigen, und alle Ausgänge an die LEDs gehängt wie vorher. Das Verhalten ist wie gestern. Ohne Takt, sollte beim Einschalten die LED an Q0 leuchten, es leuchtet aber gar keine. Das könnte nun ein Hinweis sein, daß mein Zähler nicht richtig funktioniert. Mit Takt, zählt er dann nicht regelmäßig sondern 2,5,8, usw. Hier die Bilder meines Taktes. Für mich als Laien sieht das ok aus, aber vielleicht seht Ihr das anders. Mein nächster Schritt wird jetzt sein, wieder diesen Vorteiler vorschalten und mit onboard 50MHz testen. Wenn das ordnungsgemäß läuft, werde ich einen externen Quarzoszillator an pin62 hängen und Euch berichten.
Fehler ist eingegrenzt. Auch bei runtergeteiltem 50MHz Takt, zählt der einzelne 4017 nicht wie er soll. Er zählt einmal von 0 bis 9, danach springt er aber auf 5 und zählt bis 8, und wieder auf 5 usw. Also stimmt irgendwas mit meinem Zählernachbau nicht. Komischerweise zählt er aber im anderen Projekt mit der kompletten Uhr korrekt bis 9, dann wieder auf 0 usw. Ich habe ja dieselbe Datei nur kopiert. Kann es sein, daß diese timings sowas verursachen?
:
Bearbeitet durch User
Bernhard K. schrieb: > Simuliert hast du deinen 4017 Nachbau nicht? So ein asynchrones Gebastel lässt sich doch gar nicht sinnvoll simulieren. Thomas G. schrieb: > Kann es sein, daß diese timings sowas verursachen? Ja. Aber der Witz ist, dass du kaum eine Chance hast, das in den Griff zu bekommen. Es ist mehr oder weniger Zufall, ob das Ding läuft oder zickt. Wenn ich schon den asynchronen kombinatorischen Reset sehe. In VHDL wäre das ein Kündigungsgrund.... Habe ich eigentlich schon auf den Beitrag "Re: kruder Fehler bei FPGA-Programmierung (ISE WEBpack-Schematic)" hingewiesen?
:
Bearbeitet durch Moderator
Die Flanke sieht ganz gut aus. Das Problem liegt wahrscheinlich im Code. Ich würde empfehlen die Schaltung umzustricken: Alles was im FPGA läuft: voll synchron mit 50 MHz und alle Signale von außen: mit zwei FF einsynchronisieren. Der "Sekundentakt" wird als asynchrones Signal betrachtet und da drauf machst Du eine Flankenerkennung: http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung Duke
Früher ging das doch auch mit 1Hz und den 4017. Entweder sind die 4017 nicht so aufgebaut wie im Datenblatt gemalt, oder ich habe da einen Fehler drin. Das Projekt ist eigentlich ziemlich sinnfrei, es wird eine Nixieuhr mit nicht gemultiplexten Nixies, und Pendel als clock source. Das soll auch spinnerkompatibel sein für Leute die sich vor Erdstrahlen, Elektrosmog und Aliens fürchten, und die schnellste Schwingung soll 50Hz vom Trafo sein. Ich zeichne jetzt nochmal einen neuen 4017 mit NAND gates wie im TI Datenblatt, wenn die auch nicht gehen, dann versuche ich es in vhdl oder verilog zu beschreiben. Meine Idee dazu ist, ein Zähler, und dann immer gucken bis 10s, 60s, 3600s usw rum sind, und bei true einen der 10 Ausgänge anschalten. Mir ist auch klar, daß die Uhr durch die Pendelclock dauernd falsch gehen wird. Das will ich durch einen kleinen Trick beheben, wo jede Stunde mal ein ESP aufwacht, sich die Zeit vom Internet, oder GPS holt, und den Zähler "nachstellt". Was haltet Ihr von meinen tollen Ideen'?
Thomas G. schrieb: > Früher ging das doch auch mit 1Hz und den 4017. Entweder sind die 4017 > nicht so aufgebaut wie im Datenblatt gemalt So ist es. Nur ein echter 4017 verhält sich wie ein echter 4017. Dem macht ein 5ns Glitch am Reset-Pin oder am Takteingang vermutlich nichts arg viel aus. Aber dem 4017 im FPGA eben schon. > und die schnellste Schwingung soll 50Hz vom Trafo sein. Du darfst ihnen aber nicht sagen, dass in einer steilen 20ns-Flanke überaus hohe Frequenzen stecken. > Ich zeichne jetzt nochmal einen neuen 4017 mit NAND gates wie im TI > Datenblatt, wenn die auch nicht gehen, dann versuche ich es in vhdl oder > verilog zu beschreiben. Dein Problem ist nicht die Art der Beschreibung, sondern die asynchrone Art der Schaltung. Ich hatte z.B. den /asynchronen kombinatorischen Reset/ als absoluten Show-Stopper erwähnt: wenn dort beim Weiterzählen ein kurzer Glitch auftritt, dann kann es passieren, dass nur einzelne Flipflops des Zählers zurückgesetzt werden --> dein Zähler hüpft mehr oder weniger wild durcheinander... > Mir ist auch klar, daß die Uhr durch die Pendelclock dauernd falsch > gehen wird. Das will ich durch einen kleinen Trick beheben, wo jede > Stunde mal ein ESP aufwacht, sich die Zeit vom Internet, oder GPS holt, > und den Zähler "nachstellt". > Was haltet Ihr von meinen tollen Ideen'? Ich habe seinerzeit die Pendeluhr so gebaut, dass das Pendel komplett unabhängig und komplett analog vor sich hingeschwungen hat und die Uhr komplett digital und komplett unabhängig davon die Zeit angezeigt hat. Funktioniert auch heute noch tadellos.
:
Bearbeitet durch Moderator
Ja, ich sehe das ein, die Gatter sind einfach sauschnell, vielleicht haben die da auch im "echten" 4017 diese Buffer und doppelten NOT nicht umsonst drin. Bei mir soll das Pendel ja auch analog schwingen, bzw. macht es nun auch, nachdem ich 30 Jahre später die Jakubasch ewige Pendelschaltung zum 2. Mal aufgebaut habe. An den Transistor habe ich dann einen monoflop gehangen der einen 100ms Puls macht, weil ja zig Impulse kommen wenn der Magnet über die Spule schwingt. Frage: Wie hast Du gelöst, daß das Pendel genau auf 1s schwingt? Meins ist 25cm und macht 2Hz. Meine Idee ist, die Aufhängung so in der Art einer Schieblehre zu machen, daß man auf 1/10mm verschieben kann. Eine M3 Schraube die man raus und reindreht wäre vielleicht einfacher.
Thomas G. schrieb: > Frage: Wie hast Du gelöst, daß das Pendel genau auf 1s schwingt? Gar nicht. Das schwingt irgendwie halbwegs "harmonisch" vor sich hin. Und die Uhrzeit kommt aus dem Quarz. Weil sowieso nur Minuten und Stunden angezeigt werden, fällt die fehlende Korrelation zwischen Pendel und Anzeig nicht auf... ;-) Ein anderer Versuch war, die Uhr mit dem Sekundentakt mit einem Magneten "anzuschubsen". Das ging aber (wie man sich hinterher leicht erklären kann) mit unregelmäßiger Pendelamplitude einher.
Was, du hast das Pendel nur zur Zierde, ohne Funktion. Das is ja noch viel schlimmer als mein CPLD Johnson Zähler, und vollkommen unsportlich. Dann hast Du es sicher auch noch in Nord Süd Richtung aufghängt.
Thomas G. schrieb: > Dann hast Du es sicher auch noch in Nord Süd Richtung aufghängt. Nicht mal das, sondern einfach und unspektakulär von oben nach unten... ;-)
Ich habe jetzt noch den 4017 von TI mit Nand Gates nachgemalt, und der geht genauso schlecht bzw. nicht mit meinem 2Hz Takt, mehr habe ich dann nicht noch getestet. Dann habe ich den folgenden Verilogzähler mit demselben Takt getestet, und es zählt wunderbar binär. module simple_counter (input clock , output reg [31:0] counter_out); always @ (posedge clock)// on positive clock edge begin counter_out <= #1 counter_out + 1;// increment counter end endmodule// end of module counter Vielleicht verraten die 4017 Hersteller nicht das ganze Geheimnis und die Dinger sind doch komplizierter aufgebaut als im Datenblatt gezeichnet.
Thomas G. schrieb: > Vielleicht verraten die 4017 Hersteller nicht das ganze Geheimnis und > die Dinger sind doch komplizierter aufgebaut als im Datenblatt > gezeichnet. Oder sie sind einfach so viel primitiver als deine programmierbare Hardware, dass sie ein kleines asynchrones Geflicker garnicht erst bemerken und sich davon auch nicht aus dem Takt bringen lassen...
Du könntest folgendes Probieren: An den Zähleingang zwei Inverter hintereinander malen ( in der Hoffnung, dass sie nicht weg optimiert werden ). Vielleicht beruhigt das das Signal. Oder den Trick verwenden, wie er in VHDL gemacht wird: ein kleines Schiebregister mit zwei Bit einfügen und damit den Taktwechsel detektieren, wenn das Schieberegister "01" zeigt. Das Schieberegister könnte auch aus zwei D-FF bestehen, die mit dem internen Takt "getaktet" werden.
chris schrieb: > Oder den Trick verwenden, wie er in VHDL gemacht wird: > ein kleines Schiebregister mit zwei Bit einfügen und damit den > Taktwechsel detektieren Das ist die lange Schreibweise für "synchrones Design". Denn womit wird das Schieberegister denn getaktet? > Oder den Trick verwenden, wie er in VHDL gemacht wird Das hat mit VHDL primär nichts zu tun. Es ist reinste Schaltungstechnik. Und theoretisch wären da drei Flipflops nicht von Nachteil: 1 zum Synchronisieren und 2 für die Flankenerkennung. chris schrieb: > An den Zähleingang zwei Inverter hintereinander malen ( in der Hoffnung, > dass sie nicht weg optimiert werden ). Vielleicht beruhigt das das Signal. Das Problem liegt nicht am Takt. Der sieht ja vorbildlich aus. Das Problem liegt wie mehrfach erwähnt am asynchronen, nicht reproduzierbaren Design zusammen mit der Tatsache, dass ein CPLD pfeilschnell ist und sich kurze Glitches fehlerhaft auswirken können.
:
Bearbeitet durch Moderator
>Das Problem liegt nicht am Takt. Das ist der Takt außen gemessen, oder? Man kann das interne Signal wieder nach außen routen und dann das Oszi drann hängen. Ich meine so ein ähnliches Experiment schon mit dem MACHX02 gemacht zu haben. Das Ergebnis war: Das FPGA sieht gar kein vernünftiges Signal.
chris schrieb: > Man kann das interne Signal wieder nach außen routen und dann das Oszi > drann hängen. Allemal besser, seine Zeit so zu verbringen als draußen im Regen zu stehen. > Ich meine so ein ähnliches Experiment schon mit dem MACHX02 gemacht zu > haben. Das Ergebnis war: Das FPGA sieht gar kein vernünftiges Signal. Wenn das FPGA bei einem solchen Eingangssignal ohne Überschwinger und Klingeln und mit einer völlig linearen Rampe nichts Vernünftiges erkennt, dann ist es kaputt. Und dann weiß man wenigstens, das man es tauschen muss...
Ich habe jetzt schon ein vhdl zusammengeschustert was den code http://www.lothar-miller.de/s9y/categories/48-Code-Schnipsel vor dem Lauflicht halbwegs kopiert und mir hoffentlich die Ausgänge so schaltet wie der 4017. Wenn ich den heute Nachmittag zuhause getestet habe, will ich dann noch Reset und overflow einbauen. Jetzt habe ich mal 2 Fragen: 1. Woher kommt das Bild mit den Flipflops http://www.lothar-miller.de/s9y/categories/18-Flankenerkennung Wird das von Quartus oder Xilinx aus dem code generiert (und wenn ja wo kann man das machen) oder hast Du das gemalt? 2. Gibt es sowas wie ne command line IDE für Altera, sowas wie platformio für microcontroller? http://platformio.org/ Ziel ist, das Ganze auch über ssh bedienen zu können, weil ich hier zwar Quartus habe, aber kein fpga board. P.S. Das mit dem Takt wieder ausgeben an einem anderen Pin is ne gute Sache, werde ich mir merken.
:
Bearbeitet durch User
Thomas G. schrieb: > Jetzt habe ich mal 2 Fragen: > 1. Woher kommt das Bild mit den Flipflops > Wird das von Quartus oder Xilinx aus dem code generiert Das ist der von der ISE aus der Netzliste des Synthesetools erzeugte RTL-Schaltplan. Den gibt es auch beim Quartus: https://www.google.de/search?q=rtl+schematic+quartus
Ich habe jetzt die Grundfunktion des Zählens aus diesem L Miller code kopiert, und es zählt wie es soll.
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity newsw4017 is |
6 | Port ( clk : in STD_LOGIC; |
7 | leds : out STD_LOGIC_VECTOR(9 downto 0)); |
8 | end newsw4017; |
9 | |
10 | architecture Behavioral of newsw4017 is |
11 | signal cnt : integer range 0 to 9 := 0; |
12 | signal c : integer range 0 to 2 := 0; -- bei 2Hz |
13 | signal t : std_logic := '0'; |
14 | signal x : integer range 0 to 9 := 0; |
15 | |
16 | begin
|
17 | process begin |
18 | wait until rising_edge(clk); |
19 | |
20 | if (cnt<9) then cnt <= cnt+1; |
21 | else cnt <= 0; |
22 | end if; |
23 | |
24 | case cnt is |
25 | when 9 => leds <= "1000000000"; -- Lauflichtmuster hier ablegen |
26 | when 8 => leds <= "0100000000"; |
27 | when 7 => leds <= "0010000000"; |
28 | when 6 => leds <= "0001000000"; |
29 | when 5 => leds <= "0000100000"; |
30 | when 4 => leds <= "0000010000"; |
31 | when 3 => leds <= "0000001000"; |
32 | when 2 => leds <= "0000000100"; |
33 | when 1 => leds <= "0000000010"; |
34 | when 0 => leds <= "0000000001"; |
35 | when others=>leds <= "0101010101"; |
36 | end case; |
37 | end process; |
38 | |
39 | |
40 | end Behavioral; |
Nun habe ich wieder 2 Fragen: 1. -- Signal konvertieren und casten und an LEDs ausgeben -- leds <= std_logic_vector(to_unsigned(x,10)); Hier nahm ich an, daß dann die LED entsprechend angeschaltet wird, aber es wird über mehrere LEDs ein BCD code ausgegeben. Deshalb habe ich das nicht verwendet sondern case aus dem anderen Beispiel genommen. Gibts da eine kürzere Möglichkeit kein BCD auszugeben sondern die "Zahl". 2. Wenn ich es dann geschafft habe, den 4017 in einen Block zu bringen, wo auch carry und Reset richtig funzen, kann ich dann diesen Block so nehmen wie im angehängten Bild, oder wird das auch wieder zu assynchron, verboten, Kündigungsgrund usw. und ich muß die ganze Uhr vhdl beschreiben? Ich frage das, weil ich die Uhr zu Weihnachten haben will, und meine Vhdl-künste eher bescheiden sind.
:
Bearbeitet durch Moderator
Thomas G. schrieb: > aber es wird über mehrere LEDs ein BCD code ausgegeben. Es wird einfach die Binärzahl ausgegeben. Ist ja klar, > Hier nahm ich an, daß dann die LED entsprechend angeschaltet wird Das ginge vielleicht so:
1 | :
|
2 | leds<="0000000000"; |
3 | leds(cnt)<='1'; |
4 | :
|
Thomas G. schrieb: > Ja, danke, das geht so. Damit hast du auch schon eine überaus nützliche Eigenart von signalen in Prozessen kennengelernt: sie behalten ihren Wert über alle Berechnungen hinweg bis zum Prozessende. Und erst am Prozessende wird der zuletzt für sie berechnete Wert zugewiesen. Das Signal leds(cnt) ist also nach "aussen" nie '0', auch wenn es im Code für eine Zeile so aussieht, weil ja allen leds eine '0' zugewiesen wird....
Ja, danke Lothar, da hast Du sogar meine Frage beantwortet ich hier nicht gestellt habe, weil ich nicht zur Last werden will. Ich habe dann statt
1 | leds<="0000000000"; |
2 | leds(cnt)<='1'; |
doch lieber die case statements genommen, weil ich nun auch ns glitches vermeiden will, denn das Schalten aller gates auf 0 und dann eins auf 1 würde ja auch Zeit brauchen. Aber wenn du sagst, daß ein CPLD anders als ein Microcontroller schaltet, dann wird das wohl so sein. Sehr rätselhaft diese Dinger :-)
:
Bearbeitet durch User
Thomas G. schrieb: > Aber wenn du sagst, daß ein CPLD anders als ein Microcontroller > schaltet, dann wird das wohl so sein. Obacht: das kommt nicht vom CPLD/FPGA, sondern es ist einfach eine "Eigenheit" von VHDL, die das Verhalten von Signalen in Prozessen betrifft. Wenn man sich das aber mal vergegenwärtigt hat, dann ist genau dieses Verhalten genial, weil jedes Signal während des gesamten Prozesses seinen Eingangswert "behält" und erst am Ende des Prozesses (oder beim nächsten wait) den zuletzt zugewiesenen Wert annimmt. Weil diese gesamten Berechnungen eines Prozesses aber "gleichzeitig" (also in Nullkommanichts Picosekunden) passieren, wird das Ganze nicht wie in einem Mikrocontroller als Schrittschaltwerk nach dem Motto "erst eins, dann zwei" ausgeführt, sondern es wird direkt in einen Multiplexer umgesetzt. Deshalb beschreibst du mit VHDL Hardware. Im Fall der zwei Zeilen hier wurde ein Multiplexer beschrieben, der natürlich auch ein anderes Signal auf eine LED schalten könnte:
1 | :
|
2 | leds <= (others=>'0'); |
3 | leds(cnt) <= eingang; |
4 | :
|
:
Bearbeitet durch Moderator
Kannst Du mir noch erklären wie das entschieden wird, wann genau die Ausgänge geschaltet werden. Ich habe die angehängte newsw4017.vhd Uhr zusammengeschrieben, und will dann (z.B. für die Stellfunktion oder timer) mal sowas machen wie auf Deiner Seite hier gezeigt. In einem anderen Prozess, soll z.B. ein button eingelesen werden und die Uhr gestellt oder als timer umgeschaltet werden. Dort schreibst Du: "Der nächste logische Schritt ist dann, die Erzeugung des Fortschaltimpulses in einem eigenen Prozess zu erzeugen."
1 | library IEEE; |
2 | use IEEE.STD_LOGIC_1164.ALL; |
3 | use IEEE.NUMERIC_STD.ALL; |
4 | |
5 | entity BinaryLED is |
6 | Port ( clk : in STD_LOGIC; |
7 | leds : out STD_LOGIC_VECTOR(7 downto 0)); |
8 | end BinaryLED; |
9 | |
10 | architecture Behavioral of BinaryLED is |
11 | |
12 | signal c : integer range 0 to 12499999 := 0; -- 0,25s bei 50MHz fosc |
13 | signal t : std_logic := '0'; |
14 | signal x : integer range 0 to 255 := 0; |
15 | |
16 | begin
|
17 | process begin |
18 | wait until rising_edge(clk); -- warten bis zum nächsten Takt |
19 | if (c<12499999 ) then -- 1/4 Sekunde bei 50MHz |
20 | c <= c+1; -- wenn kleiner: c weiterzählen |
21 | t <= '0'; |
22 | else -- wenn Zählerende erreicht: |
23 | c <= 0; -- Zähler c zurücksetzen |
24 | t <= '1'; -- Flag für Tick setzen |
25 | end if; |
26 | end process; |
27 | |
28 | process begin |
29 | wait until rising_edge(clk); -- warten bis zum nächsten Takt |
30 | if (t='1') then -- sind schon wieder 0,25 sec vorbei? |
31 | if (x<255) then -- ist Zähler x schon "oben" angekommen |
32 | x <= x+1; -- nein: Zähler x hochzählen |
33 | else
|
34 | x <= 0; -- ja: zurücksetzen |
35 | end if; |
36 | end if; |
37 | end process; |
38 | |
39 | -- Signal konvertieren und casten und an LEDs ausgeben
|
40 | leds <= std_logic_vector(to_unsigned(x,8)); |
41 | end Behavioral; |
Ich verstehe das so, daß die beiden Prozesse gleichzeitig ausgeführt werden, und dann am Ende die LEDs gesetzt wenn t==1(was ja vom vorherigen Takt kam), und dann warten sie wieder auf clk. Warum geht das in meiner Beschreibung nicht. Wenn ich die Ledssetzung aus dem Prozess rausnehme und vor "end Behavioral;" stecke, dann kommen jede Menge Fehlermeldungen : Error (10028): Can't resolve multiple constant drivers for net "leds[9]" at newsw4017.vhd(97) Ich sehe da keinen Unterschied zu Deinen Beispielen. Oder macht man das ganz anders und schmeißt das alles in einen Prozeß?
Thomas G. schrieb: > verstehe das so, daß die beiden Prozesse gleichzeitig ausgeführt werden Huh, da hast du ein grundlegend falsches Verständnis. Denn da wird nichts irgendwie "ausgeführt", sondern da wird Hardware draus gemacht. So z.B. für die Zähler natürlich einzelne Flipflops mit Weiterschaltlogik. Und diese Hardware ist natürlich parallel und gleichzeitig vorhanden. > und dann am Ende die LEDs gesetzt Und die Verbindung zu den LED ist natürlich auch immer vorhanden... Und so musst du dir das dann auch denken: eine VHDL Datei wird (wie auch eine Verilog-Datei) nicht "von oben her durchlaufen", sondern aus jedem Prozess, aus jeder nebenläufigen Zuweisung wird Hardware gemacht und die dann miteinander verdrahtet. > Error (10028): Can't resolve multiple constant drivers for net > "leds[9]" at newsw4017.vhd(97) Da wurden zwei Ausgänge (Treiber) von Logik oder Fiplops Nur das eine Signal leds[9] bringt einen Fehler? Mit dem angehängten Code? Damit bekomme ich diese Meldungen:
1 | WARNING:Xst:1426 - The value init of the FF/Latch dhourleds_0 hinder the constant cleaning in the block newsw4017. |
2 | You should achieve better results by setting this init to 1. |
3 | WARNING:Xst:1710 - FF/Latch <hourleds_0> (without init value) has a constant value of 1 in block <newsw4017>. This FF/Latch will be trimmed during the optimization process. |
4 | WARNING:Xst:1895 - Due to other FF/Latch trimming, FF/Latch <hourleds_1> (without init value) has a constant value of 0 in block <newsw4017>. This FF/Latch will be trimmed during the optimization process. |
5 | INFO:Xst:2261 - The FF/Latch <dhourleds_1> in Unit <newsw4017> is equivalent to the following FF/Latch, which will be removed : <dhourleds_2> |
Irgendwie klar: dhour wird gar nie verändert... Aber prinzipiell tut sich ja mit der angehängten Testbench schon was, wenn auch das Ding noch Probleme mit dem Weiterzählen der Zehenerminuten hat... Logisch geht das schief:
1 | if (dmin<5) then min <= dmin+1; |
Ich habe deinen Code mal begradigt und auch diese seltsamen Bereiche für die Zähler korrigiert, du hast da gern den obligatorischen OffByOne Fehler drin: 0..9 sind schon 10 Schritte und 0..5 schon 6 (mach da mal einen File-Compare). Jetzt tut die Uhr...
:
Bearbeitet durch Moderator
Danke Lothar das sieht sehr schön aus, ich hatte es gestern nur mit ssec und dsec auf der hardware probiert, das lief, heute habe ich dann die Minuten und Stunden dazugemacht. Und ja, ich mußte einen diff machen um "OffByOne" zu sehen. Du erklärst das ziemlich oft hier im Forum, gelesen hatte ich das schon öfters, nur nicht kapiert. Ich habe noch so einen Fehler wie von Dir aufgezeigt im dhours Zähler gefunden und korrigiert. Was ich noch nicht kapiert habe, wohin die Ausgabe der LEDs nun kommen soll. Bei mir kopiliert es nur, wenn die mit im process ist. Wenn ich die aber wie in einigen Deiner Beispiele auf http://www.lothar-miller.de/s9y/categories/48-Code-Schnipsel nach dem "process" mache, also wie hier:
1 | ...
|
2 | end if; |
3 | end process; |
4 | |
5 | -- Signal konvertieren und casten und an LEDs ausgeben
|
6 | leds <= std_logic_vector(to_unsigned(x,8)); |
7 | end Behavioral; |
dann kommen viele Fehler wie Error (10028): Can't resolve multiple constant drivers for net "leds[9]" at newsw4017.vhd(82) Error (10029): Constant driver at newsw4017.vhd(83) Error (10028): Can't resolve multiple constant drivers for net "leds[8]" at newsw4017.vhd(82) Error (10028): Can't resolve multiple constant drivers for net "leds[7]" at newsw4017.vhd(82) Error (10028): Can't resolve multiple constant drivers for net "leds[6]" at newsw4017.vhd(82) usw. Mir ist das eigentlich egal, solange die Uhr geht, aber ich würde gern den Unterschied wissen - wenn es denn da einen gibt. Warum einmal LED Ausgabe im process und bei anderen Beispielen außerhalb process. Und warum gehts bei mir nicht außerhalb?
Thomas G. schrieb: > Warum einmal LED Ausgabe im process und bei anderen Beispielen außerhalb > process. Und warum gehts bei mir nicht außerhalb? Weil du leds vermutlich auch zusätzlich im Prozess manipulierst... Diese nebenläufige Anweisung "ausserhalb" des Prozesses ist eigentlich auch nur die Kurzform eines Prozesses. Vollständig ausgeschrieben würde das als Prozess so aussehen:
1 | -- Signal konvertieren und casten und an LEDs ausgeben
|
2 | process (x) |
3 | begin
|
4 | leds <= std_logic_vector(to_unsigned(x,8)); |
5 | end process; |
Und damit ist dann klar: du treibst auf das Signal leds aus 2 Prozessen/Quellen/Treibern. Innerhalb 1 einzigen Prozesses ist die mehrfache Zuweisung kein Problem, denn "die letzte Signalzuweisung innerhalb eines Prozesses gewinnt!" Erinnerst du dich, das hatten wir im Beitrag "Re: Braucht ein CPLD einen schnellen Takt?" Zeig doch mal genau die VHDL-Beschreibung, die bei dir zu Problemen führt. Die oben Gepostete hat diese Probleme ja nicht.
:
Bearbeitet durch Moderator
Danke nochmal. Ich werde jetzt verstehen, daß der letzte Eintrag gewinnt, und alles was vorher im Prozeß mit dem Signal passiert wird nicht "ausgeführt" Der Vollständigkeit halber, hänge ich die Version an, die nicht kompiliert. Es geht wie gesagt wenn die LED Zuweisungen mit im ersten Prozeß am Ende stehen. Aber wenn das nach dem Prozeß auch nur ein Prozeß ist, dann soll es mir egal sein ob die LEDs nun im vorhergehenden oder diesem geschaltet werden. Bitte keine Zeit mehr darauf verschwenden. Meldungen in grün: Info (10041): Inferred latch for "dhourleds[0]" at newsw4017.vhd(93) Info (10041): Inferred latch for "dhourleds[1]" at newsw4017.vhd(93) ... und in rot Error (10028): Can't resolve multiple constant drivers for net "leds[9]" at newsw4017.vhd(76) Error (10029): Constant driver at newsw4017.vhd(77) Error (10028): Can't resolve multiple constant drivers for net "leds[8]" at newsw4017.vhd(76) Error (10028): Can't resolve multiple constant drivers for net "leds[7]" at newsw4017.vhd(76) ... usw.
So etwas geht nicht, weil wie gesagt jede nebenläufige Zuweisung wie ein eigener Prozess ist --> mehrfache Zuweisungen. Schreibe einfach mal alles in den einen Prozess... ;-)
Thomas G. schrieb: > Und ja, ich mußte einen diff machen um "OffByOne" zu sehen. Du erklärst > das ziemlich oft hier im Forum, gelesen hatte ich das schon öfters, nur > nicht kapiert. Das folgende Lehrmaterial war mir sehr hilfreich, vielleicht hilft es dir auch. Es geht um die unterschiedliche Sichtweisen des Ausdrucks "auf 3". Das entspricht einem Off-By-One Error. https://www.youtube.com/watch?v=vKePn-57zAA&t=1m55s
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.