当前位置:   article > 正文

VerilogHDL实现分频器_verilog将50mhz分频为1hz

verilog将50mhz分频为1hz

分频即分割频率,把周期增大,频率减小。由于晶振产生的时钟信号频率是固定的,因此当需要其他周期的时钟信号时就需要分频。例如,一个时钟源的周期为1ms,其频率为1000Hz,经过二分频,1000Hz频率就会减少为500Hz,周期增加为2ms。

1.偶数倍分频

偶数倍分频通过计数器计数是完全可以实现的。如进行N倍偶数分频,那么可以通过由待分频的时钟触发计数器计数,当计数器从0计数到N-1时,输出时钟进行翻转,并给计数器一个复位信号,使得下一个时钟从零开始计数。以此循环下去。这种方法可以实现任意的偶数分频。

二分频的简单实现如下:
功能模块:

module div_clk2(clk_out,clk_in,rst);
output clk_out;
input clk_in,rst;
reg clk_out;

always @(posedge clk_in)
begin
	if(rst)
		clk_out <= 0;
	else
		clk_out <= ~clk_out;
end

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

测试模块:

module t9_14;
reg clk_in,rst;
wire clk_out;

initial clk_in = 0;
always #5 clk_in = ~clk_in;

initial
begin
	rst = 1;
	#20 rst = 0;
	#100 $stop;
end

div_clk2 mydiv_2(clk_out,clk_in,rst);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

仿真结果:
在这里插入图片描述
可修改参数的偶数分频计数器:
功能模块:

module div_clkn(clk_out,clk_in,rst);
output clk_out;
input clk_in,rst;
reg clk_out;
reg [width(n)-1:0] count;

parameter n=4;

always @(posedge clk_in)
begin
	if(rst)
		count <= 0;
	else if(count == n-1)
		count <= 0;
	else
		count <= count + 1;
end

always @(count)
begin
	if(rst)
		clk_out = 0;
	else if(count == n-1)
		clk_out = ~clk_out;
	else
		clk_out = clk_out;
end

function integer width;
input integer size;
begin
	for(width = 0;size > 0;width = width + 1)
		size = size >> 1;
end
endfunction

endmodule 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

测试模块:

module t9_15;
reg clk_in,rst;
wire clk_out;

initial clk_in = 0;
always #5 clk_in = ~clk_in;

initial
begin
	rst = 1;
	#20 rst = 0;
	#100 $stop;
end

div_clkn mydiv_clkn(clk_out,clk_in,rst);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

仿真结果:
在这里插入图片描述

2.奇数倍分频

2.1第一种方法

对于实现占空比为50%的N倍奇数分频,首先进行上升沿触发进行模N计数,经过(N-1)/2时,翻转一次;到(N-1)时,计数器置零;就可以实现占空比为(N-1)/2N的N分频信号;同样的,进行下降沿触发进行模N计数,经过(N-1)/2时,翻转一次;到(N-1)时,计数器置零;就可以实现占空比为(N-1)/2N的N分频信号;最终将两个信号相或就能得到占空比为50%的N分频信号。

2.1.1占空比非50%的三分频

功能模块:

module div_clk3(clk_out,clk_in,rst);
output clk_out;
input rst;
input clk_in;
reg clk_out;
reg [1:0] count;   

always @ (posedge clk_in or posedge rst)//同步复位
begin
    if (rst)
	begin
      	clk_out<=1'b0;
      	count<=2'b00;
	end
    else if(count==0)// 第一个clk_in上升沿来的时候clk_out翻转一次计数器加一;
        begin
         clk_out <= ~clk_out;
         count<=count+1;
        end
    else if(count==2)//第3个clk_in上升沿来的时候输出clk_out翻转一次计数器归零;
        begin
            clk_out = ~clk_out;
            count<=2'b00;
        end
    else//第二个clk_in上升沿来的时候clk_out保持不变,计数器加一。   
        begin
        count<=count+1;
        end
end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

测试模块:

module t9_16;
    reg clk_in;
    reg rst;

    initial clk_in=0;
    always #5 clk_in=~clk_in;
    initial
    begin
        rst=1;
        #7 rst =0;
    end

    div_clk3 clk3(clk_out,clk_in,rst);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

仿真结果:
在这里插入图片描述

2.1.2占空比50%的三分频

module div_clk3(clk_out,clk,rst);
    output clk_out;
    input rst;
    input clk;
    
    reg q1,q2;                //内部寄存器变量,分别是两个占空比为1/3的分频;
    reg [1:0] count1,count2;

assign clk_out = q1|q2;

always @ (posedge clk or posedge reset) //上升沿生成的三分频q1;
begin
		if (reset)
		begin
      		clk_out <= 1'b0;
      		count1 <= 2'b00;
    	end
      	else if(count1 == 0)
        begin
         	clk_out <= ~clk_out;
         	count1 <= count1 + 1'b1;
        end
        else if(count1 == 1)
        begin
            	clk_out = ~clk_out;
           	count1 <= count1+1'b1;
        end
        else 
        begin
                count1 <= 2'b00;
        end
end
          
always @ (negedge clk or posedge rst)//同上一段always结构
begin
    	if (rst)
    	begin
      		clk_out <= 1'b0;
      		count2<=2'b00;
		end
      	else if(count2 == 0)
        begin
         	clk_out <= ~clk_out;
         	count2<=count2+1'b1;
        end
        else if(count2 == 1'b1)
        begin
            	clk_out = ~clk_out;
            	count2<=count2+1'b1;
        end
        else 
        begin
                count2<=2'b00;
        end
end  
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56

测试模块:

module t9_16;
    reg clk_in;
    reg rst;

    initial clk_in=0;
    always #5 clk_in=~clk_in;
    initial
    begin
        rst=1;
        #7 rst =0;
    end

    div_clk3 clk3(clk_out,clk_in,rst);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

仿真结果:
在这里插入图片描述

2.1.3占空比50%的五分频(可修改参数)

功能模块:

module clk_div_5(clk_out, clk_in, rst);
	input clk_in;
	input rst;
	output clk_out;
	
	reg [2:0] cnt1, cnt2;
	reg q1, q2;
	
	parameter CNT_M = 3'd4,//N-1   
			  CNT_N = 3'd2;//(N-1)/2
		
	always @(posedge clk_in) //上升沿 5 分频,占空比为 2/5
	begin 
		if(!rst) begin
			cnt1 <= 0;
			q1 <= 0;
		end
		else 
		begin
			if( cnt1 == CNT_M ) 
			begin
				cnt1 <= 0;
				q1 <= ~q1;
			end
			else 
			begin
				cnt1 <= cnt1 + 1'b1;
				if ( cnt1 == CNT_N )
					q1 <= ~q1;
				else
					q1 <= q1;
			end
		end
	end
	
	always @(negedge clk_in)  //下降沿 5 分频,占空比为 2/5
	begin
		if(!rst) 
		begin
			cnt2 <= 0;
			q2 <= 0;
		end
		else 
		begin
			if( cnt2 == CNT_M ) 
			begin
				cnt2 <= 0;
				q2 <= ~q2;
			end
			else 
			begin
				cnt2 <= cnt2 + 1'b1;
				if ( cnt2 == CNT_N )
					q2 <= ~q2;
				else
					q2 <= q2;
			end
		end
	end
	assign clk_out = q1 | q2; //错位相或
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

测试模块:

module t9_16;
    reg clk_in;
    reg rst;

    initial clk_in=0;
    always #5 clk_in=~clk_in;
    initial
    begin
        rst=1;
        #7 rst =0;
    end
    div_clk5 clk5(clk_out,clk_in,rst);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

仿真结果:
在这里插入图片描述

2.2第二种方法

使用上升沿和下降沿,两个always结构,通过状态机实现。

2.2.1 3分频信号实现

功能模块:

module div_clk3(clk_out,clk_in,rst);
output clk_out;
input clk_in,rst;

reg [1:0] temp1,temp2;

always @(posedge clk_in)
begin
	if(!rst)
		temp1 <= 2'b00;
	else 
	begin
		case(temp1)
		2'b00:temp1 <= 2'b01;
		2'b01:temp1 <= 2'b10;
		2'b10:temp1 <= 2'b000;
		default:temp1 <= 2'b00;
		endcase
	end
end

always @(negedge clk_in)
begin
	if(!rst)
		temp2 <= 2'b00;
	else 
	begin
		case(temp2)
		2'b00:temp2 <= 2'b01;
		2'b01:temp2 <= 2'b10;
		2'b10:temp2 <= 2'b00;
		default:temp2 <=2'b00;
		endcase
	end
end

assign clk_out = temp1[0] | temp2[0];

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

测试模块:

module t9_16;
    reg clk_in;
    reg rst;

    initial clk_in=1;
    always #10 clk_in=~clk_in;
    initial
    begin
        rst=1;
        #20 rst =0;
	#50 rst=1;
	#1000 $stop;
    end

    div_clk3 clk3(clk_out,clk_in,rst);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

仿真结果:
在这里插入图片描述

2.2.2 5分频信号实现

功能模块:

module div_clk5(clk_out,clk_in,rst);
output clk_out;
input clk_in,rst;

reg [2:0] temp1,temp2;

always @(posedge clk_in)
begin
	if(!rst)
		temp1 <= 3'b000;
	else 
	begin
		case(temp1)
		3'b000:temp1 <= 3'b001;
		3'b001:temp1 <= 3'b011;
		3'b011:temp1 <= 3'b100;
		3'b100:temp1 <= 3'b010;
		3'b010:temp1 <= 3'b000;
		default:temp1 <= 3'b000;
		endcase
	end
end

always @(negedge clk_in)
begin
	if(!rst)
		temp2 <= 3'b000;
	else 
	begin
		case(temp2)
		3'b000:temp2 <= 3'b001;
		3'b001:temp2 <= 3'b011;
		3'b011:temp2 <= 3'b100;
		3'b100:temp2 <= 3'b010;
		3'b010:temp2 <= 3'b000;
		default:temp2 <=3'b000;
		endcase
	end
end

assign clk_out = temp1[0] | temp2[0];

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

测试模块:

module t9_16;
    reg clk_in;
    reg rst;

    initial clk_in=1;
    always #10 clk_in=~clk_in;
    initial
    begin
        rst=1;
        #20 rst =0;
	#50 rst=1;
	#1000 $stop;
    end

    div_clk5 clk5(clk_out,clk_in,rst);

endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

仿真结果:
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/725145
推荐阅读
相关标签
  

闽ICP备14008679号