SystemVerilog: Source Order Execution

Here is a rule in SystemVerilog (SV) LRM that specifies how non-blocking statements in a begin-end block are executed. Consider the example shown below.

logic [3:0] y;
always @(posedge clock) begin
    if (reset) begin 
        y <= 4'd0;
     end else begin
         y <= 4'd1;  // line A
         y <= 4'd2;  // line B
         y <= 4'd3;  // line C
     end
end

It would appear that there are three conflicting assignments to ‘y’ on lines A, B and C. The SV LRM clearly defines the effect of these three assignments, with the “source order” rule: The last assignment on line C will override the earlier ones, and hence ‘y’ will be assigned the value 4’d3.

From the SV LRM:

Statements within a begin-end block shall be executed in the order in which they appear in that begin-end block.

This applies to both blocking and non-blocking assignments in a sequential block. The following example shows how this rule is useful to initialize variables.

logic error;
always @(posedge clock) begin
    if (reset) begin
        state <= RX;
        error <= 1'b0;  // clear at reset
    end else begin
        error <= 1'b0;  // clear error at the beginning of cycle
        case (state)
             RX: begin
                 if (rx_error) begin
                     error <= 1'b1;  // set error
                  end else begin
                     // RX logic code
                     state <= TX;
                  end
              end
              TX: begin
                  if (tx_error) begin
                      error <= 1'b1;  // set error
                   end else begin
                        // Rx logic code
                        state <= RX;
                   end
              end
           endcase
    end
end

Author: editor

Leave a Reply

Your email address will not be published. Required fields are marked *