PWM.vhd


1
-- F A C H H O C H S C H U L E - T E C H N I K U M W I E N --
2
-- --
3
-- Embedded Systems Division --
4
-- --
5
-------------------------------------------------------------------------------
6
--
7
--
8
-- Author: Wolfgang Gartner
9
--
10
-- Filename: PWM.vhd
11
--
12
-- Date of Creation: Sun March 8 1009
13
--
14
--
15
-------------------------------------------------------------------------------
16
17
library IEEE;
18
use IEEE.std_logic_1164.all;
19
use ieee.std_logic_arith.all;
20
21
entity PWM is
22
port(
23
      data_i: in std_logic_vector (7 downto 0);
24
      v_o: out std_logic;
25
      pause_i: in std_logic;
26
      play_i: in std_logic;
27
      stop_i: in std_logic;
28
      eof_i: in std_logic;
29
      led : out std_logic_vector(7 downto 0); -- value for LEDs
30
      clk_i: in std_logic;
31
      reset_n: in std_logic);
32
end PWM;
33
34
architecture rtl of PWM is
35
type t_state is (IDLE, PLAY, PAUSE); --notwendig für die Realisierung einer State Machine
36
signal s_state : t_state;         --mit einem Prozess.    
37
signal s_ctr : std_logic_vector (7 downto 0); -- da auf einen Ausgang nicht zugegriffen werden darf.    
38
signal s_ledctr : std_logic_vector (25 downto 0);
39
constant C_1HZ : std_logic_vector(25 downto 0):= "10110111000110110000000000"; --48M Dezimal
40
signal s_led : std_logic_vector (7 downto 0);
41
signal s_rep : std_logic;
42
43
begin
44
ctr: process(clk_i, reset_n)
45
begin
46
if reset_n ='1' then --asynchroner Reset
47
        s_ctr <= (others => '0');
48
elsif clk_i'event and clk_i= '1' then 
49
     if s_ctr = "11111111" then
50
        s_ctr <= "00000000";
51
     elsif pause_i /= '1' then
52
        s_ctr <= unsigned(s_ctr) + 1;
53
     end if;
54
end if;
55
end process ctr;
56
57
pwm: process (s_ctr, reset_n)
58
begin
59
if reset_n ='1' then --asynchroner Reset
60
     v_o <= '0';
61
     s_led <= (others => '1');
62
     s_state <= IDLE;
63
else
64
     case s_state is
65
        when IDLE => -- STOP
66
              if pause_i = '1' then
67
                  s_state <= PAUSE;
68
              elsif play_i = '1' then
69
                  s_state <= PLAY;
70
              elsif stop_i = '1' or eof_i = '1' then
71
                  s_state <= IDLE;
72
              else 
73
                  s_state <= IDLE;
74
              end if;
75
              v_o   <= '0';
76
              s_ctr <= (others => '0');
77
              s_led   <= s_led or "10000000";
78
        when PLAY =>
79
              if pause_i = '1' then
80
                  s_state <= PAUSE;
81
              elsif play_i = '1' then
82
                  s_state <= PLAY;
83
              elsif stop_i = '1' or eof_i = '1' then
84
                  s_state <= IDLE;
85
              else 
86
                  s_state <= PLAY;
87
              end if;
88
              s_led  <= s_led and "01111111";
89
              if s_ctr = x"00" then
90
                 v_o <= '1';
91
              elsif s_ctr = data_i then
92
                 v_o <= '0';
93
              end if; 
94
        when PAUSE =>
95
              if pause_i = '1' then
96
                  s_state <= PAUSE;
97
              elsif play_i = '1' then
98
                  s_state <= PLAY;
99
              elsif stop_i = '1' or eof_i = '1' then
100
                  s_state <= IDLE;
101
              else 
102
                  s_state <= PAUSE;
103
              end if;
104
                 v_o <= '0';
105
              if s_ledctr /= C_1HZ then
106
               -- As long as the terminal count is not reached: increment the counter.
107
                 s_ledctr <= unsigned(s_ledctr) + conv_unsigned(1,1);
108
              else
109
               -- When the terminal count is reached, set enable flag and reset the
110
               -- counter.
111
                 s_ledctr <= (others => '0');
112
                 s_led <= s_led xor "10000000";
113
              end if;
114
     end case;
115
end if;     
116
end process pwm;
117
118
119
120
led <= s_led;
121
end rtl;