EmbDev.net

Forum: FPGA, VHDL & Verilog Clock frequency reducer


von Eric J. (coderic)


Rate this post
useful
not useful
I am trying to divide my input clock signal by 10 - effectively setting 
my out HIGH 5 of ten clock pulses and LOW the other 5.

However, my counter idea does not work - the clk_ou2 signal doesn't 
update at all, and I do not know why.

1
library ieee;
2
use ieee.std_logic_1164.all;
3
use ieee.numeric_std.all;
4
5
entity Taktteiler is
6
7
port (
8
    clk_in : in std_logic;
9
    clk_out : out std_logic;
10
    reset : in std_logic
11
);
12
end Taktteiler;
13
14
architecture rtl of Taktteiler is
15
16
signal counter : unsigned(3 downto 0);
17
signal clk_out2 : std_logic := '0';
18
19
begin
20
process(clk_in)
21
    begin
22
        if(rising_edge(clk_in)) then
23
            counter <= counter + 1;
24
            if std_logic_vector(counter) = "101" then --reset the counter at 101
25
                counter <= (others => '0');
26
                clk_out2 <= clk_out2 XOR '1'; --toggle the out2 signal
27
            end if;
28
        end if;
29
        if reset = '1' then --reset on HIGH reset input
30
            counter <= (others => '0');
31
            clk_out2 <= '0';
32
        end if;
33
end process;
34
clk_out <= clk_out2;
35
end architecture rtl;

von Achim S. (Guest)


Rate this post
useful
not useful
counter is a 4 bit vector. It can never be equal to "101", because that 
ist a 3 bit vector. So std_logic_vector(counter) = "101" will never be 
true...

Try to replace line 24 by
    if counter="0101" then

If it works, then check, if you really divide by 10 or by some other 
value..

von Duke Scarring (Guest)


Attached files:

Rate this post
useful
not useful
I prefer a simple solution with just a single shift register:
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity clk_divider is
5
    port
6
    (
7
        clk_in  : in  std_logic;
8
        clk_out : out std_logic
9
    );
10
end entity clk_divider;
11
12
architecture rtl of clk_divider is
13
14
    signal clk_reg : std_logic_vector( 9 downto 0) := "0000011111";
15
16
begin
17
    
18
    process
19
    begin
20
        wait until rising_edge( clk_in);
21
        clk_reg <= clk_reg( clk_reg'high-1 downto 0) & clk_reg( clk_reg'high);
22
    end process;
23
24
    clk_out <= clk_reg( clk_reg'high);
25
26
end architecture rtl;

Duke

von Lothar M. (lkmiller) (Moderator)


Rate this post
useful
not useful
Eric J. wrote:
> signal counter : unsigned(3 downto 0);
Achim S. wrote:
> counter is a 4 bit vector. It can never be equal to "101"
To get rid of such kind of problems I would use an integer range 0 to 9 
for counting.
Then the compare for 0 and 5 is easily human readable:
1
:
2
signal counter : unsigned(3 downto 0);
3
:
4
:
5
   process(clk_in)
6
   begin
7
      if(rising_edge(clk_in)) then
8
         if counter<9 then counter <= counter + 1;
9
         else              counter <= 0;
10
         end if;   
11
         if counter = 0 then clk_out <= '0'; end if;
12
         if counter = 5 then clk_out <= '1'; end if;
13
   end process;
14
:

Duke Scarring wrote:
> I prefer a simple solution with just a single shift register
I prefer the very same without any process ;-)
1
library ieee;
2
use ieee.std_logic_1164.all;
3
4
entity clk_divider is
5
    port ( clk_in  : in  std_logic;
6
           clk_out : out std_logic);
7
end entity clk_divider;
8
9
architecture rtl of clk_divider is
10
    signal clk_reg : std_logic_vector(9 downto 0) := "0000011111";
11
begin
12
    clk_reg <= clk_reg(8 downto 0) & clk_reg(9) when rising_edge(clk_in);
13
    clk_out <= clk_reg(9);
14
end architecture rtl;

: Edited by Moderator

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig