Verilog implements decimal frequency division (taking 42.3, 1.5MHZ as an example) and key selection to adjust the frequency from 1 to 10HZ

1. Experiment purpose and requirements

Use Verilog programming to implement decimal frequency division. The input clock signal frequency is 50MHz. First, the 42.3MHz clock signal is obtained by decimal frequency division from 50MHz, and then the 42.3MHz clock frequency is divided to obtain 1Hz, 2Hz, 3Hz, 4Hz, 5Hz, 6Hz, and 7Hz. , 8Hz, 9Hz, 10Hz and other 10 clock frequencies, and the divided signal is displayed in real time with a digital tube or display.

2. Experimental content

<1>Explanation of experimental principles

Note: The output signal waveform obtained by deleting the signal in this example does not meet the duty cycle of 50%

Decimal frequency division is achieved through variable frequency division and multiple averaging methods. The frequency of the input clock signal is f0, and the expected frequency is f1, then its frequency division ratio X=(f0/f1), where X>1, assuming M The pulse deletion circuit is used to regularly delete some pulses in the clock source, thereby achieving decimal frequency division in an average sense. In the design process of hardware circuits, by using pulse deletion circuits, there will be no competition risks and glitches, and arbitrary decimal frequency division can be easily realized with hardware. Let Q=N1 + N2, P=M*(N1 + N2) + N2, then X=P/Q, where P and Q are both integers. When the input clock source inputs P pulses every time, the pulse deletion circuit is used to delete P-Q pulses from these P pulses according to a certain rule, and Q pulses are output, thus achieving X frequency division in the average sense.
The specific design idea is as follows: Set a counter so that its initial value is 0. At the rising edge of each inclk, the counter adds Q. If the value in the counter is less than P, a signal delete is sent to delete a pulse, and delete is set to high. level; if its value is greater than P, P is subtracted from the counter value, and delete is set to low level, and no delete signal pulse is issued. For example, to obtain a 42.3MHz clock signal from a 50MHz clock source, you can set P=26 and Q=22. See Table 1 for its working process.
Table 1

8d9dc7d0a6fb4eecafe3e73ed078fd2e.png

Three: Experimental code

<1>Port definition

input rst,clk50m;
input [3:0] sel;
output reg clk423m;
output reg clk_16m;
output reg clk_ry;
reg delete;
reg [19:0]temp;
integer count,cnt,delete1,count3,count1;
reg [3:0] cnt1,cnt2,cnt3;
reg clk39m;

<2>42.3MHZ frequency division

1: Frequency calculation:

f=N/(t*10^-12)=5/(120000*10^-12)=41.7MHZ

If there is Table 1, readers who find it troublesome to calculate P and Q values can also directly delete the signal pulses with specific serial numbers.

//42.3MHZ frequency division
always@(posedge clk50m or posedge rst)
begin
if(rst==1)
begin
count=0;
delete=1'b0;//Initialize the counter value
end
else
begin
count=count + 22;
if(count>=26)
begin
count=count-26;
delete=1'b0;//Do not delete the pulse
end
else
delete=1'b1;//Delete pulse
end
end

always@(delete)//Determine whether to delete the pulse based on the value of delete
begin
if(delete==1'b1)
clk423m=1'b1;
else
clk423m=clk50m;
end

2: Simulation waveform

a341460d2a8d45f98a465c1326ded1c5.png

<3>Divide the 42.3MHZ signal to get the 1.6MHZ signal

1: Code display

/1.6MHZ frequency division
always@(posedge clk423m or posedge rst) //Achieve 1.6MHZ frequency division
begin
if(rst)
begin
count1=0;delete1=1'b0;
end
else
begin
count1=count1 + 390;
if(count1>=423)
begin
count1=count1-423;
delete1=1'b0; //Do not delete the pulse
end
else
delete1=1'b1; //Delete 1 pulse
end
end

always@(delete1)
begin
if(delete1==1'b1)
clk39m=1'b1;
else
clk39m=clk423m;
end

always@(posedge clk39m or posedge rst)
begin
  if(rst==1)
  begin
    clk_16m <= 0;count3=0;
  end
  else if(count3==9)
  begin
    clk_16m <= ~clk_16m;
count3 <= 0;
  end
  else
  begin
    count3 <= count3 + 1;
  end
\t
end

2: Physical waveform effect display

67f738b0b157406391d6d737003e1538.png

Note: The output is a 1.66MHZ square wave. Waveform distortion may be caused by the count value being too large and the duration being too long when the high and low levels flip;

<4>Divide 1.6MHZ to get 1~10HZ signal

//1-10HZ arbitrary frequency division adjustable
always@(posedge clk_16m or posedge rst)
begin
  if(rst==1)
  begin
    clk_ry <= 0;
  end
  else if(cnt==1048576)
  begin
    clk_ry <= ~clk_ry;
cnt <= temp;
  end
  else
  begin
    cnt <= cnt + 1;
  end
\t
end

<5>Button control frequency division result (1~10HZ)

1: Code display

always @ (sel)
begin
   case(sel)
\t\t\t 
4'b0001:temp <= 298576;
\t\t\t 
4'b0010:temp <= 673576;
\t\t\t
4'b0011:temp <= 798576;
\t\t\t
4'b0100:temp <= 816076;
\t\t\t 
4'b0101:temp <= 898576;
\t\t\t 
4'b0110:temp <= 923576;
\t\t\t
4'b0111:temp <= 941433;
\t\t\t 
4'b1000:temp <= 954826;
\t\t\t
4'b1001:temp <= 965243;
\t\t\t
4'b1010:temp <= 973576;
\t\t\t
default:temp <= 1048574;
endcase
\t\t\t\t\t    
end

2: Physical effect display (taking 6HZ as an example)

1c56c74fd1a8455e87c30127fadf73ab.png

Four: Complete code display

module fengping_432(rst,clk50m,clk423m,clk_15m,clk_ry,sel);
input rst,clk50m;
input [3:0] sel;
output reg clk423m;
output reg clk_15m;
output reg clk_ry;
reg delete;
reg [19:0]temp;
integer count,cnt,delete1,count3,count1;
reg [3:0] cnt1,cnt2,cnt3;
reg clk39m;


//42.3MHZ frequency division
always@(posedge clk50m or posedge rst)
begin
if(rst==1)
begin
count=0;
delete=1'b0;//Initialize the counter value
end
else
begin
count=count + 22;
if(count>=26)
begin
count=count-26;
delete=1'b0;//Do not delete the pulse
end
else
delete=1'b1;//Delete pulse
end
end

always@(delete)//Determine whether to delete the pulse based on the value of delete
begin
if(delete==1'b1)
clk423m=1'b1;
else
clk423m=clk50m;
end

//1.5MHZ frequency division
always@(posedge clk423m or posedge rst) //Achieve 1.5MHZ frequency division
begin
if(rst)
begin
count1=0;delete1=1'b0;
end
else
begin
count1=count1 + 390;
if(count1>=423)
begin
count1=count1-423;
delete1=1'b0; //Do not delete the pulse
end
else
delete1=1'b1; //Delete 1 pulse
end
end

always@(delete1)
begin
if(delete1==1'b1)
clk39m=1'b1;
else
clk39m=clk423m;
end

always@(posedge clk39m or posedge rst)
begin
  if(rst==1)
  begin
    clk_15m <= 0;count3=0;
  end
  else if(count3==9)
  begin
    clk_15m <= ~clk_15m;
count3 <= 0;
  end
  else
  begin
    count3 <= count3 + 1;
  end
\t
end

                                                                            
//1-10HZ arbitrary frequency division adjustable
always@(posedge clk_15m or posedge rst)
begin
  if(rst==1)
  begin
    clk_ry <= 0;
  end
  else if(cnt==1048576)
  begin
    clk_ry <= ~clk_ry;
cnt <= temp;
  end
  else
  begin
    cnt <= cnt + 1;
  end
\t
end

//Used to control the display of 1-10HZ frequency division
always @ (sel)
begin
   case(sel)
\t\t\t 
4'b0001:temp <= 298576;
\t\t\t 
4'b0010:temp <= 673576;
\t\t\t
4'b0011:temp <= 798576;
\t\t\t
4'b0100:temp <= 816076;
\t\t\t 
4'b0101:temp <= 898576;
\t\t\t 
4'b0110:temp <= 923576;
\t\t\t
4'b0111:temp <= 941433;
\t\t\t 
4'b1000:temp <= 954826;
\t\t\t
4'b1001:temp <= 965243;
\t\t\t
4'b1010:temp <= 973576;
\t\t\t
default:temp <= 1048574;
endcase
\t\t\t\t\t    
end
\t\t
endmodule