Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1170455
  • 博文数量: 173
  • 博客积分: 4048
  • 博客等级:
  • 技术积分: 2679
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-12 18:53
文章分类

全部博文(173)

文章存档

2018年(1)

2016年(1)

2013年(1)

2012年(118)

2011年(52)

分类: 嵌入式

2011-06-22 10:58:19

在verilog中,实现边缘触发清零计数器时。综合的时候会有很多限制:
1、在多个always语句中,不能对同一个变量进行赋值。
2、如果在一个always条件加上两个边缘触发条件时,写法又似乎有一定的要求。
必须使用异步复位的方法清零,否则使用同步复位会因为赋值的延时带来一个时钟周期的延时。
反复试验得到一个勉强可以使用的代码如下:
  1. module counter(clk,rst,cnt_out,reset);
  2. input clk,rst;
  3. output cnt_out;
  4. output reset;
  5. reg rst_last/*synthesis noprune*/;
  6. reg [7:0] cnt;
  7. reg cnt_out;
  8. reg reset;
  9. wire mclk;

  10. pll p0(clk,mclk);

  11. initial
  12. begin
  13. cnt=255;
  14. cnt_out=1;
  15. end

  16. always@(posedge mclk)
  17. begin
  18. rst_last=rst;
  19. end

  20. always@(posedge mclk or negedge rst)
  21. begin
  22. if(!rst)
  23. begin
  24. if(rst_last)
  25. reset=0;
  26. else
  27. reset=1;
  28. end
  29. end

  30. always@(posedge mclk or negedge reset)
  31. begin
  32. if(!reset)
  33. cnt=0;
  34. else if(cnt!=255)
  35. cnt=cnt+1;
  36. end

  37. always@(cnt)
  38. begin
  39. if(cnt==255)
  40. cnt_out=1;
  41. else
  42. cnt_out=0;
  43. end

  44. endmodule
在上述代码中rst为输入信号,下降沿时计数器清零。
此外设置了reset变量,reset在rst下降沿时置0,并保持一个周期。
计数器变量则捕捉reset的下降沿,并且在reset为0时清零。
最终达到rst下降沿时计数器立即清零的效果,signaltap得到的图如下:

从图中可以看到,rst下降时,cnt立即置0。但cnt的计数周期会增加一个时钟周期。
因为reset=1的赋值有一定的延时,而同时cnt取reset的值进行判断此时reset仍为0。硬件中的这种延时感觉真让人蛋疼...

阅读(5262) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~