1
\$\begingroup\$

I am trying to make a clock divider commanded by 2 bits :DTPS. For instance if DTPS is:

  • "00" we get the clock as output(2^0)
  • "01" we divide the clock by 2 (2^1)
  • "10" we divide the clock by 4 (2^2)
  • "11" we divide the clock by 8 (2^3)

So i had 2 problems the first is when DTPS is "10" divison becomes 11111111111111111111111111100 I don't know why. and the second problem is that I manged to get an impulse when the DTPS ="01" but i could not make a full signal which the division of clk.

Please review my code and tell me what I i did wrong and how could the right thing that I did be improved as well as my coding style.

Thank you very much.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
Use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;

entity diviseur2n is
     Generic (Nbits : integer := 8);
    Port ( rst : in STD_LOGIC;
           clk : in  STD_LOGIC;
           DTPS : in STD_LOGIC_VECTOR(1 downto 0);
           tc : out STD_LOGIC);
end diviseur2n;

architecture architecture_diviseur of diviseur2n is

signal cpt : std_logic_vector(Nbits-1 downto 0);
signal division : integer;
signal cpt_full : std_logic;

begin
    process(clk)
      begin
        if DTPS="00" then
            division <= 1;
        else
            division <= to_integer(signed(DTPS))*2;-- value of DTPS into decimal then *2 to get 2^n= divison
        end if;
    end process;

  -- compteur 0 a division
  comptage: process(clk,rst,division)
  begin
  --cpt_full <= '0';give this error: Signal cpt_full cannot be synthesized, bad synchronous description. The description style you are using to describe a synchronous element (register, memory, etc.) is not supported in the current software release.

   if rst = '1' then
     cpt <= (others => '0');
      cpt_full <= '0';
   elsif rising_edge(clk) then     
    if cpt < division then
        cpt <= cpt + 1;
     else   
        cpt <= (others => '0');
          cpt_full <= '1';
     end if;
    end if;
  end process comptage;

  -- impulsion de sortie a division
  retenue: process(cpt_full)
    begin
        if cpt_full='1' then
            tc <= '1';
        else 
            tc <= '0';
        end if;
    end process retenue;  

end architecture_diviseur;
\$\endgroup\$
0
\$\begingroup\$

You have,

if cpt < division then

What do you expect to happen here if division is 0?

In any case, there is a much simpler approach to this kind of problem.

You can just make a modulo-8 counter.

Now, 1 bit of the count variable will be the same as a modulo-2 counter, one bit will be the same as a modulo-4 counter, and the highest order bit will be the modulo-8 counter.

A combinatorial multiplexer can connect any of these three bits (or the original input clock itself) to the output.

If you have some additional requirements, like being able to change the divisor without creating an output glitch, you may require some additional logic to time when the multiplexer select bits are updated.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Thank you, I will try doing it with modulo 8, but for the sake understanding, you said what happens when division is 0, it should never be zero since I used this lines : DTPS="00" then division <= 1; or am I wrong? \$\endgroup\$ – Ryan Nov 4 '17 at 6:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.