热度 20
2013-8-27 14:57
8799 次阅读|
1 个评论
(ps 本文代码皆搜集于网络) 第一部分计数器以及实现 第二部分 分频器以及实现 计数器的功能就是对脉冲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位计数器 verilog语言 : 计数器代码 module count4 ( out , reset , clk ); output out ; input reset , clk ; reg out ; always @( posedge clk ) begin if ( reset ) out = 0 ; else out = out + 1 ; end endmodule verilog语言 : 测试代码 `timescale 1 ns / 1 ns `include "count4.v" module coun4_tp ; reg clk , reset ; wire 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 带置数和清零功能的四位计数器 verilog语言 : 高亮代码由发芽网提供 module count ( out , data , load , reset , clk ); output out ; input data ; input load , clk , reset ; reg out ; always @( posedge clk ) begin if ( ! reset ) out = 8'h00 ; else if ( load ) out = data ; else out = out + 1 ; end endmodule 计数到10 verilog语言 : 高亮代码由发芽网提供 module count10 ( out , cout , en , clr , clk ); output out ; output cout ; input en , clr , clk ; reg 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分频。 任意N分频 N为偶数 原文地址 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 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 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/