A PWM generator creates a signal that switches on and off quickly to control power or speed, like dimming a light or controlling a motor.
PWM generator in VHDL
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pwm_generator is port( clk : in std_logic; reset : in std_logic; duty : in unsigned(7 downto 0); -- duty cycle 0-255 pwm_out : out std_logic ); end pwm_generator; architecture Behavioral of pwm_generator is signal counter : unsigned(7 downto 0) := (others => '0'); begin process(clk, reset) begin if reset = '1' then counter <= (others => '0'); pwm_out <= '0'; elsif rising_edge(clk) then if counter < 255 then counter <= counter + 1; else counter <= (others => '0'); end if; if counter < duty then pwm_out <= '1'; else pwm_out <= '0'; end if; end if; end process; end Behavioral;
The duty input controls how long the output stays high in one cycle.
The counter runs from 0 to 255 to create a full PWM cycle.
duty <= to_unsigned(128, 8); -- 50% duty cycle
duty <= to_unsigned(64, 8); -- 25% duty cycle
duty <= to_unsigned(255, 8); -- 100% duty cycle
This program creates a PWM signal with a 50% duty cycle, then changes it to 25%, and finally to 100%. The testbench simulates the clock and shows how the output changes over time.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pwm_generator is port( clk : in std_logic; reset : in std_logic; duty : in unsigned(7 downto 0); pwm_out : out std_logic ); end pwm_generator; architecture Behavioral of pwm_generator is signal counter : unsigned(7 downto 0) := (others => '0'); begin process(clk, reset) begin if reset = '1' then counter <= (others => '0'); pwm_out <= '0'; elsif rising_edge(clk) then if counter < 255 then counter <= counter + 1; else counter <= (others => '0'); end if; if counter < duty then pwm_out <= '1'; else pwm_out <= '0'; end if; end if; end process; end Behavioral; -- Testbench to simulate PWM output library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity pwm_tb is end pwm_tb; architecture Behavioral of pwm_tb is signal clk : std_logic := '0'; signal reset : std_logic := '1'; signal duty : unsigned(7 downto 0) := (others => '0'); signal pwm_out : std_logic; constant clk_period : time := 10 ns; begin uut: entity work.pwm_generator port map( clk => clk, reset => reset, duty => duty, pwm_out => pwm_out ); clk_process : process begin while true loop clk <= '0'; wait for clk_period / 2; clk <= '1'; wait for clk_period / 2; end loop; end process; stim_proc: process begin wait for 20 ns; reset <= '0'; duty <= to_unsigned(128, 8); -- 50% duty cycle wait for 2600 ns; duty <= to_unsigned(64, 8); -- 25% duty cycle wait for 2600 ns; duty <= to_unsigned(255, 8); -- 100% duty cycle wait; end process; end Behavioral;
In real hardware, the PWM frequency depends on the clock speed and counter size.
Changing the duty cycle changes how long the output stays high in each cycle.
Resetting the counter ensures the PWM starts cleanly.
PWM generator creates a signal that switches on and off to control power.
Duty cycle controls how long the signal stays on in each cycle.
VHDL uses a counter and compares it to the duty cycle to create PWM.
Practice
Solution
Step 1: Understand PWM function
PWM (Pulse Width Modulation) generates a signal that switches on and off rapidly.Step 2: Identify purpose in power control
This switching controls the power delivered to devices by changing the duty cycle.Final Answer:
To create a signal that switches on and off quickly to control power -> Option AQuick Check:
PWM controls power by switching signal [OK]
- Confusing PWM with memory storage
- Thinking PWM does arithmetic
- Assuming PWM generates random signals
Solution
Step 1: Identify correct VHDL assignment syntax
In VHDL, signal assignment uses '<=' and conditional assignment uses 'when ... else'.Step 2: Match correct comparison and syntax
pwm_out <= '1' when counter < duty_cycle else '0'; uses '<=' and 'when ... else' with correct comparison 'counter < duty_cycle'.Final Answer:
pwm_out <= '1' when counter < duty_cycle else '0'; -> Option CQuick Check:
VHDL signal conditional assignment = pwm_out <= '1' when counter < duty_cycle else '0'; [OK]
- Using ':=' instead of '<=' for signals
- Using 'if' instead of 'when' in signal assignment
- Using '=' for assignment instead of comparison
process(clk)
begin
if rising_edge(clk) then
if counter < duty_cycle then
pwm_out <= '1';
else
pwm_out <= '0';
end if;
if counter = max_count then
counter <= 0;
else
counter <= counter + 1;
end if;
end if;
end process;What is the value of
pwm_out when counter is 3 and duty_cycle is 5?Solution
Step 1: Compare counter and duty_cycle values
Counter is 3, duty_cycle is 5, so 3 < 5 is true.Step 2: Determine pwm_out value based on condition
Since counter < duty_cycle, pwm_out is assigned '1'.Final Answer:
'1' -> Option BQuick Check:
3 < 5 means pwm_out = '1' [OK]
- Confusing '<' with '>' in condition
- Assuming pwm_out is '0' when counter < duty_cycle
- Ignoring the process clock edge condition
process(clk)
begin
if clk'event and clk = '1' then
if counter <= duty_cycle then
pwm_out <= '1';
else
pwm_out <= '0';
end if;
if counter = max_count then
counter <= 0;
else
counter <= counter + 1;
end if;
end if;
end process;Solution
Step 1: Check clock edge detection method
Using 'clk'event and clk = '1' is legal but less safe than rising_edge(clk).Step 2: Identify best practice for clock edge
rising_edge(clk) is preferred for clarity and synthesis compatibility.Final Answer:
Using 'clk'event and clk = '1' instead of rising_edge(clk) -> Option AQuick Check:
Use rising_edge(clk) for clock detection [OK]
- Using 'clk'event and clk = '1' which is outdated
- Confusing '<=' with '<' in duty cycle comparison
- Ignoring reset logic necessity
Solution
Step 1: Understand dynamic frequency and duty cycle needs
Changing frequency means changing the PWM period, so a period counter is needed.Step 2: Use counters for period and duty cycle comparison
One counter tracks the period length, another compares to duty cycle to set output.Step 3: Allow dynamic updates
Both counters and duty cycle values must be variable to change PWM parameters on the fly.Final Answer:
Use two counters: one for period (frequency) and one for duty cycle comparison, both updated dynamically -> Option DQuick Check:
Two counters enable dynamic frequency and duty cycle [OK]
- Fixing duty cycle or frequency at compile time
- Using asynchronous signals causing glitches
- Trying to change frequency without a period counter
Ready to prove it?
Pass the test and this pattern moves unknown
