Forum Discussion
Clock problem
Hi All,
I am trying to reduce the clock frequency from 25 MHZ to 12.5 MHZ using VHDL. I also intend to implement this in hardware, however I am having a lot of difficulty with my code. I can not assign a new clock frequency to an output variable which I wanted to assign to an output pin. I am getting the following error for my code which is shown below: Error (10517): VHDL type mismatch error at clock.vhd(23): std_logic_vector type does not match integer literal My Code: -- Divide clock frequency by 2 -- Standard libary delarations library ieee; use ieee.std_logic_1164.all; -- define input and outputs for the entity entity clock is port( clk_in: in std_logic; clk_out: buffer std_logic; va: buffer std_logic_vector(2 downto 0) ); end clock; -- internal function of enetity architecture behave of clock is --internal variable signal count : integer :=1; begin process (clk_in,clk_out,va) begin -- Required in order to convert the sinewave to a square wave clk_out <= not clk_in; -- Check for rising edge of clock if(clk_out'event and clk_out='1') then --increment the count variable by 1 count <=count+1; -- when count is 2 if(count = 2) then --assign 1 to the variable which will be assigned to an output pin va <= 1; end if; end if; end process; end behave; Thank you in advance.12 Replies
- Altera_Forum
Honored Contributor
I can't understand what you are trying to do.
From your first sentence I assumed you want clk_out to be half the frequency of clk_in. This can be done with simple code, like this: if(clk_in'event and clk_in='1') then clk_out <= not clk_out; end if; Regarding the error. that's normal if you write va <= 1 You defined va as a std_logic vector 3 bits long, so you must use va <= "000" Anyway, your code seems to be useless since va is not initialized to any other value and assigned only to 1 when count is 2. I'd expect at least a reset signal, in order to reset count and va to initial status. - Altera_Forum
Honored Contributor
Gated clocks are bad.
but anyway, what's the point of using signal va as std_logic_vector? You're assigning one bit value to 3bit bus. Also the code logically won't work, since You don't reset the counter. - Altera_Forum
Honored Contributor
Thanks you both or replying.
I was trying to eventually reduce the frequency from 25 MHZ into 1 HZ eventually so that I can output pulses that are 1 second long in duration. I thought I would start by dividing the frequency by 2 first. On the hardware I am using the 25 MHZ crystal output is converted into square waves using the NOT function. I am not entirely sure how your code divides the frequency by 2: if(clk_in'event and clk_in='1') then clk_out <= not clk_out; Thanks to you both. - Altera_Forum
Honored Contributor
I found this piece of code which divides CLKIN to a fixed value.
Simply change the div := 2000000 assignment and renge to the value you need.
Note: this was one of the very first things I made with VHDL. Looking at it now I see some points which could have been implemented far better.:oops: Anyway it worked and you can trust using it.entity divider is port (CLKIN : in std_logic; CLKOUT : out std_logic ); end entity divider; architecture divider_a of divider is subtype small_int is natural range 0 to 2000000; begin update: process(CLKIN) is variable div : small_int := 0; variable status : bit; begin if rising_edge(CLKIN) then if div = 0 then div := 2000000; if status='0' then CLKOUT <= '1'; else CLKOUT <= '0'; end if; status := not status; else div := div - 1; end if; end if; end process; end architecture divider_a; - Altera_Forum
Honored Contributor
Thanks Cris :)
- Altera_Forum
Honored Contributor
Hi All,
I managed to get the following code working after I initially had some problems in declaring variables and generally not understanding the code. I have hardware on which there is a 25 MHZ crystal oscillator and I have reduced that frequency to 1 HZ. It worked on the simulator and on the hardware as I assigned the output to an LED. Cris kindly posted me some code and I thought it would be more beneficial for my progress I continued with mine. I have a couple of questions. 1) Is my code OK, 2) Is this the correct way to approach the problem, I have tackled it more as a software problem and VHDL is a hardware language. Would it be more proper for me to create divide by 2 counters in vhdl in order to reduce frequency. Thank you in advance for your help. My code -- Standard libary delarations library ieee; use ieee.std_logic_1164.all; -- define input and outputs for the entity entity led is port( clk_in: in std_logic; clk_out: buffer std_logic; clk: buffer std_logic); end led; -- internal function of enetity architecture behave of led is --internal variable signal count : integer :=1; begin process (clk_in,clk_out) begin -- Required in order to convert the sinewave to a square wave clk_out <= not clk_in; -- Check for rising edge of clock if(clk_out'event and clk_out='1') then --increment the count variable by 1 count <=count+1; -- when count is 2 if(count = 1250000) then clk <= not clk; count <= 1; --assign 1 to the variable which will be assigned to an output pin end if; end if; end process; end behave; - Altera_Forum
Honored Contributor
The code is now ok, although I can't get the point of this assignment
--- Quote Start --- -- Required in order to convert the sinewave to a square wave clk_out <= not clk_in; --- Quote End --- If you mean that clk_in comes from the external oscillator as a sine wave, this assignment is actually useless. FPGA is a digital device, so clk_in would be automatically converted in a square wave when it pass through the fpga input port. - Altera_Forum
Honored Contributor
Cris72, I am using a MAX7000S EPM7128LC84-10 device. The assignment is not complete I am just doing it in small steps. I would like to make a clock eventually that counts seconds, minutes and hours.
Thanks again Cris72. - Altera_Forum
Honored Contributor
Using a clock signal generated from logic is commonly a bad practice. If you mean to use it, you should route it through a global clock line, but I believe this is not possible in MAX7000S since global clocks are required to come from dedicated pins (please check this point, I'm not sure).
The correct way of operation is usually clocking everything with the global clock (clk_in in your case) and then generating proper clock enable signals, one pulse wide, in order to control the lower frequency counters. You need to change your code into: if(count = 1250000) then clk_en <= 1; count <= 1; else clk_en <= 0; end if; Then your seconds counter would be something like this: if(clk_in'event and clk_in='1') then if (clk_en = 1) seconds <= seconds+1; end if; end if; Regards - Altera_Forum
Honored Contributor
Thank you very much Cris72.