Gyldengrød <j...@teliamail.dk> wrote in message
news:01be1d79$bb596980$319fe182@sem3gr2.3...
>I´m looking for VHDL code for my FPGA chip to make PWM with freq=40kHz and
>Duty-step 1/256.
I would suggest to use a counter running at system clock. Now you just have
to calculate how many counts you have to do to reach a frequency of 40kHz
(it depends on your system clock). Every step you do count compare the
actual value against the 1/256*max.Value and if this is reached toggle the
PWM Bit. Should be made with following code:
max_value = fSys/fPWM = fSys/40kHz
A = 1/256 * max_value
CONSTANT duty_cycle : INTEGER := A; -- for easy change
of duty cycle ... :-)
..
Signal count_value : Integer Range 0 to max_value;
Signal PWM : STD_LOGIC;
..
PROCESS(CLK)
BEGIN
IF RISING_EDGE(CLK) THEN
IF (count_value < max_value) THEN
count_value <= count_value + 1;
IF (count_value = A) THEN
PWM <= NOT(PWM); -- toggle PWM Bit
END IF;
ELSE
count_value <= 0;
PWM <= '1'; -- assuming you want to
start with '1' level
END IF;
END IF;
END PROCESS;
B4N, CS
Depending on the application, the following "pulse distributor" method
may be preferable. Instead of emitting a single pulse of the right
length, it spreads out the "ON" clock cycles as evenly as possible
over the counter period. The algorithm is familiar from binary rate
multipliers and the Bresenham line-drawing algorithm. This pulse-
distribution trick minimises the low-frequency components in the
output, which is good news if you are trying to low-pass-filter the
output at some later stage in the (analog or power) chain. OTOH it
gives rise to many more transitions on the output, which in a power
application can cause lower efficiency since switching losses are
generally associated with edges. Unlike Carlhermann's solution it
allows both 0% and 100% duty cycle, by using an end-around-carry
trick that makes the PWM signal have a period of (2^N)-1 clocks
instead of the obvious 2^N clocks. The version given here has a
period of 255 clocks; note that the accumulator is NINE bits wide.
Modification to wider or parameterisable size is sraightforward.
'amplitude' is the 8-bit demand value in the range 0..255.
amplitude=0 gives 0%, amplitude=255 gives 100% duty cycle.
==========================================================
Signal acc : std_logic_vector(8 downto 0);
Signal PWM : STD_LOGIC;
PWM <= acc(8);
PROCESS(CLK) BEGIN
IF RISING_EDGE(CLK) THEN
acc <= ('0' & acc(7 downto 0) ) + amplitude + acc(8);
END IF;
END PROCESS;
===========================================================
Note that acc(8) can be fed in to the carry input of the
main adder and so the second addition comes free (if your
synthesis tools are any use).
In practice this gives similar gate counts to the other
method; it uses one N+1 bit adder and register, in place
of one N-bit counter and one N-bit equality comparator.
Hope this is of some interest
Jonathan Bromley
> 'amplitude' is the 8-bit demand value in the range 0..255.
> amplitude=0 gives 0%, amplitude=255 gives 100% duty cycle.
> ==========================================================
> Signal acc : std_logic_vector(8 downto 0);
> Signal PWM : STD_LOGIC;
>
> PWM <= acc(8);
>
> PROCESS(CLK) BEGIN
> IF RISING_EDGE(CLK) THEN
> acc <= ('0' & acc(7 downto 0) ) + amplitude + acc(8);
> END IF;
> END PROCESS;
> ===========================================================
> Note that acc(8) can be fed in to the carry input of the
> main adder and so the second addition comes free (if your
> synthesis tools are any use).
>
> In practice this gives similar gate counts to the other
> method; it uses one N+1 bit adder and register, in place
> of one N-bit counter and one N-bit equality comparator.
>
> Hope this is of some interest
>
> Jonathan Bromley
It's a simple first order DeltaSigma modulator usually drawn like this:
x >--(+)--(+)--[ z^-1 ]-+-[ Q(v) ]--+--- y
-| | | | | +1 if v >= 0
| `----------- | Q(v) = |
`----------------------------- | -1 if v < 0
I not sure but but I think it could have an advantage compared
to the normal PWM, you'll have more transistions, but I think u could
you could do with a lower clockfrequency.
-- Lasse
----------------------------------------------------------
Lasse Langwadt Christensen, M.Sc. EE (to be in 1999)
Aalborg University, Department of communication technology
Applied Signal Processing and Implementation (ASPI)
http://www.kom.auc.dk/~fuz , ICQ# 13068090
> [Jonathan Bromley wrote (snipped) details of a sort of PWM
> generator]
>
>It's a simple first order DeltaSigma modulator usually drawn like this:
>
>
> x >--(+)--(+)--[ z^-1 ]-+-[ Q(v) ]--+--- y
> -| | | | | +1 if v >= 0
> | `----------- | Q(v) = |
> `----------------------------- | -1 if v < 0
>
Clearly this is (a) true, (b) a helpful description;
but I have to confess I'd never thought of it in that way.
Thanks for the insight. It's intriguing how the same basic
ideas turn up in so many different places.
>I not sure but but I think it could have an advantage compared
>to the normal PWM, you'll have more transistions, but I think u could
>you could do with a lower clockfrequency.
For the same kind of "noise shaping" reasons as the delta-sigma
modulator, I think: it pushes the noise spectrum upwards, where
it's out of harm's way and easy to filter out. Or, as I said
(perhaps not very lucidly) in the earlier post, it minimises
the low-frequency components (and in particular the
fCLK/countlimit fundamental) in the PWM output. Hence you
may be able to get away with a lower clock frequency in some
situations.
If switching times at the output are negligible compared with
the clock period, this will be a good thing. For example,
it's the best way to do a bargain-basement D/A converter
on a single output pin of an FPGA: just add a pole or two
of low-pass filtering and voila! a free DAC. But if the PWM is
intended to drive a power stage, I imagine that the penalty of
greatly increased switching losses will more than outweigh the
benefit of simplified filtering, in most cases.
This gadget has always seemed to me to have a very high
"nifty-trick" factor, so I do my best to sell it to people
at every opportunity!
Jonathan Bromley
Jonathan Bromley wrote:
I know this one as an "error-correction-pwm". An other
"nifty-trick" is as follows:
design your pwm as a standard pwm but cross over the bits of the
counter for comparison.
it looks like (formal, not vhdl-like):
counter, dummy_sig, set_value are an n-bit-signals
-- your counter
clk'event and clk='1'
counter <= counter +1
-- now do the crossing (no additional logic, just wires)
dummy_sig(n-1) <= counter(0)
dummy_sig(n-2) <= counter(1)
...
dummy_sig(0) <= counter(n-1)
-- your comparator
if ( set_value < dummy_sig)
output <= '1'
else
output <= '0'
end if
This is indeed very easy, because you don't have to spent an extra bit
in your counter as in the solutiuon above. You can use the same design,
but with better results...Don't forget the negatives: You will get high-
frequencies emissions, so do not use it for driving a power stage amplifier.
Hagen