3

Let's say I want to write a combinational module that uses 4 inputs and 3 outputs. To model my logic, I do something like this:

module ifelse (
      input wire a,
      input wire b,
      input wire c,
      input wire d,
      output reg y1,
      output reg y2,
      output reg y3
      );

     always @* begin

       if (a==1'b1 && b==1'b0) begin
         y1 = 1'b0;
         y3 = 1'b1;
         end
       else if (a==1'b0 && c==1'b1 && d==1'b0) begin
         y2 = 1'b1;
         y1 = 1'b1;
         end
       else if (a==1'b0 && c==1'b0) begin
         y3 = 1'b0;
         y2 = 1'b0;
       end
   end
endmodule

Ok, I'm aware that this code will infer latches for y1,y2 and y3, and the way to go to avoid this is to assign always a value to every LHS in every if-else block, like this:

module ifelse (
      input wire a,
      input wire b,
      input wire c,
      input wire d,
      output reg y1,
      output reg y2,
      output reg y3
      );

     always @* begin

       if (a==1'b1 && b==1'b0) begin
         y1 = 1'b0;
         y3 = 1'b1;
         y2 = 1'bx;
         end
       else if (a==1'b0 && c==1'b1 && d==1'b0) begin
         y2 = 1'b1;
         y1 = 1'b1;
         y3 = 1'bx;
         end
       else if (a==1'b0 && c==1'b0) begin
         y3 = 1'b0;
         y2 = 1'b0;
         y1 = 1'bx;
       end
       else begin
         y1 = 1'bx;
         y2 = 1'bx;
         y3 = 1'bx;
       end
   end
endmodule

But now, imagine that there are a lot of if-else blocks (I'm trying to describe the control unit for a didactic microprocessor) and that there are a lots of outputs coming from this module (the control lines for all the registers in the data path of the microprocessor). Having to assign a value to every output in every if-else block will surely lead to an unreadable and unmaintenable code, as every new output I include in this always, will have to be included in all if-else blocks.

Then, my question is: Do I have to explicity assign a value for all outputs I'm not using in a particular if-else block. Isn't there something like a "default value" for signals not updated in an combinational always block, so that after evaluating the always block, all unassigned outputs revert to a default value, or "dont care" value?

So far, I've come with this workaround, that seems to works:

module ifelse(
    input wire a,
    input wire b,
    input wire c,
    input wire d,
    output reg y1,
    output reg y2,
    output reg y3
    );

   always @* begin
      // default values
      y1 = 1'bx;
      y2 = 1'bx;
      y3 = 1'bx;

      if (a==1'b1 && b==1'b0) begin
         y1 = 1'b0;
         y3 = 1'b1;
      end
      else if (a==1'b0 && c==1'b1 && d==1'b0) begin
         y2 = 1'b1;
         y1 = 1'b1;
      end
      else if (a==1'b0 && c==1'b0) begin
         y3 = 1'b0;
         y2 = 1'b0;
      end
   end
endmodule

But I'd like something more elegant, much in the same way Verilog 2001 handles the sensitivity list for combinational always, something like this:

module ifelse(
    input wire a,
    input wire b,
    input wire c,
    input wire d,
    output reg y1,
    output reg y2,
    output reg y3
    );

   always @* begin
      if (a==1'b1 && b==1'b0) begin
         y1 = 1'b0;
         y3 = 1'b1;
      end
      else if (a==1'b0 && c==1'b1 && d==1'b0) begin
         y2 = 1'b1;
         y1 = 1'b1;
      end
      else if (a==1'b0 && c==1'b0) begin
         y3 = 1'b0;
         y2 = 1'b0;
      end
      @* = x;  // unassigned outputs receive a default value of "dont care"
   end
endmodule

So that if I modify this always in order to add a new output that is updated only in a few blocks, I don't have to include it as well in the "default" block, the same way I don't have to include it in the sensitivity list.

So, does such feature exist in Verilog? Is actually my workaround the way to do this, or is there a more elegant solution?

Thank you very much :)

mcleod_ideafix
  • 11,128
  • 2
  • 24
  • 32
  • Your workaround with the default values at the top of the block I believe is the correct solution. I'm not aware of any syntax that doesn't require you to explicitly assign a default value to each signal. – Tim Nov 20 '13 at 00:21

1 Answers1

6

The way to do this is to assign a default value to every reg just after the begin that starts the block, before the first if statement. You can't assign 1'bx to a signal if you intend to synthesize it...what kind of hardware would you expect to get? Remember that an x appearing on a signal is an unknown value, not a don't-care condition.

  • Oh! I then misread my Verilog manual: I thought that "x" standed for "don't care". I expect this to synthetize as a pure combinational module, and the "don't cares" are to help the synthesis tool to optimize logic. Actually, for the control unit, I don't want "don't cares", but "0's" in order to deactivate every control signal I'm not updating. – mcleod_ideafix Nov 20 '13 at 01:01
  • 2
    An `x` can be used as a "don't care" only in `if` and `case` statements. Assigning a value of `x` (unknown) to a reg or wire is syntactically correct but not synthesizable. –  Nov 20 '13 at 02:11