Reputation: 11418
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 :)
Upvotes: 3
Views: 9001
Reputation:
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.
Upvotes: 6