Verilog Conditional Operator
Just what the heck is that question mark doing?
Have you ever come across a strange looking piece of Verilog code that has a question mark in the middle of it? A question mark in the middle of a line of code looks so bizarre; they’re supposed to go at the end of sentences! However in Verilog the ? operator is a very useful one, but it does take a bit of getting used to.
The question mark is known in Verilog as a conditional operator though in other programming languages it also is referred to as a ternary operator, an inline if, or a ternary if. It is used as a short-hand way to write a conditional expression in Verilog (rather than using if/else statements). Let’s look at how it is used:
Here, condition is the check that the code is performing. This condition might be things like, “Is the value in A greater than the value in B?” or “Is A=1?”. Depending on if this condition evaluates to true, the first expression is chosen. If the condition evaluates to false, the part after the colon is chosen. I wrote an example of this. The code below is really elegant stuff. The way I look at the question mark operator is I say to myself, “Tell me about the value in r_Check. If it’s true, then return “HI THERE” if it’s false, then return “POTATO”. You can also use the conditional operator to assign signals, as shown with the signal w_Test1 in the example below. Assigning signals with the conditional operator is useful!
module test2;
reg r_Check = 1'b1;
wire w_Test1;
assign w_Test1 = r_Check ? 1'b1 : 1'b0;
initial begin
#1;
$display("OUTPUT: %s", r_Check ? "HI THERE" : "POTATO");
$display("Value of w_Test1: %b", w_Test1);
$display("%h", (10 > 5) ? 16'hABCD : 16'h1234);
$display("%s", (1 == 1) ? "YES, ONE EQUALS ONE" : "HOW DID YOU GET HERE");
end
endmodule // test2
# OUTPUT: HI THERE # Value of w_Test1: 1 # abcd # YES, ONE EQUALS ONE
Nested Conditional Operators
There are examples in which it might be useful to combine two or more conditional operators in a single assignment. Consider the truth table below. The truth table shows a 2-input truth table. You need to know the value of both r_Sel[1] and r_Sel[0] to determine the value of the output w_Out. This could be achieved with a bunch of if-else if-else if combinations, or a case statement, but it’s much cleaner and simpler to use the conditional operator to achieve the same goal.
| r_Sel[1] | r_Sel[0] | Output w_Out |
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
module test3;
reg [1:0] r_Sel;
wire w_Out;
assign w_Out = r_Sel[1] ? (r_Sel[0] ? 1'b0 : 1'b1) :
(r_Sel[0] ? 1'b1 : 1'b1);
initial begin
r_Sel = 2'b00;
#1; $display("w_Out = %b", w_Out);
r_Sel = 2'b01;
#1; $display("w_Out = %b", w_Out);
r_Sel = 2'b10;
#1; $display("w_Out = %b", w_Out);
r_Sel = 2'b11;
#1; $display("w_Out = %b", w_Out);
end
endmodule // test3
# w_Out = 1 # w_Out = 1 # w_Out = 1 # w_Out = 0



The input “r_Sel” must be reg type? Could it be wire type?