Introduction ============ Pulse width modulation (PWM) is a technique to generate periodic waveforms with adjustable duty cycles. PWM is used in many application areas like communications, power control, measurement, AD/DA-conversion, etc. [[1]](https://en.wikipedia.org/wiki/Pulse-width_modulation) Features ======== * default 8-bit resolution * 8-bit control word input * Enable input for external prescaler to control PWM period General Description =================== ![Pulse Width Modulator - Schematic Symbol](images/pwm.svg){width=40%} | **Name** | **Type** | **Direction** | **Polarity** | **Description** | |-------------|----------------------|:-------------:|:------------:|-----------------| | clk_i | std_ulogic | IN | HIGH | | | rst_ni | std_ulogic | IN | LOW | | | en_pi | std_ulogic | IN | HIGH | | | pwm_width_i | std_ulogic_vector[8] | IN | HIGH | 8-bit control input word | | pwm_o | std_ulogic | OUT | HIGH | | : Pulse Width Modulator - Description of I/O Signals Functional Description ====================== A mod-256 counter ... Design Description ================== A conceptional RTL diagram is shown below. ![Pulse Width Modulator - Conceptional RTL](images/pwm_conceptional_rtl.svg){width=60%} The simulation result shows the corner cases minimum, maximum, switched off, and a cuty cycle of 50 %. ![Pulse Width Modulator - Simulation Result](images/pwm_simwave.png){width=80%} In more detail using cursors to display a PWM frequency of f~PWM~=21.7kHz ![Pulse Width Modulator - 21.7 kHz - Simulation Result](images/pwm_21.7kHz_simwave.png){width=80%} Device Utilization and Performance ================================== The following table shows the utilisation of both modules pwm and cntdnmodm. The following results are extracted from ```pure pnr/de1_pwm/de1_pwm.fit.rpt ``` ```pure +--------------------------------------------------------------------------------------+ ; Fitter Summary ; +------------------------------------+-------------------------------------------------+ ``` The following results are extracted from ```pure de1_pwm.sta.rpt ``` ```pure +----------------------------------------------------------------------------------------+ ; TimeQuest Timing Analyzer Summary ; +--------------------+-------------------------------------------------------------------+ -----------------------------------------+ ; Clocks ; +------------+------+--------+-----------+ +-----------------------------------------------------------------------------+ ; Multicorner Timing Analysis Summary ; +------------------+-------+-------+----------+---------+---------------------+ ``` Application Note ================ The following test environment on a DE1 prototype board uses a system clock frequency of 50 MHz. A prescaler is parameterised to generate an output signal with a period of 46.08 us. ![Test Environment on DE1 Prototype Board](images/de1_pwm_schematic.svg){width=70%} Appendix ======== References ---------- * [Wiki: Pulse Width Modulation](https://en.wikipedia.org/wiki/Pulse-width_modulation) Project Hierarchy ----------------- ### Module Hierarchy for Verification ```pure t_pwm(tbench) pwm(rtl) ``` ### Prototype Environment ```pure de1_pwm(structure) pwm(rtl) cntdnmodm(rtl) ``` VHDL Sources ------------ ```vhdl LIBRARY ieee; USE IEEE.std_logic_1164.ALL; USE IEEE.numeric_std.ALL; ENTITY pwm IS PORT( clk_i : IN std_ulogic; -- clock input rst_ni : IN std_ulogic; -- reset L-active en_pi : IN std_ulogic; -- enable H-active pwm_width_i : IN std_ulogic_vector(7 DOWNTO 0); -- width of pulse pwm_o : OUT std_ulogic); -- pwm output END pwm; ARCHITECTURE rtl OF pwm IS SIGNAL next_state, current_state : unsigned(7 DOWNTO 0); -- states SIGNAL buf_next : std_ulogic; -- output buffer BEGIN next_state_logic : next_state <= state_register : current_state <= (OTHERS => '0') WHEN rst_ni = '0' ELSE next_state WHEN rising_edge(clk_i) AND (en_pi = '1'); counter_output : buf_next <= -- output buffer output_register : pwm_o <= END rtl; ``` Revision History ---------------- | **Date** | **Version** | **Change Summary** | |:----------|:-------------|:--------------------| | May 2022 | 0.1 | Initial Release | | April 2022 | 0.2 | Added VHDL code |