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.
:
Verschoben durch Moderator
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-DCF77 Gustl 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
Im Anhang ist die Schaltung. Es sind noch ein paar mehr Sachen drauf, aber die werde ich dann denke ich hinbekommen.
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/
:
Bearbeitet durch Moderator
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?
1 | library ieee, |
2 | use ieee.std_logic_1164.all; |
3 | use ieee.numeric_std.all; |
4 | |
5 | entity fault is |
6 | port ( |
7 | oc_fault : in std_logic; |
8 | ov_fault : in std_logic; |
9 | ot_fault : in std_logic; |
10 | fault_all : in std_logic; |
11 | led1 : out std_logic; |
12 | led2 : out std_logic; |
13 | led3 : out std_logic; |
14 | fault_uC : inout std_logic; |
15 | |
16 | PWM_T_U_UC : in std_logic; |
17 | PWM_T_V_UC : in std_logic; |
18 | PWM_T_W_UC : in std_logic; |
19 | PWM_B_U_UC : in std_logic; |
20 | PWM_B_V_UC : in std_logic; |
21 | PWM_B_W_UC : in std_logic; |
22 | |
23 | PWM_T_U : out std_logic; |
24 | PWM_T_V : out std_logic; |
25 | PWM_T_W : out std_logic; |
26 | PWM_B_U : out std_logic; |
27 | PWM_B_V : out std_logic; |
28 | PWM_B_W : out std_logic; |
29 | );
|
30 | end fault; |
31 | |
32 | architecture behavioral of fault is |
33 | signal A1 : STD_LOGIC; -- internal input of OR gate |
34 | signal A2 : STD_LOGIC; -- internal input of OR gate |
35 | signal A3 : STD_LOGIC; -- internal input of OR gate |
36 | signal A4 : STD_LOGIC; -- internal input of OR gate |
37 | signal Y1 : STD_LOGIC; -- internal output of OR gate |
38 | begin
|
39 | Y1 <= A1 or A2 or A3 or A4; --OR Gate 4 Inputs |
40 | |
41 | A1, led1 <= not oc_fault; |
42 | A2, led2 <= not ov_fault; |
43 | A3, led3 <= not ot_fault; |
44 | A4 <= fault_all; |
45 | uC_fault <= Y1; |
46 | |
47 | PWM_PROC : process (uC_Fault) |
48 | begin
|
49 | if (uC_Fault ='0') then |
50 | PWM_T_U <= PWM_T_U_UC; |
51 | PWM_T_V <= PWM_T_V_UC; |
52 | PWM_T_W <= PWM_T_W_UC; |
53 | PWM_B_U <= PWM_B_U_UC; |
54 | PWM_B_V <= PWM_B_V_UC; |
55 | PWM_B_W <= PWM_B_W_UC; |
56 | else
|
57 | PWM_T_U <= '0'; |
58 | PWM_T_V <= '0'; |
59 | PWM_T_W <= '0'; |
60 | PWM_B_U <= '0'; |
61 | PWM_B_V <= '0'; |
62 | PWM_B_W <= '0'; |
63 | end if; |
64 | end process PWM_PROC; |
65 | end behavioral; |
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_UC when uC_Fault='0' else '0'; |
7 | PWM_T_V <= PWM_T_V_UC when uC_Fault='0' else '0'; |
8 | PWM_T_W <= PWM_T_W_UC when uC_Fault='0' else '0'; |
9 | PWM_B_U <= PWM_B_U_UC when uC_Fault='0' else '0'; |
10 | PWM_B_V <= PWM_B_V_UC when uC_Fault='0' else '0'; |
11 | PWM_B_W <= PWM_B_W_UC when uC_Fault='0' else '0'; |
12 | end behavioral; |
Und diese multiplen Zuweisungen:
1 | A1, led1 <= not oc_fault; |
Ab welcher VHDL-Version bzw. mit welchem Synthesizer geht sowas? Bin gespannt, was daraus wird:
1 | fault_uC : inout std_logic; |
:
Bearbeitet durch Moderator
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.
:
Bearbeitet durch Moderator
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.
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.