Verilog/SystemVerilog inferred latch in case state

2019-07-27 06:46发布

问题:

I am having trouble understanding why my code have a latch

logic [1:0] lru_list [0:3];

always_comb begin
    if(reset) begin
        lru_list[0] = 0;
        lru_list[1] = 0;
        lru_list[2] = 0;
        lru_list[3] = 0;
    end
    else begin
        case({access, update, access_index_i < 4})
            3'b101: begin
                lru_list[0] = lru_list[0] + 1;
                lru_list[1] = lru_list[1] + 1;
                lru_list[2] = lru_list[2] + 1;
                lru_list[3] = lru_list[3] + 1;
                lru_list[access_index_i] = 0;
            end
            3'b011: begin
                lru_list[0] = lru_list[0];
                lru_list[1] = lru_list[1];
                lru_list[2] = lru_list[2];
                lru_list[3] = lru_list[3];
                lru_list[access_index_i] = 0;
            end
            default: begin
                lru_list[0] = lru_list[0];
                lru_list[1] = lru_list[1];
                lru_list[2] = lru_list[2];
                lru_list[3] = lru_list[3];
            end
        endcase
    end

end // always_comb

In the case statement, I have a default case which will catch all the unmatched values. I have also set each index in the array a value. I don't understand where I am implicitly setting my array a implicit value.

I thought it might have to do with lru_list[access_index_i] = 0;, but commenting those two lines out will still give me the save error.

回答1:

Here is what I would start with.
First add a sensitivity list to the always statement. You have a "reset" if in there so it sounds like you want the always @ (posedge clk or posedge reset). I know you are using always_comb, but I would be curious to know if that actually does remove the issue or not. It would be telling.

EDIT: So I just realized you are doing operations on the LHS variables using the same variables on the RHS. You need to clock this. Otherwise when you combinatorially enter the counting state, it can never resolve as it is always adding in an infinite loop. Do the always @ (posedge clk or posedge reset) and you will get better results I think.

Second, and probably more important, it looks like you are using access_index_i < 4 and trying to extract a bit from it to make up the least significant bit of your concatenated vector {access, update, access_index_i < 4}. If you are shifting to the right, I think the logic would insert 4'b0000 in the result and I am guessing it is not really a bit to begin with, so I am wondering what bit actually gets used during the 3'b101 case as it would be addressed by {bit,bit,vector}. Seems like you would want to say {bit,bit,vector[4]} or something to that effect. You might actually be using the least significant 3 bits of the your access_index_i to address your combinational statement.

EDIT: Responding to your comment below. You can, (And this is what I do) break the problem into two parts, the combinatorial and the clocked.

reg [3:0] my_sig;
wire [3:0] my_sig_wire;

always @ (posedge clk)
begin
    my_sig <= my_sig_wire;
end

always (*)
   begin
     if(reset)
       begin 
        my_sig_wire = 4'b0000;  // This will also reset the clocked version
       end
     else
        begin
        my_sig_wire = my_sig;  // This is okay, because no matter
                               // how much I alter my_sig_wire, my_sig will
                               // only change on the clock pulse.  So
                               // we avoid the infinite loop problem
        my_sig_wire[index] = 1'b0;  //  Tweak one of the signals for fun.
                                    //  on the next clock, my_sig is updated!
        end
    end


回答2:

Combinatorial blocks define there output purely based on inputs, there is no state.

Sequential elements (flip-flops) contain state and therefore outputs can be based on inputs and state, or just state.

Your default statement:

default: begin
            lru_list[0] = lru_list[0];

Is maintaining state by holding a value and therefore can not be combinatorial. You have not defined a flip-flop (@(posedge clk)) so a latch has been inferred to hold the state.