![]() |
8 bit PWM modulator help
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; |
Re: 8 bit PWM modulator help
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. |
Re: 8 bit PWM modulator help
"Garrett Mace" <g.ryan@macetech.com> wrote in message news:<LFKdc.78570$4B1.14812@twister.rdc-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. |
Re: 8 bit PWM modulator help
> > 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. |
Re: 8 bit PWM modulator help
zzarsky@hotmail.com (Mark Zerr) wrote in message news:<b8ba63e7.0404091119.222dc992@posting.google. 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 |
Re: 8 bit PWM modulator help
"valentin tihomirov" <valentin_NOSPAM_NOWORMS@abelectron.com> wrote in message news:<c5be1v$2r5n2n$1@ID-212430.news.uni-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. |
Re: 8 bit PWM modulator help
chtruk@yahoo.com (Marcin) wrote in message news:<cf56decc.0404110812.2ca5b11b@posting.google. 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! |
Re: 8 bit PWM modulator help
> 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. |
Re: 8 bit PWM modulator help
"Garrett Mace" <g.ryan@macetech.com> wrote in message news:<3ezec.84859$4B1.38876@twister.rdc-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. |
Re: 8 bit PWM modulator help
On 12 Apr 2004 06:26:01 -0700, zzarsky@hotmail.com (Mark Zerr) wrote:
>"valentin tihomirov" <valentin_NOSPAM_NOWORMS@abelectron.com> wrote in message news:<c5be1v$2r5n2n$1@ID-212430.news.uni-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 |
| All times are GMT. The time now is 10:43 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.