| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| library IEEE; |
| use IEEE.STD_LOGIC_1164.all; |
| use IEEE.NUMERIC_STD.all; |
| |
| library PoC; |
| use PoC.utils.all; |
| use PoC.physical.all; |
| |
| |
| entity [docs]io_PulseWidthModulation is |
| generic ( |
| CLOCK_FREQ : FREQ := 100 MHz; |
| PWM_FREQ : FREQ := 1 kHz; |
| PWM_RESOLUTION : positive := 8 |
| ); |
| port ( |
| Clock : in std_logic; |
| Reset : in std_logic; |
| PWMIn : in std_logic_vector(PWM_RESOLUTION - 1 downto 0); |
| PWMOut : out std_logic |
| ); |
| end entity; |
| |
| |
| architecture [docs]rtl of io_PulseWidthModulation is |
| constant PWM_STEPS : positive := 2**PWM_RESOLUTION; |
| constant PWM_STEP_FREQ : FREQ := PWM_FREQ * (PWM_STEPS - 1); |
| constant PWM_FREQUENCYCOUNTER_MAX : positive := (CLOCK_FREQ+PWM_STEP_FREQ-1 Hz) / PWM_STEP_FREQ; |
| constant PWM_FREQUENCYCOUNTER_BITS : positive := log2ceilnz(PWM_FREQUENCYCOUNTER_MAX); |
| |
| signal PWM_FrequencyCounter_us : unsigned(PWM_FREQUENCYCOUNTER_BITS downto 0) := (others => '0'); |
| signal PWM_FrequencyCounter_ov : std_logic; |
| signal PWM_PulseCounter_us : unsigned(PWM_RESOLUTION - 1 downto 0) := (others => '0'); |
| signal PWM_PulseCounter_ov : std_logic; |
| |
| begin |
| |
| process(Clock) |
| begin |
| if rising_edge(Clock) then |
| if ((Reset or PWM_FrequencyCounter_ov) = '1') then |
| PWM_FrequencyCounter_us <= (others => '0'); |
| else |
| PWM_FrequencyCounter_us <= PWM_FrequencyCounter_us + 1; |
| end if; |
| end if; |
| end process; |
| |
| PWM_FrequencyCounter_ov <= to_sl(PWM_FrequencyCounter_us = PWM_FREQUENCYCOUNTER_MAX); |
| |
| process(Clock) |
| begin |
| if rising_edge(Clock) then |
| if ((Reset or PWM_PulseCounter_ov) = '1') then |
| PWM_PulseCounter_us <= (others => '0'); |
| elsif (PWM_FrequencyCounter_ov = '1') then |
| PWM_PulseCounter_us <= PWM_PulseCounter_us + 1; |
| end if; |
| end if; |
| end process; |
| |
| PWM_PulseCounter_ov <= to_sl(PWM_PulseCounter_us = ((2**PWM_RESOLUTION) - 2)) and PWM_FrequencyCounter_ov; |
| |
| PWMOut <= to_sl(PWM_PulseCounter_us < unsigned(PWMIn)); |
| end; |