“Multiple Constant Drivers” Error Verilog with Qua

2019-09-14 00:57发布

问题:

I am working on designing a finite state machine in Verilog to represent a stack. The module is as follows:

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err);
input [2:0] s;
input Enable, Clock, Resetn;
output reg [1:0] c;
output reg OF_Err = 0, UF_Err = 0;
reg [2:0] y, Y;
parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100;

always @(s, y, Enable)
    if (Enable)
        begin
            case (y)
                A: if (s == 3'b000) Y = B;
                    else
                        begin
                            Y = A;
                            UF_Err = 1;
                        end

                B: if (s == 3'b000) Y = C;
                    else if (s == 3'b001) Y = A;
                    else
                        begin
                            Y = B;
                            UF_Err = 1;
                        end

                C: if (s == 3'b000) Y = D;
                    else if (s == 3'b100) Y = C;
                    else Y = B;

                D: if (s == 3'b000) Y = E;
                    else if (s == 3'b100) Y = D;
                    else Y = C;

                E: if (s == 3'b000)
                        begin
                            Y = E;
                            OF_Err = 1;
                        end
                    else if (s == 3'b100) Y = E;
                    else Y = D;

                default: Y = 3'bxxx;
            endcase

            c[1] = y[1];
            c[0] = y[0];
        end

always @(negedge Resetn, posedge Clock)
    begin
        if (Resetn == 0)
            begin
                y <= A;
                OF_Err = 0; //Problem
                UF_Err = 0; //Problem
            end
        else y <= Y;
    end

OF_Err and UF_Err are indicators of overflow and underflow errors, respectively.

However, I get the following errors when compiling my project:

Error (10028): Can't resolve multiple constant drivers for net "OF_Err" at state_machine.v(59) Error (10029): Constant driver at state_machine.v(10) Error (10028): Can't resolve multiple constant drivers for net "UF_Err" at state_machine.v(59)

These only appeared after I added the commented lines. I want to reset the over- and underflow indicators when the FSM is reset, but I can't do it the way I have it. How do I go about doing this?

(If it's of any value, this is to be executed on an Altera DE2-115).

回答1:

As others have already pointed out, OF_Err and UF_Err were driver by two always blocks which is illegal for synthesis. I recommend creating two additional variables of_Err and uf_Err like Arvind suggested. However I recommend keeping OF_Err and UF_Err as flops.

The if (Enable) in the combinational block infers Y,c and the *_Err as level-sensitive latches. I highly doubt this is what you intendeds. I recommend moving the if (Enable) into synchronous always block and keeping the combinational logic as pure combinational.

c is a simple assignment, so it might make more sense having it as a wire instead of a reg with a simple assign statement. It can be in the combinational block, but I prefer to separate combinational input from output.

You did use @(s, y, Enable) correctly, however @* or the synonymous @(*) is recommenced for combinational block. @* is an auto sensitivity list which saves you typing, maintenance, and removes the risk of forgetting a signal.

always @*
begin
  of_Err = OF_Err; // <-- default values
  uf_Err = UF_Err;

  case (y)
    // ... your original case code with OF_Err/UF_Err renamed to of_Err/uf_Err
  endcase
end

always @(posedge Clock, negedge Resetn) // style difference, I prefer the clock to be first
begin
  if (Resetn == 1'b0)
  begin
    y <= A;
    OF_Err <= 1'b0;
    UF_Err <= 1'b0;
  end
  else if (Enable)
  begin
    y <= Y;
    OF_Err <= of_Err;
    UF_Err <= uf_Err;
  end
end
assign c[1:0] = y[1:0];


回答2:

In two always blocks you have assigned the values to OF_Err and UF_Err. This is the reason it is showing multiple constant driver error.

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err);
   input [2:0] s;
   input Enable, Clock, Resetn;
   output reg [1:0] c;
   output OF_Err, UF_Err;         //modified
   reg [2:0] y, Y;
   reg of_Err, uf_Err;              //added
   parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E =3'b100;

   always @*
   begin
        if (Enable)
        begin
            case (y)
                A: if (s == 3'b000)
                       Y = B;
                   else
                   begin
                       Y = A;
                       uf_Err = 1;      //modified
                   end

               B: if (s == 3'b000)
                    Y = C;
                  else if (s == 3'b001)
                    Y = A;
                  else
                  begin
                    Y = B;
                    uf_Err = 1;     //modified
                  end

            C: if (s == 3'b000)
                    Y = D;
                else if (s == 3'b100)
                    Y = C;
                else 
                    Y = B;

            D: if (s == 3'b000) 
                Y = E;
                else if (s == 3'b100) 
                    Y = D;
                else Y = C;

            E: if (s == 3'b000)
                    begin
                        Y = E;
                        of_Err = 1;         //modified
                    end
                else if (s == 3'b100) Y = E;
                else Y = D;

            default: Y = 3'bxxx;
        endcase

        c[1] = y[1];
        c[0] = y[0];
    end
       else
       begin
    //write the condition if the Enable signal is not high.I guess you're trying to synthesize
       end

   end

always @(negedge Resetn, posedge Clock)
begin
    if (Resetn == 0)
        begin
            y <= A;
        //    OF_Err = 0; //Problem
        //    UF_Err = 0; //Problem
        end
    else y <= Y;
end

assign OF_Err = !Resetn? of_Err : 1'b0;     //added
assign UF_Err = !Resetn? uf_Err : 1'b0;     //added

 endmodule


回答3:

Because OF_Err and UF_ERR are driven by multiple always blocks.

A reg should be driven by only one always block. And if it is having multiple drivers by design, then it should be a wire.

Here is your modified code.

module state_machine (s, Enable, Clock, Resetn, c, OF_Err, UF_Err);
input [2:0] s;
input Enable, Clock, Resetn;
output reg [1:0] c;
output reg OF_Err = 0, UF_Err = 0;
reg [2:0] y, Y;
parameter [2:0] A = 3'b000, B = 3'b001, C = 3'b010, D = 3'b011, E = 3'b100;

always @(s, y, Enable, negedge reset)
begin
  if (!reset)
  begin
    OF_Err = 0; //Problem
    UF_Err = 0; //Problem
  end
  else 
  begin 
    if (Enable)
    begin
      case (y)
      A: if (s == 3'b000) Y = B;
         else
         begin
           Y = A;
           UF_Err = 1;
         end
      B: if (s == 3'b000) Y = C;
         else if (s == 3'b001) Y = A;
         else
         begin
           Y = B;
           UF_Err = 1;
         end
      C: if (s == 3'b000) Y = D;
         else if (s == 3'b100) Y = C;
         else Y = B;
      D: if (s == 3'b000) Y = E;
         else if (s == 3'b100) Y = D;
         else Y = C;
      E: if (s == 3'b000)
         begin
           Y = E;
           OF_Err = 1;
         end
         else if (s == 3'b100) Y = E;
         else Y = D;
      default: Y = 3'bxxx;
      endcase

      c[1] = y[1];
      c[0] = y[0];
    end
  end 
end

always @(negedge Resetn, posedge Clock)
begin
  if(Resetn == 0)
    y <= A;
  else 
    y <= Y;
end


标签: verilog