1.二分频
首先要明白,二分频分的是输入时钟的频率,即CLK的频率。
思路:在每次CLK的上升沿或者下降沿让输出Q翻转不就完成频率的二分了吗?
代码:
module div_2 (q,clk,reset); // 输出q,输入时钟CLK,同步复位信号RESET.
output q;
input reset;
input clk;
reg q;
always @ (posedge clk or posedge reset)
if (reset)
q<=1'b0; // 复位置零
else
q<=~q; // 否则q信号翻转
endmodule
测试代码:
module test;
reg clk;
reg reset;
div_2 d2 (q,clk,reset);// 调用我们设计的功能模块div_2
always #20 clk=~clk;// 产生周期为40个时间单位的时钟脉冲信号
// initial块只执行一次,此处让CLK的起始电平为低,RESET为高
initial
begin
clk=1'b0;
reset=1'b1;
#24 reset =1'b0;
end
endmodule
下面我们来看一下MODELSIM的仿真波形,是不是输出Q的频率变成CLK的一半了呢?
2.三分频
此处给的不是50%占空比的三分频,稍后给出。
思路:设置一个计数器,让计数器计数到适当的值得时候输出q翻转就行了。
代码:
module div_3 (q,clk,reset);
output q;
input reset;
input clk;
reg q;
reg [1:0] count; // 设了一个2位的计数器可以从00计数到11;
always @ (posedge clk or posedge reset) // 同步复位,上升沿有效
if (reset) // 复位
begin
q<=1'b0;
count<=2'b00;
end
else if(count==0) // 第一个CLK上升沿来的时候q翻转一次计数器加一;
begin
q<=~q;
count<=count+1'b1;
end
else if(count==2) //第3个CLK上升沿来的时候输出q翻转一次计数器归零;
begin
q=~q;
count<=2'b00;
end
else // 第二个CLK上升沿来的时候q不动作,计数器加一。
begin
count<=count+1'b1;
end
endmodule
测试代码:
// 和以上2分频的一样的测试代码,就是调用功能模块的名字不同,这很好理解,就是你给的任意的CLK的
//频率我都可以三分频才对的
module test;
reg clk;
reg reset;
div_3 d3 (q,clk,reset);
always #20 clk=~clk;
initial
begin
clk=1'b0;
reset=1'b1;
#24 reset =1'b0;
end
endmodule
看一下波形,是不是原来的三个周期变成一个周期啦??也就是频率三分了
3.三分频 (占空比1/2)
思路:
占空比为50%的三分频稍微麻烦一些,其实就是两个占空比都为1/3的q1和q2相或得到占空比为50%的三分频输出q,只是这两个q1和q2分别是在时钟的上升沿和下降沿翻转而已。
代码:
module div_3 (q,clk,reset);
output q;
input reset;
input clk;
reg q1,q2; // 内部寄存器变量,分别是两个占空比为1/3的分频;
reg [1:0] count1,count2;
assign q=q1|q2; // 两个相或才是我们要得到的输出q
always @ (posedge clk or posedge reset) //上升沿生成的三分频q1;
if (reset)
begin
q1<=1'b0;
count1<=2'b00;
end
else if(count1==0)
begin
q1<=~q1;
count1<=count1+1'b1;
end
else if(count1==1)
begin
q1=~q1;
count1<=count1+1'b1;
end
else
begin
count1<=2'b00;
end
always @ (negedge clk or posedge reset) //下降沿生成的三分频信号q2, 该代码原
// 理和q1产生原理一致
if (reset)
begin
q2<=1'b0;
count2<=2'b00;
end
else if(count2==0)
begin
q2<=~q2;
count2<=count2+1'b1;
end
else if(count2==1'b1)
begin
q2=~q2;
count2<=count2+1'b1;
end
else
begin
count2<=2'b00;
end
endmodule
测试代码:
module test; // 与以上各测试代码一致
reg clk;
reg reset;
div_3 d3 (q,clk,reset);
always #20 clk=~clk;
initial
begin
clk=1'b0;
reset=1'b1;
#24 reset =1'b0;
end
endmodule
我们来看一下q的波形,是不是占空比为50%的三分频输出呢?
好了,知道了这两个分频,我想你应该可以推理出其它的奇偶分频代码了,当然,大于2的偶分频代码需要有一个count来计数,在适当的时候翻转就行,其实分频代码从某种程度上来说就是计数器的适当输出而已。