]> rtime.felk.cvut.cz Git - fpga/pwm.git/blob - pwm.vhd
Wave_table initialization data format modified.
[fpga/pwm.git] / 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.
8 --
9 -- PWM bit width is configurable by PWM_WIDTH generic parameter.
10 --
11 -- In practice, to generate PWM signal component must be fed by a counter vector
12 -- (pwm_cnt input) of appropriate width and also period! (One counter can be
13 -- used by several PWM generators and generated signals are then synchronized.)
14 --
15 -- The period of the input counter vector should be by 1 smaller than the count
16 -- of all possible PWM values, i.e. counter vector should never reaches the
17 -- maximum possible PWM value, and counting should start from 0. E.g. when full
18 -- range of PWM values is used, binary counter should be reset just one step
19 -- before it overflows. In such a case, when PWM value is maximal, output keeps
20 -- log. 1.
21 --
22 -- PWM value is buffered and any change is propageted to the output by the next
23 -- pwm period - 'pwm_cyc' must by feed.
24 --------------------------------------------------------------------------------
25
26 entity pwm is
27   generic (
28     PWM_WIDTH : integer);
29   port (
30     clk     : in  std_logic;
31     reset   : in  std_logic;
32     din     : in  std_logic_vector (PWM_WIDTH-1 downto 0);
33     sel     : in  std_logic;
34     we      : in  std_logic;
35     -- PWM interface
36     pwm_cnt : in  std_logic_vector (PWM_WIDTH-1 downto 0);
37     pwm_cyc : in  std_logic;            -- Indicate new pwm period
38     pwm     : out std_logic);
39 end pwm;
40
41 --------------------------------------------------------------------------------
42
43 architecture behavioral of pwm is
44
45   -- Register accessible from bus
46   signal reg : std_logic_vector (PWM_WIDTH-1 downto 0) := (others => '0');
47   -- Compare value during pwm cycle, loaded from 'reg' when new period begins.
48   signal cmp : std_logic_vector (PWM_WIDTH-1 downto 0) := (others => '0');
49   
50 --------------------------------------------------------------------------------
51
52 begin
53
54   -- Peripheral register
55   PWM_REGISTER : process (clk, reset)
56   begin
57     if rising_edge(clk) then
58       if reset = '1' then
59         reg <= (others => '0');
60       else
61         if we = '1' and sel = '1' then
62           reg <= din;
63         end if;
64       end if;
65     end if;
66   end process;
67
68
69   -- Generation of PWM signal
70   -- When 'pwm_cyc' is high then new 'cmp' is loaded and 'counter' is reset 
71   -- with next clk edge. Pwm output is delayed by one clock.
72   PWM_GEN : process (clk, reset)
73   begin
74     if rising_edge(clk) then
75       if reset = '1' then
76         pwm <= '0';
77
78       else  
79         if pwm_cyc = '1' then
80           cmp <= reg;
81         end if;
82         
83         if pwm_cnt < cmp then
84           pwm <= '1';
85         else
86           pwm <= '0';
87         end if;
88       end if;
89     end if;
90   end process;
91
92 end behavioral;
93