X-Git-Url: http://rtime.felk.cvut.cz/gitweb/fpga/virtex2/uart.git/blobdiff_plain/becb341a3d46f3a6458ce87a4f531f81e03e84b2..e46674ac277a1a88f8e0bcab9d52e683b1603fee:/omsp_pwm.vhd diff --git a/omsp_pwm.vhd b/omsp_pwm.vhd new file mode 100644 index 0000000..24afa76 --- /dev/null +++ b/omsp_pwm.vhd @@ -0,0 +1,96 @@ +library ieee; +use ieee.std_logic_1164.all; +use ieee.std_logic_arith.all; +use ieee.std_logic_unsigned.all; + +-------------------------------------------------------------------------------- +-- This entity is a generator of PWM signal with 16-bit MCU interface. +-- +-- PWM bit width is configurable by PWM_WIDTH generic parameter and must be in +-- range of 1 to 16. Default is 16. +-- +-- In practice, to generate PWM signal component must be fed by a counter vector +-- (pwm_cnt input) of appropriate width and also period! (One counter can be +-- used by several PWM generators and generated signals are then synchronized.) +-- +-- The period of the input counter vector should be by 1 smaller than the count +-- of all possible PWM values, i.e. counter vector should never reaches the +-- maximum possible PWM value, and counting should start from 0. E.g. when full +-- range of PWM values is used, binary counter should be reset just one step +-- before it overflows. In such a case, when PWM value is maximal, output keeps +-- log. 1. +-- +-- MCU interface consist of one r/w 16-bit register holding PWM value. +-------------------------------------------------------------------------------- + +entity omsp_pwm is + generic ( + ADDR : integer := 16#0160#; + PWM_WIDTH : integer := 16); + port ( + -- MCU peripheral interface + mclk : in std_logic; + puc : in std_logic; + per_addr : in std_logic_vector (7 downto 0); + per_en : in std_logic; + per_wen : in std_logic_vector (1 downto 0); + per_din : in std_logic_vector (15 downto 0); + per_dout : out std_logic_vector (15 downto 0); + -- PWM interface + pwm_cnt : in std_logic_vector (PWM_WIDTH-1 downto 0); + pwm : out std_logic); +end omsp_pwm; + +-------------------------------------------------------------------------------- + +architecture behavioral of omsp_pwm is + + signal pwm_value : std_logic_vector (15 downto 0); + + signal pwm_sel : boolean; + +-------------------------------------------------------------------------------- + +begin + + pwm_sel <= (per_addr = ADDR/2) and (per_en = '1'); + + per_dout <= pwm_value when pwm_sel else + (others => '0'); + + + -- Peripheral registers + process (mclk, puc) + begin + if puc = '1' then + pwm_value <= (others => '0'); + + elsif rising_edge(mclk) and pwm_sel then + if per_wen (0) = '1' then + pwm_value (7 downto 0) <= per_din (7 downto 0); + end if; + + if per_wen (1) = '1' then + pwm_value (15 downto 8) <= per_din (15 downto 8); + end if; + end if; + end process; + + + -- Generation of the PWM signal + process (mclk, puc) + begin + if puc = '1' then + pwm <= '0'; + + elsif mclk'event and mclk = '1' then + if pwm_cnt < pwm_value then + pwm <= '1'; + else + pwm <= '0'; + end if; + end if; + end process; + +end behavioral; +