📅  最后修改于: 2021-01-11 15:11:59             🧑  作者: Mango
4位计数器从4'b0000开始递增到4'h1111,然后又回到4'b0000。只要提供运行时钟,它就会一直计数,并且复位保持高电平。
当最终加法的最高有效位被丢弃时,将发生翻转。当计数器的最大值为4'h1111并收到另一个计数请求时,该计数器尝试达到5'b10000,但由于它只能支持4位,因此MSB将被丢弃,结果为0。
0000
0001
0010
...
1110
1111
rolls over
0000
0001
...
该设计包含两个输入,一个用于时钟,第二个用于低电平有效复位。低电平有效复位是在复位引脚的值为0时复位设计的地方。有一个名为out的4位输出,该输出实质上提供计数器值。
module counter (input clk, // Declare input port for the clock to allow counter to count up
input rstn, // Declare input port for the reset to allow the counter to be reset to 0 when required
output reg[3:0] out); // Declare 4-bit output port to get the counter values
// This always block will be triggered at the rising edge of clk (0->1)
// Once inside this block, it checks if the reset is 0, then change out to zero
// If reset is 1, then the design should be allowed to count up, so increment the counter
always @ (posedge clk) begin
if (! rstn)
out <= 0;
else
out <= out + 1;
end
endmodule
模块计数器具有时钟和低电平有效复位( n )作为输入,计数器值具有4位输出。
每当时钟从0过渡到1时,始终执行块,这表示上升沿或上升沿。
仅当复位保持为高电平或1(由if-else块实现)时,输出才递增。如果在时钟的上升沿复位为低电平,则输出复位为默认值4'b0000。
试验台
我们可以将设计实例化到测试平台模块中,以验证计数器是否按预期进行计数。
testbench模块名为tb_counter ,并且不需要端口,因为它是仿真中的顶级模块。但是,我们需要具有内部变量来生成,存储和驱动时钟以及复位。
为此,我们为时钟和复位声明了两个类型为reg的变量。我们还需要一个线型网络来与设计的输出建立连接。否则,它将默认为1位标量网络。
时钟是通过Always模块生成的,该模块的周期为10次。初始块用于为我们的内部变量设置初始值,并驱动设计的重置值。
设计在测试平台中实例化,并连接到我们的内部变量,以在我们从测试平台驱动它们时获取值。
我们的测试台中没有任何$ display语句,因此在控制台中将看不到任何消息。
module tb_counter;
reg clk; // Declare an internal TB variable called clk to drive clock to the design
reg rstn; // Declare an internal TB variable called rstn to drive active low reset to design
wire [3:0] out; // Declare a wire to connect to design output
// Instantiate counter design and connect with Testbench variables
counter c0 ( .clk (clk),
.rstn (rstn),
.out (out));
// Generate a clock that should be driven to design
// This clock will flip its value every 5ns -> time period = 10ns -> freq = 100 MHz
always #5 clk = ~clk;
// This initial block forms the stimulus of the testbench
initial begin
// Initialize testbench variables to 0 at start of simulation
clk <= 0;
rstn <= 0;
// Drive rest of the stimulus, reset is asserted in between
#20 rstn <= 1;
#80 rstn <= 0;
#50 rstn <= 1;
// Finish the stimulus after 200ns
#20 $finish;
end
endmodule
请注意,当低电平有效复位变为0时,计数器复位为0,并且在约150ns时取消复位时,计数器从下一次出现时钟正沿开始计数。
硬件原理图