Forum: FPGA, VHDL & Co. PWM: uC oder CPLD ?


von Benedikt (Gast)


Angehängte Dateien:

Lesenswert?

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 ?

von Henrik (Gast)


Angehängte Dateien:

Lesenswert?

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

von Henrik (Gast)


Lesenswert?

P.S.: Ich arbeite mich auch noch in diese Materie ein. Wenn es jemand
besser weiß, möge er mich bitte korrigieren!

Henrik

von Benedikt (Gast)


Lesenswert?

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.

von Henrik (Gast)


Lesenswert?

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

von Benedikt (Gast)


Lesenswert?

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.

von Hagen (Gast)


Lesenswert?

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

von Henrik (Gast)


Lesenswert?

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

von Stephan Hochberger (Gast)


Lesenswert?

Also 4 Bit ergeben nach meiner Rechnung genau 16 verschiedene
PWM-Tastverhältnisse...

von Hagen (Gast)


Angehängte Dateien:

Lesenswert?

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

von Henrik (Gast)


Lesenswert?

@ 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

von Hagen (Gast)


Lesenswert?

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

von Benedikt (Gast)


Lesenswert?

>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.

von Stephan Hochberger (Gast)


Lesenswert?

@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.

von Peter D. (peda)


Lesenswert?

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

von Benedikt (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.