Search code examples
verilogxilinx-ise

Mix of blocking and non-blocking assignments error


I'm getting this error in my code about blocking and non-blocking assignments. I put initially had some blocking assignments done on initialization but moved them to the initial section. I'm still encountering the issue though, and don't know what else to change. Any help addressing it would be much appreciated.

It's my first time using Verilog for an individual project so if you see any beginner mistakes, I would love to learn.

Error:

Line 89: Mix of blocking and non-blocking assignments to variable is not a recommended coding practice.

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    13:21:27 09/10/2021 
// Design Name: 
// Module Name:    avg_small 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////

module mux8(
    data0,
    data1,
    data2,
    data3,
     data4,
     data5,
     data6,
     data7,
    select,
    data_output
);

  parameter WIDTH = 8;

  input [WIDTH-1:0] data0;
  input [WIDTH-1:0] data1;
  input [WIDTH-1:0] data2;
  input [WIDTH-1:0] data3;
  input [WIDTH-1:0] data4;
  input [WIDTH-1:0] data5;
  input [WIDTH-1:0] data6;
  input [WIDTH-1:0] data7;
  input [2:0] select;
  output [WIDTH-1:0] data_output;

reg [WIDTH-1:0] data_bus ;
  always @ (*) begin
    case (select)
      0: data_bus <= data0 ;
      1: data_bus <= data1 ;
      2: data_bus <= data2 ;
      3: data_bus <= data3 ;
        4: data_bus <= data4 ;
        5: data_bus <= data5 ;
        6: data_bus <= data6 ;
        7: data_bus <= data7 ;
    endcase
  end
  assign data_output = data_bus ;
endmodule


module add_8_10_10(ctrl,a,b,out);
    input [2:0] ctrl;
    input [7:0] a;
    input [10:0] b;
    output [10:0] out;
    
    reg [10:0] out_hold; // can this just be out as a reg/ can out be a reg?
    
    always @(ctrl) begin
        out_hold <= a+b;
        end
        assign out = out_hold;
        
endmodule


module avg_small(
    input clk,
    input rs,
    output [7:0] ave8,
    input  [7:0] num_in
    );
     
     reg [7:0] registers [7:0] ;
     reg [2:0] state;
     reg [2:0] next_state;
     reg [10:0] temp_sum;
     reg [7:0] output_register;
     
     wire [7:0] a;
     wire [10:0] b;
     wire [10:0] c;
     wire [10:0] add_wire;
     
     mux8 muxy(    
     .data0(registers[0]),
    .data1(registers[1]),
    .data2(registers[2]),
    .data3(registers[3]),
     .data4(registers[4]),
     .data5(registers[5]),
     .data6(registers[6]),
     .data7(num_in),
    .select(state),
    .data_output(a)
);
     
     add_8_10_10 add(
        .ctrl(state),
       .a(a),
        .b(temp_sum),
        .out(add_wire)
     );
     
     
     initial begin
         next_state <= 3'd0;
         temp_sum <= 11'd0;
         output_register <= 7'd0;
     
         registers[0] <= 0;
         registers[1] <= 0;
         registers[2] <= 0;
         registers[3] <= 0;
         registers[4] <= 0;
         registers[5] <= 0;
         registers[6] <= 0;
         registers[7] <= 0;
         state=0;
     end
     
     
     
     always@(posedge clk) begin
        if(rs) begin
                state <= 0;
                //TODO -- clear registers
        end else begin
     
            case(state)
            0:begin
                registers[0] <= registers[1];
                state = #50 1;
            end
            1:begin
                registers[1] <= registers[2];
                #50;
                state <= 2;
            end
            2:begin
                registers[2] <= registers[3];
                #50;
                state = 3;
            end
            3:begin
                registers[3] <= registers[4];
                #50;
                state = 4;
            end
            4:begin
                registers[4] <= registers[5];
                #50;
                state = 5;
            end
            5:begin
                registers[5] <= registers[6];
                #50;
                state = 6;
            end
            6:begin
                registers[6] <= registers[7];   
                #50;
                state = 7;
            end
            7:begin
                registers[7] <= num_in;
                output_register <= add_wire;
                #50;
                state = 0;
            end
         
         endcase
         end
     end
     assign ave8 = output_register;
     
endmodule
     

Solution

  • This is line 89:

     reg [2:0] state;
    

    The message is telling you that you are making two types of assignments to the state signal.

    Line 140 is a nonblocking assignment because it uses <=:

                state <= 0;
    

    Line 147 is a blocking assignment because it uses =:

                state = #50 1;
    

    The recommended coding practice is to choose one or the other. In this case, since state is assigned inside a sequential logic always block, you should use nonblocking for all assignments to state. It is sequential because it is sensitive to an edge of a clock signal:

     always@(posedge clk) begin
    

    You should avoid adding delays to state as well. So, this line should be changed from:

                state = #50 1;
    

    to:

                state <= 1;
    

    You should delete the assignment to state from the initial block. The recommended coding practice is to make all assignments to a signal within a single block.

    All of this advice applies to your other reg signals as well, such as registers. It would be better to keep these in the always block, which is what it sounds like you had done originally.


    For the rest of your code, you should use blocking assignments since you have no other sequential always blocks.

    For a rigorous review of your code in the future, you can post at Code Review. But, your code must be working code with no error messages.