Menu Close

Verilog 语法练习(10)复杂计数器的设计

接下来的问题是一个系列,由简单的小电路逐渐组合成完成复杂计数器的实现。

1.

实现一个带有高电平同步复位信号,从 0 到 999 ,周期为 1000 个周期的计数器。

参考波形图:

完善下列代码:

module top_module (
    input clk,
    input reset, //高电平同步复位信号
    output [9:0] q
);

endmodule

 

参考代码:

[content_control]

1.txt

[/content_control]

 

 

2.

实现一个4-bit移位寄存器,这个寄存器同时也可以用作递减计数器。 当 shift_ena 为 1 时,数据q进行左移,并将输入data补入最低位。当 count_ena 为 1 时,移位寄存器中的数字根据时钟的节奏递减1。由于整个系统不会同时使用 shift_ena 和 count_ena,因此 shift_ena 和 count_ena优先级并不重要。参考波形如下:

完善下列代码:

module top_module (
    input clk,
    input shift_ena,
    input count_ena,
    input data,
    output [3:0] q
);

endmodule

 

参考代码:

[content_control]

solution_2.txt

[/content_control]

Test bench:

[content_control]

tb2.txt

[/content_control]

 

3.

实现一个状态机,在输入比特流中搜索序列 1101。 找到序列后,应将 start_shifting 设置为 1,直到reset高电平同步复位信号将其置为0。 示意波形图如下:

 

完善下列代码:

module top_module (
    input clk,
    input reset,      // 高电平同步复位信号
    input data,
    output start_shifting
);

endmodule

 

参考代码:

[content_control]

solution_3.txt

[/content_control]

Test bench:

[content_control]

tb3.txt

[/content_control]

 

4.

状态机在reset时,将 shift_ena 置位 4 个周期  其余时间值为 0(直到下一次reset),示意波形图如下:

完善下列代码:

module top_module (
    input clk,
    input reset,      // Synchronous reset
    output shift_ena);

endmodule

 

参考代码:

[content_control]

solution_4.txt

solution_4_2.txt

[/content_control]

 

5.

实现一个带有高电平同步复位信号的计时器,要点如下(本问题只要求实现控制定时器的状态机,不需要考虑数据,计数器等。):

  • 先检测特定序列 (1101)
  • 如果检测到特定序列,将shift_ena精准置高4个时钟周期,(移 4 位寄存器这里暂不实现)
  • shift_ena被置低后,再置高计数器使能counting
  • counting一直为高,直到输入信号done_counting立起来之后,counting才被置低,并且将done置高
  • 直到接收到输入信号ack,done才被置低,然后才开始寻找下一次出现的启动序列(1101)

见以下波形图示例,图中 ‘x’ 状态(阴影部分)表示不关心。例如,一旦检测到 1101 模式,状态机将不再查看数据输入,直到完成其他所有操作后再重新检测序列(1101)。

完善下列代码:

module top_module (
    input clk,
    input reset,      //高电平同步复位
    input data,

    input done_counting,
    input ack,

    output shift_ena,
    output counting,
    output done
);

endmodule

 

参考代码:

[content_control]

solution_5.txt

another_solution_5.txt

tb5_question10.txt

[/content_control]

参考状态转移图:

 

6.

结合问题1-问题5,将上述几个子电路构建成一个复杂的计数器,要点如下:

  • 当检测到data中出现特定序列 (1101) 时启动
  • 再将data移 4 位(首先出现的位是最高有效位/MSB,比如接下来data是0-0-0-1,那么对应的延迟count[3:0]应该是4’b0001)以确定延迟的持续时间
  • 计数器进行计数:
    • 如果data移位确定的延迟为 count[3:0],状态机必须精确计数 (count[3:0] + 1) * 1000 个时钟周期。例如,count = 0 表示总共计数 1000 个周期,count = 5 表示总共计数 6000 个周期。每计数1000个时钟周期,count = count – 1。当电路不计数时,不关心count[3:0] 输出。
  • 完成后,置位done信号,等待ack信号,握手后可以进行下一次检测特定序列
  • 高电平同步复位信号将状态机重置为检测特定序列(1101)

 

 

见以下波形图示例:

在上图所示例子中,电路计数 2000 个时钟周期,因为 count[3:0] 值为 4’b0001。最后几个周期以 count[3:0] = 4’b1110 开始另一个计数,它将计数 15000 个周期。

 

完善以下代码:

module top_module (
    input clk,
    input reset,     
    input data,
    output [3:0] count,
    output counting,
    output done,
    input ack
 );

endmodule

 

参考代码:

[content_control]

6.txt

6_solution_2.txt

tb6_question10.txt

[/content_control]

 

Posted in FPGA, FPGA 教材教案, FPGA习题库, Verilog, 教材与教案, 文章, 编程语言

发表回复

相关链接