Forum: FPGA, VHDL & Co. PWM Frequenz unterteilen


von Ja D. (jacoie)


Angehängte Dateien:

Lesenswert?

Hallo,
ich habe das Beispiel vom Herrn Miller implementiert, in dem er das 
Trägersignal auf 1 kHz reduziert (prescaled):
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.NUMERIC_STD.ALL;
4
5
entity PWM is
6
    Generic ( width: natural := 8;        -- Breite
7
              fclk : integer := 50000000; -- Taktfrequenz
8
              fpwm : integer := 1000      -- PWM-Frequenz
9
             ); 
10
    Port    ( clk      : in  std_logic;
11
              pwmvalue : in  std_logic_vector (width-1 downto 0);
12
              pwmout   : out std_logic
13
             );
14
end PWM;
15
16
architecture Behavioral of PWM is
17
signal   cnt : integer range 0 to 2**width-2 := 0;
18
signal   pre : integer range 0 to fclk/(fpwm*(2**width-2)) := 0;
19
begin
20
   -- Vorteiler teilt FPGA-Takt auf PWM-Frequenz*Zählschritte
21
   process begin
22
      wait until rising_edge(clk);
23
      if (pre<fclk/(fpwm*(2**width))) then 
24
         pre <= pre+1;
25
      else
26
         pre <= 0;
27
      end if;
28
   end process;
29
   
30
   -- PWM-Zähler         
31
   process begin
32
      wait until rising_edge(clk);
33
      if (pre=0) then
34
         if (cnt<2**width-2) then cnt <= cnt+1;
35
         else                     cnt <= 0;
36
         end if;
37
      end if;
38
   end process;
39
   
40
   -- Vergleicher, registriert für Ausgabe auf IO-Pin ohne Glitches
41
   process begin
42
      wait until rising_edge(clk);
43
      if (cnt>=to_integer(unsigned(pwmvalue))) then pwmout <= '0';
44
      else                                          pwmout <= '1';
45
      end if;
46
   end process;
47
end Behavioral;

Die Simulation (siehe Anhang) zeigt jedoch unterschiedliche Frequenzen 
des pwmout und nicht die gewünschte 1 kHz. Es scheint, als ob man hier 
keine Pulsweitenmodulation beabsichtigt, sondern eine 
Pulsfrequenzmodulation. Obwohl der code eigentlich nachvollziebar ist 
und genau das tut, was er tuen muss, gibt es trotzdem irgendwo noch 
einen Fehler! Hat jemand bereits damit Erfahrung gemacht?
Für jede Hilfe wäre ich dankbar

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


Angehängte Dateien:

Lesenswert?

Ja D. schrieb:
> gibt es trotzdem irgendwo noch einen Fehler!
Der Fehler ist nicht im geposteten Code. Oder wenigstens nicht 
ausschließlich...  ;-)

Im Anhang ein Screenshot von genau diesem Code mit der passenden 
Testbench. Zeig doch mal deine TB.

> Für jede Hilfe wäre ich dankbar
Bitte das nächste Mal die Hinweise über der Eingabebox beachten:
1
Antwort schreiben
2
Wichtige Regeln - erst lesen, dann posten!
3
...
4
Formatierung (mehr Informationen...)
5
...
6
    [vhdl]VHDL-Code[/vhdl]

: Bearbeitet durch Moderator
von Carpe diem (Gast)


Lesenswert?

Ja D. schrieb:
> Hallo,



Der zähler cnt zählt von 0 bis 2 hoch 8 - 2 (siehe width) während die 
pwm den ausgangswert bei cnt > 1000 (pwmvalue) wechselt.

von Ja D. (jacoie)


Lesenswert?

Hallo Herr Miller und schön, dass Sie zurückschreiben. Das ist die 
Testbench, mit der ich simuliert habe. Auch nach einer Implementierung 
auf einem Spartan3AN sind Frequenzen von 4,5 bzw. 5 kHz sichtlich.
1
LIBRARY ieee;
2
USE ieee.std_logic_1164.ALL;
3
 
4
-- Uncomment the following library declaration if using
5
-- arithmetic functions with Signed or Unsigned values
6
--USE ieee.numeric_std.ALL;
7
 
8
ENTITY TB_06 IS
9
END TB_06;
10
 
11
ARCHITECTURE behavior OF TB_06 IS 
12
 
13
    -- Component Declaration for the Unit Under Test (UUT)
14
 
15
    COMPONENT MainPWM
16
    PORT(
17
         clk : IN  std_logic;
18
         pwmoutHigh : OUT  std_logic;
19
         pwmoutLow : OUT  std_logic
20
        );
21
    END COMPONENT;
22
    
23
24
   --Inputs
25
   signal clk : std_logic := '0';
26
27
   --Outputs
28
   signal pwmoutHigh : std_logic;
29
   signal pwmoutLow : std_logic;
30
31
   -- Clock period definitions
32
   constant clk_period : time := 20 ns;
33
 
34
BEGIN
35
 
36
  -- Instantiate the Unit Under Test (UUT)
37
   uut: MainPWM PORT MAP (
38
          clk => clk,
39
          pwmoutHigh => pwmoutHigh,
40
          pwmoutLow => pwmoutLow
41
        );
42
43
   -- Clock process definitions
44
   clk_process :process
45
   begin
46
    clk <= '0';
47
    wait for clk_period/2;
48
    clk <= '1';
49
    wait for clk_period/2;
50
   end process;
51
 
52
53
   -- Stimulus process
54
   stim_proc: process
55
   begin    
56
      -- hold reset state for 100 ns.
57
      wait for 100 ns;  
58
59
      wait for clk_period*10;
60
61
      -- insert stimulus here 
62
63
      wait;
64
   end process;
65
66
END;

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


Lesenswert?

Leider nicht testbar, weil MainPWM (und was dazugehört) nicht dabei 
ist...

von VHDL Schütze (Gast)


Lesenswert?

Generic map fehlt, damit sind die verkorksten Defaults aktiv.

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


Lesenswert?

Ja D. schrieb:
> mit der ich simuliert habe
Mein Vorschlag: hänge alle VHDL-Dateien (mit der Endung *.vhd oder 
*.vhdl) hier an. Dann sieht man das besser...

von Ja D. (jacoie)


Angehängte Dateien:

Lesenswert?

Anbei, der gesamte Beispielscode...Danke im Voraus!

von Ja D. (jacoie)


Lesenswert?

Carpe diem schrieb:
>  bei cnt > 1000 (pwmvalue) wechselt.

stimmt nicht, pwmvalue maximaler Wert ist 256. cnt zählt bis 254

von Lattice User (Gast)


Lesenswert?

Unter der Annahme dass "sinusplusoffset" der Input für die PWM ist, ist 
der Fehler offensichtlich: Dieser Wert ändert sich viel zu schnell für 
eine 1 kHz PWM.

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


Lesenswert?

Lothar M. schrieb:
> Mein Vorschlag: hänge alle VHDL-Dateien (mit der Endung *.vhd oder
> *.vhdl) hier an.
Ja D. schrieb:
> VHDL.zip
> Anbei, der gesamte Beispielscode...
Tja, da kann man mit einem Handy dann leider nichts ausrichten. 
Entzippen und dann ansehen geht damit nicht. Nicht ohne Nachdenken hatte 
ich deshalb von "einzelnen VHDL-Dateien" geschrieben. Aber offenbar 
wurde der Fehler ja schon lokalisiert...

Ein Tipp: man kann mit den Simulator auch Signale in Submodulen 
auswählen und diese in die Waveform zur genauen Analyse einfügen.

: Bearbeitet durch Moderator
von Ja D. (jacoie)


Lesenswert?

Lattice User schrieb:
Dieser Wert ändert sich viel zu schnell für
> eine 1 kHz PWM.

Tatsächlich :-) Danke an Euch alle

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.