-1

I've been trying to implement a simple verilog program, but I consistently keep running into two error's and I can seem to find the solution. The two errors I'm receiving are:

1. Line 21: Empty module <AddOrSubtractThenSelectAndDecodedInto7SegmentsDisplay> remains a black box. 

2. Line 40: Signal Result[3] in unit AddOrSubtractThenSelectAndDecodedInto7SegmentsDisplay is connected to following multiple drivers:

Driver 0: output signal Result[3] of instance Latch (Result[3]).
Driver 1: output signal Result[3] of instance Latch (_i000011).
Driver 0: output signal Result[2] of instance Latch (Result[2]).
Driver 1: output signal Result[2] of instance Latch (_i000012).
Driver 0: output signal Result[1] of instance Latch (Result[1]).
Driver 1: output signal Result[1] of instance Latch (_i000013).
Driver 0: output signal Result[0] of instance Latch (Result[0]).
Driver 1: output signal Result[0] of instance Latch (_i000014).
Module AddOrSubtractThenSelectAndDecodedInto7SegmentsDisplay remains a blackbox, due to errors in its contents

I've attempted to find the solution prior to asking, but can't find the proper solution for my question. So my question is: Why is this happening and what is the best solution to solve this?

Here's my verilog code (without test bench):

module AddOrSubtractThenSelectAndDecodedInto7SegmentsDisplay(A,B,S,Result,OF,Display);

// Inputs A,B,S
input [3:0] A;
input [3:0] B;
input [1:0] S;

// Outputs OF,Result,Display
output reg [6:0] Display;
output reg [3:0] Result;
output reg OF;

reg [3:0] Result_reg;

// Wires
wire [3:0] A;
wire [3:0] B;
wire [1:0] S;

always @(A,B,S) begin
    if (S == 1)
        {OF,Result} = A + B;
    else if (S == 0)
        {OF,Result} = A - B;
end 

always @(OF,Result) begin
    case (Result) 
        5'b00000: Display = 7'b1111110;//0
        5'b00001: Display = 7'b0110000;//1
        5'b00010: Display = 7'b1101101;//2
        5'b00011: Display = 7'b1111001;//3
        5'b00100: Display = 7'b0110011;//4
        5'b00101: Display = 7'b1011011;//5
        5'b00110: Display = 7'b1011111;//6
        5'b00111: Display = 7'b1110000;//7
        5'b01000: Display = 7'b1111111;//8
        5'b01001: Display = 7'b1111011;//9
        5'b01010: Display = 7'b1110111;//A
        5'b01011: Display = 7'b0011111;//B
        5'b01100: Display = 7'b1001110;//C
        5'b01101: Display = 7'b0111101;//D
        5'b01110: Display = 7'b1001111;//E
        5'b01111: Display = 7'b1000111;//F
        default: Display = 7'bx;
    endcase

     if (OF == 1)begin
        Result = 4'bx;
        Display = 7'b0011101;
    end

end

endmodule
mur7ay
  • 803
  • 3
  • 16
  • 44

2 Answers2

2

You are inferring a latch here:

always @(A,B,S) begin
    if (S == 1)
        {OF,Result} = A + B;
    else if (S == 0)
        {OF,Result} = A - B;
    // <-- inferred latch because S=2 and S=3 is not described
end 

Generally (level sencitive) latches are not recommend. They have value, but you need to be carful with them or you get timing and metastability issues. For more see

The second driver is because you are driving Result in two always blocks. It works in simulator, but is illegal for synthesis.

always @(OF,Result) begin
  // ...

  if (OF == 1)begin
    Result = 4'bx; // <-- second driver on 'Result'. Illegal for synthesis
    Display = 7'b0011101;
  end
end

Note: It is usually considered bad practice to assign something you plan to synthesize to a value to X.

To resolve the multiple driver error, you have to have all the assigments to Result in the same always block. Either move the assignment or merge the always blocks.

Note: Unless are required to follow strict 1995 coding practices, you should not declare the signals in the sensitivity list. Instead use auto-sensitivity list (@* or @(*)) added to verilog in 2001. You have 2001 support because 1995 does not support commas as a signal separator for sensitivity list; 1995 uses or as the signal separator for sensitivity list.

Community
  • 1
  • 1
Greg
  • 18,111
  • 5
  • 46
  • 68
0

I have already written an answer for the same question. You can check in the link : Verilog Subtraction and addition

You have inferred Latch, because you have taken "S" of 2 bits wide and you have not specified the value of "Result" for 2 options of the "S".

Incomplete if or case statement can potentially be synthesized into a latch. Because for tool, you didn't specify, what to drive on a net for rest of the if/case condition. In this case, tool will try to make a hardware, which will drive the previous values for those conditions. And to do so, a Latch will be inferred.

always @(A,B,S) begin
    if (S == 1)
        {OF,Result} = A + B;
    else if (S == 0)
        {OF,Result} = A - B;
    // What for S == 2 or S == 3?
    // So tool thinks, that you want to have previous value of Result
    // in both cases, and hence it needs to infer a latch for Result to
    // have the previous value.
end 

Now, you are getting multiple driver error, because "Result" is being driven through multiple always blocks.

A "reg" variable, can't have multiple drivers. But a "wire" can certainly have. So, if a net has multiple drivers, then it has to be of "wire" type.

Community
  • 1
  • 1
Karan Shah
  • 1,912
  • 1
  • 29
  • 42