when if(a) will return true in Verilog - verilog

I am new to Verilog and I had been asked the following question:
Consider a = reg[3:0], then what values can a have so if(a) will return true?
I have no idea where to start, tried to compile some examples but all failed syntax problem.

Writing if (a) is the same as writing if (a !=0). Since a is a 4-bit variable, you can expand that out to if (a[0] != 0 | a[1] ! = 0 | a[2] != 0 | a[3] !=0). So a 1 in any bit position makes the expression true. Note that an unknown value x or z as an operand with the equality/inequality operators results in an unknown and is considered false. But an unknown or'ed with true is true.

reg is a verilog keyword used to declare variable types, and the expression you provided is an illegal verilog expression. You can declare a to be a 4-bit reg as the following:
reg[3:0] a;
the above makes a a 4-bit vector. Now, verilog bits might have 4 states: 0, 1, x, and z. So, any one of 4 bits of a can be in any of those states. Now you have 256 possible combinations. If you ignore x and z states, you can get 16 combinations expressed in decimals as 0 to 15.
true means that at least one bit in a is 1. In all other cases it will be false.

Related

Signed and Unsigned Multiplication Problem in Verilog

I have been working on approximate multiplication recently and I want to write a Verilog code for dynamic segment multiplication (DSM) . It suggest that you find the first index in you number which has a value of 1 and then take other 3 indexes next to it to form a 4 bit number that represent an 8 bit number then you should multiply these 4 bit numbers instead of 8 bits then some shifts to have the final result it helps a lot on hardware actually.. but my problem is about multiplication of these segments because sometimes they should be considered signed and some time unsigned I have the last 3 lines of my code: (a and b are input 8 bit numbers) and m1 and m2 are segments I wrote m,m2 as reg signed [3:0] and a and b as input signed [7:0]
Here is my code:
assign out = ({a[7],b[7]}==2'b11)||({a[7],b[7]}==2'b00) ? ($unsigned(m1)*$unsigned(m2)) << (shift_m1+shift_m2) : 16'dz;
assign out = ({a[7],b[7]}==2'b01) ? ($signed({1'b0,m1})*$signed(m2)) << (shift_m1+shift_m2) : 16'dz;
assign out = ({a[7],b[7]}==2'b10) ? ($signed(m1)*$signed({1'b0,m2})) << (shift_m1+shift_m2) : 16'dz;
But in simulation Verilog always considers segments as unsigned and does unsigned multiplication even though I noted signed or unsigned mark...
Can anyone help? I read all of the questions about this problem in stackoverflow and other places but still cannot solve this issue...
The rules for non-self determined operands say that if one operand is unsigned, the result is unsigned. 16'dz is unsigned.
The conditional operator i ? j : k has the condition operand i self-determined, but the two selections j and k are in a context based on the assignment or expression it is a part of. The shift operator i << j has the shift amount operand j self-determined.
All of the context rules are explained in section 11.6.1 Rules for expression bit lengths in the IEEE 1800-2017 SystemVerilog LRM.
You can get your desired result by using the signed literal 16'sdz.
However the logic you wrote may not be synthesizable for certain technologies that do not allow using a z state inside your device. The correct and more readable way is using a case statement:
alway #(*) case({a[7],b[7]})
2'b00,
2'b11: out = $unsigned(m1)*$unsigned(m2) << shift_m1+shift_m2;
2'b01: out = $signed({1'b0,m1})*m2 << shift_m1+shift_m2;
2'b10: out = m1*$signed({1'b0,m2}) << shift_m1+shift_m2;
endcase

Verilog assign statement result check

new to Verilog (well, SystemVerilog really, but I found that for the very basic keywords like assign and initialize I am able to learn from Verilog resources as well). I am following example 2 on this link chipverify example 2. It's simple so I'll write it down. I feel as if they've made a mistake, but since I am a newbie it's hard to know if my feeling is correct or not.
module xyz (input [3:0] x, //let x='hC or x='b1100 for this example's purposes
input y, //y is a 1bit scalar y='h1 = 'b1
output [4:0] z);
//case 8
assign z = {3{y}};
endmodule
For case 8, they are saying that z will result in z='b00111. I don't think it's correct! Following their case 3, where z only got bits [4:1] assigned,it stated that the reaming bit will be undriven and thus result in high impedance Z. Shouldn't the result of case 8 then be z ='bZZ111 and not z='b00111?
Let me know, thanks! =)
From section 10.7 (Assignment extension and truncation) in IEEE Std 1800-2017 (the SystemVerilog standard),
When the right-hand side evaluates to fewer bits than the left-hand side, the right-hand side value is padded to the size of the
left-hand side.
In your case, {3{y}} is an unsigned value, so it is 0-padded to 5 bits, that is 5'b00111, and then assigned to z.

Unexpected result of Not operator in assignment

I have two 8-bit inputs A and B,
input [7:0] A,B;
and a 9-bit output F,
output reg [8:0] F;
A and B are combined and assigned to F like this:
F <= ~(A^B);
If A is equal to 8'hFF, and B is equal to 8'hF0, why does F become 9'h1F0 and not 9'h0F0?
Why is the output 9'h1F0 and not 9'h0F0?
You defined F as 9 bits wide. Thus the compiler will expand the right-hand-side arguments to 9 bits before doing any operations.
As both A and B are unsigned they become resp
A = 9'h0FF, B=9'h0F0. EXOR gives 9'h00F. Ones complement then gives 9'h1F0.
Beware that the width expansion does not happen if you put the expression between {}:
F2 = {~(A^B)};
F2 will be 9'h0F0;
Because sections 11.8.2 Steps for evaluating an expression and 11.8.3 Steps for evaluating an assignment of the IEEE 1800-2017 LRM effectively say that the operands get extended first to match the size of the result before any operation is performed.

Simple "Assign" Function

i have just started to learn some verilog and came across a problem that would normally be solved using a for loop in other languages.
s2 s1 s0 m
0 0 0 u
0 0 1 v
0 1 0 w
0 1 1 x
1 0 0 y
1 0 1 z
This is the truth table of the problem where s2,s1,s0 are switches, (u,v,w,x,y,z) are inputs and if certain switches are set, the output(m) will be set as one of the inputs. However, this is only 1 bit wide and we can just assign each m to be one of the following inputs provided that s0,s1,s2 matches. If it were 3 bit wide input and output ex:(u0,u1,u2),(m0,m1,m2) but each of the variables still follows the same logic with one another(ex: u0,u1,u2 will all be the outputs m0,m1,m2 provided that all switches are 0) how can i shorten my code. Am i allowed to do:
assign m[3:0] = (~s0&~s1&~s2&u[3:0])
No, that is not a good solution. Verilog will extend your select signals to be the same width as m before performing the & operation, and the default behavior is to add zeros on the left to extend a signal. It might work if you declared the select signals to be signed but I think you can do better.
Furthermore, the example you provide only deals with the first row of your truth table. For the other seven combinations of s0, s1, and s2 you would be assigning all zeros to m. If you want to do this in a single combinational assignment then you would need 8 logical expressions like the one you have, all ORed together to get the final result.
A much cleaner way of doing this is with an if-then-else or case statement inside an always block.
Try a case statement:
always #* begin
case ({s2,s1,s0})
3'b000 : m = u;
3'b001 : m = v;
3'b010 : m = w;
3'b011 : m = x;
3'b100 : m = y;
3'b101 : m = z;
default: m = 0; /* <-- catch all */
endcase
end
Note: Use default if the truth table is incomplete. Otherwise a latch will be inferred.
Working example: http://www.edaplayground.com/s/6/187

What is the difference between == and === in Verilog?

What is the difference between:
if (dataoutput[7:0] == 8'bx) begin
and
if (dataoutput[7:0] === 8'bx) begin
After executing dataoutput = 52'bx, the second gives 1, but the first gives 0. Why? (0 or 1 is the comparison result.)
Some data types in Verilog, such as reg, are 4-state. This means that each bit can be one of 4 values: 0,1,x,z.
With the "case equality" operator, ===, x's are compared, and the result is 1.
With ==, the result of the comparison is not 0, as you stated; rather, the result is x, according to the IEEE Std (1800-2009), section 11.4.5 "Equality operators":
For the logical equality and logical
inequality operators (== and !=), if,
due to unknown or high-impedance bits
in the operands, the relation is
ambiguous, then the result shall be a
1-bit unknown value (x).
In Verilog:
== tests logical equality (tests for 1 and 0, all other will result in x)
=== tests 4-state logical equality (tests for 1, 0, z and x)
== For comparing bits (0 or 1)
=== For comparing all 4 states (0, 1, x, z)
== can be synthesized into a hardware (x-nor gate), but === can't be synthesized as x is not a valid logic level in digital, it is infact having voltages in between 0 and 1. And z is not itself any logic, it shows disconnection of the circuit.
As many already commented, in case a signal has an X, the "normal" comparison operator can led to unknow states/answers. Therefore, if you are comparing from a RAM that can deliver U or X states and you want to really check a match, then you should use the "===" and "!==" operators.
See picture from the systemverilog reference documentation.

Resources