对于时钟的分频,Verilog而言如果是偶数分频那就可以直接用计数的方式进行分频。
如对频率进行二分频:
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
div_2_r<=0;
else
div_2_r<=~div_2_r;
end
对于四分频如下:
reg [1:0]count;
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
count<=0;
else
count<=count+1'b1;
end
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
div_4_r<=0;
else if (count==0||count==2'b10)
div_4_r<=~div_4_r;
else
div_4_r<=div_4_r;
end
而对于三分频,五分频的话用以上计数的方式就似乎行不通了。这里用了一种很巧妙的方式来处理:
reg [1:0]s;
reg [1:0]n;
parameter s0=2'b00;
parameter s1=2'b01;
parameter s2=2'b10;
parameter n0=2'b00;
parameter n1=2'b01;
parameter n2=2'b10;
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
s<=s0;
else
begin
case(s)
s0:s<=s1;
s1:s<=s2;
s2:s<=s0;
default:s<=s0;
endcase
end
end
[email protected](negedge Clk or negedge Rst)
begin
if(!Rst)
n<=n0;
else
begin
case(n)
n0:n<=n1;
n1:n<=n2;
n2:n<=n0;
default:n<=n0;
endcase
end
end
assign div_3=~(s[1]|n[1]);
这里用了两个状态机去实现三分频,注意这里的是s与n状态的触发条件是不一样的,一个是上升沿敏感,一个是下降沿敏感。要特别注意。
以下是完整代码
module div(
input Clk,
input Rst,
output div_2,
output div_3,
output div_4,
output div_6,
output div_8,
output div_50Hz
);
reg div_2_r;
reg div_6_r;
reg div_4_r;
reg div_8_r;
reg [1:0]count;
reg [1:0]count_1;
reg [1:0]count_3;
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
count<=0;
else
count<=count+1'b1;
end
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
count_1<=0;
else if(count_1>2'b01)
count_1<=0;
else
count_1<=count_1+1'b1;
end
[email protected](negedge Clk or negedge Rst)
begin
if(!Rst)
count_3<=0;
else if(count_3>2'b01)
count_3<=0;
else
count_3<=count_3+1'b1;
end
//二分频
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
div_2_r<=0;
else
div_2_r<=~div_2_r;
end
//四分频
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
div_4_r<=0;
else if (count==0||count==2'b10)
div_4_r<=~div_4_r;
else
div_4_r<=div_4_r;
end
//八分频
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
div_8_r<=0;
else if(count==0)
div_8_r<=~div_8_r;
else
div_8_r<=div_8_r;
end
//六分频
[email protected](negedge Clk or negedge Rst)
begin
if(!Rst)
div_6_r<=0;
else if(count_1==2'b01&&count_3==2'b01)
div_6_r<=~div_6_r;
else
div_6_r<=div_6_r;
end
//频率为50HZ的信号
reg [19:0]count_2;
reg div_50Hz_r;
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
count_2<=0;
else if(count_2<1_000_000)
count_2<=count_2+1'b1;
else
count_2<=0;
end
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
div_50Hz_r<=0;
else if(count_2==999_999)
div_50Hz_r<=~div_50Hz_r;
else
div_50Hz_r<=div_50Hz_r;
end
//三分频,这里用到了状态机
reg [1:0]s;
reg [1:0]n;
parameter s0=2'b00;
parameter s1=2'b01;
parameter s2=2'b10;
parameter n0=2'b00;
parameter n1=2'b01;
parameter n2=2'b10;
[email protected](posedge Clk or negedge Rst)
begin
if(!Rst)
s<=s0;
else
begin
case(s)
s0:s<=s1;
s1:s<=s2;
s2:s<=s0;
default:s<=s0;
endcase
end
end
[email protected](negedge Clk or negedge Rst)
begin
if(!Rst)
n<=n0;
else
begin
case(n)
n0:n<=n1;
n1:n<=n2;
n2:n<=n0;
default:n<=n0;
endcase
end
end
assign div_3=~(s[1]|n[1]);
assign div_2=div_2_r;
assign div_6=div_6_r;
assign div_4=div_4_r;
assign div_8=div_8_r;
assign div_50Hz=div_50Hz_r;
endmodule
测试代码如下
module div_tb;
reg clk_50m;
reg rst_n;
wire div_2;
wire div_3;
wire div_4;
wire div_6;
wire div_8;
wire div_50hz;
div div_inst
(
.Clk(clk_50m),
.Rst(rst_n),
.div_2(div_2),
.div_3(div_3),
.div_4(div_4),
.div_6(div_6),
.div_8(div_8),
.div_50Hz(div_50hz)
);
initial begin
rst_n=0;
clk_50m=0;
#200 ;
rst_n=1;
end
always begin
#10;
clk_50m=~clk_50m;
end
endmodule
用modelsim仿真时序如下: