Incomplete assignment and latches

只愿长相守 提交于 2021-02-11 05:54:16

问题


When incompletely assigning a value I get a latch. But why did I get a latch in the example below? I think there is no need for the latch of F output because it is defined at all values of SEL.

Verilog code:

always @ (ENB or D or A or B pr SEL)
    if (ENB)
    begin 
        Q=D;
        if (SEL)
            F=A;
        else
            F=B;
    end

Inferred logic:

https://imgur.com/kLW4QGe


回答1:


Although it is defined at all values of SEL, it is not defined for all values of ENB. If ENB = 0, your code says that both Q and F should hold the value from the previous cycle. This is also what is inferred in the image you are linking: only update Q and F if ENB = 1.

If you want Q to be a latch and F not, you can do this:

always @ (ENB or D or A or B or SEL)
begin
    if (ENB)
        Q=D;

    if (SEL)
        F=A;
    else
        F=B;
end

Edit: additional information

As pointed out in the comments, I only showed how you could realize combinational logic and a latch, without modifying your code too much. There are, however, some things which could be done better. So, a non-TL;DR version:

  1. Although it is possible to put combinational logic and latches in one procedural block, it is better to split them into two blocks. You are designing two different kinds of hardware, so it is also better to seperate them in Verilog.
  2. Use nonblocking assignments instead of blocking assignments when modeling latches. Clifford E. Cummings wrote an excellent paper on the difference between blocking and nonblocking assignments and why it is important to know the difference. I am also going to use this paper as source here: Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!

    First, it is important to understand what a race condition in Verilog is (Cummings):

    A Verilog race condition occurs when two or more statements that are scheduled to execute in the same simulation time-step, would give different results when the order of statement execution is changed, as permitted by the IEEE Verilog Standard.

    Simply put: always blocks may be executed in an arbitrary order, which could cause race conditions and thus unexpected behaviour.

    To understand how to prevent this, it is important to understand the difference between blocking and nonblocking assignments. When you use a blocking assignment (=), the evaluation of the right-hand side (in your code A, B, and D) and assignment of the left-hand side (in your code Q and F) is done without interruption from any other Verilog statement (i.e., "it happens immediately"). When using a nonblocking assignment (<=), however, the left-hand side is only updated at the end of a timestep.

    As you can imagine, the latter assignment type helps to prevent race conditions, because you know for sure at what moment the left-hand side of your assignment will be updated.

    After an analysis of the matter, Cummings concludes, i.a., the following:

    Guideline #1: When modeling sequential logic, use nonblocking assignments.

    Guideline #2: When modeling latches, use nonblocking assignments.

    Guideline #3: When modeling combinational logic with an always block, use blocking assignments.

    A last point which I want to highlight from the aforementioned paper is the "why". Except from the fact that you are sure the right hardware is infered, it also helps when correlating pre-synthesis simulations with the the behaviour of your actual hardware:

    But why? In general, the answer is simulation related. Ignoring the above guidelines [about using blocking or nonblocking assignments on page 2 of the paper] can still infer the correct synthesized logic, but the pre-synthesis simulation might not match the behavior of the synthesized circuit.

  3. This last point is not possible if you want to strictly adhere to Verilog2001, but if you are free to choose your Verilog version, try to use always_combfor combinational logic and always_latch for latches. Both keywords automatically infer the sensitivity list, and it is easier for tools to find out if you actually coded up the logic you intended to design.

    Quoting from the SystemVerilog LRM:

    The always_latch construct is identical to the always_comb construct except that software tools should perform additional checks and warn if the behavior in an always_latch construct does not represent latched logic, whereas in an always_comb construct, tools should check and warn if the behavior does not represent combinational logic.

With these tips, your logic would look like this:

always_latch
begin
    if (ENB)
       Q <= D;
end

always_comb
begin
    if (SEL)
        F = A;
    else
        F = B;
end


来源:https://stackoverflow.com/questions/57650276/incomplete-assignment-and-latches

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!