Dual Edged Counter

Discussion in 'VHDL' started by Cory Shol, Apr 17, 2013.

  1. Cory Shol

    Cory Shol Guest

    Hi All,

    I am researching ways onto create a dual edged Counter.

    Problem details:

    Original Clock = 25 MHz Put the Original clock through a PLL and multiply it by 5 making a new: Clk_125MHz = 125 MHz clock.

    Using the 125 MHz clock, I want to use a 9 bit register [Called Duty_cycle] to state the Duty cycle of a PWM.
    For example if the Duty_cycle = "011111111" it will have a 50% duty cycle. Duty_cycle = "1111111110" it will have a ~0.2% duty cycle etc...

    The period of the PWM is 4096 ns (125 Mhz/ 2^9) = 125000000/512 = 244KHz =1/244KHz= 4096 ns.
    Code looks something like:

    process(clk_125Mhz, reset)

    begin
    if (reset = '1') then
    dc_count_i <= X"00" &'0'; -- you can use others statement as well.
    elsif(rising_edge(clk_125Mhz)) then
    if(dc_count_i < duty_cycle) then
    duty_out <='0';
    else
    duty_out <= '1';
    end if;
    dc_count_i <= dc_count_i + 1;
    end if;
    end process;

    Alright this is all fine and works decent.

    Now the extension I want to make my PWM have a period of 2048 ns. There are three ways I can think of to do this:
    1) PLL the clock to 250 MHz ( Do not want to run at Max frequency in the device)
    2) Change the 9 bit Duty Cycle register to 8 bits (Lower the resolution)
    3) Every time there is a rising or falling edge count up the counter

    This is coming back to topic title: to create a dual Edged Counter that can generate a duty cycle of a PWM.

    I tried something like:
    ------------------------------------------------------
    process(clk_125Mhz, reset)

    begin
    if (reset = '1') then
    rise_counter <= X"00" &'0';
    elsif(rising_edge(clk_125Mhz)) then

    rise_counter <= rise_counter + 2;
    end if;
    end process;

    process(clk_125Mhz, reset)

    begin
    if (reset = '1') then
    fall_counter <= X"00" &'1';
    elsif(falling_edge(clk_125Mhz)) then
    fall_counter <= fall_counter + 2;
    end if;
    end process;


    process(xor_counter, final_counter)
    begin
    final_counter <= final_counter + 1;
    end process;


    xor_counter <= rise_counter XOR fall_counter;

    dc_count <= final_counter;

    duty_out <= '0' when (final_counter < duty_cycle) else '1';

    But this creates a Combinatorial loop.

    I tried:
    ---------------------------------------------------

    process(clk_125Mhz, reset)

    begin
    if (reset = '1') then
    rise_counter <= X"00" &'0';
    elsif(rising_edge(clk_125Mhz)) then

    rise_counter <= rise_counter + 2;
    end if;
    end process;

    final_counter <= rise_counter when clk_125Mhz ='1' else (rise_counter or "000000001");

    duty_out <= '0' when (final_counter < duty_cycle) else '1';

    But this produced a glitch in simulation.

    Does anyone else have any other ideas, on how to implement a dual edged counter? I feel like this should be an easy solution, I just keep thinking too complex.
    Cory Shol, Apr 17, 2013
    #1
    1. Advertising

  2. Cory Shol

    GaborSzakacs Guest

    Cory Shol wrote:
    > Hi All,
    >
    > I am researching ways onto create a dual edged Counter.
    >
    > Problem details:
    >
    > Original Clock = 25 MHz Put the Original clock through a PLL and multiply it by 5 making a new: Clk_125MHz = 125 MHz clock.
    >
    > Using the 125 MHz clock, I want to use a 9 bit register [Called Duty_cycle] to state the Duty cycle of a PWM.
    > For example if the Duty_cycle = "011111111" it will have a 50% duty cycle. Duty_cycle = "1111111110" it will have a ~0.2% duty cycle etc...
    >
    > The period of the PWM is 4096 ns (125 Mhz/ 2^9) = 125000000/512 = 244KHz =1/244KHz= 4096 ns.
    > Code looks something like:
    >
    > process(clk_125Mhz, reset)
    >
    > begin
    > if (reset = '1') then
    > dc_count_i <= X"00" &'0'; -- you can use others statement as well.
    > elsif(rising_edge(clk_125Mhz)) then
    > if(dc_count_i < duty_cycle) then
    > duty_out <='0';
    > else
    > duty_out <= '1';
    > end if;
    > dc_count_i <= dc_count_i + 1;
    > end if;
    > end process;
    >
    > Alright this is all fine and works decent.
    >
    > Now the extension I want to make my PWM have a period of 2048 ns. There are three ways I can think of to do this:
    > 1) PLL the clock to 250 MHz ( Do not want to run at Max frequency in the device)
    > 2) Change the 9 bit Duty Cycle register to 8 bits (Lower the resolution)
    > 3) Every time there is a rising or falling edge count up the counter
    >
    > This is coming back to topic title: to create a dual Edged Counter that can generate a duty cycle of a PWM.
    >
    > I tried something like:
    > ------------------------------------------------------
    > process(clk_125Mhz, reset)
    >
    > begin
    > if (reset = '1') then
    > rise_counter <= X"00" &'0';
    > elsif(rising_edge(clk_125Mhz)) then
    >
    > rise_counter <= rise_counter + 2;
    > end if;
    > end process;
    >
    > process(clk_125Mhz, reset)
    >
    > begin
    > if (reset = '1') then
    > fall_counter <= X"00" &'1';
    > elsif(falling_edge(clk_125Mhz)) then
    > fall_counter <= fall_counter + 2;
    > end if;
    > end process;
    >
    >
    > process(xor_counter, final_counter)
    > begin
    > final_counter <= final_counter + 1;
    > end process;
    >
    >
    > xor_counter <= rise_counter XOR fall_counter;
    >
    > dc_count <= final_counter;
    >
    > duty_out <= '0' when (final_counter < duty_cycle) else '1';
    >
    > But this creates a Combinatorial loop.
    >
    > I tried:
    > ---------------------------------------------------
    >
    > process(clk_125Mhz, reset)
    >
    > begin
    > if (reset = '1') then
    > rise_counter <= X"00" &'0';
    > elsif(rising_edge(clk_125Mhz)) then
    >
    > rise_counter <= rise_counter + 2;
    > end if;
    > end process;
    >
    > final_counter <= rise_counter when clk_125Mhz ='1' else (rise_counter or "000000001");
    >
    > duty_out <= '0' when (final_counter < duty_cycle) else '1';
    >
    > But this produced a glitch in simulation.
    >
    > Does anyone else have any other ideas, on how to implement a dual edged counter? I feel like this should be an easy solution, I just keep thinking too complex.


    Is the output of the PWM going to a pin that is supported by a DDR
    output flop? If so, then you could simply reduce the counter
    by one bit, but compare it with the upper bits of the duty cycle
    input. If the LSB of the duty cycle is zero, then the output DDR
    flop D inputs go from 11 to 00, but the it is 1, then the D inputs
    go from 11 to 10 to 00 as you pass the duty cycle threshold.
    No internal dual edges, no glitches.

    --
    Gabor
    GaborSzakacs, Apr 17, 2013
    #2
    1. Advertising

  3. Cory Shol

    Cory Shol Guest

    On Wednesday, April 17, 2013 10:21:19 AM UTC-5, Gabor Sz wrote:
    > Cory Shol wrote:
    >
    > > Hi All,

    >
    > >

    >
    > > I am researching ways onto create a dual edged Counter.

    >
    > >

    >
    > > Problem details:

    >
    > >

    >
    > > Original Clock = 25 MHz Put the Original clock through a PLL and multiply it by 5 making a new: Clk_125MHz = 125 MHz clock.

    >
    > >

    >
    > > Using the 125 MHz clock, I want to use a 9 bit register [Called Duty_cycle] to state the Duty cycle of a PWM.

    >
    > > For example if the Duty_cycle = "011111111" it will have a 50% duty cycle. Duty_cycle = "1111111110" it will have a ~0.2% duty cycle etc...

    >
    > >

    >
    > > The period of the PWM is 4096 ns (125 Mhz/ 2^9) = 125000000/512 = 244KHz =1/244KHz= 4096 ns.

    >
    > > Code looks something like:

    >
    > >

    >
    > > process(clk_125Mhz, reset)

    >
    > >

    >
    > > begin

    >
    > > if (reset = '1') then

    >
    > > dc_count_i <= X"00" &'0'; -- you can use others statement as well.

    >
    > > elsif(rising_edge(clk_125Mhz)) then

    >
    > > if(dc_count_i < duty_cycle) then

    >
    > > duty_out <='0';

    >
    > > else

    >
    > > duty_out <= '1';

    >
    > > end if;

    >
    > > dc_count_i <= dc_count_i + 1;

    >
    > > end if;

    >
    > > end process;

    >
    > >

    >
    > > Alright this is all fine and works decent.

    >
    > >

    >
    > > Now the extension I want to make my PWM have a period of 2048 ns. There are three ways I can think of to do this:

    >
    > > 1) PLL the clock to 250 MHz ( Do not want to run at Max frequency in the device)

    >
    > > 2) Change the 9 bit Duty Cycle register to 8 bits (Lower the resolution)

    >
    > > 3) Every time there is a rising or falling edge count up the counter

    >
    > >

    >
    > > This is coming back to topic title: to create a dual Edged Counter that can generate a duty cycle of a PWM.

    >
    > >

    >
    > > I tried something like:

    >
    > > ------------------------------------------------------

    >
    > > process(clk_125Mhz, reset)

    >
    > >

    >
    > > begin

    >
    > > if (reset = '1') then

    >
    > > rise_counter <= X"00" &'0';

    >
    > > elsif(rising_edge(clk_125Mhz)) then

    >
    > >

    >
    > > rise_counter <= rise_counter + 2;

    >
    > > end if;

    >
    > > end process;

    >
    > >

    >
    > > process(clk_125Mhz, reset)

    >
    > >

    >
    > > begin

    >
    > > if (reset = '1') then

    >
    > > fall_counter <= X"00" &'1';

    >
    > > elsif(falling_edge(clk_125Mhz)) then

    >
    > > fall_counter <= fall_counter + 2;

    >
    > > end if;

    >
    > > end process;

    >
    > >

    >
    > >

    >
    > > process(xor_counter, final_counter)

    >
    > > begin

    >
    > > final_counter <= final_counter + 1;

    >
    > > end process;

    >
    > >

    >
    > >

    >
    > > xor_counter <= rise_counter XOR fall_counter;

    >
    > >

    >
    > > dc_count <= final_counter;

    >
    > >

    >
    > > duty_out <= '0' when (final_counter < duty_cycle) else '1';

    >
    > >

    >
    > > But this creates a Combinatorial loop.

    >
    > >

    >
    > > I tried:

    >
    > > ---------------------------------------------------

    >
    > >

    >
    > > process(clk_125Mhz, reset)

    >
    > >

    >
    > > begin

    >
    > > if (reset = '1') then

    >
    > > rise_counter <= X"00" &'0';

    >
    > > elsif(rising_edge(clk_125Mhz)) then

    >
    > >

    >
    > > rise_counter <= rise_counter + 2;

    >
    > > end if;

    >
    > > end process;

    >
    > >

    >
    > > final_counter <= rise_counter when clk_125Mhz ='1' else (rise_counter or "000000001");

    >
    > >

    >
    > > duty_out <= '0' when (final_counter < duty_cycle) else '1';

    >
    > >

    >
    > > But this produced a glitch in simulation.

    >
    > >

    >
    > > Does anyone else have any other ideas, on how to implement a dual edged counter? I feel like this should be an easy solution, I just keep thinking too complex.

    >
    >
    >
    > Is the output of the PWM going to a pin that is supported by a DDR
    >
    > output flop? If so, then you could simply reduce the counter
    >
    > by one bit, but compare it with the upper bits of the duty cycle
    >
    > input. If the LSB of the duty cycle is zero, then the output DDR
    >
    > flop D inputs go from 11 to 00, but the it is 1, then the D inputs
    >
    > go from 11 to 10 to 00 as you pass the duty cycle threshold.
    >
    > No internal dual edges, no glitches.
    >
    >
    >
    > --
    >
    > Gabor


    The research is for an Microsemi Actel Igloo AGL1000. I don't think it has a DDR output flop.
    Cory Shol, Apr 17, 2013
    #3
  4. Cory Shol

    GaborSzakacs Guest

    Cory Shol wrote:
    > On Wednesday, April 17, 2013 10:21:19 AM UTC-5, Gabor Sz wrote:
    >> Cory Shol wrote:
    >>
    >>> Hi All,
    >>> I am researching ways onto create a dual edged Counter.
    >>> Problem details:
    >>> Original Clock = 25 MHz Put the Original clock through a PLL and multiply it by 5 making a new: Clk_125MHz = 125 MHz clock.
    >>> Using the 125 MHz clock, I want to use a 9 bit register [Called Duty_cycle] to state the Duty cycle of a PWM.
    >>> For example if the Duty_cycle = "011111111" it will have a 50% duty cycle. Duty_cycle = "1111111110" it will have a ~0.2% duty cycle etc...
    >>> The period of the PWM is 4096 ns (125 Mhz/ 2^9) = 125000000/512 = 244KHz =1/244KHz= 4096 ns.
    >>> Code looks something like:
    >>> process(clk_125Mhz, reset)
    >>>
    >>> begin
    >>> if (reset = '1') then
    >>> dc_count_i <= X"00" &'0'; -- you can use others statement as well.
    >>> elsif(rising_edge(clk_125Mhz)) then
    >>> if(dc_count_i < duty_cycle) then
    >>> duty_out <='0';
    >>> else
    >>> duty_out <= '1';
    >>> end if;
    >>> dc_count_i <= dc_count_i + 1;
    >>> end if;
    >>> end process;
    >>> Alright this is all fine and works decent.
    >>> Now the extension I want to make my PWM have a period of 2048 ns. There are three ways I can think of to do this:
    >>> 1) PLL the clock to 250 MHz ( Do not want to run at Max frequency in the device)
    >>> 2) Change the 9 bit Duty Cycle register to 8 bits (Lower the resolution)
    >>> 3) Every time there is a rising or falling edge count up the counter
    >>> This is coming back to topic title: to create a dual Edged Counter that can generate a duty cycle of a PWM.
    >>> I tried something like:
    >>> ------------------------------------------------------
    >>> process(clk_125Mhz, reset)
    >>>
    >>> begin
    >>> if (reset = '1') then
    >>> rise_counter <= X"00" &'0';
    >>> elsif(rising_edge(clk_125Mhz)) then
    >>> rise_counter <= rise_counter + 2;
    >>> end if;
    >>> end process;
    >>> process(clk_125Mhz, reset)
    >>>
    >>> begin
    >>> if (reset = '1') then
    >>> fall_counter <= X"00" &'1';
    >>> elsif(falling_edge(clk_125Mhz)) then
    >>> fall_counter <= fall_counter + 2;
    >>> end if;
    >>> end process;
    >>> process(xor_counter, final_counter)
    >>> begin
    >>> final_counter <= final_counter + 1;
    >>> end process;
    >>> xor_counter <= rise_counter XOR fall_counter;
    >>> dc_count <= final_counter;
    >>>
    >>> duty_out <= '0' when (final_counter < duty_cycle) else '1';
    >>> But this creates a Combinatorial loop.
    >>> I tried:
    >>> ---------------------------------------------------
    >>> process(clk_125Mhz, reset)
    >>>
    >>> begin
    >>> if (reset = '1') then
    >>> rise_counter <= X"00" &'0';
    >>> elsif(rising_edge(clk_125Mhz)) then
    >>> rise_counter <= rise_counter + 2;
    >>> end if;
    >>> end process;
    >>> final_counter <= rise_counter when clk_125Mhz ='1' else (rise_counter or "000000001");
    >>> duty_out <= '0' when (final_counter < duty_cycle) else '1';
    >>> But this produced a glitch in simulation.
    >>> Does anyone else have any other ideas, on how to implement a dual edged counter? I feel like this should be an easy solution, I just keep thinking too complex.

    >>
    >>
    >> Is the output of the PWM going to a pin that is supported by a DDR
    >>
    >> output flop? If so, then you could simply reduce the counter
    >>
    >> by one bit, but compare it with the upper bits of the duty cycle
    >>
    >> input. If the LSB of the duty cycle is zero, then the output DDR
    >>
    >> flop D inputs go from 11 to 00, but the it is 1, then the D inputs
    >>
    >> go from 11 to 10 to 00 as you pass the duty cycle threshold.
    >>
    >> No internal dual edges, no glitches.
    >>
    >>
    >>
    >> --
    >>
    >> Gabor

    >
    > The research is for an Microsemi Actel Igloo AGL1000. I don't think it has a DDR output flop.


    Realize that without an output DDR flop, there will be some influence
    of routing delays between even and odd values of duty cycle, but the
    same approach of using a shorter counter to make the PWM with half the
    resolution could work. Follow that with a single flop on the falling
    clock edge. Then you have two PWM signals offset by half a clock cycle.
    At the output, you would either select the first, or the OR of the two
    signals based on the LSB of duty cycle. Again no glitches, but the
    monotonicity could suffer slightly.

    --
    Gabor
    GaborSzakacs, Apr 17, 2013
    #4
  5. Cory Shol

    Cory Shol Guest

    On Wednesday, April 17, 2013 10:54:46 AM UTC-5, Gabor Sz wrote:
    > Cory Shol wrote:
    >
    > > On Wednesday, April 17, 2013 10:21:19 AM UTC-5, Gabor Sz wrote:

    >
    > >> Cory Shol wrote:

    >
    > >>

    >
    > >>> Hi All,

    >
    > >>> I am researching ways onto create a dual edged Counter.

    >
    > >>> Problem details:

    >
    > >>> Original Clock = 25 MHz Put the Original clock through a PLL and multiply it by 5 making a new: Clk_125MHz = 125 MHz clock.

    >
    > >>> Using the 125 MHz clock, I want to use a 9 bit register [Called Duty_cycle] to state the Duty cycle of a PWM.

    >
    > >>> For example if the Duty_cycle = "011111111" it will have a 50% duty cycle. Duty_cycle = "1111111110" it will have a ~0.2% duty cycle etc...

    >
    > >>> The period of the PWM is 4096 ns (125 Mhz/ 2^9) = 125000000/512 = 244KHz =1/244KHz= 4096 ns.

    >
    > >>> Code looks something like:

    >
    > >>> process(clk_125Mhz, reset)

    >
    > >>>

    >
    > >>> begin

    >
    > >>> if (reset = '1') then

    >
    > >>> dc_count_i <= X"00" &'0'; -- you can use others statement as well.

    >
    > >>> elsif(rising_edge(clk_125Mhz)) then

    >
    > >>> if(dc_count_i < duty_cycle) then

    >
    > >>> duty_out <='0';

    >
    > >>> else

    >
    > >>> duty_out <= '1';

    >
    > >>> end if;

    >
    > >>> dc_count_i <= dc_count_i + 1;

    >
    > >>> end if;

    >
    > >>> end process;

    >
    > >>> Alright this is all fine and works decent.

    >
    > >>> Now the extension I want to make my PWM have a period of 2048 ns. There are three ways I can think of to do this:

    >
    > >>> 1) PLL the clock to 250 MHz ( Do not want to run at Max frequency in the device)

    >
    > >>> 2) Change the 9 bit Duty Cycle register to 8 bits (Lower the resolution)

    >
    > >>> 3) Every time there is a rising or falling edge count up the counter

    >
    > >>> This is coming back to topic title: to create a dual Edged Counter that can generate a duty cycle of a PWM.

    >
    > >>> I tried something like:

    >
    > >>> ------------------------------------------------------

    >
    > >>> process(clk_125Mhz, reset)

    >
    > >>>

    >
    > >>> begin

    >
    > >>> if (reset = '1') then

    >
    > >>> rise_counter <= X"00" &'0';

    >
    > >>> elsif(rising_edge(clk_125Mhz)) then

    >
    > >>> rise_counter <= rise_counter + 2;

    >
    > >>> end if;

    >
    > >>> end process;

    >
    > >>> process(clk_125Mhz, reset)

    >
    > >>>

    >
    > >>> begin

    >
    > >>> if (reset = '1') then

    >
    > >>> fall_counter <= X"00" &'1';

    >
    > >>> elsif(falling_edge(clk_125Mhz)) then

    >
    > >>> fall_counter <= fall_counter + 2;

    >
    > >>> end if;

    >
    > >>> end process;

    >
    > >>> process(xor_counter, final_counter)

    >
    > >>> begin

    >
    > >>> final_counter <= final_counter + 1;

    >
    > >>> end process;

    >
    > >>> xor_counter <= rise_counter XOR fall_counter;

    >
    > >>> dc_count <= final_counter;

    >
    > >>>

    >
    > >>> duty_out <= '0' when (final_counter < duty_cycle) else '1';

    >
    > >>> But this creates a Combinatorial loop.

    >
    > >>> I tried:

    >
    > >>> ---------------------------------------------------

    >
    > >>> process(clk_125Mhz, reset)

    >
    > >>>

    >
    > >>> begin

    >
    > >>> if (reset = '1') then

    >
    > >>> rise_counter <= X"00" &'0';

    >
    > >>> elsif(rising_edge(clk_125Mhz)) then

    >
    > >>> rise_counter <= rise_counter + 2;

    >
    > >>> end if;

    >
    > >>> end process;

    >
    > >>> final_counter <= rise_counter when clk_125Mhz ='1' else (rise_counter or "000000001");

    >
    > >>> duty_out <= '0' when (final_counter < duty_cycle) else '1';

    >
    > >>> But this produced a glitch in simulation.

    >
    > >>> Does anyone else have any other ideas, on how to implement a dual edged counter? I feel like this should be an easy solution, I just keep thinking too complex.

    >
    > >>

    >
    > >>

    >
    > >> Is the output of the PWM going to a pin that is supported by a DDR

    >
    > >>

    >
    > >> output flop? If so, then you could simply reduce the counter

    >
    > >>

    >
    > >> by one bit, but compare it with the upper bits of the duty cycle

    >
    > >>

    >
    > >> input. If the LSB of the duty cycle is zero, then the output DDR

    >
    > >>

    >
    > >> flop D inputs go from 11 to 00, but the it is 1, then the D inputs

    >
    > >>

    >
    > >> go from 11 to 10 to 00 as you pass the duty cycle threshold.

    >
    > >>

    >
    > >> No internal dual edges, no glitches.

    >
    > >>

    >
    > >>

    >
    > >>

    >
    > >> --

    >
    > >>

    >
    > >> Gabor

    >
    > >

    >
    > > The research is for an Microsemi Actel Igloo AGL1000. I don't think it has a DDR output flop.

    >
    >
    >
    > Realize that without an output DDR flop, there will be some influence
    >
    > of routing delays between even and odd values of duty cycle, but the
    >
    > same approach of using a shorter counter to make the PWM with half the
    >
    > resolution could work. Follow that with a single flop on the falling
    >
    > clock edge. Then you have two PWM signals offset by half a clock cycle.
    >
    > At the output, you would either select the first, or the OR of the two
    >
    > signals based on the LSB of duty cycle. Again no glitches, but the
    >
    > monotonicity could suffer slightly.
    >
    >
    >
    > --
    >
    > Gabor


    THE DDR flip flop got me thinking. So I went back and looked at Spartan 3A user guide to see the DDR flip flop.

    I then looked for a similar flip flop in the Actel AGL1000 and it indeed does have a DDR register input or output type.

    Even after working 2 years in Logic design I still feel like I know nothing.
    Cory Shol, Apr 17, 2013
    #5
  6. Cory Shol

    rickman Guest

    On 4/17/2013 1:45 PM, Cory Shol wrote:
    >
    > Even after working 2 years in Logic design I still feel like I know nothing.


    I know the feeling. There is just so much to learn.

    Are you looking for an *average* PWM on the pin or does it need to be
    exact on every cycle? If the average value is what is important you can
    use a fractional divider which should be easier and can get you even
    more precision.

    A fractional divider just counts the number of PWM cycles and
    periodically adds or subtracts one from the duty_cycle value. This can
    be done in a manner that is not actually periodic so that the side tones
    it introduces are spread out and at a low level if that is important.

    You might also consider using a DCO. I tried to do that for a few
    minutes and couldn't think of how that would work. But I'm pretty sure
    there is a way. I'm just drawing a blank at the moment. A DCO will
    give you a much more precise average value with one clock cycle of
    jitter on the edge, similar to the fractional divider, but easier to tune.

    --

    Rick
    rickman, Apr 17, 2013
    #6
  7. Cory Shol

    rickman Guest

    On 4/17/2013 3:18 PM, rickman wrote:
    >
    > You might also consider using a DCO. I tried to do that for a few
    > minutes and couldn't think of how that would work. But I'm pretty sure
    > there is a way. I'm just drawing a blank at the moment. A DCO will give
    > you a much more precise average value with one clock cycle of jitter on
    > the edge, similar to the fractional divider, but easier to tune.


    Ok, brain cramp over...

    Use a DCO to generate a ramp signal in as many bits as you want. The
    step size will set the rate at which it rolls over and so the PWM
    frequency. Since the DCO can be lots of bits, the duty_cycle can be
    more bits than with a simple counter. So the point in the cycle where
    the counter is above the duty_cycle will jitter around a clock edge, but
    the average can be very precise, as long as your step_size is not an
    integer ratio to the modulus. You need the steps to walk around the
    number space.

    --

    Rick
    rickman, Apr 17, 2013
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Nicolas Matringe

    Synthesizable (kind of) dual-edge FF

    Nicolas Matringe, Sep 27, 2004, in forum: VHDL
    Replies:
    1
    Views:
    926
    Ralf Hildebrandt
    Oct 12, 2004
  2. john

    FPGA and Dual Port RAM

    john, Nov 3, 2004, in forum: VHDL
    Replies:
    2
    Views:
    3,587
  3. john

    Dual port RAM

    john, Nov 4, 2004, in forum: VHDL
    Replies:
    1
    Views:
    768
    mike_treseler
    Nov 4, 2004
  4. The Eeediot
    Replies:
    3
    Views:
    2,213
    =?Utf-8?B?UnVsaW4gSG9uZw==?=
    Dec 22, 2004
  5. George2
    Replies:
    1
    Views:
    781
    Alf P. Steinbach
    Jan 31, 2008
Loading...

Share This Page