接下来的问题是一个系列,由简单的小电路逐渐组合成完成复杂计数器的实现。
1.
实现一个带有高电平同步复位信号,从 0 到 999 ,周期为 1000 个周期的计数器。
参考波形图:

完善下列代码:
module top_module (
input clk,
input reset, //高电平同步复位信号
output [9:0] q
);
endmodule
参考代码:
[content_control]
[/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]
[/content_control]
Test bench:
[content_control]
[/content_control]
3.
实现一个状态机,在输入比特流中搜索序列 1101。 找到序列后,应将 start_shifting 设置为 1,直到reset高电平同步复位信号将其置为0。 示意波形图如下:

完善下列代码:
module top_module (
input clk,
input reset, // 高电平同步复位信号
input data,
output start_shifting
);
endmodule
参考代码:
[content_control]
[/content_control]
Test bench:
[content_control]
[/content_control]
4.
状态机在reset时,将 shift_ena 置位 4 个周期 其余时间值为 0(直到下一次reset),示意波形图如下:

完善下列代码:
module top_module (
input clk,
input reset, // Synchronous reset
output shift_ena);
endmodule
参考代码:
[content_control]
[/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]
[/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]
[/content_control]