EmbDev.net

Forum: FPGA, VHDL & Verilog Synchronous two PWM signals generator


von Stas I. (stasik_30)


Attached files:

Rate this post
useful
not useful
Hi to all,

I try to generate two synchronous PWM signals however I missing 
something. I'll be grateful if you could assist me.

1. Two signals should start at the same time.

2. When PWM_1 is rising edge the PWM_2 should be start either.

3. PWM_1 is 1us period , 0.5 uS high ('1') and 0.5 uS low ('0'). 50% 
Duty cycle.

4. PWM_2 is 1uS period , 0.3uS high ('1') and 0.7 us low ('0'). 30% Duty 
cycle.

Code and simulation attached .

Simulation :
Attached image of simulation Sim.PNG




CODE :
1
LIBRARY IEEE;
2
USE IEEE.STD_LOGIC_1164.ALL;
3
4
ENTITY clk1 IS
5
PORT (
6
clk : IN STD_LOGIC;
7
reset : IN STD_LOGIC;
8
clk_out : OUT STD_LOGIC;
9
pwm_1 : OUT STD_LOGIC;
10
pwm_2 : OUT STD_LOGIC
11
);
12
END clk1;
13
14
ARCHITECTURE Behavioral OF clk1 IS
15
SIGNAL temporal_1 : STD_LOGIC;
16
SIGNAL temporal_2 : STD_LOGIC;
17
SIGNAL temporal_4 : STD_LOGIC;
18
SIGNAL counter_1 : INTEGER RANGE 0 TO 4 := 0;--780 original
19
SIGNAL counter_2 : INTEGER RANGE 0 TO 4 := 0;--780 original
20
SIGNAL counter_3 : INTEGER RANGE 0 TO 4 := 0;--780 original
21
SIGNAL counter_4 : INTEGER RANGE 0 TO 4 := 0;--780 original
22
BEGIN
23
freq_divider_1 : PROCESS (reset, clk)
24
BEGIN
25
26
IF rising_edge(clk) THEN
27
counter_3 <=counter_3+1;
28
--counter_4 <=counter_3+1;
29
END IF;
30
31
IF (reset = '1') THEN
32
temporal_1 <= '0';
33
counter_1 <= 0;
34
ELSIF rising_edge(clk) THEN
35
36
IF (counter_1 = 4) THEN
37
38
temporal_1 <= NOT(temporal_1);
39
40
counter_1 <= 0;
41
ELSE
42
counter_1 <= counter_1 + 1;
43
END IF;
44
45
END IF;
46
47
48
IF (reset = '1') THEN
49
temporal_2 <= '0';
50
counter_2 <= 0;
51
ELSIF rising_edge(clk) THEN
52
53
IF (counter_2 = 3) THEN
54
55
temporal_2 <= NOT(temporal_2);
56
counter_2 <= 0;
57
ELSE
58
counter_2 <= counter_2 + 1;
59
IF counter_2 = 2 THEN
60
temporal_2 <= '0';
61
ELSE
62
temporal_2 <=temporal_2;
63
END IF;
64
END IF;
65
66
END IF;
67
68
END PROCESS;
69
70
clk_out <= temporal_1;
71
pwm_1 <= temporal_1;
72
pwm_2 <= temporal_2;
73
74
END Behavioral;



Thanks.

Stas.

: Edited by Moderator
von Lothar M. (lkmiller) (Moderator)


Rate this post
useful
not useful
The forum sw has some problems with correct rendering since the last 
update...

But to cut down your code it looks like that:
1
freq_divider_1 : PROCESS (reset, clk)
2
BEGIN
3
4
IF rising_edge(clk) THEN
5
:
6
END IF;
7
8
9
IF (reset = '1') THEN
10
:
11
ELSIF rising_edge(clk) THEN
12
:
13
END IF;
14
15
16
IF (reset = '1') THEN
17
:
18
ELSIF rising_edge(clk) THEN
19
:
20
END IF;
21
22
END PROCESS;
Where did you find that fairless amazing coding style with several 
"subprocesses" in one process?

Are you sure, that your synthesizer is able to generate hardware out of 
this?

> however I missing something.
I would implement 1 counter steadily counting from 0 to 9. One step each 
100ns. Then I would set both of the PWM outputs high with counter = 0, 
and I would reset one PWM output with counter = 4 and the second PWM 
output with counter = 6. Sounds kind of easy...

von Stas I. (stasik_30)


Rate this post
useful
not useful
Thank you Lothar.
It has been synthesized. I tried what you had offered and the  PWM 2 
doesn't starts synchronous with PWM 1, it synchronous for the first time 
only.

I changed my code at all. Similar to state machine.
Thank you a lot.
My regards,
Stas.

von Lothar M. (lkmiller) (Moderator)


Attached files:

Rate this post
useful
not useful
Stas I. wrote:
> I tried what you had offered and the  PWM 2 doesn't starts synchronous
> with PWM 1, it synchronous for the first time only.
With only 1 counter for both of those PWM outputs they never ever can 
get out of synchronicity:
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
4
use IEEE.NUMERIC_STD.ALL;
5
6
entity doublepwm is
7
    Port ( clk  : in  STD_LOGIC;
8
           pwm1 : out  STD_LOGIC := '1';
9
           pwm2 : out  STD_LOGIC := '1');
10
end doublepwm;
11
12
architecture Behavioral of doublepwm is
13
signal cnt : integer range 0 to 9 := 0;
14
constant pwmvalue_1 : integer := 5;
15
constant pwmvalue_2 : integer := 3;
16
begin
17
   process begin
18
      wait until rising_edge(clk);
19
20
      if cnt = 9 then  cnt <= 0;
21
      else             cnt <= cnt + 1;
22
      end if;
23
      
24
      if cnt = 0 then
25
         pwm1 <= '1';
26
         pwm2 <= '1';
27
      end if;
28
      
29
      if cnt = pwmvalue_1 then
30
         pwm1 <= '0';
31
      end if;
32
33
      if cnt = pwmvalue_2 then
34
         pwm2 <= '0';
35
      end if;
36
      
37
   end process;
38
end Behavioral;

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig