So I'm trying to implement a counter that takes a one-clock-cycle enable and starts counting from there. It sends a one-clock-cycle expired once the counter finishes counting. The enable will never be sent again until the counter is done counting, and the value input is continuous.
I was thinking of just using a reg variable that is changed to high when enable = 1, and changed to low once the counter finishes counting. I fear this may imply latches that I don't want... is there a better way to do this?
current code:
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
Well, you seem to be on the right track, but you are correct that your current design will imply latches. You can fix this by making hold
its own flipflop and only counting when its set as you have done, clearing it once your counting is complete. Note this will impact the timing of your system, so you have to make sure everything happens on the correct cycle. Its hard to say from your description whether you want expired
to be set on the " value
"th cycle or " value
+ 1"th cycle. In order to show you a few of what youll need to do to your code to get it to compile and have the proper timing, Im going to assume a few things:
value
is held at a constant number and doesnt not change while counting expired
will pulse on the value
th clock after start_timer
is set value
will not be 4'h0
(though this is easy to deal with, as no counting is required based on assumption 1) So, your module would look like this:
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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.