所以我试图实现一个采用一个时钟周期启用的计数器并从那里开始计数。一旦计数器完成计数,它就会发送一个时钟周期。在计数器完成计数之前,永远不会再次发送启用,并且值输入是连续的。
我在考虑使用一个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
答案 0 :(得分:0)
嗯,你似乎走在了正确的轨道上,但你说你的当前设计意味着锁定是正确的。您可以通过将hold
设置为自己的触发器来解决这个问题,并且只计算完所设置的时间,并在计数完成后将其清除。请注意,这会影响系统的时间,因此您必须确保所有操作都在正确的周期内完成。很难从您的描述中说明您是希望在“expired
”周期或“value
+ 1”周期设置value
。为了向您展示您需要对代码执行哪些操作以使其编译并具有适当的时序,我将假设一些事情:
value
保持一个常数,并且在计算时不会改变expired
将在value
设置后的start_timer
时间脉冲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