Im working on a project and after chasing down a bug i narrowed it down to it being caused by an Always block that doesnt trigger correctly.
module Counter(start,clk_len,done,clk,reset);
input [4:0] clk_len;
input clk,start,reset;
output done;
reg [4:0] cntr_var = 0; reg start_val = 0;
assign done = !start_val;
reg test = 0;
always @(reset){cntr_var,start_val} = 2'b0;
always @(posedge start) begin
start_val = start;
end
always @((done and cntr_var == clk_len)) begin // <=== This is the source of the problem
cntr_var = 0;
start_val = 0;
test = 1;
end
always @(clk and !reset) begin
if (start_val == 1 && cntr_var != clk_len)
cntr_var = cntr_var + 1;
end
endmodule
One of the always blocks is supposed to trigger when done
AND (cntr_var == clk_len)
.
I tried using both &&
and and
as the logic operator.
Why isnt this working?
Your first big problem is
@(expression)
means "wait until the expression has a value change". That change could be from 1➩0 or 0➩1. Typically one only usesalways @(posedge clk)
for synchronous logic, oralways @(*)
for combinational logic. (always_comb
in SystemVerilog)Your other problem is you should only be making assignments to a particular variable from one, and only one always block.