fpga学习日记12,Verilog基础模块之计数器和分频器

第一部分计数器以及实现

第二部分 分频器以及实现

计数器的功能就是对脉冲CP进行计数

常用在分频,定时,产生节拍脉冲和脉冲序列,进行数字运算等

计数器其实在设计中经常遇到的 计数的场合有很多 

比如流水线产品数量统计   定时固定长时间比如1s 10ms等

计数器一般有三个功能

1,计数不断加1    2,清零功能  3,进位

当然在mcu内部设计时还会有一些状态标识来供查看

 

0.jpg

 

1.jpg

常用的74系列计数芯片有

74LS161 4位十进制同步计数器(异步清除)

74LS190 4位十进制加/减同步计数器

74LS163 4位二进制同步计数器(异步清除)

 74LS191 4位二进制加/减同步计数器

74LS160 4位十进制同步计数器(同步清除)

74LS192 4位十进制加/减同步计数器(双时钟)

 74LS162 4位二进制同步计数器(同步清除)

74LS193 4位二进制加/减同步计数器(双时钟) 

 

下面用verilog实现一个最基本的4位计数器

 

verilog语言计数器代码
module count4(out,reset,clk);
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
 
 
 
verilog语言测试代码
`timescale 1ns/1ns
`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

 

带置数和清零功能的四位计数器

module count(out,data,load,reset,clk);
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
endmodule

计数到10

module count10(out,cout,en,clr,clk);
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(偶)分频。
 

000.jpg

 

2 ,奇分频
 实现奇数(N)分频,分别用上升沿计数到(N-1)/2,再计数到N-1;用下降沿计数到(N-1)/2,再计数到N-1,得到两个波形,然后把它们相或即可得到N分频。

001.jpg

 原文地址 http://www.eefocus.com/alvin1130/blog/12-01/236724_76b10.html

 

verilog语言偶数分频N倍
module fp_even(clk_out,clk_in,rst);
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

 

三分频 通过对输入时钟计数 然后适当的时候产生翻转即可

verilog语言3分频
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

其他分频实例和方法可参考

可实现任意倍分频

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/

posted @ 2015-07-31 18:00  苍月代表我  阅读(3078)  评论(0编辑  收藏  举报