Hat hier eventuell jemand noch ein oder zwei einfache Beispiele für Xilinx-CPLDs in VHDL zur Hand? Ist für mich ziemliches Neuland, und die Beispiele im ISE enthalten nur den Johnson-Counter als Beispiel für CPLDs, alles andere ist für FPGAs und übersteigt mein derzeitiges Vorstellungsvermögen von HDLs. ;-)
Das war mein erstes Projekt, was ich mit einem XC9536 gemacht habe: http://www.jcwolfram.de/projekte/vhdl/parout16/main.php Jörg
Meinst du mit Beispiele kurze Ausschnitte in VHDL oder komplette lauffähige Projekte? Für ersteres schau mal auf der Seite von Lothar Miller, er hat da etliche schöne Sachen gesammelt: http://www.lothar-miller.de
Nanu? Versucht ihr euch jetzt in programmierbarer Logik? Oder ist das privat? Schau dir doch mal eine der Logic-Analyser-Implementierungen hier an, die laufen ja auf CPLDs. Ansonsten ist vom reinen VHDL ja kein Unterschied zwischen FPGA und CPLD. Erst bei so speziellen Sachen wie DCM, FIFOs usw. unterscheidet sich das....
Benedikt K. schrieb: > Meinst du mit Beispiele kurze Ausschnitte in VHDL oder komplette > lauffähige Projekte? Komplett lauffähige Projekte. Jörgs Link klingt von der Beschreibung her, als würde das passen, danke! Christian R. schrieb: > Versucht ihr euch jetzt in programmierbarer Logik? Das machen wir schon lange -- nur halt nicht ich. ;-) > Oder ist das privat? Ja, genau. Ich möchte einfach mal ein paar eigene Erfahrungen auf dem Gebiet von HDLs sammeln, purer persönlicher Ehrgeiz. Daher möchte ich auch eher beim "Hello world!" beginnen und nicht beim kompletten Betriebssystem in Hardware. ;-) > Schau dir doch mal eine der Logic-Analyser-Implementierungen > hier an, die laufen ja auf CPLDs. Klingt, als wäre es für den Anfang eine Nummer zu groß zum Überschauen. Etwas, was noch in ein XC9536/9572[XL] passt, ist mir für den Einstieg schon lieber.
> Hat hier eventuell jemand noch ein oder zwei einfache Beispiele für > Xilinx-CPLDs in VHDL zur Hand? Der 7-Segment-Decoder ist m.E. eine hübsche Sache. Siehe dazu den Beitrag "Re: Durch 10 teilen" Da sind schon ein paar Cremestückchen Code drin versteckt ;-)
Joerg Wolfram schrieb:
> Das war mein erstes Projekt, was ich mit einem XC9536 gemacht habe:
Sieht erst einmal nett aus, und man könnte das ja sogar testen. ;-)
Wie ist das, wenn ich dazu Fragen habe: soll ich hier einen Thread
aufmachen, damit wir es öffentlich diskutieren, oder soll ich dich
lieber per mail fragen?
Joerg Wolfram schrieb:
> Das war mein erstes Projekt, was ich mit einem XC9536 gemacht habe:
Ich verstehe zumindest nicht gleich "Bahnhof", wenn ich reingucke,
danke. :-)
Ich habe mir mal im ISE Webpack (noch eine 10.1 aber) ein Projekt
daraus gemacht, aber der mag das nicht in ein 9536 reinpacken:
1 | Re-checking device resources ... |
2 | ERROR:Cpld:853 - Insufficient number of product terms. This design needs at |
3 | least 186 but only 180 left after allocating other resources. |
4 | Device 9536XL44VQ was disqualified. |
5 | ERROR:Cpld:868 - Cannot fit the design into any of the specified devices with |
6 | the selected implementation options. |
Daran ändert sich auch nichts, wenn ich das optimization goal von "Speed" (ist die Voreinstellung) auf "Area" umschalte. Mach ich was falsch, oder ist der Compiler da einfach schlechter als der von dir verwendete?
Ich habs mal getestet mit der 11.3 hier. Passt nur rein, wenn man bei den Process Properties bei Synthese und Fit die Optimierungen auf Maximum stellt, besonders Bei Sythese auf "Area" und "High" und bei Fit "Optimize Density". Dann klappts. Mit den Standard-Einstellungen gehts auch nicht.
> oder ist der Compiler da einfach schlechter
Offenbar.
Als Trost: in ein 9572 passt es rein... ;-)
BTW:
1 | port ( lpstrobe : in std_logic; |
2 | zahl : in std_logic; |
3 | invalue : inout std_logic_vector(3 downto 0); |
4 | da1 : inout std_logic_vector(3 downto 0); |
5 | da2 : inout std_logic_vector(3 downto 0); |
6 | da3 : inout std_logic_vector(3 downto 0); |
7 | da4 : inout std_logic_vector(3 downto 0)); |
Das ist unschön.
Bidirektionale Ports sollten nur dort verwendet werden, wo es solche
auch wirklich gibt: an den Pins, im Top-Level.
Sowas wird gemacht, um auf einen out-Port lesend zugreifen zu können,
aber auch um einen Tristate-IO-Buffer beschreiben zu können. Du kannst
es am port selber aber nicht unterschieden.
Besser so:
Wenn ein Signal gelesen werden soll, dann wird das über lokale Signale
beschrieben, die dann an einen out-Port zugewiesen werden.
> der Compiler
Die Terminologie ist ein wenig anders, etwa so:
Software Hardware(CPLD)
Compiler Synthesizer
Assembler Translate
Optimierung Fitter
Linker Fitter
Christian R. schrieb: > ..., besonders Bei Sythese auf "Area" und "High" Das hatte ich schon gefunden. > und bei Fit > "Optimize Density". Dann klappts. Ah!, dass man dort auch nochmal schrauben kann, war mir entgangen. Danke, jetzt passt es hier auch.
Lothar Miller schrieb: > Bidirektionale Ports sollten nur dort verwendet werden, wo es solche > auch wirklich gibt: an den Pins, im Top-Level. Danke, das wäre eine meiner nächsten Fragen gewesen :), darüber hatte ich mich auch schon gewundert. > Wenn ein Signal gelesen werden soll, dann wird das über lokale Signale > beschrieben, die dann an einen out-Port zugewiesen werden. Das kannte ich zumindest schon. >> der Compiler > Die Terminologie ist ein wenig anders, etwa so: > Software Hardware(CPLD) > Compiler Synthesizer > Assembler Translate > Optimierung Fitter > Linker Fitter OK, ich hatte hier erstmal mit "Compiler" die Gesamtmenge aus Synthesizer, Translator und Fitter gemeint. Danke für die Erklärung.
> die Gesamtmenge aus Synthesizer, Translator und Fitter ...
... wird dann diplomatisch und universell die Toolchain genannt ;-)
Jörg Wunsch schrieb: > Wie ist das, wenn ich dazu Fragen habe: soll ich hier einen Thread > aufmachen, damit wir es öffentlich diskutieren, oder soll ich dich > lieber per mail fragen? Lieber hier im Forum, dann haben alle etwas davon - und du wartest unter Umständen noch weniger lang auf eine Antwort ;-)
Lothar Miller schrieb: > Das ist unschön. > Bidirektionale Ports sollten nur dort verwendet werden, wo es solche > auch wirklich gibt: an den Pins, im Top-Level. Das Projekt ist inzwischen ein paar Jahre her und mein erstes gewesen, inzwischen mache ich es meist auch so (außer für "quick and dirty" Lösungen, um mal schnell was zu testen). Da ich die gesamte Toolchain unter Linux über ein Script steuere, müsste ich nachsehen wie bei mir die Optimierungseinstellungen sind. Wie die dann in der ISE einzustellen sind, kann ich aber nicht sagen, da ich irgendwann alles was ich nicht brauche gelöscht habe. Jörg
Joerg Wolfram schrieb: > Da ich die gesamte Toolchain unter Linux über ein Script steuere, müsste > ich nachsehen wie bei mir die Optimierungseinstellungen sind. Das fand ich übrigens interessant daran, dieser Teil interessiert mich dann auch noch irgendwann... Sooo toll wiederum finde ich die ISE nun auch nicht. Das VHDL kann ich ja genauso gut im Emacs editieren. Simulierst du das auch irgendwie unter Linux zum Testen?
> Das VHDL kann ich ja genauso gut im Emacs editieren. Nicht genausogut sondern besser. :-) > Simulierst du das auch irgendwie unter Linux zum Testen? Zumindest fuer Verilog gibt es unter Linux einen Compiler der ein Datenfile erzeugt das du dir dann wieder als Grafik anzeigen lassen kannst. Es gibt da nur leider ein Problem. Es ist sehr einfach Programme zu schreiben die gut aussehen, in der emulation das machen was sie sollen, aber in der Praxis nicht funktionieren. BTW: CPLDs sind sauschnell. Da gewinnt das Wort Terminierung und kurze Kabel eine ganz neue Bedeutung! Als ich yu Testzwecken dort einen I2C-Bus Slave reinprogrammiert habe musste ich bereits bei 10cm Kabel terminieren sonst hat das nicht funktioniert. Olaf
Olaf schrieb: >> Das VHDL kann ich ja genauso gut im Emacs editieren. > > Nicht genausogut sondern besser. :-) Ja, natürlich. ;-) > BTW: CPLDs sind sauschnell. Och, ich glaube ich habe nur langsame mit 10 ns Spezifikation. :) > Da gewinnt das Wort Terminierung und > kurze Kabel eine ganz neue Bedeutung! Danke für den Hinweis. Was machst du da, 33-Ω-Widerstände vor die Pins?
> Was machst du da, 33-Ω-Widerstände vor die Pins?
100R+100pF nach Masse. War mal ein Tip von Barbecue-Joerg.
Funktioniert gut.
Olaf
Olaf schrieb: >> Was machst du da, 33-Ω-Widerstände vor die Pins? > > 100R+100pF nach Masse. Also 100 Ω, dann 100 pF als Tiefpass? Oder beide parallel, und dann gegen Masse? 100 pF kommt mir etwas heftig vor.
@ Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite >> 100R+100pF nach Masse. >Also 100 ?, dann 100 pF als Tiefpass? Ja. > Oder beide parallel, und dann gegen Masse? NEIN! >100 pF kommt mir etwas heftig vor. Macht halt 10ns Zeitkonstante oder ~22ns Anstiegszeit. Damit wirkt ein sauschneller CPLD mit 2ns und weniger als gemächlicher HC Baustein. Passt schon. MFG Falk
Falk Brunner schrieb:
> Macht halt 10ns Zeitkonstante oder ~22ns Anstiegszeit.
OK, bisschen langsamer als TTL, aber genügt sicher meist.
Joerg Wolfram schrieb: > Das war mein erstes Projekt, was ich mit einem XC9536 gemacht habe: > > http://www.jcwolfram.de/projekte/vhdl/parout16/main.php Wenn man das Rücksetzen von busy via trigger-Impuls erreichen möchte, funktioniert das nur, wenn lpdata(0) zuvor auf '0' gesetzt worden ist (bspw. indem man lpdata auf "0001010" = "\n" gesetzt hatte). Ist das Absicht oder ein Fehler? Ich hatte mal ein wenig mit dem ISE-Simulator spielen wollen und mich gewundert, warum ich das busy dann nicht mehr los geworden bin. Testbench zum Vergleich anbei.
@Jörg Wunsch Mal eine Frage hattest du meine PN gekriegt oder hat das Baord die verschluckt?
Läubi .. schrieb: > Mal eine Frage hattest du meine PN gekriegt oder hat das Baord die > verschluckt? Ja, sorry, dass ich auf die Mail noch nicht geantwortet habe.
Jörg Wunsch schrieb: > Läubi .. schrieb: > >> Mal eine Frage hattest du meine PN gekriegt oder hat das Baord die >> verschluckt? > > Ja, sorry, dass ich auf die Mail noch nicht geantwortet habe. Kein Problem, hatte mich nur gewundert da ich noch eine PN geschrieben hatte an wen anders die nicht angekommen ist ob dan wenigstens die an dich angekommen war :D
Jörg Wunsch schrieb: > Wenn man das Rücksetzen von busy via trigger-Impuls erreichen > möchte, funktioniert das nur, wenn lpdata(0) zuvor auf '0' > gesetzt worden ist (bspw. indem man lpdata auf "0001010" = "\n" > gesetzt hatte). > > Ist das Absicht oder ein Fehler? Ja, das ist Absicht. Damit wird nur bei "+" das Busy-Signal aktiviert und bei "*" nicht. Jörg
Joerg Wolfram schrieb: > Ja, das ist Absicht. Damit wird nur bei "+" das Busy-Signal aktiviert > und bei "*" nicht. Das war mir klar, aber die Sache ist halt, dass man das busy erst wieder los wird, wenn man danach noch ein Zeichen ausgibt, bei dem lp(0) = '0' ist. Mit dem angehängten Patch bekomme ich zwar in der Simulation das von mir erwartete Verhalten, d. h. ich muss nach dem "+" nicht noch zwingend ein "\n" ausgeben, damit der trigger-Impuls das busy wieder abschaltet, aber dafür lässt sich die Logik nicht mehr synthetisieren. ERROR:Xst:827 - "/home/joerg/Xilinx/lpout/main.vhd" line 91: Signal busy cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release. :-( Irgendwie habe ich den Eindruck, dass man das Teil in größeren Zügen umbauen müsste, um das von mir gewünschte/erwartete Verhalten real zu implementieren. Wenn mir mal einer auf die Sprünge helfen könnte, was denn da genau schief gelaufen ist, wäre ich dankbar.
Da werd ich mal die Ingrid machen. > ..., aber dafür lässt sich die Logik nicht mehr synthetisieren. > > ERROR:Xst:827 - "/home/joerg/Xilinx/lpout/main.vhd" line 91: Signal busy > cannot be synthesized, bad synchronous description. The description > style you are using to describe a synchronous element (register, memory, > etc.) is not supported in the current software release. busy hatte nun zwei Takte, von deren Flanken es abhing: strobe und trigger. Das mag die Synthese so nicht, verständlich. Gibt es dann eigentlich überhaupt eine Realisierungschance, ohne dass man seinen von busy und trigger separaten externen Takt anlegt?
1 | if (falling_edge(strobe) and set_busy = '1' and dreset='1') |
Das ist ein etwas gewagt beschriebenes synchrones Enable. Aber das ginge schon noch ;-) Allerdings im Zusammenhang mit dem Original-Code
1 | process(strobe,trigger,lpdata,dreset) is |
2 | begin
|
3 | if (strobe='0' and setout='1' and lpdata(0)='1') -- original !!! |
4 | if (falling_edge(strobe) and set_busy = '1' and dreset='1') -- neu !!!! |
5 | then
|
6 | busy <='1'; |
7 | elsif (dreset='0') |
8 | then
|
9 | busy <='0'; |
10 | elsif (rising_edge(trigger)) |
11 | then
|
12 | busy <='0'; |
13 | end if; |
14 | end process; |
Das wäre dann ein FF, das auf die fallende Flanke eines Signals und auf die steigende Flanke eines anderen Signals reagieren müsste. Der Code bereinigt und nach busy aufgelöst:
1 | process(strobe,trigger,lpdata,dreset) is |
2 | begin
|
3 | if (falling_edge(strobe) ...) |
4 | then
|
5 | busy <='1'; |
6 | :
|
7 | :
|
8 | elsif (rising_edge(trigger)) |
9 | then
|
10 | busy <='0'; |
11 | end if; |
12 | end process; |
Sowas hast du in einem XC95xx nicht :-( EDIT: Das Fenster hat zu lange unbenutzt herumgestanden, du hast die Antwort vorher selbst gefunden...
Lothar Miller schrieb: > Das Fenster hat zu lange unbenutzt herumgestanden, du hast die Antwort > vorher selbst gefunden... Danke trotzdem, deine Verdeutlichung macht mir klar, auf was ich selbst achten muss, wenn ich mich mit Logiksynthese befassen will. So gaaanz laaangsam begreife ich die ersten Zusammenhänge. ;-) > Sowas hast du in einem XC95xx nicht :-( Gegenfrage: ich vermute mal, in einem FPGA wäre sowas synthetisierbar, oder?
> Gegenfrage: ich vermute mal, in einem FPGA wäre sowas synthetisierbar, > oder? Nein. Mit zwei verschiedenen Taktquellen sicher nicht. Mit einer Taktquelle könnte man evtl. mit DDR-FFs was zurechtbasteln... Der/Mein Ansatz auf einem FPGA wäre ein ganz anderer: Man nimmt einen Takt mit 50MHz und synchronisiert diese langsamen LPT-Signale ein. Und arbeitet fortan Taktsynchron. Nur so ist ein FPGA-Design kontrollierbar und (vor allem) portierbar.
Lothar Miller schrieb: > Der/Mein Ansatz auf einem FPGA wäre ein ganz anderer: > Man nimmt einen Takt mit 50MHz und synchronisiert diese /langsamen/ > LPT-Signale ein. Und arbeitet fortan Taktsynchron. Nur so ist ein > FPGA-Design kontrollierbar und (vor allem) portierbar. Gut, das müsste ja sogar auf dem CPLD gehen, braucht halt nur einen externen Takt, und würde außerdem vermutlich die Anzahl der FFs des an der Erbrechensgrenze betriebenen originalen XC9536 überschrei- ten.
> und würde außerdem vermutlich die Anzahl der FFs des an der > Erbrechensgrenze betriebenen originalen XC9536 überschreiten. Exakt, denn da sind z.B. schon mal 3 FF weg fürs Eintakten+Flankenerkennung. Im FPGA habe ich FFs im Überfluss (die bekomme ich gar nie alle verdrahtet), im CPLD kann ich die Dinger (fast schon) an einer Hand abzählen... :-/
@ Lothar Miller (lkmiller) >bekomme ich gar nie alle verdrahtet), im CPLD kann ich die Dinger (fast >schon) an einer Hand abzählen... :-/ Bist du ein Tausendfüssler? ;-)
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.