--! --! @file pwm_gen.vhd --! @brief Generic width PWM --! --! 1 output WIDTH bit PWM, with enable (for clock division) --! --! @par License: --! Creative Commons Attribution-ShareAlike --! http://creativecommons.org/licenses/by-sa/3.0/ --! --! @par Authors: --! Sylvain MIERMONT --! --! @par Id: $Id$ --! library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; entity pwm_gen is generic ( WIDTH : positive := 8 ); port ( reset_n : in std_logic; clk : in std_logic; enable : in std_logic; -- enable counting value : in std_logic_vector((WIDTH - 1) downto 0); pwm_out : out std_logic ); end entity pwm_gen; architecture RTL of pwm_gen is signal cpt_r : unsigned((WIDTH - 1) downto 0); signal value_r : unsigned((WIDTH - 1) downto 0); begin -- WIDTH bit counter counting from 0 to (2^WIDTH)-2, not (2^WIDTH)-1 master_cpt: process(clk, reset_n) begin if reset_n = '0' then cpt_r <= to_unsigned(0, WIDTH); elsif rising_edge(clk) and enable = '1' then if cpt_r = to_unsigned((2**WIDTH)-2, WIDTH) then cpt_r <= to_unsigned(0, WIDTH); else cpt_r <= cpt_r + 1; end if; end if; end process master_cpt; -- WIDTH bit register to hold the value reg_value: process(clk, reset_n) begin if reset_n = '0' then value_r <= x"00"; elsif rising_edge(clk) and cpt_r = to_unsigned((2**WIDTH)-2, WIDTH) and enable = '1' then value_r <= unsigned(value); end if; end process reg_value; -- decision logic pwm_logic: process(clk, reset_n) begin if reset_n = '0' then pwm_out <= '0'; elsif rising_edge(clk) and enable = '1' then if cpt_r = x"00" then pwm_out <= '1'; end if; if cpt_r >= value_r then pwm_out <= '0'; end if; end if; end process pwm_logic; end architecture RTL;