1

I found this code in how to make a clock divider. I have a general understanding on how to make a divider using counters but i not sure what this code is doing and why its doing it.

entity clkdiv is
    Port ( mclk : in  STD_LOGIC;
           clr : in  STD_LOGIC;
           clk190 : out  STD_LOGIC;
           clk48 : out  STD_LOGIC);
end clkdiv;

architecture clkdiv of clkdiv is
signal q: std_logic_vector(23 downto 0);
begin
    --clock divider
    process(mclk,clr)
    begin   
        if clr ='1' then
            q <= X"000000";
        elsif mclk'event and mclk = '1' then
            q <= q+1;
        end if;
    end process;
    clk48 <= q(19);
    clk190 <= q(17);

end clkdiv;

I know that the example is on the basis 2 board, the input clock is 50MHz. This code is supposed to create a 48hz clock signal and 190hz clock signal.

user1175889
  • 141
  • 3
  • 4
  • 13

2 Answers2

2

50MHz/48Hz = 104166.7, so you can't get there exactly.

If you use a counter which counts up to 104167 at 50MHz, you'll get a single pulse at close to 48 Hz (47.9999846 Hz - which is probably good enough for most purposes).

Don't use the output of the counter as a clock, use a single pulse when it wraps around as a clock enable - you get much better results that way. A single clock throughout the design with enabled sections is the way to do it.

Martin Thompson
  • 16,395
  • 1
  • 38
  • 56
  • Do you mean like this 'architecture clkdiv of clkdiv is signal Count5Hz : std_logic_vector(27 downto 0) := (others => '0'); constant clk5HzEndVal : STD_LOGIC_VECTOR(27 downto 0) := X"2FAF080"; begin--clock divider process(mclk,clr) begin if (clr ='1') then Count5Hz <= X"0000000"; clk200 <= '0'; clk5 <= '0'; elsif rising_edge(mclk) then if (Count5Hz = clk5HzEndVal) then clk5 <= not clk5; Count5Hz <= X"0000000"; else Count5Hz <= Count5Hz + '1'; end if; end if; end process;' – user1175889 Nov 01 '13 at 15:02
  • I can't read that code as a comment, but I'd suggest using INTEGER types as it's easier to work with than std_logic_vectors for this sort of thing. You can also use the compiler to calculate the end value from the required frequency and the known clock frequency instead of just hard coding constants that are hard to check – Martin Thompson Nov 03 '13 at 19:53
  • would that be using the ip core in xilinx, yeah i don't know how to use that. – user1175889 Nov 04 '13 at 21:02
  • No, no IP core required, just write your VHDL using `integer` types – Martin Thompson Nov 05 '13 at 17:05
1

What the above code does is simply that it creates a VHDL module containing a 24 bit counter q, which is counted up on each rising edge from the master clock mclk. It then derives clk190 and clk48 by using different bits of this counter directly as clock signals.

For instance, with mclk at 50 MHz, the lsb (q(0)), would effectively run at 25 MHz. Each rising edge of mclk gives you one edge on q(0) - similarly upwards, so that each subsequent bit runs at half the frequency of the previous bit.

For instance:

mclk = 50 MHz
q(0) = mclk / 2 = 25 Mhz
q(1) = q(0) / 2 = mclk / 4 = 12.5 MHz
...
q(n) = mclk / (2^(n+1))

Your derived clocks will thus be depend on your master clock, and be:

q(17) = 50 MHz / 262144 = 191 Hz
q(19) = 50 MHz / 1048576 = 48 Hz

However - generating clocks like this is often the wrong way to do it!

It may seem as if you get nice synchronized clocks, but in reality, they'll be slightly skewed compared to each other, since you're generating what is known as a gated clock (many tools will even warn you about this).

More info on that here, including a way of doing the same thing (but better) with clock enables: VHDL: creating a very slow clock pulse based on a very fast clock

Community
  • 1
  • 1
sonicwave
  • 5,952
  • 2
  • 33
  • 49
  • So if i am using a 100MHz clock, how could i generate these frequencies (190hz, 48hz) – user1175889 Oct 31 '13 at 14:18
  • Is it that hard to see?;) Just shift the bits you're using one to the left, that is `clk48 <= q(20)` and `clk190 <= q(18)`, that'll double the divisor, and give you what you need from a 100 MHz clock. Be sure that you understand the pitfalls of gated clocks before you base too much of your design on these though... – sonicwave Oct 31 '13 at 14:23
  • The reason why i ask is because i did shift the bits to the left and the signal was not great, that was the first thing i tried, i assume i did something wrong, but thank you for the example – user1175889 Oct 31 '13 at 14:26
  • What do you mean by "the signal was not great"? – sonicwave Oct 31 '13 at 14:28
  • How much too fast? As Martin mentions in his answer, you can't hit those frequencies exactly... – sonicwave Nov 01 '13 at 07:13
  • The clock signal generated was used to scroll numbers across seven segment display, the speed was meant to be slow enough to see the change, when i did it, it scrolled so fast that i could not see the change in numbers only flashes – user1175889 Nov 01 '13 at 14:55
  • But did you check whether this was actually due to your clock running too fast, or due to a mistake somewhere else in the design? – sonicwave Nov 02 '13 at 15:42
  • i dont think it was the design because the code came straight from the book i was using, the book used a board whose clock was 50hz, mine board uses a 100mhz clock, and i shifted the bits as mentioned, but as i mentioned it went too fast – user1175889 Nov 03 '13 at 17:37