Increasing dutycycle for an output signal

Guest #4245985
Rate this post
• ▲ useful
▼ not useful
Hi all,

I want to increase the duty cycle slowly from 0%-50% in the period of 
0-10 ms for an output signal(150KHz) generated from a clock of 50MHz.

I am able to generate the output for 50%. I am not sure how to vary the 
duty cycle from 0-50% (between 0-10ms). Below is the code:
1
entity Gen_150 is
2
port ( sys_clk,reset: in std_logic; --sys_clk:50MHz
3
a_out, b_out: out std_logic);       --a_out,b_out:150KHz
4
end Gen_150 ;
5
 
6
architecture bhv of Gen_150 is
7
 
8
signal count: integer:=0;
9
signal tmp : std_logic := '1';
10

11
begin
12
 
13
process(sys_clk,reset)
14
begin
15
if(reset='0') then
16
count<=0;
17
tmp<='1';
18
elsif(sys_clk'event and sys_clk='1') then
19
  count <=count+1;
20

21
  if (count = 166) then   -- dutycycle=50% ((50000000/150000)/2)
22
     tmp <= NOT tmp;
23
     count<= 0;  
24
  end if;
25
end if;
26
a_out <= tmp;
27
b_out <= NOT tmp after 10ns; -- output delayed by 10ns
28
end process;
29
 
30
end bhv;

Thank you!
Moderator (Company: Titel) #4246005
Rate this post
• ▲ useful
▼ not useful
Robert wrote:
> Below is the code:
> entity Gen_150 is
A VHDL code start well before the keyword "entity"...


> b_out <= NOT tmp after 10ns; -- output delayed by 10ns
Thats not synthesizeable! You know that?


> I want to increase the duty cycle slowly from 0%-50%
Try that and change the value of pwm:
1
signal count: integer:=0;
2
signal pwm: integer:=100;
3
:
4
:
5
elsif(sys_clk'event and sys_clk='1') then
6
  count <=count+1;
7

8
  if (count = 332) then
9
     count <= 0;  
10
  end if;
11
   
12
end if;
13

14
tmp <= '1' when (count < pwm) else '0';
15
:
16
:
17
end process;
Now you have a changing output signal. And the only thing you must du, 
is to produce a ramp on the "pwm" signal. Thats fairly easy...
Guest #4246097
Rate this post
• ▲ useful
▼ not useful
Thank you!
I implemented the ramping function with a counter=500000 (0-10ms). 
Please correct if I am wrong.

And I am getting an syntax error for the below:

tmp <= '1' when(count < pwm) else tmp <= '0';
1
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.numeric_std.ALL;
4
 
5
entity Gen_150 is
6
port ( sys_clk,reset: in std_logic;
7
a_out, b_out: out std_logic);
8
end Gen_150 ;
9
 
10
architecture bhv of Gen_150 is
11
 
12
signal count: integer:=0;
13
signal tmp : std_logic := '1';
14
signal counter: integer := 0;
15
signal pwm: integer := 0;
16

17
begin
18
 
19
process(sys_clk,reset)
20
begin
21
if(reset='0') then
22
count<=0;
23
tmp<='1';
24
elsif(sys_clk'event and sys_clk='1') then
25
  count <=count+1;
26
  --counter <= counter +1;
27
  if (count = 332) then
28
    -- tmp <= NOT tmp;
29
     count<= 0;  
30
  end if;
31
end if;
32
tmp <= '1' when(count < pwm) else tmp <= '0'; 
33

34
a_out <= tmp;
35
b_out <= NOT tmp;
36

37
end process;
38

39
Ramp : process (reset, sys_clk)
40
begin
41
  if reset = '0' then
42
    pwm      <= 0;
43
  elsif rising_edge(sys_clk)  then
44
    counter <= counter +1;
45
    if counter<=500000 then -- 500000 cycles =10ms
46
      
47
        case  counter  is
48
          when  50000     =>  pwm  <= 25;    
49
          when  100000  =>  pwm  <= 33;  
50
          when  150000  =>  pwm  <= 44;  
51
          when  200000  =>  pwm  <= 66;  
52
          when  250000  =>  pwm  <= 77;  
53
          when  300000  =>  pwm  <= 99;            
54
          when  350000  =>  pwm  <= 120;  
55
          when  400000  =>  pwm  <= 132;  
56
          when  450000  =>  pwm  <= 145;  
57
          when  500000  =>  pwm  <= 166;  
58
          
59
          when  others  =>  pwm  <= 0;    
60
        end case;
61
      
62
    else
63
      pwm      <= 0;
64
    end if;
65
  end if;
66

67
end process Ramp;
68
 
69
end bhv;
Moderator (Company: Titel) #4246111
Rate this post
• ▲ useful
▼ not useful
Robert wrote:
> And I am getting an syntax error for the below:
>
> tmp <= '1' when(count < pwm) else tmp <= '0';
Of course you do. What's the correct syntax for the when/else statement?
Why didn't you simply copy it from me?
Mine will not conclude in an error message.

And for the PWM value: let start it from 0. And then increment it every 
500000/166 clocks. So you will only need an additional counter from 0 to 
500000/166. And when the counter reaches that value you must reset it to 
0 and increment the PWM value until its 166.

You see that there's no whatsoever "case" statement necessary at all and 
the PWM value will increase smoothly from 0 to 166...
Guest #4246119
Rate this post
• ▲ useful
▼ not useful
Lothar M. wrote:
> Robert wrote:
>> And I am getting an syntax error for the below:
>>
>> tmp <= '1' when(count < pwm) else tmp <= '0';
> Of course you do. What's the correct syntax for the when/else statement?
> Why didn't you simply copy it from me?
> Mine will not conclude in an error message.

Sorry it was my mistake. Its fine now. But is the ramp function 
implemented correct?
Guest #4247830
Rate this post
• ▲ useful
▼ not useful
I want to add delays between the outputs (a_out and b_out).

Is it ok to add a min delay(is 10ns too much?) just by adding a temp 
register to delay out_b?
1
if(reset='0') then
2
count<=0;
3
tmp<='1';
4
elsif(sys_clk'event and sys_clk='1') then
5
:
6
:
7
end if;
8
end if;
9
a_out <= tmp; -- at falling edge
10
d_b_out <= NOT tmp; -- at falling edge
11
b_out <= d_b_out; -- delayed by 10ns - at rising edge
12
:
13
:

I am not sure as the Input clock has a frequeny of 50MHz and the outputs 
are at 150KHz.
Guest #4266617
Rate this post
• ▲ useful
▼ not useful
How do I introduce a 180° phase shift between a_out and b_out. I tried 
using an inverting output. But when dutycycle is 10% for a_out, it is 
90% for b_out. But I want a 10% dutycycle for b_out with 180° phase 
shift.

Any suggestions?
Moderator (Company: Titel) #4266707
Rate this post
• ▲ useful
▼ not useful
Wil wrote:
> How do I introduce a 180° phase shift between a_out and b_out.
> I tried using an inverting output.
A phase shift is only defined for sinusoidal signals. And then inverting 
is correct.

> How do I introduce a 180° phase shift between a_out and b_out.
What you want in fact is a delay of half the cycle duration for one of 
the signals.

Reply

Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.

Formatting
  • [c]C-Code[/c]
  • [vhdl]VHDL-Code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]
  • [[Title]] – link to an article
  • Link to another post: right-click its post ID (#8078628), copy the address, paste it into the text

More about formatting

Post long source code as an attachment, not in the text.

Already registered? Log in

Not shown to anyone. We send you a link; your post appears once you confirm it there.

By submitting you create a free account and accept the terms of use.