PWM

Für ein 16Bit/48kHz PWM wird ein Takt von 2^16*48kHz=3.146 GHz benötigt. Dieser kann noch halbiert werden, da bei der steigenden und fallenden Flanke der PWM-Zähler hochgezählt werden kann.

Auf unserem Board DE0-Nano stehen uns lediglich 50 MHz zur Verfügung. Diese können mit der PLL auf ca. 500MHz hochgetaktet werden. Wir müssen also bei der Bitbreite oder Abtastfrequenz des PWM sparen. z.B: 14Bit/24KHz: 2^14*24kHz/2=196.6MHz

Um die Funktionsweise des PWM zu testen haben wir uns vorerst auf ein 8Bit PWM beschränkt. In folgenden Zeitdiagrammen ist die Funktionsweise deutlich zu sehen:

Bei jedem Nulldurchgang des Zählers T wird der am Eingang X anliegende Weit ins Register X1 gespeichert und der Ausgang Y auf 1 gesetzt (ausser X=0, dann bleibt der Ausgang 0). Danach wird T hochgezählt, bis der Wert von X1 erreicht ist und Y wieder auf 0 gesetzt wird. So ist es nun möglich, ein Rechtecksignal Y zu generieren, dessen Pulsbreite über den digitalen Wert X gesteuert werden kann.

//
// 8 Bit PWM
//
// Clock > 2^8 * srate / 2
// z.B. @ 48 kHz: 6.1 MHz
//
module PWM_8
(SYS_CLK, X, Y, X1, T);
//
input             SYS_CLK;
input [7:0]        X;
//
output            Y;
output    [7:0]    X1;
output    [7:0]    T;
//
wire [7:0]        X;
reg  [7:0]        X1;
reg              Y;
reg  [7:0]        T;

initial begin
    Y <= 0;
    T <= 8'h00;
    X1 <= 8'h00;
end

// always @(SYS_CLK) does not work, why?
always @(posedge SYS_CLK)
begin
    if (T==0) begin
        X1 <= X;
        if(X1 != 0) Y  <= 1;
    end
    else if (T==X1) begin
        Y <= 0;
    end
    T  <= T + 1;
end
endmodule

Quartus Projekt: fpga_synth.zip

 

Join the Conversation

3 Comments

  1. Hier, was ich alles versucht habe, und die entsprechenden Fehlermeldungen:

    // always @(SYS_CLK) does not work, does not trigger, why?

    // always @(posedge SYS_CLK or negedge SYS_CLK): Error (10239): Verilog HDL Always Construct error at PWM_8.v(35): event control cannot test for both positive and negative edges of variable “SYS_CLK”

    // assign NEG_CLK=~SYS_CLK;
    // always @(posedge SYS_CLK or posedge NEG_CLK): Error (10200): Verilog HDL Conditional Statement error at PWM_8.v(36): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct

  2. //
    // 8 Bit PWM testbench for ModelSim
    //
    module PWM_8_tb ();
    reg SYS_CLK;
    reg [7:0] X;
    wire [7:0] T;
    wire Y;

    PWM_8 i1 (
    .SYS_CLK(SYS_CLK),
    .X(X),
    .T(T),
    .Y(Y)
    );

    initial
    begin
    SYS_CLK=0;
    X=0;
    $display(“init done”);
    end

    always
    begin
    repeat (256) begin
    #5 SYS_CLK=1;
    #5 SYS_CLK=0;
    end
    X = X +1;
    end
    endmodule

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.