The VHDL module we'll write to fade LEDs is surprisingly and thankfully simple. It's a combo of our log table and a few counters, thus the code is split into two main parts:
-Logrithmic Value Table
-PWM Generation Counters
The table of values is hardcoded in a ROM inside the VHDL. Then when a value is needed the PWM counters insert an address into the ROM and the ROM spits out the correlating logarithmic value.
VHDL ROM
------------« Begin Code »------------
type nums is array(0 to 31) of integer; constant my_nums : nums := ( 0 => 0, 1 => 2, 2 => 4, 3 => 6, 4 => 8, 5 => 10, 6 => 12, 7 => 15, 8 => 18, 9 => 21, 10 => 24, 11 => 28, 12 => 31, 13 => 34, 14 => 38, 15 => 42, 16 => 46, 17 => 51, 18 => 56, 19 => 61, 20 => 66, 21 => 72, 22 => 85, 23 => 93, 24 => 102, 25 => 112, 26 => 123, 27 => 137, 28 => 153, 29 => 174, 30 => 204, 31 => 255 );
------------« End Code »------------
The Main PWM generation code uses some counters and a constant period of 256 clock cycles. A seperate counter constantly counts up to 31 and back to 0, this is what tells the ROM which 0-255 value to use in the main PWM loop.
PWM Pulse Generation
------------« Begin Code »------------
IF(RISING_EDGE(clk))THEN --1 Period = 512 Clock Cycles --Nevative Duty Cycle IF(pwm_cnt = 256-my_nums(int_cnt_0))THEN pwm_cnt := pwm_cnt + 1; LED_OUTPUT(9 DOWNTO 5) <= "00000"; LED_OUTPUT(4 DOWNTO 0) <= "11111"; --Positive Duty Cycle ELSIF(pwm_cnt = 256+my_nums(int_cnt_0))THEN pwm_cnt := 0; LED_OUTPUT(9 DOWNTO 5) <= "11111"; LED_OUTPUT(4 DOWNTO 0) <= "00000"; ELSE pwm_cnt := pwm_cnt + 1; END IF; --Clk_Cnt here will set how fast the LEDs fade in and out. IF(clk_cnt = 500000)THEN --Increment IF(direction = 0)THEN IF(int_cnt_0 = 31)THEN direction := 1; ELSE int_cnt_0 := int_cnt_0 + 1; END IF; clk_cnt := 0; --Decrement ELSE IF(int_cnt_0 = 1)THEN direction := 0; ELSE int_cnt_0 := int_cnt_0 - 1; END IF; clk_cnt := 0; END IF; ELSE clk_cnt := clk_cnt + 1; END IF; END IF;
------------« End Code »------------
After all that wire wrapping and code writing, let's program the CPLD and see how well it works!