Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Duty Cycle by using VHDL

Status
Not open for further replies.

Jaiko

Newbie level 5
Joined
May 21, 2016
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
66
Hello,

I want to design 30% duty cycle using VHDL. My clock frequency is 50MHz and frequency divider is 500Hz. Here I attach code for 10% duty cycle. I want change this code from 10% duty cycle to 30% duty cycle. Please someone help me.

Thank you.

[/10% Duty Cycle]

Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;
 
entity DutyCycle500Hz is
    port( clock   : in STD_LOGIC;
             clear  : in std_logic;-- 50 Mhz
          pwmout  : out STD_LOGIC);
end DutyCycle500Hz ;
 
architecture Behavioral of DutyCycle500Hz is
  signal cnt: integer range 0 to (50000000/500)-1 := 0;
  constant cmp: integer := (50000000/5000); -- PWM = 10%
begin
 
  process(clock,clear) begin
    if (clear = '1') then
      cnt<=0;
     elsif rising_edge(clock) then
      if cnt<(50000000/500)-1 then cnt<=cnt+1;
      else cnt<=0;
      end if;
    end if;
  end process;
  
  pwmout <= '1' when cnt<cmp else '0';
end Behavioral;

This is for testbench:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
-- TestBench Template 
 
LIBRARY ieee;
  USE ieee.std_logic_1164.ALL;
  USE ieee.numeric_std.ALL;
 
  ENTITY DutyCycle500Hz_tb IS
  END DutyCycle500Hz_tb;
 
  ARCHITECTURE behavior OF DutyCycle500Hz_tb IS 
 
  -- Component Declaration
          COMPONENT DutyCycle500Hz
    port( clock   : in STD_LOGIC; 
             clear  : in std_logic;-- 50 Mhz
          pwmout  : out STD_LOGIC);
          END COMPONENT;
 
          SIGNAL clock :  std_logic :='0';
             signal clear : std_logic := '0';
          SIGNAL pwmout :  std_logic;
          
        constant clock_period : time:= 20 ns;
  BEGIN
 
  -- Component Instantiation
          uut: DutyCycle500Hz PORT MAP(
                  clock => clock,
                        clear => clear,
                  pwmout => pwmout
          );
   clock_process :process
   begin
        clock <= '0';
        wait for clock_period/2;  --wait for 10ns
        clock <= '1';
        wait for clock_period/2;  --wait for 10ns
   end process;
    
      stim_proc: process
   begin        
      -- hold reset state for 100ms.
      wait for 10 ms;clear <='1';
        wait for 100 ms;clear <='0';  
      wait;
   end process;
  END;

 

Hi,

constant cmp: integer := (50000000/5000); -- PWM = 10%
This sets duty cycle to 10%.

-->
Try this:

constant cmp: integer := (50000000/1667); -- PWM = 30%

Klaus
 
  • Like
Reactions: Jaiko

    Jaiko

    Points: 2
    Helpful Answer Positive Rating
How to calculate to get 1667?
 

(1/5000)*3 ~1/1667
 
  • Like
Reactions: Jaiko

    V

    Points: 2
    Helpful Answer Positive Rating

    Jaiko

    Points: 2
    Helpful Answer Positive Rating
Thanks for your help. It's helpful. Is it possible from that code to do a variable duty cycle of 10% and 30%?
 

Hi,

I think the solution is obvious:

Either you use COM1 for 10% and COM2 for 30% and switch both values.

Or you don't define it as constant, but as a variable then you can dynamically choose any value.

Klaus
 

Is it possible from that code to do a variable duty cycle of 10% and 30%?

Why don't you add another STD_LOGIC input on the entity declaration, acting as a selector ?
On the process implementation, use a if...end if to switch among them accordingly.
 

Actually, I need to design variable duty cycle, which is 10%, 30%, 50%, 70% and 90% from variable frequency. First of all, I need to design for fixed duty cycle. For variable frequency, I already got the answer. Now, I stuck in a variable duty cycle. By the way, thanks for your reply.
 

The general PWM would be an accumulator and a comparator.

To get variable frequency, you adjust the amount added to the accumulator each cycle.
To get variable duty cycle, you adjust the comparator.

This method introduces some small amount of error, but it is usually very small.


You can also do this by adjusting the terminal count of the accumulator, as you have done. But then you end up with a multiplier to get the value to use for the comparator.

There is also a method that works for a specific set of frequency/ratio combinations, if the required intervals can be generated by the clock.
 

Actually I don't know how to start it. I don't know how to related my variable frequency with variable duty cycle. It's been like this, for example, if 1 kHz freq, it will be 10%, 30%, 50% and so on for duty cycle.
 

By saying "10%, 30%, 50% and so on" you're lacking the clarity required for a VHDL code specification. Does it mean 10, 30, 50, 70, 90 and no other values?

Presently your design has neither a frequency nor a duty cycle input. For both quantities, you need to specify range and resolution respectively a word width.

vGoodtimes suggested to set the frequency by using a NCO scheme (accumulator with variable increment) opposite to the usual setting of an integer period. Need to find out if this scheme is useable for your application.
 

Its mean 10, 30, 50, 70 and 90. No other values.
 

And this is 500Hz only? I'm assuming so as you've not mentioned specific requirements.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top