1

I'm new to Verilog. I tried the below code calling the 'task' into a if loop.. Syntax is correct. But when I execute behavioral simulation with choice as 010 the loop is not working. The output is shown all zeroes and the synthesis report shows latches are generated..How to fix these two.

module a(choice,data1,data2,result);
  input[2:0]choice;
  input[6:0]data1;
  input[8:0]data2;
  output[8:0]result;

  reg[8:0]reg_result;

  wire[3:0]choice;
  wire[6:0]data1;
  wire[8:0]data2;
  wire[8:0]result;

  initial///initailllllllllllllllllllllllllll
  begin
    reg_result=0; //declaring output register to 0 initially
  end

  always @(data1 or data2 or choice )
  begin
    if(choice==001)////if loop 1
    begin
      taskoperation(data1,reg_result);///load result from task 
    end
    if(choice==010)//when choice is given as 010 the simulated output gives me all    
    begin//zeroes in   result(output reg) 
      taskoperation(data2,reg_result);
    end
  end
  //task operation
  task taskoperation(
    input [8:0]datainput;
    output [8:0]dataoutput
  );
    dataoutput[8:0]=~(datainput[8:0]);//taskoperation
  endtask

  assign result=reg_result;

endmodule
Greg
  • 18,111
  • 5
  • 46
  • 68

3 Answers3

0

Latches

The latches are probably generated due to your use of 2 if statements as selectors. These should be case statements.

case (choice) 
 3'b001 : 
     begin
         taskoperation(data1,reg_result);
     end 
 3'b010 : 
     begin
         taskoperation(data2,reg_result);
     end
 default : $display("Error in choice");  //Know when there are other issues!
 endcase

Why is 010 not working?

See how in my case statement I use 3'b001 and 3'b010 to represent the cases? By including the size prefix 3 I indicate how many bits I need that bus to be. By including the b I indicate that I want my numbers to be interpreted as binary values. So 3'b001 is equivalent to the decimal value 1. Likewise 3'b010 is interpreted as 2. If I just write 010 without any prefix, the compiler thinks I am talking about a decimal value and interprets it as a 10 in decimal. That is where you were probably going wrong. The 010 case was simply never being reached. Moral of the story always write prefixes when coding in literals!

Notes

Note that if you do think if statements are the right tool for the job make sure to ALWAYS include an else block to avoid latch generation.

Literals: http://www.asic-world.com/verilog/syntax1.html

Another case reference: http://verilog.renerta.com/source/vrg00004.htm

And finally a beginners reference on why latches happen: http://www.asic-world.com/verilog/verifaq2.html

0

010 is inferred as a decimal, making it the value ten. Define it with Boolean base literal; 3'b010. you should also correct 001 to 3'b001.

The SystemVerilog follows the same rule. This is the definition from IEEE Std 1800-2012 § 5.7.1 Integer literal constants

Integer literal constants can be specified in decimal, hexadecimal, octal, or binary format.

There are two forms to express integer literal constants. The first form is a simple decimal number, which shall be specified as a sequence of digits 0 through 9, optionally starting with a plus or minus unary operator. The second form specifies a based literal constant, which shall be composed of up to three tokens—an optional size constant, an apostrophe character (', ASCII 0x27) followed by a base format character, and the digits representing the value of the number. It shall be legal to macro-substitute these three tokens.

The latch is being caused for two reasons:

  1. choice==010 means {29'b0,choice}==32'd10 which is never true and will be optimized out durring sunthesis.
  2. There is no else condition when choice is not 1 or 2. This means reg_result will keep its value. Since this in in combinatorial logic, a latch is inferred.

Turn if(choice==010) to else if(choice==2'b010) and add an else condition assigning reg_result a value.

Fix the syntax error: input [8:0]datainput; needs to be input [8:0]datainput, (semicolon to comma).


Other suggestions:

  • Use always @* instead of @(data1 or data2 or choice) unless you are required to follow strict Verilog95 standards. Using @* can help prevent inferred latches when the sensitivity list is long. Refer to What is inferred latch and how it is created when it is missing else statement in if condition.can anybody explain briefly?
  • Use functions instead of tasks whenever possible when intending to synthesize. Tasks allow time blocking which is not synthesizable.
  • Use ANSI style port declarations. Non-ANSI style is required only for Verilog95. Example:
    module a(
    input      [2:0] choice,
    input      [6:0] data1,
    input      [8:0] data2,
    output reg [8:0] result );

ANSI-style is supported from Verilog-2001.

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

Latches are generated any time you have a non-sequential block (any always block which does not have a @posedge or @negedge in the sensitivity list), and there is a possible code path in the RTL which results in a signal retaining its old value.

Example:

if (foo)
  bar = 1;
// no else

In this case, a latch will be inferred because if foo == 0 then bar will retain its value (it is stateful). To fix this, either use an else:

if (foo)
  bar = 1;
else
  bar = ~fred;

Or, if your decision tree is complicated, assign a default value and override it later:

bar = ~fred;
if (foo)
  bar = 1;

The latter is frequently used with state machines, where it can be difficult to make sure you have a full case/if/else tree for every signal.

Guy
  • 167
  • 9