如何使用单时钟脉冲使能启动计数器
How to start a counter using a one clock pulse enable
所以我正在尝试实现一个计数器,它需要一个时钟周期启用并从那里开始计数。一旦计数器完成计数,它就会发送一个时钟周期过期。直到计数器完成计数,并且值输入是连续的。
才会再次发送使能。
我正在考虑只使用一个 reg 变量,它在 enable = 1 时变为高电平,并在计数器完成计数后变为低电平。我担心这可能意味着我不想要的闩锁...有更好的方法吗?
当前代码:
module Timer(
input [3:0] value,
input start_timer,
input clk,
input rst,
output reg expired
);
//counter var
reg [3:0] count;
//hold variable
reg hold;
//setting hold
always @*
begin
if (start_timer == 1'b1)
hold <= 1'b1;
end
//counter
if (hold == 1'b1)
begin
always @ (posedge(clk))
begin
if(count == value - 1)
begin
expired <= 1'b1;
count <= 4'b0;
hold <= 1'b0;
end
else
count <= count + 1'b1;
end
end
endmodule
好吧,您似乎走在了正确的轨道上,但是您当前的设计将暗示闩锁是正确的。您可以通过制作 hold
自己的触发器来解决此问题,并且仅在设置完成后才计数,并在计数完成后将其清除。请注意,这会影响系统的时序,因此您必须确保一切都在正确的周期内发生。从你的描述中很难说你是否希望 expired
在“value
"th cycle or "value
+ 1” 循环中设置。为了向您展示您需要对代码执行哪些操作才能使其编译并获得正确的时间,我将假设一些事情:
value
保持在一个常数,并且在计数时不会改变
expired
将在设置 start_timer
后的第 value
个时钟上发出脉冲
value
不会是4'h0
(虽然这很容易处理,因为根据假设1不需要计算)
因此,您的模块将如下所示:
module Timer(
input [3:0] value,
input start_timer,
input clk,
input rst,
output expired
);
//counter var
reg [3:0] count;
//hold variable
reg hold;
// Note you cannot assign hold from multiple blocks, so the other one has been removed
// In order to meet the timing from assumption 2, we need to combinationally determine expired (be sure we only set it while we are counting; thus the dependence on hold)
assign expired = (count == value - 4'd1) && (hold == 1'b1);
//counter
// Note, you cannot have logic outside of a procedural block!
always @(posedge clk) begin
if ((hold == 1'b0) && (start_timer == 1'b1)) begin
hold <= 1'b1; // Hold is part of the register, making it its own flipflop
count <= 4'd0;
end
else if (hold == 1'b1) begin
if (count == value - 4'd1) begin
hold <= 1'b0; // Clear hold, we are done counting
// No need to clear count, it will be cleared at the start of the timer
end
else begin
count <= count + 4'd1;
end
end
end
endmodule
所以我正在尝试实现一个计数器,它需要一个时钟周期启用并从那里开始计数。一旦计数器完成计数,它就会发送一个时钟周期过期。直到计数器完成计数,并且值输入是连续的。
才会再次发送使能。我正在考虑只使用一个 reg 变量,它在 enable = 1 时变为高电平,并在计数器完成计数后变为低电平。我担心这可能意味着我不想要的闩锁...有更好的方法吗?
当前代码:
module Timer(
input [3:0] value,
input start_timer,
input clk,
input rst,
output reg expired
);
//counter var
reg [3:0] count;
//hold variable
reg hold;
//setting hold
always @*
begin
if (start_timer == 1'b1)
hold <= 1'b1;
end
//counter
if (hold == 1'b1)
begin
always @ (posedge(clk))
begin
if(count == value - 1)
begin
expired <= 1'b1;
count <= 4'b0;
hold <= 1'b0;
end
else
count <= count + 1'b1;
end
end
endmodule
好吧,您似乎走在了正确的轨道上,但是您当前的设计将暗示闩锁是正确的。您可以通过制作 hold
自己的触发器来解决此问题,并且仅在设置完成后才计数,并在计数完成后将其清除。请注意,这会影响系统的时序,因此您必须确保一切都在正确的周期内发生。从你的描述中很难说你是否希望 expired
在“value
"th cycle or "value
+ 1” 循环中设置。为了向您展示您需要对代码执行哪些操作才能使其编译并获得正确的时间,我将假设一些事情:
value
保持在一个常数,并且在计数时不会改变expired
将在设置start_timer
后的第value
个时钟上发出脉冲value
不会是4'h0
(虽然这很容易处理,因为根据假设1不需要计算)
因此,您的模块将如下所示:
module Timer(
input [3:0] value,
input start_timer,
input clk,
input rst,
output expired
);
//counter var
reg [3:0] count;
//hold variable
reg hold;
// Note you cannot assign hold from multiple blocks, so the other one has been removed
// In order to meet the timing from assumption 2, we need to combinationally determine expired (be sure we only set it while we are counting; thus the dependence on hold)
assign expired = (count == value - 4'd1) && (hold == 1'b1);
//counter
// Note, you cannot have logic outside of a procedural block!
always @(posedge clk) begin
if ((hold == 1'b0) && (start_timer == 1'b1)) begin
hold <= 1'b1; // Hold is part of the register, making it its own flipflop
count <= 4'd0;
end
else if (hold == 1'b1) begin
if (count == value - 4'd1) begin
hold <= 1'b0; // Clear hold, we are done counting
// No need to clear count, it will be cleared at the start of the timer
end
else begin
count <= count + 4'd1;
end
end
end
endmodule