di2956.txt ;******************************************************************************** ; ; LISTING 1 - AHDL CODE FOR PWM GENERATOR ; ; "PLD code creates PWM generators," EDN, Aug 8, 2002, pg 108 ; ;********************************************************************************* % Simulated and tested 05/29/01 % INCLUDE "LPM_COUNTER.INC"; INCLUDE "LPM_COMPARE.INC"; INCLUDE "LPM_FF.INC"; PARAMETERS ( PWM_WIDTH = 6, -- Bits (set to 6 for testing) AVALUE = B"100000" -- Async reset value ); SUBDESIGN pwm ( clock : INPUT; aclr : INPUT; enable : INPUT = VCC; -- zeros PWM output write : INPUT; -- writes into holding register data[PWM_WIDTH-1..0] : INPUT; q : OUTPUT; -- period_pulse : OUTPUT; -- for debug and ext sync -- cout : OUTPUT; ) VARIABLE pwm : LPM_COUNTER WITH (LPM_WIDTH = PWM_WIDTH, LPM_DIRECTION = "DOWN"); cntr : LPM_COUNTER WITH (LPM_WIDTH = PWM_WIDTH, LPM_DIRECTION = "DOWN"); pwm_ff : SRFF; pwm_reg : LPM_FF WITH (LPM_WIDTH = PWM_WIDTH, LPM_AVALUE = AVALUE); pwm_preout : NODE; period_pulse : NODE; -- for debug and ext sync cout : NODE; BEGIN ASSERT REPORT "PWM_WIDTH: %" PWM_WIDTH SEVERITY INFO; % PWM Holding Register % pwm_reg.clock = clock; pwm_reg.aset = aclr; pwm_reg.enable = write; pwm_reg.data[] = data[]; % PWM Counter % cntr.clock = clock; cntr.aclr = aclr; cntr.cnt_en = enable; period_pulse = DFF(cntr.cout, clock, !aclr, VCC); % PWM Counter % pwm.clock = clock; pwm.aclr = aclr; pwm.sload = cntr.cout; pwm.data[] = pwm_reg.q[]; pwm.cnt_en = enable; cout = pwm.cout; % PWM Output F/F % pwm_ff.clk = clock; pwm_ff.clrn = !aclr; pwm_ff.s = !cout AND period_pulse; -- turn FF on at beginning of interval pwm_ff.r = cout OR !enable; -- turn off at carry overflow. pwm_preout = pwm_ff.q; q = DFF(enable AND pwm_preout, clock, !aclr, VCC); END;