Ich benötige 64 PWM Kanäle mit 4bit Auflösung. Die Frequenz muss nicht hoch sein, daher würde ein uC ausreichen. Allerdings hat dieser nicht genügend IOs, so dass ich noch Schiftregister oder ähnliches benötigen würde. Daher die Idee, das ganz per CPLD zu machen. In einen XC9572 passen aber gerade mal 7 PWMs. Gibt es da irgendeinen Trick um mehr PWMs unterzubringen, oder soll ich es doch besser per Software in einem uC machen ? Wiso wird für die beiden 4bit Werte eigentlich ein 5bit Komparator verwendet ? Kann man das noch irgendwie optimieren, so dass ein 4bit Komparator ausreicht ?
Das wirst du nicht hinkriegen! Ich habe deinen Code etwas verändert. Einmal habe ich ihn etwas optimiert in Hinsicht auf die verbrauchten Macrozellen (von 76 werden jetzt nur noch 44 gebraucht) und ich habe eine andere Schnittstelle zum MC programmiert, die ich dir empfehlen möchte. Für 64 PWM brauchst du: 64*4 (für den Speicher) + 64 (um die Ausgangssignale zu erzeugen) + 4 (für den Zähler) = 324 Macrozellen Aber 64 PWM-Ausgänge sind auch verdammt viel Zeug! Überleg mal, ob man da nicht mit Multiplexern was dran drehen kann. Es spielt übrigens keine Rolle, ob du inder RTL-Schematik einen 5 Bit oder einen 4 Bit Komparator siehst. Das wird alles mit einer Macrozelle gemacht. Und da ist es egal, ob die 5 oder 4 Bit vergleicht. Der Schaltplan ist sowieso nur eine Hilfe für den Entwickler. Du kannst viele Zellen sparen, indem du die internen Signale PWMWX NICHT über Flanken aktualisierst. Sonst wird das als extra Speicher realisiert. Daher kommt auch die Differenz von 32 Zellen (8*4) zwischen deinem und meinem Code. Gruß Henrik
P.S.: Ich arbeite mich auch noch in diese Materie ein. Wenn es jemand besser weiß, möge er mich bitte korrigieren! Henrik
Danke, das hilft weiter. Multiplex darf ich leider nicht verwenden, so ist die Vorgabe. Ich denke ich werde das ganze über einen uC machen, da sind die 32Bytes an RAM kein Problem, die ich für die PWM brauche. Zurück zum Programm: Ich habe das ganze mal ausprobiert (da ich öfters dieses serielle Schieberegister verwende um Daten vom uC in den CPLD zu laden), und die optimierte Version wäre sa schon gut. In dieser Zeile Field(conv_integer(set)):=sdata; kommt der Fehler ERROR:HDLParsers:800 - C:/8051/Xilinx/Projekts/pwm/pwm.vhd Line 56. Type of Field is incompatible with type of sdata. Könntest du mir auch mal erklären, wodurch im Code das Schieberegister gebildet wird ? Field ist ja nur ein 8 Felder großes Array zu je 4 bit. Ich verstehe nicht, wie da die Daten seriell eingelesen werden.
Es gibt indem Code kein Schieberegister! Der Speicher wird durch 8*4 Bit große Latches gebildet. Die werden geladen, indem du an sel (3 Bit breit) die Nummer des Kanals legst, an sdata den Wert (4 Bit) und eine steigende Flanke an sclk erzeugst. Deinen Fehler konnte ich nicht nachvollziehen. Bei mir lässt sich das alles Compilieren und Fitten und zwar ohne Fehler oder Warnungen. Hast du auch die geänderte Entity übernommen? (Wenn nicht, würde das den Fehler erklären) Erstellt wurde dieser Code nämlich auch mit Xilinx-Software. Ich würde dir satt eines MCs trotzdem einen CPLD empfehlen, vorallem, wenn der PWM sehr schnell arbeiten soll. Das mit dem "nicht hinkriegen" war NUR auf den XC9572 bezogen! Mit einem größeren, der genug Macrozellen hat, ist das ohne weiteres machbar (und wie ich finde eleganter als mit einem MC, aber das ist Geschmackssache). Gruß Henrik
Stimmt, die geänderte Entity hatte ich übersehen. Jetzt läuft es, zumindest mit 8 PWMs. Kann man da wirklich nichts mehr an der eigentlichen PWM optimieren ? Bei 12 PWMs bekomme ich nämlich bei fitten immer den Fehler: Mapping a total of 64 equations into 4 function blocks..................................................ERROR:Cpld:892 - Cannot place signal Field_6_3. Consider reducing the collapsing input limit or the product term limit to prevent the fitter from creating high input and/or high product term functions. See the fitter report for details.
Doch könntest du eventuell. Jenachdem wie die Komparatoren umgesetzt werden könntest du diese ersetzen und somit Makrozellen sparen. Du vergleichst einen 4Bit Zähler mit einem 4Bit Wert per Komparator. Statt so versuche mal den Zähler mit dem 4Bit Wert zu laden und dann zu dekrementieren. Bei "0000" im Zähler muß dieser neu geladen werden und die PWM Ausgänge getoggelt werden. Eine Auswertung auf "0000" könnte uU. mit wenigern Makrozellen auskommen als ein Komparator. Diese Logik kannst du invertieren indem du den Zähler mit einem "invertierten" Startwert initialsierst. D.h. Zähler = "10000" - PWM_Dauer. Nun den Zähler inkrementieren und bei Überlauf == "0000" den PWM Ausgang togglen und Zähler neu laden. Im Grunde die gleiche Logik wie beim Dekrementieren. Oder du ersetzt einfach if (PWMC < PWMW1) then pwm1 <= '0'; else pwm1 <= '1'; end if; Durch if (PWMC = PWMW1) then pwm1 <= not pwm1; Das wäre dann intern eine simple AND Verküpfung. Natürlich musst du bei "0000" in den Zählern die PWM Ausgänge auf '0' setzen, und diese Ausgänge müssen als Buffer deklariert werden (was wiederum eine Makrozelle mehr kosten könnte). Gruß Hagen
Das mit dem ladbaren Zähler verwende ich für andere Zwecke. Der Nachteil ist, das der Zähler immer sehr regelmäßig(!) nachgeladen werden muß. Schließlich will er ja ein kontinuierliches PWM-Signal haben und nicht nur ab und zu einen längenmodulierten Impuls. Dieses Verfahren kann man mit 5 Macrozellen realisieren, bezogen auf die 8 PWMs bräuchte man "nur" noch 40 Zellen. 4 Zellen Ersparniss sind aber nicht wirklich viel, mit dem Nachteil den Zähler dauernd per MC nachladen zu müssen. Das Verfahren lohnt sich hochgerechnet auf 64 PWMs erst recht nicht, da die Ersparniss hier wieder nur bei 4 Zellen liegt. Wenn er nur ab und zu einen Impuls bräuchte wäre das die beste Lösung, er will aber wohl ein kontinierliches, saubers Signal. Dein Vorschlag, die Zeilen zum Vergleichen abzuändern minimiert vieleicht die Logik inder Vergleichs-Zelle, ändert aber nicht die Tatsache, dass trotzdem eine zusätzlich gebraucht wird. Ob die nun zu 10 oder 40% ausgelastet ist, spielt ja keine Rolle. Gruß Henrik
Also 4 Bit ergeben nach meiner Rechnung genau 16 verschiedene PWM-Tastverhältnisse...
tja so ist das mit Schnellschüssen. Der erste Vorschlag -> statt einen Counter eben pro PWM einen Counter zu dekrementieren, ist natürlich Schwachsinn. Da man dort die fast doppelte Menge als Makrozellen benötigt, einmal für die Initalisierungswerte der Zähler und einmal die Zähler pro PWM selber. Macht also keinerlei Ersparnis. Die zweite Idee -> statt Komparator einen Gelichheitsvergleich zu machen, stellte sich ebenfalls als sinnlos heraus. Der Verbrauch an Makrozellen ist identisch wie zu euren Lösungen. Dafür ergeben sich aber andere Nachteile -> Synchronisation der Ausgänge beim Nachladen der Register. Im Anhang mal mein Versuch, der zwar nicht weniger Makrozellen benötigt aber dafür ein bischen besser im Source ist :=) Gruß Hagen
@ Stefan: Wie ist das zu verstehen? Es hat doch niemand etwas anderes behauptet. @ Hagen: Fast perfekt, aber "pins" muß kein "buffer" sein, ein "out" tut es auch! @ Benedikt: Ob du den Code von Hagen oder mir nimmst ist egal, beides wird auf die gleiche Hardware gefittet. Gruß Henrik
Hi Hendrik, ich weis, aber der auskommentierte Part im VHDL benötigt unbedingt das Pins als Buffer deklariert wird, sonst funktioniert er nicht. Nur ist es eben so das dieser Teil des VHDL's keinerlei Makrozellen eingespart hat im Vergleich zum jetzt aktiven Source :) Naja, auf alle Fälle haben sich alle meine obigen Idee als "untauglich" herausgestellt und weitere "Optimierungen" fallen mir auch nicht mehr ein. Es wird wohl nicht besser gehen auf den Xilinx/Altera CPLDs. Es gibt aber CPLD's von Lattice die die nötigen Latches nicht per FF's sondern per RAM Zellen darstellen können. Diese CPLD's wären die einzigste Möglichkeit die ich noch sehe bevor man gleich auf FPGA's umsteigt. Es gäbe nur noch eine Idee die ich hätte: am CPLD einen SRAM anschließen und dort die PWM Werte speichern lassen. Allerdings dürfte die Zugriffslogik um diese Werte aus dem SRAM zu laden auch einiges an Makrozellen kosten. Fazit: nimm den kleinsten und preiswertesten CPLD, und baue dann deine Anzahl von nötigen PWM Kanäle durch Kaskadierung von zb. 8 solcher CPLD's auf. Aber ich fände diesen Aufwand zu groß denn ein simpler ATMega mit genügend IO's schafft dies alles lässig. Gruß Hagen
>Aber ich fände diesen Aufwand zu groß >denn ein simpler ATMega mit genügend IO's schafft dies alles lässig. Ja, diese Überzeugung habe ich mittlerweile auch: Ein mega8515 schafft problemlos eine 32 Kanal PWM, selbst mit 8bit Auflösung.
@Henrik: Nachdem ich mal in den Code gesehen hab war mein Kommentar wohl nicht arg zielführend... Ich meinte das so, dass intern ja eigentlich 8 PWMs reichen müssten. Vorausgesetzt die Tastverhältnisse müssen nicht zur Laufzeit geändert werden können sollte es dann in nen 9572 passen. Die 8 Signale müssten ja nur, ggfls invertiert, zu den entsprechenden Pins geroutet werden. Änderungen gehen dann halt nur mit Flashen des CPLDs. Ansonsten sind wohl mehrere Controller definitiv die einfachere Variante.
Ich denke mal, daß sowas mit einem MC wesentlich einfacher und kostengünstiger ist. Z.B. mit einem ATMega8 für je 16 Ausgänge als SPI- oder I2C-Slave von der Haupt-CPU gesteuert. Ist dann auch egal, ob 4, 8, 16 oder 32 Bit, SRAM ist ja genug da. Peter
Ich habe das ganze jetzt mit einem mega8515 gelöst: Dieses bietet 35 IOs, von denen leider 4 für die SPI verwendet werden, so dass noch 31 Ausgänge bleiben. Mit etwas optimiertem Code komme ich auf 150Hz Ausgangsfrequenz bei 8bit PWM. Bei einer 4bit PWM wären es sogar über 2,5kHz an jedem Ausgang. Und das alles ohne ein externes Bauteil, nur der uC mit internem 8MHz Takt...
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.