]> rtime.felk.cvut.cz Git - fpga/virtex2/uart.git/blob - omsp_pwm.vhd
+ README
[fpga/virtex2/uart.git] / omsp_pwm.vhd
1 library ieee;
2 use ieee.std_logic_1164.all;
3 use ieee.std_logic_arith.all;
4 use ieee.std_logic_unsigned.all;
5
6 --------------------------------------------------------------------------------
7 -- This entity is a generator of PWM signal with 16-bit MCU interface.
8 --
9 -- PWM bit width is configurable by PWM_WIDTH generic parameter and must be in
10 -- range of 1 to 16. Default is 16.
11 --
12 -- In practice, to generate PWM signal component must be fed by a counter vector
13 -- (pwm_cnt input) of appropriate width and also period! (One counter can be
14 -- used by several PWM generators and generated signals are then synchronized.)
15 --
16 -- The period of the input counter vector should be by 1 smaller than the count
17 -- of all possible PWM values, i.e. counter vector should never reaches the
18 -- maximum possible PWM value, and counting should start from 0. E.g. when full
19 -- range of PWM values is used, binary counter should be reset just one step
20 -- before it overflows. In such a case, when PWM value is maximal, output keeps
21 -- log. 1.
22 --
23 -- MCU interface consist of one r/w 16-bit register holding PWM value.
24 --------------------------------------------------------------------------------
25
26 entity omsp_pwm is
27   generic (
28     ADDR      : integer := 16#0160#;
29     PWM_WIDTH : integer := 16);
30   port (
31     -- MCU peripheral interface
32     mclk     : in  std_logic;
33     puc      : in  std_logic;
34     per_addr : in  std_logic_vector (7 downto 0);
35     per_en   : in  std_logic;
36     per_wen  : in  std_logic_vector (1 downto 0);
37     per_din  : in  std_logic_vector (15 downto 0);
38     per_dout : out std_logic_vector (15 downto 0);
39     -- PWM interface
40     pwm_cnt  : in  std_logic_vector (PWM_WIDTH-1 downto 0);
41     pwm      : out std_logic);
42 end omsp_pwm;
43
44 --------------------------------------------------------------------------------
45
46 architecture behavioral of omsp_pwm is
47
48   signal pwm_value : std_logic_vector (15 downto 0);
49   
50   signal pwm_sel : boolean;
51   
52 --------------------------------------------------------------------------------
53
54 begin
55
56   pwm_sel <= (per_addr = ADDR/2) and (per_en = '1');
57
58   per_dout <= pwm_value when pwm_sel else
59               (others => '0');
60   
61
62   -- Peripheral registers
63   process (mclk, puc)
64   begin
65     if puc = '1' then
66       pwm_value <= (others => '0');
67
68     elsif rising_edge(mclk) and pwm_sel then
69       if per_wen (0) = '1' then
70         pwm_value (7 downto 0) <= per_din (7 downto 0);
71       end if;
72       
73       if per_wen (1) = '1' then
74         pwm_value (15 downto 8) <= per_din (15 downto 8);
75       end if;
76     end if;
77   end process;
78
79
80   -- Generation of the PWM signal
81   process (mclk, puc)
82   begin
83     if puc = '1' then
84       pwm <= '0';
85       
86     elsif mclk'event and mclk = '1' then
87       if pwm_cnt < pwm_value then
88         pwm <= '1';
89       else
90         pwm <= '0';
91       end if;
92     end if;
93   end process;
94
95 end behavioral;
96