Verilog and condition for Always block

2k Views Asked by At

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?

1

There are 1 best solutions below

0
On

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 uses always @(posedge clk) for synchronous logic, or always @(*) 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.