首页 > 代码库 > 分频器的verilog设计

分频器的verilog设计

笔者最近由于实验室老师的任务安排重新又看了一下分频器的verilog实现,现总结如下,待以后查看之用(重点是查看计数器计到哪个值clk_out进行状态翻转

1.偶数分频占空比为50%

其实质还是一个N计数器模块来实现,首先要有复位信号,这个复位信号的作用就是使计数器和分频输出clk_out刚开始有一个复位值,其次就是计数翻转了,注意这里是计到哪个值翻转,首先刚开始时reset复位时计数器赋初值为0,然后计数器计到N/2-1时进行clk-out状态翻转,即clk_out<=~clk_out,此时别忘了计数器接着加1操作(count<=count+1),紧接着在计数器计到N-1时clk_out再翻转状态,与此同时计数器进行清零操作。count<=0;

这部分的程序代码如下:

module tmm_c(clk,reset,m,clk_out);
input clk;
input reset;
input [7:0]m;

output clk_out;

reg [7:0]count;
reg clk_out;

always@(posedge clk)
begin
if(reset)
begin
count<=0;
clk_out<=0;
end

else
if(count==m-1)
begin
clk_out<=~clk_out;
count<=0;
end
else
if(count==m/2-1)
begin
clk_out<=~clk_out;
count<=count+1;
end
else
count<=count+1;
end

endmodule

与此相关的testbench代码如下:

`timescale 1ns/1ns
module tmm_c_tb;
reg clk;
reg reset;
reg[7:0] m;
wire clk_out;

tmm_c u1(clk,reset,m,clk_out);

initial
begin
clk=0;
reset=1;
m=4;
#10 reset=0;
#1000 $stop;
end
always #5 clk=~clk;

endmodule

modelsim仿真波形图:

 

2.奇数分频占空比为50%

其实质也是一个计数器,思想和偶数分频相似,不过奇数分频前期需要两个always模块,这两个always模块的输出分别为clk_out1、clk_out2,用到两个count1、count2,其中clk_out1的输出是待分频时钟的上升沿触发进行的计数输出的结果,这个也需要计数器模块和reset复位信号,但此时计到何值clk_out1进行翻转呢?复位完之后还是输出和计数全部为零,然后当计数到count=(N-1)/2时clk_out1进行翻转,计数到count=N-1时计数器清零,clk_out进行翻转。clk_out2的计数器和输出同count1和clk_out1.但不同的是它是在待分频时钟的下降沿进行触发。最总的结果是clk_out=clk_out1|clk_out2(进行或运算)

以下是程序代码:

module tnn_c(clk,reset,n,clk_out);
input clk;
input reset;
input[7:0]n;
output clk_out;

reg [7:0]count1;
reg [7:0]count2;
//reg clk_out;
reg clk1;
reg clk2;

always@(posedge clk)
begin
if(reset)
begin
count1<=0;
clk1<=0;
end
else
if(count1==n-1)
begin
count1<=0;
clk1=~clk1;
end

else
if(count1==(n-1)/2)
begin
clk1=~clk1;
count1<=count1+1;
end
else
count1<=count1+1;

end

always@(negedge clk)
begin
if(reset)
begin
count2<=0;
clk2<=0;
end
else
if(count2==n-1)
begin
count2<=0;
clk2=~clk2;
end
else
if(count2==(n-1)/2)
begin
clk2=~clk2;
count2<=count2+1;
end
else
count2<=count2+1;

end

assign clk_out=clk1|clk2;

endmodule

相应的testbench:

`timescale 1ns/1ns
module tnn_c_tb;
reg clk;
reg reset;
reg[7:0] n;
wire clk_out;

tnn_c u(clk,reset,n,clk_out);

initial
begin
clk=0;
reset=1;
n=5;
#30 reset=0;
#1000 $stop;
end
always #5 clk=~clk;

endmodule

 modelsim仿真图: