# Verilog中的If语句导致锁存推断？[英] If statements causing latch inference in Verilog?

### 问题描述

```always@(b1 or b2)

.....
// b1_map,b2_map,m1_map & m2_map are derived from combinational functions using b1 & b2
.....

if(b1_map<=20 && m2_map<=20 && b1_map>=0 && m2_map>=0)

begin
accumulator1[b1_map][m2_map]= accumulator1[b1_map][m2_map] + 1;
end

if(b2_map<=20 && m2_map<=20 && b2_map>=0 && m2_map>=0)

begin
accumulator2[b2_map][m2_map]= accumulator2[b2_map][m2_map] + 1;
end

//accumulator1  & accumulator2 are 2d registers mapped like 2d arrays
```

## 推荐答案

```always @* begin
if (a) begin
b <= c & d;
e <= f;
end else begin
b <= c | d;
end
end
```

```always @(a) begin
if (a) begin
b <= c & d;
end else begin
b <= c | d;
end
end
```

## 其他推荐答案

if用其他语句完成，违约的案例卡斯塔内在设置明智的值(0)可以帮助避免这些意外闩锁.

### 问题描述

I am writing a Verilog code for synthesis of an algorithm, I am a little confused on what cases might cause latches to be inferred. Below is one such section of the code, though it works fine in simulation, I am worried it might cause problems on hardware.

```always@(b1 or b2)

.....
// b1_map,b2_map,m1_map & m2_map are derived from combinational functions using b1 & b2
.....

if(b1_map<=20 && m2_map<=20 && b1_map>=0 && m2_map>=0)

begin
accumulator1[b1_map][m2_map]= accumulator1[b1_map][m2_map] + 1;
end

if(b2_map<=20 && m2_map<=20 && b2_map>=0 && m2_map>=0)

begin
accumulator2[b2_map][m2_map]= accumulator2[b2_map][m2_map] + 1;
end

//accumulator1  & accumulator2 are 2d registers mapped like 2d arrays
```

So, In this case I want the data to be mapped only if it is in the specified limits. Will a latch be inferred because there is no "else" scenario defined? I didn't add an else statement because there is nothing I want to do with that data if it's not in the limits.

## 推荐答案

If you write your if statements correctly, you will be fine. Latches are generated when there are paths through the if statement that do not update one or more of the outputs. Code like the following will generate a latch:

```always @* begin
if (a) begin
b <= c & d;
e <= f;
end else begin
b <= c | d;
end
end
```

Notice that e is assigned only when a is true? This requires a latch to implement correctly.

Another posibility that will generate a latch is when the sensitivity list does not contain a signal used in the code.

```always @(a) begin
if (a) begin
b <= c & d;
end else begin
b <= c | d;
end
end
```

This code will generate latches on c and d or on b because it will only allow b to be updated when a changes.

## 其他推荐答案

You've misunderstood your problem (and you shouldn't have accepted an answer) - the issue isn't fundamentally related to 'latches'. Your code doesn't make sense (for synthesis). Quartus knows this, and it's basically telling you to rewrite your code.

You've got a combinatorial block that increments a number (immediately) when a signal changes. Two problems: (1) this is certainly not what you want in real hardware, and (2) the number must remain the same, and not increment, when b1 and b2 don't change. The second isue is the one Quartus is reporting - your circuit needs memory of some sort, which it's reporting as a 'latch'. It's not smart enough to report the first problem, which is the real issue.

Try to draw your circuit as a schematic with real hardware. What does 'any change on b1 or b2' actually mean? How are you going to maintain the value of the accumulators when b1 and b2 don't change? The circuit isn't impossible, but it's way beyond an SO question.

Make you circuit synchronous, triggering on a clock edge, with only a clock (and possibly a reset) in the sensitivity list, and keep the innards exactly the same. There's nothing wrong with your if statement, since you actually want the accumulator to remain unchanged if nothing interesting is happening on b1/b2.

## 其他推荐答案

Inferred latches can come from an incomplete sensitivity list or incomplete assignments.

Sensitivity lists for combinatorial blocks should generally be written with always @*. This avoid coding bugs when updating code. Combinatorial blocks (those not including an edge sensitivity) are once synthesised will perform in the manner of always @*. Specifically naming signals adds more work and will likely lead to RTL to gate level (post synthesis) errors.

Incomplete assignments which imply the value has to be held will infer a latch. Latches are not inherently bad but require careful consideration. Inferred one in this manner removes the thought fullness and control you would otherwise have over it. This can lead to complex timing issues. As the latch is level sensitive rather than edge sensitive. Ideally you want the latch to be open for the first have of the clock cycle so that it is closed when the data will be read from it. Inferred latches remove this control.

Completing if statements with an else, of default for case castanets which sets a sensible value (0's) can help avoid these accidental latches.