2021年6月21日 星期一

Verilog Circuits Sequential Logic ---- Sequential Logic Counters (2)

 3.2.2 Counters

3.2.2.1 Four-bit binary counter(Count15)

3.2.2.2 Decade counter(Count10)

3.2.2.3 Decade counter again(Count1to10)

3.2.2.4 Show decade counter(Countslow)

3.2.2.5 Counter 1-12(Exams/ece241 2014 q7a)

3.2.2.6 Counter 1000(Exams/ece241 2014 q7b)

3.2.2.7 4-digit decimal counter(Countbcd)

3.2.2.8 12-hour clock(Count clock)


3.2.2 Counters

3.2.2.1 Four-bit binary counter(Count15)

  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 <= 4'd0;
  8. end
  9. else begin
  10. q <= q + 1'b1;
  11. end
  12. end
  13. endmodule

这道题是要实现一个计数到15清零的计数器,大家注意,如果不是计数到15,需要加一个清零条件。这道题目可以不用添加。

3.2.2.2 Decade counter(Count10)

  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 <= 4'd0;
  8. end
  9. else if(q == 4'd9)begin
  10. q <= 4'd0;
  11. end
  12. else begin
  13. q <= q + 1'b1;
  14. end
  15. end
  16. endmodule

这道题目就需要加一个清零条件。

3.2.2.3 Decade counter again(Count1to10)

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

这道题目修改了复位条件,改成了复位为1,原理是相同的。

3.2.2.4 Show decade counter(Countslow)

  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 <= 4'd0;
  9. end
  10. else if(slowena)begin
  11. if(q == 4'd9)begin
  12. q <= 4'd0;
  13. end
  14. else begin
  15. q <= q + 1'b1;
  16. end
  17. end
  18. end
  19. endmodule

这道题多了一个使能信号,只有使能信号为高的时候计数器才开始工作,否则就保持原来的值。

3.2.2.5 Counter 1-12(Exams/ece241 2014 q7a)

  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. assign c_enable = enable;
  11. assign c_load = reset | ((Q == 4'd12) && enable == 1'b1);
  12. assign c_d = c_load ? 4'd1 : 4'd0;
  13. count4 u_counter (clk, c_enable, c_load, c_d, Q);
  14. endmodule

3.2.2.6 Counter 1000(Exams/ece241 2014 q7b)

  1. module top_module (
  2. input clk,
  3. input reset,
  4. output OneHertz,
  5. output [2:0] c_enable
  6. ); //
  7. wire[3:0] one, ten, hundred;
  8. assign c_enable = {one == 4'd9 && ten == 4'd9, one == 4'd9, 1'b1};
  9. assign OneHertz = (one == 4'd9 && ten == 4'd9 && hundred == 4'd9);
  10. bcdcount counter0 (clk, reset, c_enable[0], one);
  11. bcdcount counter1 (clk, reset, c_enable[1], ten);
  12. bcdcount counter2 (clk, reset, c_enable[2], hundred);
  13. endmodule

这两道题目都是例化作者已经写好的module从而创造一种新的计数器。

3.2.2.7 4-digit decimal counter(Countbcd)

  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. reg [3:0] ones;
  7. reg [3:0] tens;
  8. reg [3:0] hundreds;
  9. reg [3:0] thousands;
  10. always@(posedge clk)begin
  11. if(reset)begin
  12. ones <= 4'd0;
  13. end
  14. else if(ones == 4'd9)begin
  15. ones <= 4'd0;
  16. end
  17. else begin
  18. ones <= ones + 1'b1;
  19. end
  20. end
  21. always@(posedge clk)begin
  22. if(reset)begin
  23. tens <= 4'd0;
  24. end
  25. else if(tens == 4'd9 && ones == 4'd9)begin
  26. tens <= 4'd0;
  27. end
  28. else if(ones == 4'd9) begin
  29. tens <= tens + 1'b1;
  30. end
  31. end
  32. always@(posedge clk)begin
  33. if(reset)begin
  34. hundreds <= 4'd0;
  35. end
  36. else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)begin
  37. hundreds <= 4'd0;
  38. end
  39. else if(tens == 4'd9 && ones == 4'd9) begin
  40. hundreds <= hundreds + 1'b1;
  41. end
  42. end
  43. always@(posedge clk)begin
  44. if(reset)begin
  45. thousands <= 4'd0;
  46. end
  47. else if(thousands == 4'd9 && hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9)begin
  48. thousands <= 4'd0;
  49. end
  50. else if(hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9) begin
  51. thousands <= thousands + 1'b1;
  52. end
  53. end
  54. assign q = {thousands, hundreds, tens, ones};
  55. assign ena[1] = (ones == 4'd9) ? 1'b1 : 1'b0;
  56. assign ena[2] = (tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
  57. assign ena[3] = (hundreds == 4'd9 && tens == 4'd9 && ones == 4'd9) ? 1'b1 : 1'b0;
  58. endmodule

这道题目大家只要掌握好清零条件和加一条件就好了。对于我的这种写法,更好的写法应该是讲条件单独用assign写下来,这样计数器的层次感比较强,代码可阅读性更好。下面的这道题目就是这种方式。

3.2.2.8 12-hour clock(Count clock)

  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. reg pm_temp;
  10. reg [3:0] ss_ones;
  11. reg [3:0] ss_tens;
  12. reg [3:0] mm_ones;
  13. reg [3:0] mm_tens;
  14. reg [3:0] hh_ones;
  15. reg [3:0] hh_tens;
  16. wire add_ss_ones;
  17. wire end_ss_ones;
  18. wire add_ss_tens;
  19. wire end_ss_tens;
  20. wire add_mm_ones;
  21. wire end_mm_ones;
  22. wire add_mm_tens;
  23. wire end_mm_tens;
  24. wire add_hh_ones;
  25. wire end_hh_ones_0;
  26. wire end_hh_ones_1;
  27. wire add_hh_tens;
  28. wire end_hh_tens_0;
  29. wire end_hh_tens_1;
  30. wire pm_ding;
  31. always@(posedge clk)begin
  32. if(reset)begin
  33. ss_ones <= 4'd0;
  34. end
  35. else if(add_ss_ones)begin
  36. if(end_ss_ones)begin
  37. ss_ones <= 4'd0;
  38. end
  39. else begin
  40. ss_ones <= ss_ones + 1'b1;
  41. end
  42. end
  43. end
  44. assign add_ss_ones = ena;
  45. assign end_ss_ones = add_ss_ones && ss_ones == 4'd9;
  46. always@(posedge clk)begin
  47. if(reset)begin
  48. ss_tens <= 4'd0;
  49. end
  50. else if(add_ss_tens)begin
  51. if(end_ss_tens)begin
  52. ss_tens <= 4'd0;
  53. end
  54. else begin
  55. ss_tens <= ss_tens + 1'b1;
  56. end
  57. end
  58. end
  59. assign add_ss_tens = end_ss_ones;
  60. assign end_ss_tens = add_ss_tens && ss_tens == 4'd5;
  61. always@(posedge clk)begin
  62. if(reset)begin
  63. mm_ones <= 4'd0;
  64. end
  65. else if(add_mm_ones)begin
  66. if(end_mm_ones)begin
  67. mm_ones <= 4'd0;
  68. end
  69. else begin
  70. mm_ones <= mm_ones + 1'b1;
  71. end
  72. end
  73. end
  74. assign add_mm_ones = end_ss_tens;
  75. assign end_mm_ones = add_mm_ones && mm_ones == 4'd9;
  76. always@(posedge clk)begin
  77. if(reset)begin
  78. mm_tens <= 4'd0;
  79. end
  80. else if(add_mm_tens)begin
  81. if(end_mm_tens)begin
  82. mm_tens <= 4'd0;
  83. end
  84. else begin
  85. mm_tens <= mm_tens + 1'b1;
  86. end
  87. end
  88. end
  89. assign add_mm_tens = end_mm_ones;
  90. assign end_mm_tens = add_mm_tens && mm_tens == 4'd5;
  91. always@(posedge clk)begin
  92. if(reset)begin
  93. hh_ones <= 4'd2;
  94. end
  95. else if(add_hh_ones)begin
  96. if(end_hh_ones_0)begin
  97. hh_ones <= 4'd0;
  98. end
  99. else if(end_hh_ones_1)begin
  100. hh_ones <= 4'd1;
  101. end
  102. else begin
  103. hh_ones <= hh_ones + 1'b1;
  104. end
  105. end
  106. end
  107. assign add_hh_ones = end_mm_tens;
  108. assign end_hh_ones_0 = add_hh_ones && hh_ones == 4'd9;
  109. assign end_hh_ones_1 = add_hh_ones && (hh_tens == 4'd1 && hh_ones == 4'd2);
  110. always@(posedge clk)begin
  111. if(reset)begin
  112. hh_tens <= 4'd1;
  113. end
  114. else if(add_hh_tens)begin
  115. if(end_hh_tens_0)begin
  116. hh_tens <= 4'd0;
  117. end
  118. else if(end_hh_tens_1)begin
  119. hh_tens <= hh_tens + 1'b1;
  120. end
  121. end
  122. end
  123. assign add_hh_tens = end_mm_tens;
  124. assign end_hh_tens_0 = add_hh_tens && end_hh_ones_1;
  125. assign end_hh_tens_1 = add_hh_tens && end_hh_ones_0;
  126. alwaysosedge clk)begin
  127. if(reset)beg@(p
  128. in
  129. pm_temp <= 1'b0;
  130. end
  131. else if(pm_ding)begin
  132. pm_temp <= ~pm_temp;
  133. end
  134. end
  135. assign pm_ding = hh_tens == 4'd1 && hh_ones == 4'd1 && end_mm_tens;
  136. assign ss = {ss_tens, ss_ones};
  137. assign mm = {mm_tens, mm_ones};
  138. assign hh = {hh_tens, hh_ones};
  139. assign pm = pm_temp;
  140. endmodule

沒有留言:

張貼留言

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...