Create a gist now

Instantly share code, notes, and snippets.

@jjcarrier /PWM.vhd
Last active Dec 29, 2015

What would you like to do?
A parameterized PWM module written in VHDL
-- Written By Jon Carrier
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.numeric_std.all;
entity PWM is
generic (
prescale: integer := 0; --frequency(PWM_clk)=frequency(i_CLK/(prescale+1))
quantas: integer := 8 --PWM stages, determines granularity
port (
i_CLK: in std_logic; --Main input clock signal
i_PWM: in std_logic_vector(31 downto 0); --Controls the Duty Cycle of o_PWM
o_PWM: out std_logic := '1' --The Pulse Width Modulated output signal
end PWM;
architecture PWM_arch of PWM is
signal PWM_clk : std_logic :='0';
signal PWM_acc : std_logic_vector(31 downto 0) := x"00000000";
--Generates the clock divided signal, frequency(PWM_clk)=frequency(i_CLK/(prescale+1))
--PWM_clk drives the rest of the PWM logic
prescale_proc: process(i_CLK)
variable prescale_cnt : std_logic_vector(31 downto 0) := x"00000000";
if rising_edge(i_CLK) then
if prescale_cnt >= prescale then
prescale_cnt := x"00000000";
PWM_clk <= not PWM_clk;
prescale_cnt := prescale_cnt + 1;
end if;
end if;
end process;
--Generates the accumlation variable PWM_acc
--This variable is used in the PWM as a means to determine
--when the PWM signal should switch.
accumulate: process(PWM_clk)
if falling_edge(PWM_clk) then
if PWM_acc >= std_logic_vector(to_unsigned(quantas - 1, PWM_acc'length)) then
PWM_acc <= x"00000000";
PWM_acc <= PWM_acc + 1;
end if;
end if;
end process;
--Generates the PWM output signal, o_PWM
--i_PWM controls the output and specifies how many Time Quantas
--out of a Total Quanta the output must be set HIGH
modulate: process(PWM_clk, i_PWM)
if rising_edge(PWM_clk) then
if PWM_acc >= i_PWM then
o_PWM <= '0';
elsif PWM_acc = x"00000000" then
o_PWM <= '1';
end if;
end if;
end process;
end PWM_arch;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment