How to divide a 24MHz clock to get 1kHz (in Verilog)

  • Thread starter EugP
  • Start date
  • Tags
    Clock
In summary: I'm not sure what's going on. I don't see any syntax errors, although there are some unnecessary wires in the top level file. I don't think that would stop the simulator, though.Sorry I can't be more help. I've never used Altera chips, and I don't have access to the tools here. I'm going home now, so I can't check back until tomorrow. Good luck!In summary, the conversation discusses using an Altera Cyclone II FPGA Development Board to control a relay by dividing a 24MHz signal to get 1kHz. One solution is to use a 10-bit counter, while another involves using the 8254 chip. The individual seeking help
  • #1
EugP
107
0
Hey guys,

I'm using the Altera Cyclone II FPGA Development Board, with the goal of controlling a relay. I need to divide 24MHz to get 1kHz, but I don't know how to write the code for it. I know one way to divide it, would be to have a 10bit counter, which will allow me to divide it by 1k, then all that's left is to divide it by 24, which can just be another counter that counts to 23. Again, though, I don't know what the code would look like. I looked online but for some reason I couldn't find any help.

Could anyone point me in the right direction? I don't want any code, just an explanation (if possbile...)

Thanks in advance.
 
Engineering news on Phys.org
  • #2
Am I missing something here? All you need is a counter to count your 24 MHz pulses and a bit of code to read that counter; when it gets to 12,000 it toggles an output pin (or whatever it is you need done) then resets the counter back to zero for the next half-cycle.
 
  • #3
There's a wonderful programmable chip called the 8254 which can be instructed to do exactly what you're asking for. You can see its spec sheet at http://jwc.seu.edu.cn/jpkc/declare/08wjjk/louyuwu/jbsc/8254.pdf .

You would want to set a counter up in Mode 3: Square Wave Generator, and feed your 24 MHz signal into the clock input. Program the chip to count to 24000, and the output will be a square wave with frequency of 1 kHz.

I have worked with this chip to provide a timebase for a data acquisition system, so if you have further questions feel free to ask.
 
Last edited by a moderator:
  • #4
It sounds like he wants to do it in the FPGA, not in a uC or a separate 8254 chip.

EugP -- what learning resources do you have for Verilog? The wikipedia.org page is a reasonable place to start:

http://en.wikipedia.org/wiki/Verilog

.
 
  • #5
Thanks everyone for the replies.

negitron - it makes sense to me, but I don't know how to implement it

Fenn - I'm trying to use the FPGA on the development board, but thank you anyway, I might use that for some other project.

berkeman - I've looked at a bunch of Verilog tutorials, but I can't seem to find a good explanation. I might be able to find the exact code I need, but I want to understand how it works so then I will be able to divide any frequency. I found the code I used to to divide 50MHz to get 38k, by having a counter count till 1302. That makes sense because 50M/1302 = 38kHz. So by following that logic I tried setting the counter to 24k (24M/24k = 1kHz), but that didn't work for some reason
 
  • #6
Can you post the code for the 1302 counter/divider? I use HDL mostly, but there are several Verilog guys here that I can ask about this if we can't figure it out quickly.
 
  • #7
Yup. Here is the code I wrote last summer:

Code:
module freq_divider(
	clk,				//Clock 50 MHz
	reset_n,			//Active low reset
	divided_frequency,	//Divided frequency
	new_freq,
	current_q			//Current value
);

input clk;
input reset_n;

output divided_frequency;
output [11:0] current_q;
output new_freq;

reg divided_frequency;
reg divided_frequency_next;
reg [11:0] current_q;
reg [11:0] next_d;
reg new_freq;

//Flip Flops
always @(posedge clk or negedge reset_n)
begin
	if (!reset_n)
		begin
			divided_frequency <= 1'b0;
			current_q <= 12'b000000000000;
		end

	else
		begin
			divided_frequency <= divided_frequency_next;
			current_q <= next_d;
		end
end

//Parallel Counter Logic
always @(current_q or divided_frequency)
begin
	if (current_q == 1302)
		begin
			next_d <= 12'b0000_0000_0000;
			divided_frequency_next <= 1'b1;
		end

	 else
		begin
			divided_frequency_next <= 1'b0;
			next_d <= current_q + 1;
		end

end

always @(posedge divided_frequency)
begin
	new_freq <= !new_freq;
end

endmodule
 
  • #8
And how did you modify it to try to get the divide-by-24K?
 
  • #9
My clock input is now 24MHz, and the current_q == 1302, I have counter == 24000.
 
  • #10
EugP said:
My clock input is now 24MHz, and the current_q == 1302, I have counter == 24000.

And 12 bits can count how high...?
 
  • #11
Oh no no I changed the counter size as well (naturally) to 15 bits.
 
  • #12
Ah, okay. Just checking.

So what doesn't work? Does it not compile? Or you just do not get the output signal you expect?
 
  • #13
Well the module "freq_divider" is an instance in my top level file. Maybe I defined it wrong or something, because in my simulations, the signals don't do anything. Here is the new frequency divider and top level modules (I tried cleaning up the top level as much as possible, because most of the code has nothing to do with this implementation):

Top Level
Code:
module project_top
	(
		////////////////////	Clock Inputs	 	////////////////////	 
		CLOCK_24,						//	24 MHz
		CLOCK_27,						//	27 MHz
		CLOCK_50,						//	50 MHz
		EXT_CLOCK,						//	External Clock

		////////////////////	Push Buttons		////////////////////
		KEY,							//	Pushbutton[3:0]

		////////////////////	GPIO	////////////////////////////
		GPIO_0							//	GPIO Connection 0
		GPIO_1							//	GPIO Connection 1
						
	);

////////////////////////	Clock Input	 	////////////////////////
input	[1:0]	CLOCK_24;				//	24 MHz
input	[1:0]	CLOCK_27;				//	27 MHz
input			CLOCK_50;				//	50 MHz
input			EXT_CLOCK;				//	External Clock


////////////////////////	Push Button		////////////////////////
input	[3:0]	KEY;					//	Pushbutton[3:0]


////////////////////////	GPIO	////////////////////////////////
//input	[35:0]	GPIO_0;					//	GPIO Connection 0
output	[35:0]	GPIO_0;					//	GPIO Connection 0
//inout	[35:0]	GPIO_1;					//	GPIO Connection 1


wire	divided_frequency;
wire	new_freq;
wire	boost;
wire	[7:0]	relay_on, relay_off;
wire	[4:0]	counter;
wire	[2:0]	sm_state;
wire	[14:0]	counter1;

assign GPIO_0[5] = new_freq;
assign GPIO_0[6] = divided_frequency;
assign GPIO_0[7] = boost;
assign GPIO_0[8] = relay_on[0];
assign GPIO_0[9] = relay_on[1];
assign GPIO_0[10] = relay_on[2];
assign GPIO_0[11] = relay_on[3];
assign GPIO_0[12] = relay_on[4];
assign GPIO_0[13] = relay_on[5];
assign GPIO_0[14] = relay_on[6];
assign GPIO_0[15] = relay_on[7];
assign GPIO_0[16] = relay_off[0];
assign GPIO_0[17] = relay_off[1];
assign GPIO_0[18] = relay_off[2];
assign GPIO_0[19] = relay_off[3];
assign GPIO_0[20] = relay_off[4];
assign GPIO_0[21] = relay_off[5];
assign GPIO_0[22] = relay_off[6];
assign GPIO_0[23] = relay_off[7];
assign GPIO_0[24] = counter[0];
assign GPIO_0[25] = counter[1];
assign GPIO_0[26] = counter[2];
assign GPIO_0[27] = counter[3];
assign GPIO_0[28] = counter[4];
assign GPIO_0[29] = sm_state[0];
assign GPIO_0[30] = sm_state[1];
assign GPIO_0[31] = sm_state[2];

freq_divider divider(
						.clk(EXT_CLOCK),
						.rst_n(KEY[0]),
						.new_freq(new_freq),
						.divided_frequency(divided_frequency),
						.counter(counter1)
);


project project(
					.clk(EXT_CLOCK),
					.rst_n(KEY[0]),
					.btn_on_n(KEY[3]),
					.btn_off_n(KEY[2]),
					.boost(boost),
					.relay_on(relay_on),
					.relay_off(relay_off),
					.counter(counter),
					.sm_state(sm_state)
);
endmodule

Frequency Divider
Code:
module freq_divider(
					clk,				//Clock 24 MHz
					rst_n,				//Active low reset
					divided_frequency,	//Divided frequency
					new_freq,
					counter				//Current value
);

input clk;
input rst_n;

output divided_frequency;
output [14:0] counter;
output new_freq;

reg divided_frequency, divided_frequency_next;
reg [14:0] counter, counter_next;
reg new_freq;

//Flip Flops
always @(posedge clk or negedge rst_n)
begin
	if (!rst_n)
		begin
			divided_frequency <= 1'b0;
			counter <= 15'b0000000_0000_0000;
		end

	else
		begin
			divided_frequency <= divided_frequency_next;
			counter <= counter_next;
		end
end

//Parallel Counter Logic
always @(counter or divided_frequency)
begin
	if (counter == 24000)
		begin
			counter_next <= 15'b0000000_0000_0000;
			divided_frequency_next <= 1'b1;
		end

	 else
		begin
			divided_frequency_next <= 1'b0;
			counter_next <= counter + 1;
		end

end

always @(posedge divided_frequency)
begin
	new_freq <= !new_freq;
end

endmodule
 
  • #14
You mean you see the clock going in, but in the new code, the counter is not counting?
 

Related to How to divide a 24MHz clock to get 1kHz (in Verilog)

1. How do I divide a 24MHz clock in Verilog to get 1kHz?

In order to divide a 24MHz clock to get 1kHz in Verilog, you can use a counter and a comparator. The counter will count the number of clock cycles and the comparator will compare the count value to a predefined value, at which point the output can be toggled to generate a 1kHz signal.

2. What is the formula for calculating the value to compare in the comparator?

The formula for calculating the value to compare in the comparator is: (24MHz/1kHz)-1. This will give you the number of clock cycles that need to pass before the output is toggled.

3. Can I use a variable instead of a predefined value in the comparator?

Yes, you can use a variable in the comparator as long as it is assigned the correct calculated value before the comparison is made. This allows for flexibility in the desired output frequency.

4. How do I ensure that the output frequency is exactly 1kHz?

To ensure that the output frequency is exactly 1kHz, it is important to use a clock with a stable and accurate frequency of 24MHz. Additionally, you can use a counter with a higher resolution and a larger value in the comparator to improve the accuracy of the output frequency.

5. How can I test and verify the output frequency in Verilog?

You can test and verify the output frequency in Verilog by simulating the design in a software such as ModelSim or using a hardware debugger. By observing the output waveform and measuring its frequency, you can confirm that it is exactly 1kHz.

Similar threads

Replies
9
Views
5K
  • Programming and Computer Science
2
Replies
39
Views
3K
  • Electrical Engineering
Replies
6
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
2
Views
2K
  • Electromagnetism
2
Replies
67
Views
5K
  • Sticky
  • Programming and Computer Science
Replies
13
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
2K
  • Engineering and Comp Sci Homework Help
Replies
1
Views
4K
  • Engineering and Comp Sci Homework Help
Replies
9
Views
3K
Back
Top