tag 标签: 异步计数器

相关博文
  • 热度 21
    2016-4-15 19:47
    1052 次阅读|
    0 个评论
    本次笔记记录的是计数器的使用   在FPGA设计中,计数器的使用占据很大的比重,在后面接触的FPGA设计的,总少不了计数器的身影,有时候计数器的性能决定了一个项目的成败,本笔记中,我做了两种计数器的设计:第一种就是 综合工具自动综合出来的计数器 .第二种就是使用  IP 核的计数器 。   如果按照计数器中的触发器是否同时翻转分类,可将计数器分为 同步计数器和异步计数器 两种。 1.基本概念:每个不同的计数器,在设计之初,被设计者设定为感应固定的波形的某一部分(一般为瞬态感应),比如方波的下降沿(或上升沿); 2. 同步计数 :当你所购得的计数器为同步计数器,所谓同步,就是该计数器只有当输入信号的下降沿(或上升沿)来临时,计数器才会开始处理,其他时间无论高低电平,计数器都会无视; 3. 异步计数 :所谓异步,就是你随时达到所设定的值,它立刻就跳转,并不等待下一个下降沿(或上升沿)的到来; 综上可以看出,同步,异步说的都是相对于输入信号,计数器在达到最大计数值时的响应是同步于该输入信号,还是异步于它;   下面我们先分别看一下同步计数器和异步计数器的实现 同步计数器 : module counter(rst_n,clk,out_cnt); input clk; input rst_n; output reg out_cnt; reg cnt; always @(posedge clk or negedge rst_n) if(!rst_n) cnt = 8'd0; else if(cnt == 8'd125) cnt = 8'd0; else cnt = cnt + 1'b1; always @(posedge clk or negedge rst_n) if(!rst_n) out_cnt = 1'b1; else if(cnt == 8'd125) out_cnt = ~out_cnt; else out_cnt = out_cnt; endmodule ///////////////////`tb `timescale 1ns/1ns `define clock_period 20 module counter_tb; reg clk; reg rst_n; wire out_cnt; counter counter(.rst_n(rst_n),.clk(clk),.out_cnt(out_cnt)); initial clk = 1; always #(`clock_period/2) clk = ~clk; initial begin rst_n = 1'b0; #(`clock_period *20); rst_n = 1'b1; #(`clock_period *2000); $stop; end endmodule 仿真波形图: 异步计数 : module asyn_counter(rst_n,clk,out_cnt,asyn_out); input clk; input rst_n; output reg out_cnt; output reg asyn_out; reg  cnt; always @(posedge clk or negedge rst_n) if(!rst_n)  cnt = 8'd0; else if(cnt == 8'd125) cnt = 8'd0; else  cnt = cnt + 1'b1; always @(posedge clk or negedge rst_n) if(!rst_n) out_cnt = 1'b1; else if(cnt == 8'd125)  out_cnt = ~out_cnt; else out_cnt = out_cnt; //always @(clk or rst_n) always @(cnt) if(!rst_n) asyn_out = 1'b1; else if(cnt == 8'd125)  asyn_out = ~asyn_out; else asyn_out = asyn_out; endmodule  //////`tb 更改一下例化就行了 asyn_counter counter( .rst_n(rst_n), .clk(clk), .out_cnt(out_cnt), .asyn_out(asyn_out) );   IP 核的计数器 ip核设置如下(Quartus 15.0):   计数到100清零,此程序中 carry_in /out 可以不选 如上图打开 可以找到例化模块  counter(.........) 设置ip/counter.qip为顶层文件 仿真代码: `timescale 1ns/1ns `define clock_period 20 module counter_tb; reg cin; //进位输入 reg clk; //计数基准时钟 wire cout;//进位输出 wire   q; counter counter0( .cin(cin), .clock(clk), .cout(cout), .q(q) ); initial clk = 1; always #(`clock_period/2)clk = ~clk; initial begin repeat(300)begin   // cin = 0; #(`clock_period*5)cin = 1; #(`clock_period)cin = 0; end #(`clock_period*200); $stop; end endmodule 波形图: 上图箭头所产生的时间极短的尖峰,在此可以不考虑,等后续笔记会做"竞争冒险"讲述     由于本人能力有限,出错之处的请各位给予帮助. 谢谢!        更多资料参考                 发烧友小梅哥专版 http://bbs.elecfans.com/zhuti_fpga_1.html                     梦翼师兄的炼狱传奇