# [SOLVED]Frequency divider with changeable frequency

Status
Not open for further replies.

#### Feco

##### Newbie level 6
Hello everyone.

I'm new to the FPGA world and a got a little problem.

I wanted to make a simple frequency divider with changeable frequency rate. The first part works good (there are lot of tutorials), but the second...
I have 8 buttons, with them I wanted to change the frequency between 0 and 255 Hz. It seemed, that it is an easy task. I coded it and its working, but not properly. When I use the buttons there is a delay time around 3-4 seconds (or even more). I don't think it should work that way. Is there any possibility to correct that delay?

Here is the code:

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
use IEEE.NUMERIC_STD.ALL;

entity clk_div is
Port ( CLK  : in  STD_LOGIC;
Freq : in  STD_LOGIC_VECTOR(7 downto 0);
CLK2 : out  STD_LOGIC);
end clk_div;

architecture Behavioral of clk_div is

signal max : integer := (100000000/(to_integer(signed(Freq))*2))-1;
signal CLK_count : STD_LOGIC_VECTOR (30 downto 0);
signal sCLK2 : STD_LOGIC;
begin

process(CLK, max)
begin

if (rising_edge(CLK)) then
if (CLK_count = max) then
CLK_count <= (others => '0');
sCLK2 <= not(sCLK2);
else
CLK_count <= CLK_count + 1;
end if;
else
null;
end if;
end process;

CLK2 <= sCLK2;
end Behavioral;

Maybe the type conversion takes long time?
If it matter, I use Digilent Nexys3 board with Spartan 6 FPGA.

Thanks.

#### bking

##### Member level 5
You are checking the 'CLK_count' to see if it matches 'max'. If you change the settings for 'max' to something less than what the count is already at, you have to let in count all the way up to where it wraps back to zero, then count from that point to see the 'max' value again. You can either change the if statement to check for >= to 'max' (and adjust for the one extra count difference), or change it to < and swap the if and else parts of the statement so it adds to the count when the count is less than 'max'.

*** Why don't you use an integer for the clock count as well??

Last edited:
Feco

### Feco

Points: 2

#### TrickyDicky

Type conversions mean nothing in logic - remember on the circuit its just a load of bits. Types in VHDL are just for user convenience.

And why do you have an else clause with the clock?

#### lucbra

the statement
Code:
signal max : integer := (100000000/(to_integer(signed(Freq))*2))-1;
bothers me.

I think this only works with generics, not with a port input.
So if you want Max to be kept up to date, you'll need to assign it differently.

Code:
And why do you have an else clause with the clock?
actually, he doesn't. "null" has no meaning in real logic. But to be clear, you can leave the else clause out.
be carefull to check Max (an integer) against Clk_Count (a std_logic_vector). VHDL is strongly typed.
And with Max changing, you better check for Count <= Max as :
Code:
if reset = '1' then -- I prefer a hard coded reset
sCLK2 <= '0';
Clk_Count <= 0; -- define as natural
elsif rising_edge(Clk) then
if Clk_Count <= Max then
sCLK2 <= not sCLK2;
Clk_Count <= 0;
else
Clk_Count <= Clk_Count + 1;
end if;
end if;

tpetar

### tpetar

Points: 2

#### FvM

##### Super Moderator
Staff member
The reason for the delay has been explained correctly by bking, I think.

Although the type conversion doesn't involve a problem, the divider inferred from the max expression requires a lot of logic. I guess, you actually want Freq interpreted as unsigned quantity!

By changing the design to a use a DDS phase accumulator, the logic effort can be most likely reduced.
Code:
if akku >= 100000000 then
akku <= akku + Freq -100000000;
sCLK2 <= not sCKL2;
else
akku <= akku + Freq;
end if;
In contrast to the original design, it will generate an exact fractional division.

P.S.:
the statement
Code:
signal max : integer := (100000000/(to_integer(signed(Freq))*2))-1;bothers me.

I think this only works with generics, not with a port input.
So if you want Max to be kept up to date, you'll need to assign it differently.

This is possibly tool dependent, but most tools will infer a divider for this expression.

tpetar

### tpetar

Points: 2

#### Feco

##### Newbie level 6
bking's was the correct answer, it solved the problem, thanks.

*** Why don't you use an integer for the clock count as well??

Well, I have no idea, I just learnt that way, but you are right, I should use integer.

And why do you have an else clause with the clock?

I think it's better to know that 'else nothing happens...'

Now I have a new problem with that. It works great except between 127-255. I don't know why. I changed to freq from (7 downto 0) to (8 downto 0), now it works between 127-255, but not between 256-511. So there is something wrong with the most significant bit. Any idea why?

#### TrickyDicky

I think it's better to know that 'else nothing happens...'

I dont. And its not included in any register templates anywhere. Think about it - do you ever think anything ever could happen in that else block? if you ever did include code in there, you will get synthesis failures and quirky simulation results.

Now I have a new problem with that. It works great except between 127-255. I don't know why. I changed to freq from (7 downto 0) to (8 downto 0), now it works between 127-255, but not between 256-511. So there is something wrong
with the most significant bit. Any idea why?

Got a testbench?

#### FvM

##### Super Moderator
Staff member
It works great except between 127-255.
As already said, you make an erroneous conversion to signed(), which explains the observation. Should be unsigned().

tpetar and Feco

Points: 2

### tpetar

Points: 2

#### mrflibble

I think it's better to know that 'else nothing happens...
You just think it is. Remember, it's called hardware description language for a reason. You try and describe your design according to a set of rules such that THE SYNTHESIZER (aka, not you) thinks it's a good idea and understands what logic to infer. While you may think it's pretty, the synthesizer may go WTF? and decide to infer something unintended based on your attempted hardware description. It really is just a matter of knowing what templates the synthesizer will recognize, and sticking with it. Making up your own because you feel it makes sense to you will not help you in getting a working design.

Short version: stick to the boring templates and stuff will actually work as intended.

#### Feco

##### Newbie level 6
Oh, I haven't seen it, thx.

Status
Not open for further replies.