1 | ----------------------------------------------------------------------------------
|
2 | -- Company:
|
3 | -- Engineer:
|
4 | --
|
5 | -- Create Date: 10.02.2015 11:18:22
|
6 | -- Design Name:
|
7 | -- Module Name: PWM - PWM_Arch
|
8 | -- Project Name:
|
9 | -- Target Devices:
|
10 | -- Tool Versions:
|
11 | -- Description: Simple Timer & PWM Module
|
12 | --
|
13 | -- Dependencies:
|
14 | --
|
15 | -- Revision:
|
16 | -- Revision 0.01 - File Created
|
17 | -- Additional Comments:
|
18 | --
|
19 | ----------------------------------------------------------------------------------
|
20 | |
21 | library IEEE;
|
22 | use IEEE.STD_LOGIC_1164.ALL;
|
23 | use IEEE.NUMERIC_STD.ALL;
|
24 | use IEEE.STD_LOGIC_unsigned.all;
|
25 | |
26 | -- Uncomment the following library declaration if instantiating
|
27 | -- any Xilinx leaf cells in this code.
|
28 | --library UNISIM;
|
29 | --use UNISIM.VComponents.all;
|
30 | |
31 | entity Timer is
|
32 | Generic ( Width : integer := 8 );
|
33 | Port ( Clock_In : in STD_LOGIC;
|
34 | Prescaler : in STD_LOGIC_VECTOR(2 downto 0);
|
35 | Preload : in STD_LOGIC_VECTOR(Width - 1 downto 0);
|
36 | Capture : in STD_LOGIC_VECTOR(Width - 1 downto 0);
|
37 | Reset : in STD_LOGIC := '1';
|
38 | PWM_Enable : in STD_LOGIC := '0';
|
39 | PWM_Inv : in STD_LOGIC := '0';
|
40 | Compare : out STD_LOGIC := '0';
|
41 | Overflow : out STD_LOGIC := '0';
|
42 | PWM : out STD_LOGIC := '0';
|
43 | Clock_Out : out STD_LOGIC);
|
44 | end Timer;
|
45 | |
46 | architecture Timer_Arch of Timer is
|
47 | |
48 | signal Clock_Intern : std_logic;
|
49 | signal Counter : std_logic_vector(Width - 1 downto 0) := (others => '0');
|
50 | signal Counter_Timer: std_logic_vector(Width - 1 downto 0) := (others => '0');
|
51 | |
52 | begin
|
53 | |
54 | -- Prescaler
|
55 | process(Clock_In, Reset, Prescaler)
|
56 | begin
|
57 | if(Reset = '1') then
|
58 | Counter <= (others => '0');
|
59 | elsif(rising_edge(Clock_In)) then
|
60 | Counter <= Counter + 1;
|
61 | end if;
|
62 |
|
63 | case Prescaler is
|
64 | when "001" => Clock_Intern <= Counter(1);
|
65 | when "010" => Clock_Intern <= Counter(2);
|
66 | when "011" => Clock_Intern <= Counter(3);
|
67 | when "100" => Clock_Intern <= Counter(4);
|
68 | when "101" => Clock_Intern <= Counter(5);
|
69 | when "110" => Clock_Intern <= Counter(6);
|
70 | when "111" => Clock_Intern <= Counter(7);
|
71 | when others => Clock_Intern <= Counter(0);
|
72 | end case;
|
73 | end process;
|
74 |
|
75 | process
|
76 | begin
|
77 | wait until(rising_edge(Clock_Intern));
|
78 | Counter_Timer <= Counter_Timer + 1;
|
79 | |
80 | if(PWM_Enable = '0') then
|
81 |
|
82 | -- Compare Interrupt
|
83 | if(Counter_Timer(Width - 1 downto 0) > (Preload(Width - 1 downto 0) - 1)) then
|
84 | Compare <= '1';
|
85 | Counter_Timer <= (others => '0');
|
86 | else
|
87 | Compare <= '0';
|
88 | end if;
|
89 |
|
90 | else
|
91 |
|
92 | -- Overflow Interrupt
|
93 | if(Counter_Timer = ((2**Width) - 1)) then
|
94 | Overflow <= '1';
|
95 | else
|
96 | Overflow <= '0';
|
97 | end if;
|
98 |
|
99 | -- Capture Compare
|
100 | if(Counter_Timer(Width - 1 downto 0) > (Capture(Width - 1 downto 0) - 1)) then
|
101 | PWM <= PWM_Inv;
|
102 | else
|
103 | PWM <= not PWM_Inv;
|
104 | end if;
|
105 | end if;
|
106 | end process;
|
107 |
|
108 | Clock_Out <= Clock_Intern;
|
109 |
|
110 | end Timer_Arch;
|