当前位置:   article > 正文

Verilog HDLBits 第二十一期:3.3.1 Building larger circuits(3.3.1-3.3.7)_verilog中delay-num

verilog中delay-num

目录

前言

3.3.1 Counter with period 1000(Exams/review2015 count1k)

Solution:

3.3.2 4-bit shift register and down counter(Exams/review2015 shiftcount)

Solution:

3.3.3 FSM:Sequence 1101 recognizer(Exams/review2015 fsmseq)

Solution:

 3.3.4 FSM:Enable shift register(Exams/review2015 fsmshift)

Solution:

3.3.5 FSM:The complete FSM(Exams/review2015 fsm)

Solution:

 3.3.6 The complete timer(Exams/review2015 fancytimer)

Solution:

3.3.7 FSM:One-hot logic equations(Exams/review2015 fsmonehot)

Solution:


前言

HDLbits网站如下

Problem sets - HDLBits (01xz.net)

从本期开始我们继续HDLbits第三章Circuits的学习,本期的内容是Building larger circuits(3.3.1-3.3.7)


3.3.1 Counter with period 1000(Exams/review2015 count1k)

构建一个计数范围为0到999(含0到999)的计数器,周期为1000个周期。复位输入是同步的,应将计数器重置为0。

Solution:

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

3.3.2 4-bit shift register and down counter(Exams/review2015 shiftcount)

这是一系列五个练习的第一部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise

构建一个四位移位寄存器,它也可以作为下行(递减)计数器。当shift_ena为1时,data向最高有效位移位即左移。当count_ena为1时,移位寄存器中当前的数字递减。由于整个系统从未同时使用shift_ena和count_ena,因此如果两个控制输入都为1(这主要意味着哪种情况具有更高的优先级),则电路的功能无关紧要。

Solution:

  1. module top_module (
  2. input clk,
  3. input shift_ena,
  4. input count_ena,
  5. input data,
  6. output [3:0] q);
  7. always@(posedge clk) begin
  8. if(shift_ena)
  9. q<={q[2:0],data};
  10. else if(count_ena)
  11. q<=q-1;
  12. end
  13. endmodule

3.3.3 FSM:Sequence 1101 recognizer(Exams/review2015 fsmseq)

这是一系列五个练习的第二部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise

构建一个在输入比特流中搜索序列1101的有限状态机。找到序列后,应将start_shifting设置为1,直到复位。保持最终状态是为了在一个尚未实施的更大的FSM中模拟前往其他状态。我们将在接下来的几个练习中扩展此FSM。

Solution:

  1. module top_module (
  2. input clk,
  3. input reset, // Synchronous reset
  4. input data,
  5. output start_shifting);
  6. parameter s0=0,s1=1,s11=2,s110=3,s1101=4;
  7. reg [2:0]state,next;
  8. always@(posedge clk) begin
  9. if(reset)
  10. state<=0;
  11. else
  12. state<=next;
  13. end
  14. always@(*) begin
  15. case(state)
  16. s0:next=data?s1:s0;
  17. s1:next=data?s11:s0;
  18. s11:next=data?s11:s110;
  19. s110:next=data?s1101:s0;
  20. s1101:next=s1101;
  21. endcase
  22. end
  23. assign start_shifting=(state==s1101);
  24. endmodule

 3.3.4 FSM:Enable shift register(Exams/review2015 fsmshift)

这是一系列五个练习的第三部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise

作为用于控制移位寄存器的FSM的一部分,我们希望能够在检测到正确的位模式时,使移位寄存器能够精确地工作4个时钟周期。我们在3.3.3中处理序列检测,因此FSM的这部分仅处理移位寄存器的4个周期启用。

无论何时复位FSM,都要将shift_ena有效4个周期,然后永远为0(直到复位)。

Solution:

  1. module top_module (
  2. input clk,
  3. input reset, // Synchronous reset
  4. output shift_ena);
  5. reg [2:0]cnt;
  6. always@(posedge clk) begin
  7. if(reset)
  8. cnt<=0;
  9. else if(cnt<=3)
  10. cnt<=cnt+1;
  11. else
  12. cnt<=cnt;
  13. end
  14. always@(*) begin
  15. if(cnt==4)
  16. shift_ena=0;
  17. else
  18. shift_ena=1;
  19. end
  20. endmodule

3.3.5 FSM:The complete FSM(Exams/review2015 fsm)

这是一系列五个练习的第四部分,这些练习用几个较小的电路构建复杂的计数器。有关整体设计,请参见 3.3.6the final exercise

我们想创建一个计时器:

  1. 当检测到特定序列(1101)时启动
  2. 再移位四位以确定延迟的持续时间
  3. 等待计数器完成计数
  4. 通知用户并等待用户确认计时器。

在这个问题中,只实现控制计时器的FSM。这里不包括数据路径(计数器和一些比较器)。

串行数据在数据输入引脚上可用。当接收到序列1101时,状态机必须在整整4个时钟周期内使shift_ena有效。

之后,状态机使其计数输出有效,以指示它正在等待计数器,并等待直到输入done_counting为高。

此时,状态机必须断言done以通知用户计时器已超时,并等待直到输入 ack为1,然后再复位,以查找启动序列的下一次出现(1101)。

状态机应复位为开始搜索输入序列1101的状态。

以下是预期输入和输出的示例。“x”状态读起来可能有点混乱。它们表明FSM不应该关心该周期中的特定输入信号。例如,一旦检测到1101模式,FSM将不再查看数据输入,直到完成所有其他操作后恢复搜索。

Hint:

Solution:

  1. module top_module (
  2. input clk,
  3. input reset, // Synchronous reset
  4. input data,
  5. output shift_ena,
  6. output counting,
  7. input done_counting,
  8. output done,
  9. input ack );
  10. parameter s=0,s1=1,s11=2,s110=3,shift=5,count=6,idle=7;
  11. reg [2:0]state,next;
  12. reg [2:0]cnt;
  13. always@(*) begin
  14. case(state)
  15. s:next=data?s1:s;
  16. s1:next=data?s11:s;
  17. s11:next=data?s11:s110;
  18. s110:next=data?shift:s;
  19. shift:next=(cnt<3)?shift:count;
  20. count:next=done_counting?idle:count;
  21. idle:next=ack?s:idle;
  22. endcase
  23. end
  24. always@(posedge clk) begin
  25. if(reset)
  26. state<=s;
  27. else
  28. state<=next;
  29. end
  30. always@(posedge clk) begin
  31. case(state)
  32. s110:cnt<=0;
  33. shift:cnt<=cnt+1;
  34. endcase
  35. end
  36. assign shift_ena = (state==shift);
  37. assign counting = (state==count);
  38. assign done = (state==idle);
  39. endmodule

 3.3.6 The complete timer(Exams/review2015 fancytimer)

这是一系列五个练习的第五部分,这些练习用几个较小的电路构建复杂的计数器。

我们想创建一个计时器:

  1. 当检测到特定序列(1101)时启动
  2. 再移位四位以确定延迟的持续时间
  3. 等待计数器完成计数
  4. 通知用户并等待用户确认计时器。

串行数据在data输入引脚上可用。当接收到序列1101时,电路必须在接下来的4位中移位,最高有效位首先移位。这4位决定计时器延迟的持续时间。我称之为delay[3:0]。

之后,状态机使其counting输出有效,以指示其正在计数。状态机必须精确计数(delay[3:0]+1)*1000个时钟周期。 例如,delay=0表示计数1000个周期,delay=5表示计数6000个周期。同时输出当前剩余时间。这等价于delay对应1000个周期,delay-1对应1000个周期,依此类推,直到0对应1000个周期。当电路不计数时,count[3:0]输出是dont-care(无论什么值便于实现)。

此时,电路必须断言done,以通知用户计时器已超时,并等待输入ack为1,然后再复位,以查找下一次出现的启动序列(1101)。

电路应复位至开始搜索输入序列1101的状态。

以下是预期输入和输出的示例。“x”状态读起来可能有点混乱。它们表明FSM不应该关心该周期中的特定输入信号。例如,一旦1101和delay[3:0]被读取,电路将不再查看数据输入,直到完成所有其他操作后恢复搜索。在本例中,电路计数2000个时钟周期,因为delay[3:0]值为4'b0001。最后几个周期开始另一次计数,delay[3:0]=4'b1110,这将计15000个周期。

Solution:

  1. module top_module (
  2. input clk,
  3. input reset, // Synchronous reset
  4. input data,
  5. output [3:0] count,
  6. output counting,
  7. output done,
  8. input ack );
  9. parameter idle=0,s1=1,s11=2,s110=3,shift=4,timer=5,wait_=6;
  10. reg[2:0]state,next;
  11. always@(*) begin
  12. case(state)
  13. idle:next=data?s1:idle;
  14. s1:next=data?s11:idle;
  15. s11:next=data?s11:s110;
  16. s110:next=data?shift:idle;
  17. shift:next=(shift_cnt==3)?timer:shift;
  18. timer:next=(timer_cnt==(delay+1)*1000-1)?wait_:timer;
  19. wait_:next=ack?idle:wait_;
  20. endcase
  21. end
  22. always@(posedge clk) begin
  23. if(reset)
  24. state<=idle;
  25. else
  26. state<=next;
  27. end
  28. reg[3:0]delay;
  29. always@(posedge clk) begin
  30. if(reset)
  31. delay<=4'b0;
  32. else if(state==shift)
  33. delay<={delay[2:0],data};
  34. else
  35. delay<=delay;
  36. end
  37. reg[1:0]shift_cnt;
  38. always@(posedge clk) begin
  39. if(reset)
  40. shift_cnt<=0;
  41. else if(state==shift&&shift_cnt<2'd3)
  42. shift_cnt<=shift_cnt+2'd1;
  43. else
  44. shift_cnt<=0;
  45. end
  46. reg[15:0]timer_cnt;
  47. always@(posedge clk) begin
  48. if(reset)
  49. timer_cnt<=16'd0;
  50. else if(state==timer&&timer_cnt<((delay+1)*1000-1))
  51. timer_cnt<=timer_cnt+16'd1;
  52. else
  53. timer_cnt<=16'd0;
  54. end
  55. reg[10:0]cnt_1k;
  56. reg[3:0]num_1k;
  57. always@(posedge clk) begin
  58. if(reset)
  59. cnt_1k<=11'd0;
  60. else if(state==timer&&cnt_1k!=11'd999)
  61. cnt_1k<=cnt_1k+11'd1;
  62. else
  63. cnt_1k<=11'd0;
  64. end
  65. always@(posedge clk) begin
  66. if(reset)
  67. num_1k<=4'd0;
  68. else if(cnt_1k==11'd999)
  69. num_1k<=num_1k+1'b1;
  70. else if(state==timer)
  71. num_1k<=num_1k;
  72. else
  73. num_1k<=4'd0;
  74. end
  75. assign counting=(state==timer);
  76. assign done=(state==wait_);
  77. assign count=(state==timer)?(delay-num_1k):4'b0;
  78. endmodule

3.3.7 FSM:One-hot logic equations(Exams/review2015 fsmonehot)

给定以下具有3个输入、3个输出和10个状态的状态机:

假设使用以下独热码,通过检查推导next_state态逻辑方程和output逻辑方程:(S、S1、S11、S110、B0、B1、B2、B3、Count、Wait)=(10'b0000000001、10'b0000000010、10'b0000000100、…、10'b1000000000) 

编写生成以下方程式的代码:

  • B3_next -- B3的下个状态
  • S_next
  • S1_next
  • Count_next
  • Wait_next
  • done -- output logic
  • counting
  • shift_ena

Solution:

  1. module top_module(
  2. input d,
  3. input done_counting,
  4. input ack,
  5. input [9:0] state, // 10-bit one-hot current state
  6. output B3_next,
  7. output S_next,
  8. output S1_next,
  9. output Count_next,
  10. output Wait_next,
  11. output done,
  12. output counting,
  13. output shift_ena
  14. ); //
  15. parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
  16. reg[9:0]next;
  17. always@(*) begin
  18. next[S]=(state[S]&&~d)||(state[S1]&&~d)||(state[S110]&&~d)||(state[Wait]&&ack);
  19. next[S1]=state[S]&&d;
  20. next[S11]=state[S1]&&d;
  21. next[S110]=state[S11]&&~d;
  22. next[B0]=state[S110]&&d;
  23. next[B1]=state[B0];
  24. next[B2]=state[B1];
  25. next[B3]=state[B2];
  26. next[Count]=state[B3]||state[Count]&&~(done_counting);
  27. next[Wait]=state[Count]&&done_counting||state[Wait]&&~ack;
  28. end
  29. assign B3_next=next[B3];
  30. assign S_next=next[S];
  31. assign S1_next=next[S1];
  32. assign Count_next=next[Count];
  33. assign Wait_next=next[Wait];
  34. assign done=state[Wait];
  35. assign counting=state[Count];
  36. assign shift_ena=state[B0]||state[B1]||state[B2]||state[B3];
  37. endmodule

3.3.6分解成小任务就没有那么难了

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

闽ICP备14008679号