Servus zusammen,
ich bin an der Entwicklung eines Wechselrichters in dem ein uC die
Regelung übernehmen soll und ein FPGA (Lattice ice40) zur Überwachung
dient. Leider habe ich nicht sehr viel Erfahrung mit VDHL oder Verilog.
Zu meinem Problem/ Frage:
Ich möchte unter anderem die PWM‘s die vom uC generiert werden mit dem
FPGA überprüfen und dann weitergeben, sprich, das PWM Signal vom uC
durchschleifen. Jemand eine Idee, wie ich am besten vorgehe? Wie ich PWM
Signale mit dem Fpga erzeuge mit einer clock ist mir bekannt aber nicht
in diesem Zusammenhang mit der Abtastung eines Input Signals.
Die PWM‘s sollen dann bei einer Fehlerdetektion abgeaschaltet werden
(für den Zusammenhang für euch).
Vielen Dank im Voraus.
Du brauchst im FPGA gar keine PWM zu erzeugen. Die kann man 1:1
durchreichen und gleichzeitig auch im FPGA auswerten oder sonst wie
gucken ob deine Bedingungen erfüllt sind. Genauso kann man die PWM auch
abschalten. Ist eben ein enable Signal.
Flepple schrieb:> Wie ich PWM Signale mit dem Fpga erzeuge mit einer clock ist mir bekannt> aber nicht in diesem Zusammenhang mit der Abtastung eines Input Signals.
Du vermisst einfach das PWM-Signal, indem du einen (oder ein paar)
schnell getaktete Zähler nimmst und die Zeiten zwischen den Flanken
ermittelst und auf Plausibilität prüfst.
Wenn die FPGA-Zählerfrequenz z.B. 50MHz ist, dann kannst du ein
50kHz-Signal auf 1/1000stel (also auf 10 Bit) genau abtasten.
Gustl B. schrieb:> Du brauchst im FPGA gar keine PWM zu erzeugen. Die kann man 1:1> durchreichen und gleichzeitig auch im FPGA auswerten oder sonst wie> gucken ob deine Bedingungen erfüllt sind. Genauso kann man die PWM auch> abschalten. Ist eben ein enable Signal.
Hast du mir ein Beispiel dazu? Ich habe leider nichts gefunden wie ich
den Code aufbauen könnte.
Naja, das steht und fällt damit, wie du deine
Flepple schrieb:> Fehlerdetektion
baust. Wie soll die funktionieren?
Die PWM oder sonstige digitale Signale durschschleifen geht mit
Ausgang <= Eingang;
und mit enable
Ausgang <= Eingang when enable = '1' else 'Z';
Jetzt musst du nur noch beschreiben wie deine Fehlererkennung
funktionieren soll, denn die erzeugt dir dein enable.
Flepple schrieb:> Ich habe leider nichts gefunden wie ich den Code aufbauen könnte.
Du musst zuallererst eine Schaltung, ein Konzept, eine Struktur haben.
Und die beschreibst du dann mit der Hardwarebeschreibungssprache VHDL
oder Verilog.
Flepple schrieb:> Leider habe ich nicht sehr viel Erfahrung mit VDHL
Dann weißt du, wo du ansetzen musst. Überleg dir, wie du z.B. einen
Zähler starten und anhalten kannst.
Dort im im DCF77-Empfänger messe ich auch die Pulsdauer des
Eingangssignals und werte es aus:
http://www.lothar-miller.de/s9y/categories/56-DCF77Gustl B. schrieb:> Ausgang <= Eingang when enable = '1' else 'Z';
Naja, ich würde da eher den definierten "AUS"-Pegel ausgeben, statt die
Abschaltung dem Glück zu überlassen... ;-)
Lothar M. schrieb:> Naja, ich würde da eher den definierten "AUS"-Pegel ausgeben, statt die> Abschaltung dem Glück zu überlassen... ;-)
Ja, kann und sollte man vielleicht machen. Dazu hat er bisher zu wenige
Informationen geliefert.
Ja im Prinzip reicht mir zunächst das durchschleifen und die
Abschaltung. Die Fehlerdetektion basiert einfach auf einem
Eingangssignal, das LOW oder HIGH ist. Bei LOW wird eine LED angesteuert
und die PWM´s abgeschaltet
Flepple schrieb:> Die Fehlerdetektion basiert einfach auf einem Eingangssignal, das LOW> oder HIGH ist. Bei LOW wird eine LED angesteuert und die PWM´s> abgeschaltet
Also eine rein kombinatorische Mimik? Bestenfalls noch mit einem Latch?
Dann ist ein FPGA echt mal technischer Overkill...
Flepple schrieb:> Ich möchte unter anderem die PWM‘s die vom uC generiert werden mit dem> FPGA überprüfen
Ja, was denn nun?
In der "Echtzeitüberprüfung der PWM Signale" sehe ich eine nette kleine
Aufgabe: weil da kein externer Oszillator drauf ist, würde ich den
internen SB_HFOSC mit seinen 48MHz nehmen. Und weil der nicht "genau"
ist, würde ich mit einem Zähler an der PWM-Frequenz der Phasen (die sich
ja hoffentlich nicht laufend ändert) einen Kalibrierwert ausmessen. Ich
vermesse also die Zyklusdauer einer Phase und weiß, wie lange ein
PWM-Zyklus normalerweise dauern sollte.
Anhand dieses "Sollwertes" könte ich dann alle Phasensignale auf
irgendwelche Timeouts und/oder Überlappungen überprüfen. Es darf ja z.B.
auch nicht T und B einer Phase gleichzeitig angesteuert werden. Oder es
muss evtl. eine bestimmte Totzeit zwischen T und B eingehalten werden.
Und solche Zyklus-/High-/Low-Zeiten werden immer gleich ermittlet:
1. Signal einsynchronisieren
2. Signalflanke erkennen
3. je nach Flanke den Zähler zurücksetzen oder speichern bzw. auswerten
> die Schaltung
Ich würde da den Pin 5 auch noch versorgen...
Wie gesagt, für den Anfang würde die rein kombinatorische Mimik reichen
(klar dass da ein FPGA Overkill ist), im weiteren Verlauf soll dann noch
die Überprüfung der PWM´s hinzukommen.
Naja die Frequenz der PWM´s soll schon konstant bleiben, allerdings
ändert sich der Duty cycle ja durchgehend, aber das hat ja keine
Auswirkung auf die Gesamtphasendauer
Flepple schrieb:> im weiteren Verlauf soll dann noch die Überprüfung der PWM´s hinzukommen.> ... die Frequenz der PWM´s soll schon konstant bleiben.
Ich hätte dem FPGA dafür noch so einen winzigen Quarzoszillator (die
dafür nötigen 2x2,5mm dürften sich schon finden lassen) mit 10..50MHz
spendiert, dann müsste ich mich nicht auf den windigen internen
RC-Oszillator "verlassen". Oder eher: dessen Fehler "wegkalibireren".
Ein definierter Takt am FPGA würde das Design insgesamt extrem
vereinfachen. Neben der Verwendung von festen vorberechneten Grenzwerten
(statt taktabhängiger "Kalibrierwerte") könnte dann z.B. zudem die
absolute PWM-Frequenz und damit die Korrektheit des µC-Takts
kontrolliert werden.
BTW:
> PWM´s
Lass den Apostroph weg, der zählt zu den sogenannten Deppenapostrophen:
http://www.deppenapostroph.info/
Lothar M. schrieb:> BTW:>> PWM´s> Lass den Apostroph weg, der zählt zu den sogenannten Deppenapostrophen:> http://www.deppenapostroph.info/
Alles klar, hab ich noch nie gehört aber merke ich mir :)
Lothar M. schrieb:> Ich hätte dem FPGA dafür noch so einen winzigen Quarzoszillator (die> dafür nötigen 2x2,5mm dürften sich schon finden lassen) mit 10..50MHz> spendiert, dann müsste ich mich nicht auf den windigen internen> RC-Oszillator "verlassen". Oder eher: dessen Fehler "wegkalibireren".
Danke für den Tipp. Ich werde so oder so noch eine neue Hardware Version
machen, wenn ein externer Oszi benötigt und hilfreich ist mach ich einen
drauf.
Kann jemand überprüfen, ob mein Code in die richtige Richtung geht, bzw.
Verbesserungsvorschläge?
Flepple schrieb:> Kann jemand überprüfen, ob mein Code in die richtige Richtung geht, bzw.> Verbesserungsvorschläge?
Auf den ersten Blick sieht das ok aus.
Ich würde mich genau jetzt an dieser Stelle mit dem Thema 'Testbench'
befassen, weil diese Dir die Frage nach geht, geht nicht oder könnte
gehen besser und schneller beantworten kann, als das Forum.
Duke
Duke Scarring schrieb:> Auf den ersten Blick sieht das ok aus.
Abgesehen von der unvollständigen Sensitivliste des kombinatorischen
Prozesses... ;-)
Da müssten nämlich alle 6 PWM_x_y_UC Signale auch mit rein. Derzeit wird
zwar funktionierende Hadware erzeugt, aber die Simulation passt nicht
dazu.
Alternativ könnte man das ohne Prozess und ohne fehlerhafte
Sensitivliste einfach nebenläufig machen:
1
:
2
:
3
A4<=fault_all;
4
uC_fault<=Y1;
5
6
PWM_T_U<=PWM_T_U_UCwhenuC_Fault='0'else'0';
7
PWM_T_V<=PWM_T_V_UCwhenuC_Fault='0'else'0';
8
PWM_T_W<=PWM_T_W_UCwhenuC_Fault='0'else'0';
9
PWM_B_U<=PWM_B_U_UCwhenuC_Fault='0'else'0';
10
PWM_B_V<=PWM_B_V_UCwhenuC_Fault='0'else'0';
11
PWM_B_W<=PWM_B_W_UCwhenuC_Fault='0'else'0';
12
endbehavioral;
Und diese multiplen Zuweisungen:
1
A1,led1<=notoc_fault;
Ab welcher VHDL-Version bzw. mit welchem Synthesizer geht sowas?
Bin gespannt, was daraus wird:
Hallo Flepple
Nur mal so aus reiner Neugierde, welche Art von Fehlern sollen denn
später einmal von FPGA bei den PWM Signalen entdeckt werden?
Gruß
Kioskman
Lothar M. schrieb:> Und diese multiplen Zuweisungen: A1, led1 <= not oc_fault;> Ab welcher VHDL-Version bzw. mit welchem Synthesizer geht sowas?
Sorry, bin selber beim synthetisieren auf die ganzen kleinen Fehler
gestoßen, hätte danach den Code hier rein stellen sollen.
Lothar M. schrieb:> Bin gespannt, was daraus wird: fault_uC : inout std_logic;
Hmm, aber ich benötige dieses Signal ja als Input und Output. Gibt es da
bessere Alternativen?
Duke Scarring schrieb:> Ich würde mich genau jetzt an dieser Stelle mit dem Thema 'Testbench'> befassen
Ja bin ich dabei. Allerdings bin ich wie gesagt noch kein VHDL Experte
und etwas in der C Denke und muss erstmal wieder umdenken um den Aufbau
des Programms richtig hinzubekommen. Deshalb bin ich froh, wenn dieser
wenigstens schonmal stimmt :D
Kioskman schrieb:> Nur mal so aus reiner Neugierde, welche Art von Fehlern sollen denn> später einmal von FPGA bei den PWM Signalen entdeckt werden?
Wie Lothar schon geschrieben hat, sollte u.a. die Totzeit überwacht
werden und die Phasendauer.
Flepple schrieb:> Hmm, aber ich benötige dieses Signal ja als Input und Output.
in deinem bisherigen Code benötigst du es als internes Signal und als
Output, aber nicht als Input der Entity. (wobei du in deinem Code zwei
verschiedene Schreibwesen verwendest).
Flepple schrieb:> Gibt es da> bessere Alternativen?
Es gäbe noch die Variante "buffer" (ein rücklesbarer Ausgang) anstelle
von inout.
Aber die übliche Variante ist: du arbeitest in der Entity mit einem
Signal uc_fault, das du lesen und schreiben darfst. Und in der Port-List
der Entity nutzt du ein reines Ausgangssignal (z.B. uc_fault_out), das
du in der architecture fest mit dem internen Signal verbindest.
uc_fault_out <= uc_fault;
Flepple schrieb:> Lothar M. schrieb:>> Bin gespannt, was daraus wird: fault_uC : inout std_logic;> ich benötige dieses Signal ja als Input und Output.
Ja, deshalb bin ich ja daruf gespannt. Denn das Signal geht ja auf dem
Schaltplan nur irgendwo hin.
Wer definiert bei diesem inout, wann das Signal ein Ausgang und wann ein
Eingang ist? Und weiß der Andere, der an der selben Leitung hängt, das
auch?
Oder soll das einfach ein Open-Collector Pin sein, der auf der Platine
parallel zu anderen Open-Collector Pins hängt und per Pullup hochgezogen
wird?
Achim S. schrieb:> Es gäbe noch die Variante "buffer" (ein rücklesbarer Ausgang) anstelle> von inout.
"buffer" ist ein unsauberer Murks, den Schreibfaule nehmen, um sich ein
lokales Signal zu "sparen".
Man kann mit einem "buffer" aber eben keinen Pinpegel "zurücklesen".
Lothar M. schrieb:> "buffer" ist ein unsauberer Murks, den Schreibfaule nehmen, um sich ein> lokales Signal zu "sparen".
genau deswegen habe ich dem TO ja erklärt, wie man das üblicherweise
macht.
Lothar M. schrieb:> Man kann mit einem "buffer" aber eben keinen Pinpegel "zurücklesen".
Der TO hat zwar geschrieben, dass der das Signal als input und output
nutzen will. Aber sein bisheriger Code zeigt was anderes:
Achim S. schrieb:> in deinem bisherigen Code benötigst du es als internes Signal und als> Output, aber nicht als Input der Entity.
D.h. es sieht laut Code so aus, als würde er tatsächlich einen
rücklesbaren Ausgang brauchen (was einen Anfänger schon mal zu einem
inout führen kann).
Achim S. schrieb:> Aber die übliche Variante ist: du arbeitest in der Entity mit einem> Signal uc_fault, das du lesen und schreiben darfst. Und in der Port-List> der Entity nutzt du ein reines Ausgangssignal (z.B. uc_fault_out), das> du in der architecture fest mit dem internen Signal verbindest.> uc_fault_out <= uc_fault;
Ja so brauche ich es. Macht Sinn, ist mir irgendwie durchgegangen.
Flepple schrieb:> ist mir irgendwie durchgegangen.
Mir auch durch den einen nicht verwendeten Port namens "fault_uC" und
das nicht deklarierte Signal namens "uC_Fault".
BTW: die Namensgebung ist insgesamt mindestens sportlich wenn nicht gar
verwirrend (auch im Schaltplan, wo Signale einfach nur ihren Namen
ändern). Auch wenn VHDL es zulässt, dass "uC_Fault" und "uc_fault" das
selbe Signal meinen, so verwirrt es doch den Leser der VHDL-Beschreibung
ein wenig.
Lothar M. schrieb:> BTW: die Namensgebung ist insgesamt mindestens sportlich wenn nicht gar> verwirrend (auch im Schaltplan, wo Signale einfach nur ihren Namen> ändern). Auch wenn VHDL es zulässt, dass "uC_Fault" und "uc_fault" das> selbe Signal meinen, so verwirrt es doch den Leser der VHDL-Beschreibung> ein wenig.
Ja der Schaltplan wird noch geändert und überarbeitet, das ist eine alte
Version und nur für erste Tests. Aber danke für den Hinweis.
Wie kann man denn eine Testbench erstellen, die PWM erzeugt, die dann in
der oben stehenden Software quasi durchgereicht werden?
Flepple schrieb:> Wie kann man denn eine Testbench erstellen, die PWM erzeugt, die dann in> der oben stehenden Software quasi durchgereicht werden?
Eine Testbench ist einfach ein VHDL-Modul ohne Ports. In diesem Modul
wird der Prüfling als Komponente instantiiert. Und dann werden die
µC-Signale erzeugt und an diesen Prüfling angeschlossen.
Hier mache ich das mit dem Takt für die blinkende LED:
http://www.lothar-miller.de/s9y/archives/80-Hello-World!.html
Und hier gebe ich zusätzlich Sollwerte für einen PWM-Generator vor:
http://www.lothar-miller.de/s9y/archives/54-PWM.html
Weil du den PWM-Generator nicht synthetisieren musst, kannst du ich auch
einfach anstatt mit Zählern mit einem "wait for" realisieren (so wie die
LED im ersten Versuch auch nur mit "wait for 500 ms" angesteuert wurde).
Der Witz ist: in Testbenches kannst du einen Großteil von VHDL verenden
um das Verhalten der "Umwelt" deines Moduls zu beschreiben.
In einem VHDL Modul für die Synthese kannst du bestenfalls 5% von VHDL
einsetzen. Udn musst noch bestimmte Vorgaben einhalten.
Man kann z.B. die Stimulidaten/Zeiten auch aus Textdateien einlesen:
http://www.pldworld.com/_hdl/2/_tutor/www.stefanvhdl/vhdl/html/file_read.html
Einfach mal ein paar Testbenches anschauen:
http://esd.cs.ucr.edu/labs/tutorial/tb_ckt.vhd
Mit ein wenig Herumspielen findest du dann kürzere Varianten für die
PWM-Beschreibung.