fpga学习日记12,Verilog基础模块之计数器和分频器
第一部分计数器以及实现
第二部分 分频器以及实现
计数器的功能就是对脉冲CP进行计数
常用在分频,定时,产生节拍脉冲和脉冲序列,进行数字运算等
计数器其实在设计中经常遇到的 计数的场合有很多
比如流水线产品数量统计 定时固定长时间比如1s 10ms等
计数器一般有三个功能
1,计数不断加1 2,清零功能 3,进位
当然在mcu内部设计时还会有一些状态标识来供查看
常用的74系列计数芯片有
74LS161 4位十进制同步计数器(异步清除)
74LS190 4位十进制加/减同步计数器
74LS163 4位二进制同步计数器(异步清除)
74LS191 4位二进制加/减同步计数器
74LS160 4位十进制同步计数器(同步清除)
74LS192 4位十进制加/减同步计数器(双时钟)
74LS162 4位二进制同步计数器(同步清除)
74LS193 4位二进制加/减同步计数器(双时钟)
下面用verilog实现一个最基本的4位计数器
output[3:0] out;
input reset,clk;
reg[3:0] out;
always @(posedge clk)
begin
if (reset) out<=0;
else out<=out+1;
end
endmodule
`include "count4.v"
module coun4_tp;
reg clk,reset;
wire[3:0] out;
parameter DELY=100;
count4 mycount(out,reset,clk);
always #(DELY/2) clk = ~clk;
initial
begin
clk =0; reset=0;
#DELY reset=1;
#DELY reset=0;
#(DELY*20) $finish;
end
initial $monitor($time,,,"clk=%d reset=%d out=%d", clk, reset,out);
endmodule
带置数和清零功能的四位计数器
output[7:0] out;
input[7:0] data;
input load,clk,reset;
reg[7:0] out;
always @(posedge clk)
begin
if (!reset) out = 8'h00;
else if (load) out = data;
else out = out + 1;
end
计数到10
output[3:0] out;
output cout;
input en,clr,clk;
reg[3:0] out;
always @(posedge clk or posedge clr)
begin
if (clr) out = 0;
else if(en)
begin
if(out==9) out=0;
else out = out+1;
end
end
assign cout =((out==9)&en)?1:0;
endmodule
第二部分:分频器
系统的输入频率只有一个如果我们在应用中需要不同的频率那怎么办呢
一般的mcu内部有锁相环可通过设置倍频和分频
这里我们看看最基本的分频方法
1,偶分频比较简单,假设为N分频,只需计数到N/2-1,然后时钟翻转、计数清零,如此循环就可以得到N(偶)分频。
2 ,奇分频
实现奇数(N)分频,分别用上升沿计数到(N-1)/2,再计数到N-1;用下降沿计数到(N-1)/2,再计数到N-1,得到两个波形,然后把它们相或即可得到N分频。
原文地址 http://www.eefocus.com/alvin1130/blog/12-01/236724_76b10.html
output clk_out;
input clk_in;
input rst;
reg [1:0] cnt;
reg clk_out;
parameter N=6;
always @ (posedge clk_in or negedge rst)
begin
if(!rst)
begin
cnt <= 0;
clk_out <= 0;
end
else begin
if(cnt==N/2-1)
begin clk_out <= !clk_out; cnt<=0; end
else
cnt <= cnt + 1;
end
end
endmodule
三分频 通过对输入时钟计数 然后适当的时候产生翻转即可
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
其他分频实例和方法可参考
可实现任意倍分频
http://www.cnblogs.com/FPGA_DSP/archive/2010/07/16/1778835.html
http://www.eefocus.com/alvin1130/blog/12-01/236724_76b10.html
http://blog.163.com/cl2006ky@126/blog/static/87195173200947115921562/