Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
14 years ago

Generate PWM signal

Hello everyone,

I am new in fpga and right now I need to generate PWM signal.

I do not understand how the following syntax work in order to generate PWM.

1. module PWM(clk, PWM_in, PWM_out);

2. input clk;

3. input [7:0] PWM_in;

4. output PWM_out;

5. reg [8:0] PWM_accumulator;

6. always @(posedge clk) PWM_accumulator <= PWM_accumulator[7:0] + PWM_in;

7. assign PWM_out = PWM_accumulator[8];

8. endmodule

How could the positive edge signal of 'PWM_accumulator <= PWM_accumulator[7:0] + PWM_in' become PWM signal?

What is your suggestion about this syntax?

Thank you very much.

11 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    To understand this issue I have this overview of modulo adder accumulator in general:

    It is very flexible and of several uses. It is just an adder that accumulates its input (for ever) and is allowed up to a maximum called modulus. for example modulo 512 adder runs from 0 to 511 (or 1 to 512 if zero not allowed by tool).

    It does not have to be binary but can be any value modulus. The binary case is simple to implement, just let it go freely.

    The flexibility comes when you choose input value (increment). The increment can be anything from 1 and up modulus-1.

    (1) The accumulator can be used to to generate regular addressing for waveform generators i.e. it acts as phase indicators in DSP terms.

    It is used in DDS(NCO) under the name phase accumulator.

    In this application, the accumulator can be as wide as the address or much much wider to increase phase resolution in which case only the MSB of result are used for addressing thus it is better called phase accumulator than address generator.

    (2) It is also used in cases of sampling rate converters as polyphase indicators i.e. which subfilter to choose.

    (3) can be used to generate any rate clock enable from a given clock

    for example you have a clock at 10MHz and want to generate 1.2288MHz then run an accumulator at a ratio of 12288/100000

    (or reduce the ratio down) i.e. add 12288 modulo 10,0000 then your clock enable is the overflow pulse.

    (4) similarly, in this thread we used it as duty cycle generator by looking at its MSB(option 1) or deciding a new comparator result (option 2).

    In all above cases, you can visualise an accumulator in space as a wheel e.g. of values from 0 to 15 and an arrow that starts from say zero. when you add incr value of say 7, arrow moves to new location at 7 then 14 then wraps around the wheel to 6 (21-15) and so on carrying info of first cycle into next.

    It will overflow at a rate of 7/15 of given clock that runs it.

    If you look at MSB of this accumulator then it will alternate between zero and one. In other words, zero in the first half of the wheel and one in the second half of the wheel. The ratio of 0/1 will tend to be equal because there is equal probability of both halves of the wheel in a binary adder. The increment 7 will just decide how quickly you move from first half to next half and back. If incr = 1 then that is the slowest case naturally as you run full wheel from one location to next without any jump.

    To work as duty cycle generator, we have to alter the ratio of 0/1 probabilty by not allowing the wheel to go free binary(one option). Or by looking at another bit (rather than MSB of accumulator) that compares accumulator result against a ref point that is not just half of max but anywhere.