Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > 8 bit PWM modulator help

Reply
Thread Tools

8 bit PWM modulator help

 
 
Mark Zerr
Guest
Posts: n/a
 
      04-09-2004
I am currently working on a 8 bit pulse width modulator circuit for a
graduate level Digital Design course. I have a couple problems with
my current code. I am using Altera's UP-1 education board with a Flex
10K CPLD. I am using Altera's Max Plus II Baseline educational
license for VHDL compiling and simulating. I am passing the PWM
output to all 8 segments of one of the LEDs on the board and using the
8 bit switch block for user control.

1. My counter seems to double count 1111 1111 and 0000 0000. This
does not really affect the operation, except that the counter causes
the overall PWM output's period to last 2 clock cycles longer than it
should.

2. Do I really need a clock divider process to be able to slow down
the PWM train to accurately be able to use the PWM output to vary the
LED brightness? Currently, I reduce the 25 Mhz clock down to about
123 Khz, which gives 240 PWM periods per second.

3. I have a glitch on the 1111 1111 control input condition caused by
my bad counter issue in #1 above. Not a big deal, but I like my stuff
to be perfect.


Here is my current code...any help or suggestions for improving it are
welcomed.

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.all;
USE IEEE.STD_LOGIC_ARITH.all;
USE IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY PWM_8BIT is
PORT( clk, RESET : IN STD_LOGIC;
CONTROL : IN STD_LOGIC_VECTOR(7 downto 0);
COUNT_OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
PWM_LED_OUT : OUT STD_LOGIC_VECTOR(7 downto 0);
CLK_DIV_OUT : OUT STD_LOGIC);
END PWM_8BIT;

ARCHITECTURE ARCHI of PWM_8BIT is
SIGNAL clk_div : STD_LOGIC;
SIGNAL COUNT_ALL : STD_LOGIC_VECTOR(7 downto 0);
SIGNAL CONTROL_INT : STD_LOGIC_VECTOR(7 downto 0);
SIGNAL PWM_INT : STD_LOGIC_VECTOR(7 downto 0);

BEGIN
CONTROL_INT <= CONTROL; --Store the User input in a signal

-- An up/down counter
PROCESS (clk_div, RESET)
VARIABLE UP_DOWN_INT : STD_LOGIC;
VARIABLE COUNT_INT : STD_LOGIC_VECTOR(7 downto 0);
VARIABLE DIRECTION : INTEGER;

BEGIN
IF RESET = '0' THEN --If RESET than count goes to "0"
COUNT_INT := "00000000";
ELSE
IF COUNT_INT = "00000000" THEN --Find the count direction
UP_DOWN_INT := '1';
END IF;
IF COUNT_INT = "11111111" THEN
UP_DOWN_INT := '0';
END IF;

IF UP_DOWN_INT = '1' THEN --Inc or dec selection
DIRECTION := 1;
ELSE
DIRECTION := -1;
END IF;

IF (clk_div'EVENT AND clk_div = '1') THEN --Update the counter on
the clock edge
COUNT_INT := COUNT_INT + DIRECTION;
END IF;
END IF;

COUNT_OUT <= COUNT_INT; --Copy the count to the output pins
COUNT_ALL <= COUNT_INT; --Pass the count to an internal signal
END PROCESS;

--Comparator Logic
PROCESS (clk_div, RESET)
BEGIN
IF RESET = '0' THEN --If reset then make pwm-->0
PWM_INT <= "11111111";
ELSE
IF COUNT_ALL >= CONTROL_INT THEN --Compare the count to the control
input value
PWM_INT <= "11111111"; --if bigger, then turn on the pwm
ELSE
PWM_INT <= "00000000"; --if smaller, then turn off the pwm
END IF;
END IF;
END PROCESS;

--Hack the PWM output if it is screwed up!
PROCESS (clk_div, RESET)
BEGIN
IF (clk_div'EVENT AND clk_div = '1') THEN --This makes sure the PWM
only changes on an edge
-- IF CONTROL_INT = "11111111" THEN --This stuff attempts to fix
"11111111" condition.
-- PWM_LED_OUT <= "00000000"; --This stuff attempts to fix
"11111111" condition.
-- ELSE --This stuff attempts to fix "11111111" condition.
PWM_LED_OUT <= PWM_INT;
-- END IF; --This stuff attempts to fix "11111111" condition.
END IF;
END PROCESS;

--Stupid clock divider
PROCESS(clk)
VARIABLE i : INTEGER range 0 to 100 := 0;
BEGIN
IF clk'event AND clk = '1' THEN
IF i = 100 THEN
i := 0;
clk_div <= NOT clk_div;
ELSE
i := i + 1;
END IF;
END IF;
CLK_DIV_OUT <= clk_div;
END PROCESS;

END ARCHI;
 
Reply With Quote
 
 
 
 
Garrett Mace
Guest
Posts: n/a
 
      04-10-2004
1. Is your up/down counter REALLY behaving the way you want it to? Is there
anything about your end-value comparisons that might keep your up/down
toggles from being activated in the current clock cycle?

2. Do you really even need an up/down counter, instead of a simple counter
that just rolls over to zero?

I haven't looked at the code very hard, but these might be two things to
consider.


 
Reply With Quote
 
 
 
 
Mark Zerr
Guest
Posts: n/a
 
      04-10-2004
"Garrett Mace" <(E-Mail Removed)> wrote in message news:<LFKdc.78570$(E-Mail Removed)-kc.rr.com>...
> 1. Is your up/down counter REALLY behaving the way you want it to? Is there
> anything about your end-value comparisons that might keep your up/down
> toggles from being activated in the current clock cycle?


I suspect this is my problem, but I cannot figure out what is wrong
with my programming as it is currently coded.

>
> 2. Do you really even need an up/down counter, instead of a simple counter
> that just rolls over to zero?


Yes, it must be an up/down counter....it is a requirement of the
project to simulate a triangular wave for the comparison to generate
the PWM train output.


>
> I haven't looked at the code very hard, but these might be two things to
> consider.



Thanks for your help though....any other ideas comments are
appreciated.
 
Reply With Quote
 
valentin tihomirov
Guest
Posts: n/a
 
      04-11-2004

> > 2. Do you really even need an up/down counter, instead of a simple

counter
> > that just rolls over to zero?

>
> Yes, it must be an up/down counter....it is a requirement of the
> project to simulate a triangular wave for the comparison to generate
> the PWM train output.

What are advantages of traingular over saw-edged wave? BTW, they both are
triangular.


 
Reply With Quote
 
Marcin
Guest
Posts: n/a
 
      04-11-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (Mark Zerr) wrote in message news:<(E-Mail Removed). com>...
> I am currently working on a 8 bit pulse width modulator circuit for a
> graduate level Digital Design course. I have a couple problems with
> my current code. I am using Altera's UP-1 education board with a Flex
> 10K CPLD. I am using Altera's Max Plus II Baseline educational
> license for VHDL compiling and simulating. I am passing the PWM
> output to all 8 segments of one of the LEDs on the board and using the
> 8 bit switch block for user control.
>
> 1. My counter seems to double count 1111 1111 and 0000 0000. This
> does not really affect the operation, except that the counter causes
> the overall PWM output's period to last 2 clock cycles longer than it
> should.
>
> 2. Do I really need a clock divider process to be able to slow down
> the PWM train to accurately be able to use the PWM output to vary the
> LED brightness? Currently, I reduce the 25 Mhz clock down to about
> 123 Khz, which gives 240 PWM periods per second.
>
> 3. I have a glitch on the 1111 1111 control input condition caused by
> my bad counter issue in #1 above. Not a big deal, but I like my stuff
> to be perfect.
>
>
> Here is my current code...any help or suggestions for improving it are
> welcomed.


Mark,

Look carefully at the sensitivity list - comparator logic is simple
combinational logic. I will change it to: PROCESS (COUNT_ALL,
CONTROL_INT, RESET)

[...]
> --Comparator Logic
> PROCESS (clk_div, RESET)
> BEGIN
> IF RESET = '0' THEN --If reset then make pwm-->0
> PWM_INT <= "11111111";
> ELSE
> IF COUNT_ALL >= CONTROL_INT THEN --Compare the count to the control
> input value
> PWM_INT <= "11111111"; --if bigger, then turn on the pwm
> ELSE
> PWM_INT <= "00000000"; --if smaller, then turn off the pwm
> END IF;
> END IF;
> END PROCESS;
>

[...]

Stupid clock divider is really stupid without reset

> --Stupid clock divider
> PROCESS(clk)
> VARIABLE i : INTEGER range 0 to 100 := 0;
> BEGIN
> IF clk'event AND clk = '1' THEN
> IF i = 100 THEN
> i := 0;
> clk_div <= NOT clk_div;
> ELSE
> i := i + 1;
> END IF;
> END IF;
> CLK_DIV_OUT <= clk_div;
> END PROCESS;
>
> END ARCHI;


I hope this help a little.

Marcin
 
Reply With Quote
 
Mark Zerr
Guest
Posts: n/a
 
      04-12-2004
"valentin tihomirov" <(E-Mail Removed)> wrote in message news:<c5be1v$2r5n2n$(E-Mail Removed)-berlin.de>...
> > > 2. Do you really even need an up/down counter, instead of a simple

> counter
> > > that just rolls over to zero?

> >
> > Yes, it must be an up/down counter....it is a requirement of the
> > project to simulate a triangular wave for the comparison to generate
> > the PWM train output.

> What are advantages of traingular over saw-edged wave? BTW, they both are
> triangular.


To be honest....I would have not even wanted to use an up/down
counter. I would have simply counted from 0 to max...with the middle
being the the pseudo cross over point for the "triangular" wave. For
some reason my professor wanted a true up/down counter. I think it
was to show the problems that can arise when designing a counter like
this. As for the saw toothed wave, I am not sure what the advantage
of that wave would be compared to the way I am doing it now. In all
reality it does not matter. The circuit works perfectly fine right
now, but I was curious if I was missing some good design principles,
since I am so new to vhdl.
 
Reply With Quote
 
Mark Zerr
Guest
Posts: n/a
 
      04-12-2004
(E-Mail Removed) (Marcin) wrote in message news:<(E-Mail Removed). com>...

>
> Mark,
>
> Look carefully at the sensitivity list - comparator logic is simple
> combinational logic. I will change it to: PROCESS (COUNT_ALL,
> CONTROL_INT, RESET)
>


Yes this is a good point. I have changed the sensitivity list.
Sometimes I still get confused about the proper sensitivities for a
given process. VHDL is very foreign to me since everything is
happening concurrently. This type of programming caused me major
headaches when I first started learning a couple weeks ago.

>
> Stupid clock divider is really stupid without reset
>
>
> I hope this help a little.
>
> Marcin


I agree that my clock divider should have a reset. This has been
fixed. It was an oversight...trust me!

Thanks for your input Marcin!
 
Reply With Quote
 
Garrett Mace
Guest
Posts: n/a
 
      04-12-2004

> To be honest....I would have not even wanted to use an up/down
> counter. I would have simply counted from 0 to max...with the middle
> being the the pseudo cross over point for the "triangular" wave. For
> some reason my professor wanted a true up/down counter. I think it
> was to show the problems that can arise when designing a counter like
> this. As for the saw toothed wave, I am not sure what the advantage
> of that wave would be compared to the way I am doing it now. In all
> reality it does not matter. The circuit works perfectly fine right
> now, but I was curious if I was missing some good design principles,
> since I am so new to vhdl.



A saw-toothed "wave" is simpler to understand and implement. Part of a
project I did a while back was generating eight different sine waves through
PWM. I used one very simple PWM clock that looked like this:

***
entity PWMClock is
port (
CLK, Enable, RST : in std_logic;
PWMClockOut : out std_logic_vector(7 downto 0)
);
end PWMClock;

architecture PWM of PWMClock is

signal PWMTemp : std_logic_vector(7 downto 0);

begin

process (CLK, RST)
begin
if (RST = '1') then
PWMTemp <= "00000000";
elsif (rising_edge(CLK) and Enable = '1') then
PWMTemp <= PWMTemp + 1;
end if;
end process;

PWMClockOut <= PWMTemp;

end PWM;
***



This was a "sawtooth wave," merely a counter that rolls over. Then the eight
PWM modules all used this same clock. The actual PWM output modules were
also very simple:



***
entity PWMOutput is
port (
RST : in std_logic;
PWMLevel, PWMClock : in std_logic_vector(7 downto 0);
PWMOut : out std_logic
);
end PWMOutput;

architecture PWM of PWMOutput is

signal PWMOutTemp : std_logic;

begin

process (PWMClock, RST) is

begin

if (PWMClock = "00000000") then
PWMOutTemp <= '1';
elsif (PWMClock = PWMLevel or RST = '1') then
PWMOutTemp <= '0';
end if;

end process;

PWMOut <= PWMOutTemp;

end PWM;
***

PWMLevel was piped in from a sine table. As you can see, the PWM module just
checked for equality and then toggled a flip-flop, to turn off the output
once the PWM value had been reached. This was Xilinx VHDL instead of Altera,
so some parts might be less familiar to you. There may be a more optimized
solution for PWM if you work in structural instead of behavioral, but this
is pretty simple.


 
Reply With Quote
 
Mark Zerr
Guest
Posts: n/a
 
      04-13-2004
"Garrett Mace" <(E-Mail Removed)> wrote in message news:<3ezec.84859$(E-Mail Removed)-kc.rr.com>...
>
> A saw-toothed "wave" is simpler to understand and implement. Part of a
> project I did a while back was generating eight different sine waves through
> PWM. I used one very simple PWM clock that looked like this:
>
> ***
> entity PWMClock is
> port (
> CLK, Enable, RST : in std_logic;
> PWMClockOut : out std_logic_vector(7 downto 0)
> );
> end PWMClock;
>
> architecture PWM of PWMClock is
>
> signal PWMTemp : std_logic_vector(7 downto 0);
>
> begin
>
> process (CLK, RST)
> begin
> if (RST = '1') then
> PWMTemp <= "00000000";
> elsif (rising_edge(CLK) and Enable = '1') then
> PWMTemp <= PWMTemp + 1;
> end if;
> end process;
>
> PWMClockOut <= PWMTemp;
>
> end PWM;
> ***
>
>
>
> This was a "sawtooth wave," merely a counter that rolls over. Then the eight
> PWM modules all used this same clock. The actual PWM output modules were
> also very simple:
>


OK...this makes sense.

>
>
> ***
> entity PWMOutput is
> port (
> RST : in std_logic;
> PWMLevel, PWMClock : in std_logic_vector(7 downto 0);
> PWMOut : out std_logic
> );
> end PWMOutput;
>
> architecture PWM of PWMOutput is
>
> signal PWMOutTemp : std_logic;
>
> begin
>
> process (PWMClock, RST) is
>
> begin
>
> if (PWMClock = "00000000") then
> PWMOutTemp <= '1';
> elsif (PWMClock = PWMLevel or RST = '1') then
> PWMOutTemp <= '0';
> end if;
>
> end process;
>
> PWMOut <= PWMOutTemp;
>
> end PWM;
> ***
>
> PWMLevel was piped in from a sine table. As you can see, the PWM module just
> checked for equality and then toggled a flip-flop, to turn off the output
> once the PWM value had been reached. This was Xilinx VHDL instead of Altera,
> so some parts might be less familiar to you. There may be a more optimized
> solution for PWM if you work in structural instead of behavioral, but this
> is pretty simple.


Yeah...I see where you are going now...this is a nice method. I have
decided that my current glitch is not that big of deal though, and I
intend to just leave it the way I am currently doing it. Thanks for
all the input though...it was interesting learning another way to
accomplish this circuit.
 
Reply With Quote
 
Brian Drummond
Guest
Posts: n/a
 
      04-14-2004
On 12 Apr 2004 06:26:01 -0700, (E-Mail Removed) (Mark Zerr) wrote:

>"valentin tihomirov" <(E-Mail Removed)> wrote in message news:<c5be1v$2r5n2n$(E-Mail Removed)-berlin.de>...
>> > > 2. Do you really even need an up/down counter, instead of a simple

>> counter
>> > > that just rolls over to zero?
>> >
>> > Yes, it must be an up/down counter....it is a requirement of the
>> > project to simulate a triangular wave for the comparison to generate
>> > the PWM train output.

>> What are advantages of traingular over saw-edged wave? BTW, they both are
>> triangular.

>
>To be honest....I would have not even wanted to use an up/down
>counter. I would have simply counted from 0 to max...with the middle
>being the the pseudo cross over point for the "triangular" wave. For
>some reason my professor wanted a true up/down counter.


Single-sided PWM (sawtooth) and double-sided PWM (triangle) have
different distortion characteristics, double sided having lower
distortion because it isn't also a form of PPM (pulse position
modulation). Perhaps this is what your professor is looking for?

- Brian
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
PWM using FPGA iceman VHDL 10 03-29-2011 03:21 PM
Verilog PWM DC motor carl12 VHDL 0 02-24-2009 12:58 AM
Is pwm Python MegaWidgets viable? Paul Watson Python 4 04-04-2006 12:08 AM
Adaptation from PI output to PWM??? nesppi@gmail.com VHDL 0 01-17-2006 07:47 PM
need help with RF modulator and VHS dubbing Deb Digital Photography 9 11-04-2003 03:55 PM



Advertisments