Forum: FPGA, VHDL & Co. PWM Signal von uC überprüfen und weitergeben


von Flepple (Gast)


Lesenswert?

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
von Gustl B. (gustl_b)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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.

von Flepple (Gast)


Lesenswert?

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.

von Gustl B. (-gb-)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von Gustl B. (-gb-)


Lesenswert?

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.

von Flepple (Gast)


Lesenswert?

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

von Flepple (Gast)


Angehängte Dateien:

Lesenswert?

Im Anhang ist die Schaltung.
Es sind noch ein paar mehr Sachen drauf, aber die werde ich dann denke 
ich hinbekommen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von Flepple (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Flepple (Gast)


Lesenswert?

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;

von Duke Scarring (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Kioskman (Gast)


Lesenswert?

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

von Flepple (Gast)


Lesenswert?

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.

von Achim S. (Gast)


Lesenswert?

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;

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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

von Achim S. (Gast)


Lesenswert?

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

von Flepple (Gast)


Lesenswert?

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.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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
von Flepple (Gast)


Lesenswert?

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?

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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