Forum: FPGA, VHDL & Co. VHDL Timer & PWM


von Daniel K. (daniel_k80)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich habe meine Timer + PWM Schaltung fertig gemacht und möchte die im 
nächsten Schritt in einen IP-Core gießen um die dann per AXI in meinem 
Zynq zu verwenden.
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;

Jetzt habe ich mal ein bisschen mit Vivado rum gespielt und mir mal die 
Schaltung ausgeben lassen.
In dem angehängten Bild (Bild 1) ist die Eingangsstufe für den Takt 
gezeigt. Warum werden da zwei Buffer verwendet (wovon einer invertiert)?

Wenn ich mir jetzt ein Top-Design dafür erstelle und es synthetisiere 
und mir anschließend die Schaltung ausgebe, dann optimiert die Toolchain 
die Schaltung weg (siehe Bild 2):
1
----------------------------------------------------------------------------------
2
-- Company: 
3
-- Engineer: 
4
-- 
5
-- Create Date:         10.02.2015 07:51:07
6
-- Design Name: 
7
-- Module Name:         Top - Top_Arch
8
-- Project Name: 
9
-- Target Devices: 
10
-- Tool Versions: 
11
-- Description: 
12
-- 
13
-- Dependencies: 
14
-- 
15
-- Revision:-- Revision 0.01 - File Created
16
-- Additional Comments:
17
-- 
18
----------------------------------------------------------------------------------
19
20
library IEEE;
21
use IEEE.STD_LOGIC_1164.ALL;
22
use IEEE.NUMERIC_STD.ALL;
23
24
entity Top is
25
    Port (  Output : out STD_LOGIC;
26
            Clock_In : in STD_LOGIC);
27
end Top;
28
29
architecture Top_Arch of Top is
30
31
    signal Compare      : std_logic;
32
    signal Overflow     : std_logic;
33
    signal PWM          : std_logic;
34
    signal Clock_Out    : std_logic;
35
36
    component Timer is
37
        Generic (   Width : integer := 8 );
38
        Port (      Clock_In : in STD_LOGIC;
39
                    Reset : in STD_LOGIC;
40
                    Prescaler : in STD_LOGIC_VECTOR(2 downto 0);
41
                    Preload : in STD_LOGIC_VECTOR(Width - 1 downto 0);
42
                    Capture : in STD_LOGIC_VECTOR(Width - 1 downto 0);
43
                    PWM_Enable : in STD_LOGIC;
44
                    PWM_Inv : in STD_LOGIC;
45
                    Compare : out STD_LOGIC;
46
                    Overflow : out STD_LOGIC;
47
                    PWM : out STD_LOGIC;
48
                    Clock_Out : out STD_LOGIC); 
49
    end component;
50
    
51
begin
52
53
    -- Device Instantiation
54
    TT0: Timer port map(Clock_In, '0', "000", "00000000", "00000000", '0', '0', Compare, Overflow, PWM, Clock_Out);
55
56
end Top_Arch;

Warum tut er das?
Danke für die Hilfe :)

: Bearbeitet durch User
von Dennis R. (dennis_r93)


Lesenswert?

In der Synthese wird alles weggekürzt was nicht notwendig ist.

Dein Topdesign hat nur das Ausgabesignal Output.
Dieses Signal wird nie zugewiesen. Der restliche Teil deiner Architektur 
verlässt das TopDesign nie. Deshalb kann es einfach weggekürzt werden.

Du musst dafür sorgen, dass das Outputsignal im Topdesign verändert 
wird.
Dann wird alles, von dem das Signal abhängt nicht entfernt.
1
 TT0: Timer port map(Clock_In, '0', "000", "00000000", "00000000", '0', '0', Compare, Overflow, PWM, Output);

von Daniel K. (daniel_k80)


Lesenswert?

Ahhh.... ok.
Das Signal habe ich wohl übersehen. Das erklärt dann auch warum er in 
der Schaltung die Clock-Leitung nicht angeschlossen hat oder?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.