I've seen Verilog code where the bitwise or operator ("|") is used monadic. What's the purpose?
For example
| address[15:14]==0
or
|address[15:14]? io_din : ramrd
Cann't we omit the "|" in these cases?
In this case it acts as a reduction operator, for example:
|4'b1000 => 1'b1 (OR)
&4'b1000 => 1'b0 (AND)
^4'b1000 => 1'b1 (XOR)
|4'b0000 => 1'b0
&4'b1111 => 1'b1
^4'b1111 => 1'b0
ORing the entire bus to a 1 bit value, or applying an AND/XOR to the entire bus.
This is referred to as a 'unary' operator as it only take a right hand argument. They are covered in Section 11.4.9 of SystemVerilog IEEE1800-2012.
|address[15:14]? io_din : ramrd
is the shortcut for writing
(address[15] | address[14]) ? io_din : ramrd
i.e bitwise ORing of all bits of the bus together to generate a 1bit value.
In this case it will evaluate as HIGH if either(or both) bit 15 OR bit 14 is HIGH.
similarly you can write other bitwise operators
&address[15:14]? io_din : ramrd // ANDing
^address[15:14]? io_din : ramrd // XORing
In the examples provided, the code with | is functionally equivalent to the same coded with the | omitted. Three possible reason to have and keep the | for the provided code are:
It gives guidance to the synthesizer: first OR the address bits then compare to 0, instead of comparing each address bit to 0 then ANDing the results. It is the same functional result with different gate configurations.
It following a coding style or formatting style requirement.
It just read better (visually/structurally appealing) because there is a |address[15:14]==1 on a near by line of code to |address[15:14]==0. (Reminder: |address[15:14]==1 is not the same as address[15:14]==1)
On the specific question of whether the '|' can be omitted in these cases:
Whether |address[15:14] and address[15:14] are identical depends on the context (in general, they aren't, because unknowns are handled differently). Your first example compared to 0, and it's true that the | can be dropped in this particular case, but it wouldn't be true if you compared to anything other than 0.
Your second example is trickier. The LRM doesn't appear to specify how the first expression in a ternary is evaluated. I know of 2 sims that evaluate it as a reduction-OR, so the | can be dropped in those cases. However, if a sim instead evaluates it in the same way as an if (ie if(address[15:14])) then the | is required.
Synthesis is simpler, of course, since the synthesiser doesn't have to worry about unknowns.
Related
Consider the following assignment
A1 = (b[3:0] ==c[3:0] & d[3:0]==e[3:0]) ? 1'b1 : 1'b0 ;
A2 = (b[3:0] ==c[3:0] && d[3:0]==e[3:0]) ? 1'b1 : 1'b0 ;
Are the 2 assignments equivalent or they could be different depending on tools?
Is it possible that (b[3:0] ==c[3:0]) evaluated as T/F is dependent on tool Whether it stores T as '1' or '0'.
The result of the equality, relational and logical operators are defined in sections 11.4.4-7 of the IEEE 1800-2017 LRM. There is no room for implementation differences. Truth is defined as 1'b1, and false is defined as 1'b0.
Note there are slight differences in precedence between the logical and bitwise operators, and it's easy to mix them up when you start dealing with multiple bit results, so use the bitwise operators only if your intent is to deal with multi-bit results.
I'm currently reading through John C. Mitchell's Foundations for Programming Languages. Exercise 2.2.3, in essence, asks the reader to show that the (natural-number) exponentiation function cannot be implicitly defined via an expression in a small language. The language consists of natural numbers and addition on said numbers (as well as boolean values, a natural-number equality predicate, & ternary conditionals). There are no loops, recursive constructs, or fixed-point combinators. Here is the precise syntax:
<bool_exp> ::= <bool_var> | true | false | Eq? <nat_exp> <nat_exp> |
if <bool_exp> then <bool_exp> else <bool_exp>
<nat_exp> ::= <nat_var> | 0 | 1 | 2 | … | <nat_exp> + <nat_exp> |
if <bool_exp> then <nat_exp> else <nat_exp>
Again, the object is to show that the exponentiation function n^m cannot be implicitly defined via an expression in this language.
Intuitively, I'm willing to accept this. If we think of exponentiation as repeated multiplication, it seems like we "just can't" express that with this language. But how does one formally prove this? More broadly, how do you prove that an expression from one language cannot be expressed in another?
Here's a simple way to think about it: the expression has a fixed, finite size, and the only arithmetic operation it can do to produce numbers not written as literals or provided as the values of variables is addition. So the largest number it can possibly produce is limited by the number of additions plus 1, multiplied by the largest number involved in the expression.
So, given a proposed expression, let k be the number of additions in it, let c be the largest literal (or 1 if there is none) and choose m and n such that n^m > (k+1)*max(m,n,c). Then the result of the expression for that input cannot be the correct one.
Note that this proof relies on the language allowing arbitrarily large numbers, as noted in the other answer.
No solution, only hints:
First, let me point out that if there are finitely many numbers in the language, then exponentiation is definable as an expression. (You'd have to define what it should produce when the true result is unrepresentable, eg wraparound.) Think about why.
Hint: Imagine that there are only two numbers, 0 and 1. Can you write an expression involving m and n whose result is n^m? What if there were three numbers: 0, 1, and 2? What if there were four? And so on...
Why don't any of those solutions work? Let's index them and call the solution for {0,1} partial_solution_1, the solution for {0,1,2} partial_solution_2, and so on. Why isn't partial_solution_n a solution for the set of all natural numbers?
Maybe you can generalize that somehow with some metric f : Expression -> Nat so that every expression expr with f(expr) < n is wrong somehow...
You may find some inspiration from the strategy of Euclid's proof that there are infinitely many primes.
Our professor gave us this skeleton for a case statement, and so far no one is able to understand what it's doing.
always#(*)
begin
case(state)
3'b000:{nout, nstate} = (in)?(in=1):(in=0)
endcase
end
More insight:
This is being implemented as a button debouncer.
nout is the output of the next state: a single bit
nstate is the next state: 3 bits
in is also 1 bit wide
My understanding is that the concatenation operator will append nout to nstate resulting in 4 bits. (ie: if nout is 1 and nstate is 010, this part of the statement will produce 1010)
On the other side of the equality assignment we have a simple comparator, which upon further inspection, doesn't seem to do anything...
It's basically saying
if(in == 1) {
in = 1;
} else {
in = 0;
}
With that understanding, we're assigning a single bit to nout and nstate?
This understanding doesn't make any sense to me. I've compared my notes with 2 other classmates whom wrote the exact same thing so I'm thinking either we don't understand the code or there's an error.
Further insight:
Upon researching further, I've found the state diagram appear in multiple places, which makes me fairly confident that this is a common Moore Machine.
i hope that you did not cut and paste those expressions correctly.
3'b000:{nout, nstate} = (in)?(in=1):(in=0);
The above statement is a complete mess. Most likely it will fail any linting. It might be ok syntactically, but makes no sense logically and makes such code unreadable and not maintainable. It has to look like the following:
3'b000:{nout, nstate} = (in)?(1'b1):(1'b0);
The left hand side concat represents a signal with lower 3 bit associated with nstate, and upper n bits with nout. The right hand side ternary operator produces either one bit '1' or 1 bit '0' (actually id does the same int the original expression, because 'in' is 1 bit wide. Verilog will extend the rhs one bit to the size of the lhs and add missing '0's. As a result nout will be 0 and nstate will be either 3'b000 or 3'b001, depending on the value of in.
This discussion of Verilog relational operators at ASIC World clearly has at least one mistake:
The result is a scalar value (example a < b)
0 if the relation is false (a is bigger then b)
1 if the relation is true (a is smaller then b)
x if any of the operands has unknown x bits (if a or b contains X)
Note: If any operand is x or z, then the result of that test is
treated as false (0)
Clearly, "a is bigger than b" should be "a is bigger than or equal to b".
There is something else that looks wrong to me, but I don't know if it's just because I'm a Verilog novice. The last bullet point seems to contradict the subsequent note, unless there is a difference between an operand having all unknown bits (in which case the result of a relational operator will be x) and an operand being x (in which case the result will be 0).
Is there a difference between an operand being x and all of its bits being X? I know Verilog is case-sensitive.
verilog is known for its x-propagation pessimism.
From lrm 11.4.4
An expression using these relational operators shall yield the scalar value 0 if the specified relation is false
or the value 1 if it is true. If either operand of a relational operator contains an unknown (x) or highimpedance
(z) value, then the result shall be a 1-bit unknown value (x).
so, if any of the values contains 'x' bits the result will be 'x'.
Now in case, when the result is used as a conditional expression, the if statement will take true brunch if and only if the result is '1'. Otherwise it will take the false branch. Also, there are conversion rules in verilog, where x and z values are converted to 0 in binary operations, which conditional operation is.
so, the comment on the site is correct, it is talking of the results of a test (as in if statement)
If any operand is x or z, then the result of that test is treated as false (0)
I think you should take your comments to the author of that website.
I take the statement inside the ()'s to be an example
1 if the relation is true (if for example, a is smaller then b)
The subsequent note refers to a more general issue not specific to relational operators. When you have
if (expression) true_statement; else false_statement;
When expression evaluates to an X or 0, the false_statement branch is taken.
Also, Verilog is not case sensitive about numeric literals. 'habcxz and 'hABCXZ are equivalent.
Say I have a scenario in which I need to compare only a few bits of a register and I don't care about other bits. eq, I need to check the first and last bits of a 3 bit register (A[2:0]) and I don't care about the middle bit, say compare vector is 3'b1X0 (Parameter).
Simplest way to do this is choose all the bits I care about, AND them and I have generated a control signal:
if ((A[2]==1) & ((A[0]==0)) Here the condition inside if statement is my control signal.
Another way is to use a casex statement: casex(A) begin 3'b1?0: ... , ... endcase.
Is there anything like ifx-elsex statement or something that can be used to do this kind of operation without using the 1st and 2nd method?
Thanks!
if (A[2:0] inside {3'b1?0} )
SystemVerilog keyword inside. It has been supported since at least Accellera's SystemVerilog 3.1 (before SystemVerilog was a part of IEEE). IEEE Std 1800-2012 11.4.13 has examples of use. inside is synthesizable.
There is also if ( A[2:0] ==? 3'b1?0 ) (IEEE Std 1800-2012 11.4.6). The only reference I have on hand (a book published 2004) says it is not supported for synthesis yet. You are welcome to try it.
(A[2]==1) is a logical expression the & is a bitwise operator, although either works it would be better semantics to use the && logical and operator. This is slightly different to most other languages where the && is a short-circuit operator.
Logically what you want is if ((A[2]==1) && ((A[0]==0)) but it could be reduced to a bitwise expression :
if ( ~A[0] & A[2] )
NB: Try to avoid using casex, the unknown parts will match x's in simulation. Try to use casez instead, ? can still be used to match don't cares.
Update comparing inside to casez
Case statements a clean control structure used in most languages to avoid large if elsif else chains. the inside operation will match x's to the do not care '?' values. this makes it usage similar to the casex which is considered to be bad practise to use as it can hide simulation fails.
casez(sel)
4'b1??? a= 3'd4;
4'b01?? a= 3'd3;
4'b001? a= 3'd2;
4'b0001 a= 3'd1;
4'b0000 a= 3'd0;
endcase
vs
if (sel inside {4'b1???})
a= 3'd4;
else if (sel inside {4'b01??})
a= 3'd3;
else if (sel inside {4'b001?})
a= 3'd2;
...
The above is actually equal to the casex (but more verbose) I believe that instead of casex you could also use :
case(sel) inside
4'b1??? a= 3'd4;
4'b01?? a= 3'd3;
4'b001? a= 3'd2;
4'b0001 a= 3'd1;
4'b0000 a= 3'd0;
endcase
but then I would never use a casex.
There's no operator I'm aware of that allows you to use '?' or 'x' inside an equality comparison to have them ignored.
Another alternative that you didn't mention would be to use a bitmask to select the bits you only care about. If you have a lot of bits this can be more compact than testing each bit individually.
If you only care about A == 3'b1?0, then it can be written as such:
if((A & 3'b101) == 3'b100)