当前位置:   article > 正文

HDL Bits(Counters答案)_hdlbits答案counter

hdlbits答案counter

本节为时序电路的设计,需要重点掌握。

第一题:4-bits binary counters:

构建一个4位二进制计数器,计数从0到15(包括15),周期为16。复位输入是同步的,应该将计数器复位为0。

正确答案:

时序电路中,我总结了一个这样的习惯:

先设置清零的条件、其次为复位的条件、最后为计数(else);

注意在时序电路中如果要给输出赋值,应该使用<=符号,一般逻辑赋值语句使用=;

该题正确答案:因为该题的最大值即15,无需设置复位,4bits直接就是0-15;

  1. module top_module (
  2. input clk,
  3. input reset, // Synchronous active-high reset
  4. output [3:0] q);
  5. always@(posedge clk)begin
  6. if(reset)begin
  7. q[3:0] <= 0;
  8. end
  9. else begin
  10. q[3:0] <= q[3:0]+1'b1;
  11. end
  12. end
  13. endmodule

第二题:count10:

构建一个从0到9(包括9)的十进制计数器,周期为10。复位输入是同步的,应该将计数器复位为0。上题已经讲过:一般时序电路我们可以以清零、复位(或进一)、计数(else)的逻辑先后顺序来进行。

正确答案:

  1. module top_module (
  2. input clk,
  3. input reset, // Synchronous active-high reset
  4. output [3:0] q);
  5. always@(posedge clk)begin
  6. if(reset)begin
  7. q[3:0]<=0;
  8. end
  9. else if(q[3:0]==4'd9)begin
  10. q[3:0]<=0;
  11. end
  12. else begin
  13. q[3:0]<=q[3:0]+4'b1;
  14. end
  15. end
  16. endmodule

解析:第一个if是清零信号,当reset==1时,可使q<=0;

第二个else if是复位信号,当q[3:0]==9时(注意4'd9指的是该位为4bits,d指的是十进制,9为十进制中的9)。

第三个else 指的是其他情况下(posedge clk)都可以进行计数。

本题也可以将清零和复位信号结合起来:

  1. always@(posedge clk)begin
  2. if(reset||q[3:0]==4'd9)begin
  3. q[3:0]<=0;
  4. end
  5. else begin
  6. q[3:0]<=q[3:0]+4'b1;
  7. end
  8. end

第三题:Count1to10:

制作一个从1数到10的10秒计数器。复位输入是同步的,应该将计数器复位为1。

正确答案:

  1. module top_module (
  2. input clk,
  3. input reset,
  4. output [3:0] q);
  5. always@(posedge clk)begin
  6. if(reset||q[3:0]==4'd10)begin
  7. q[3:0]<=4'd1;
  8. end
  9. else begin
  10. q[3:0]<=q[3:0]+4'd1;
  11. end
  12. end
  13. endmodule

第四题:Countslow:

本题需要在slowena为1时才能计数,所以计数的该条件(slowena==1)为置数和计数的必要条件。

正确答案:

  1. module top_module (
  2. input clk,
  3. input slowena,
  4. input reset,
  5. output [3:0] q);
  6. always@(posedge clk)begin
  7. if(reset)begin
  8. q[3:0]<=0;
  9. end
  10. else if(slowena&&q[3:0]==4'd9)begin
  11. q[3:0]<=0;
  12. end
  13. else if(slowena&&q[3:0]<4'd9)begin
  14. q[3:0]<=q[3:0]+4'd1;
  15. end
  16. end
  17. endmodule

第五题:exams:

设计1-12计数器,要求如下:

Reset同步活动高电平复位,强制计数器为1;

设置计数器运行的高值;

Clk正极触发时钟输入;

Q[3:0]计数器的输出;

c_enable, c_load, c_d[3:0]进入提供的4位计数器的控制信号,因此可以验证正确的操作。

c_enable、c_load和c_d输出分别是进入内部计数器的enable、load和d输入的信号。它们的目的是允许检查这些信号的正确性。

正确答案:

  1. module top_module (
  2. input clk,
  3. input reset,
  4. input enable,
  5. output [3:0] Q,
  6. output c_enable,
  7. output c_load,
  8. output [3:0] c_d
  9. ); //
  10. count4 the_counter (clk, c_enable, c_load, c_d,Q);
  11. assign c_enable = enable;
  12. assign c_load =reset||((enable)&&(Q[3:0]==4'd12));
  13. assign c_d = c_load?4'd1:4'd0;
  14. endmodule

第六题:Counter1000

正确答案:

  1. module top_module (
  2. input clk,
  3. input reset,
  4. output OneHertz,
  5. output [2:0] c_enable
  6. ); //
  7. wire [3:0]a,b,c;
  8. assign OneHertz = (a[3:0]==4'd9)&&(b[3:0]==4'd9)&&(c[3:0]==4'd9);
  9. assign c_enable = {(a[3:0]==4'd9&&b[3:0]==4'd9),(a[3:0]==4'd9),1'b1};
  10. bcdcount counter0 (clk, reset, c_enable[0],a);
  11. bcdcount counter1 (clk, reset, c_enable[1],b);
  12. bcdcount counter2 (clk, reset, c_enable[2],c); //分频器大概是把1000分成三部分的
  13. endmodule

第七题:CountBCD:

构建一个4位BCD(二进制编码的十进制)计数器。每个十进制数字用4位编码:q[3:0]是个位数,q[7:4]是十位,等等。对于数字[3:1],还输出一个enable信号,指示何时应增加前三位数字中的每一位。enable信号有三位,其实就是这个四位数的前面三位一个一个地进位,个位进位使enable[1]=1;十位进位使enable[2]=1,以此类推。

您可以实例化或修改一些十位计数器。

先尝试写出来:

正确答案:
 

  1. module top_module (
  2. input clk,
  3. input reset, // Synchronous active-high reset
  4. output [3:1] ena,
  5. output [15:0] q);
  6. //分开写,千位
  7. always@(posedge clk)begin
  8. if(reset)begin
  9. q[15:12]<=0;
  10. end
  11. else if(q[15:12]==4'd9&&q[11:8]==4'd9&&q[7:4]==4'd9&&q[3:0]==4'd9)begin
  12. q[15:12]<=0;
  13. end
  14. else if(q[11:8]==4'd9&&q[7:4]==4'd9&&q[3:0]==4'd9)begin
  15. q[15:12]<=q[15:12]+1'b1;
  16. end
  17. end
  18. //百位:
  19. always@(posedge clk)begin
  20. if(reset)begin
  21. q[11:8]<=0;
  22. end
  23. else if(q[11:8]==4'd9&&q[7:4]==4'd9&&q[3:0]==4'd9)begin
  24. q[11:8]<=0;
  25. end
  26. else if(q[7:4]==4'd9&&q[3:0]==4'd9)begin
  27. q[11:8]<=q[11:8]+1'b1;
  28. end
  29. end
  30. //十位
  31. always@(posedge clk)begin
  32. if(reset)begin
  33. q[7:4]<=0;
  34. end
  35. else if(q[7:4]==4'd9&&q[3:0]==4'd9)begin
  36. q[7:4]<=0;
  37. end
  38. else if(q[3:0]==4'd9)begin
  39. q[7:4]<=q[7:4]+1'b1;
  40. end
  41. end
  42. //个位:
  43. always@(posedge clk)begin
  44. if(reset)begin
  45. q[3:0]<=0;
  46. end
  47. else if(q[3:0]==4'd9)begin
  48. q[3:0]<=0;
  49. end
  50. else begin q[3:0]<=q[3:0]+1'b1;
  51. end
  52. end
  53. assign ena[1] = q[3:0]==4'd9;
  54. assign ena[2] = q[7:4]==4'd9&&ena[1];
  55. assign ena[3] = q[11:8]==4'd9&&ena[2];
  56. endmodule

第八题:Count Clock

本题要求:

  创建一组适合作为12小时时钟使用的计数器(带有am/pm指示器)。您的计数器由一个快速运行的时钟进行计时,每当您的时钟应该增加时(即每秒一次),就会有一个脉冲。

  reset将时钟重置到12:00 AM。pm是0表示AM, 1表示pm。hh、mm和ss是两个BCD(二进制编码十进制)数字,分别表示小时(01-12)、分钟(00-59)和秒(00-59)。Reset具有比enable更高的优先级,并且即使在未启用时也可能发生。

  下面的时间图显示了从11:59:59 AM到12:00:00 PM的滚动行为以及同步重置和启用行为。

正确答案:

PM的翻转模块,该模块仅仅是判断十二点时的早晚状态的,所以只需要写关于11:59:59&&ena的逻辑便可,再将值赋到output PM 上。

然后即秒个位(ena2_ss)、秒十位(ena1_ss)、分个位(ena2_mm)、分十位(ena1_mm)的逻辑编写,大同小异,都是在前一个位数满足跳变的基础上再加上ena电平给这个判断成功条件;如分个位(ena2_mm)是ena&&秒设置为59才可以触发。我在其中为了使代码看起来更简洁,将一些条件赋值为wire中间向量了。

其中时的设计有些难写,首先要满足假如时钟点为12的时候,计数器就变成01,然后再是判断ena&&09:59:59的复位情况,这种情况ena&&9X"59"59与情况12无关,所以我们要分开判断,不能在条件里嵌套,不然会非常混乱。

最后才是计数的判断,是出复位判断以外的ena&&09"59"59的条件,这是复位情况的母条件,所以可以嵌套来写。

整体就是这样的思路:需要注意的是,你必须将分、秒的个位十位都分开写,逻辑思路清晰的前提下,可以尽可能地使用赋值语句使代码更简洁,最后就是翻转模块。

正确答案:

  1. module top_module(
  2. input clk,
  3. input reset,
  4. input ena,
  5. output pm,
  6. output [7:0] hh,
  7. output [7:0] mm,
  8. output [7:0] ss);
  9. //思路:pm模块、时、分、秒十位个位分写的逻辑模块
  10. //声明部分:
  11. //1指的是十位的使能、复位、翻转
  12. wire [3:0]ena1_ss,end1_ss;//秒的十位
  13. wire [3:0]ena1_mm,end1_mm;//分的十位
  14. wire [3:0]ena1_hh,end1_hh;//包括使能键、复位键、翻转键,时的十位
  15. //2指的都是个位的使能、复位、翻转
  16. wire [3:0]ena2_ss,end2_ss;//秒的十位
  17. wire [3:0]ena2_mm,end2_mm;//分的十位
  18. wire [3:0]ena2_hh,end2_hh;//包括使能键、复位键\时的十位
  19. reg ena_pm;//时置一的信号
  20. wire ss1,ss2,mm1,mm2,hh1;
  21. assign ena2_ss = ss[3:0];
  22. assign ena1_ss = ss[7:4];
  23. assign ena2_mm = mm[3:0];
  24. assign ena1_mm = mm[7:4];
  25. assign ena2_hh = hh[3:0];
  26. assign ena1_hh = hh[7:4];
  27. assign ss1 = ena2_ss==4'd9;
  28. assign ss2 = ss1&&ena1_ss==4'd5;
  29. assign mm1 = ss2&&ena2_mm==4'd9;
  30. assign mm2 = mm1&&ena1_mm==4'd5;
  31. assign hh1 = mm2&&ena2_hh==4'd9;
  32. //时、分、秒
  33. always@(posedge clk)begin //时针的十位
  34. if(reset)begin //清零
  35. hh[7:4]<=1;
  36. end
  37. else if(ena2_hh==4'd2&&ena1_hh==4'd1&&ena&&mm2)begin
  38. hh[7:4]<=4'd0;
  39. end
  40. else if(ena&&hh1)begin //复位、翻转
  41. if(ena1_hh==4'd9)begin
  42. hh[7:4]<=4'd0;
  43. end
  44. else begin //计数
  45. hh[7:4]<=hh[7:4]+1'b1;
  46. end
  47. end
  48. end
  49. always@(posedge clk)begin //时针的个位
  50. if(reset)begin //清零
  51. hh[3:0]<=2;
  52. end
  53. else if(ena&&mm2&&ena2_hh==4'd2&&ena1_hh==4'd1)begin //复位、翻转
  54. hh[3:0]<=4'd1;
  55. end
  56. else if(ena&&mm2)begin
  57. if(ena2_hh==4'd9)begin
  58. hh[3:0]<=4'd0;
  59. end
  60. else begin //计数
  61. hh[3:0]<=hh[3:0]+1'b1;
  62. end
  63. end
  64. end
  65. always@(posedge clk)begin //分针的十位
  66. if(reset)begin //清零
  67. mm[7:4]<=0;
  68. end
  69. else if(ena&&mm1)begin //复位、进一
  70. if(ena1_mm==4'd5)begin
  71. mm[7:4]<=4'd0;
  72. end
  73. else begin //计数
  74. mm[7:4]<=mm[7:4]+1'b1;
  75. end
  76. end
  77. end
  78. always@(posedge clk)begin //分针的个位
  79. if(reset)begin //清零
  80. mm[3:0]<=0;
  81. end
  82. else if(ena&&ss2)begin
  83. if(ena2_mm==4'd9)begin//复位、进一
  84. mm[3:0]<=4'd0;
  85. end
  86. else begin //计数
  87. mm[3:0]<=mm[3:0]+1'b1;
  88. end
  89. end
  90. end
  91. always@(posedge clk)begin //秒针的十位
  92. if(reset)begin //清零
  93. ss[7:4]<=0;
  94. end
  95. else if(ena&&ss1)begin
  96. if(ena1_ss==4'd5)begin//复位、进一
  97. ss[7:4]<=4'd0;
  98. end
  99. else begin //计数
  100. ss[7:4]<=ss[7:4]+1'b1;
  101. end
  102. end
  103. end
  104. always@(posedge clk)begin //秒针的个位
  105. if(reset)begin //清零
  106. ss[3:0]<=0;
  107. end
  108. else if(ena)begin
  109. if(ss1)begin //复位、进一
  110. ss[3:0]<=4'd0;
  111. end
  112. else begin //计数
  113. ss[3:0]<=ss[3:0]+1'b1;
  114. end
  115. end
  116. end
  117. //ena_pm模块
  118. // PM位 start
  119. always @(posedge clk) begin
  120. if (reset) begin
  121. pm <= 0;
  122. end
  123. else if (ena_pm) begin
  124. pm <= ~pm; // pm信号翻转
  125. end
  126. end
  127. assign ena_pm = (ena&&mm2)&&(hh[7:4]==4'd1) && (hh[3:0]==4'd1);
  128. endmodule

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/648865
推荐阅读
相关标签
  

闽ICP备14008679号