The difference between x and z - verilog

While reading the syntax of Verilog, I came across the four logic values: 0 1 x z.
After searching the web, seeking to find the difference between x and z, I found only that x is unknown value and z is high impedance (tristate). I think that I understand the definition of x but didn't quite understood the one of z - what does it mean "high impedance (tristate)"?
I would like to see an example for each logic value out of the two: x z

Z means the signal is in a high-impedance state also called tri-state. Another signal connected to it can change the value: a 0 will pull it low, a 1 will pull it high.
To understand impedance (and thus high impedance) you should have some understanding of resistance, voltage and current and their relations as defined by Ohms law.
I can't give you an example of 'X' or 'Z', just as I can't give you an example of '1' or '0'. These are just definitions of signal states. In fact in Verilog there are more then four states. There are seven strengths.
(See this webpage).
Here is a principle diagram of how a chip output port makes a zero, one or Z. In reality the switches are MOSFETs.
Tri-state signals are no longer used inside chips or inside FPGA's. They are only used outside for connecting signals together.

x, as you had already found describes an unknown state. By default verilog simulation starts with all variables initialized to this value. One of the task of the designer is to provide correct reset sequences to bring the model into a known state, without 'x', i.e.
always #(posedge clk)
if (rst)
q <= 0;
In the above example initial value of q which was x is replaced by a known value of 0.
The difference between 'x' and 'z' is that 'z' is a known state of high impedance, meaning actually disconnected. As such, it could be driven to any other value with some other driver. It is used to express tri-state buses or some other logic.
wire bus;
assign bus = en1 ? value1 : 1'bz;
...
assign bus = en2 ? value2 : 1'bz;
In the above example the bus is driven by 2 different drivers. If 'en1' or 'en2' is high, the bus is driven with a real 'value1' or 'value2'. Otherwise its state is 'z'.
verilog has truth tables for every operator for all the values. You can check how they are used. i.e. for '&'
& 0 1 x z
0 0 0 0 0
1 0 1 x x
x 0 x x x
z 0 x x x
you can find for every other gate as well. Note that there are no 'z' in the result, just 'x's.

In system verilog X is treated like unconnected wire and Z is Weak HIGH.
Suppose a situation where you have wire connecting 2 modules m1 and m2.
If you are driving Z onto that wire from m1 then you can pull down this wire by assigning it to zero by m2.

As I figured out :
"tristate" or "high impedance" In transistors occures when you have "nothing" in the output.
that may occur, for example :
In a situation that you have an nMOS transistor let's call that T1:
the gate value of T1 is for example 0
so T1 would not conduct and there is no conduction path between your supply (probably 0 ) and the drain(output)
-that may occur a "Z" or tristate
--
It may occur for PMOS transistors with value -> 1 too.

Related

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.

Is there a method in verilog to start reading ROM data from a specific address?

I've designed a ROM for coefficients and an up-down counter to read these coefficients one by one but there are two cases for the starting point where a specific number of coefficients for type1 and another set of coefficients for type 2 ... so for example for type 1 I want to start from address zero and for type 2 start from address 30 ... I remember that someone told me it is possible using some # or something but I don't remember what is the actual way to do this
this for my counter code
module UDcounter(input clk,rst,up,GItype,
output reg [5:0]addr);
always #(posedge clk,posedge rst)
if (rst)
addr<=6'b0;
else
begin
if (GItype) //assume 1 is a long GI type
begin
// addr=6'b000000;
if (up)
addr=addr+1;
else addr=addr-1;
end
else //for short GI
begin
//addr=6'b100000;
if (up)
addr=addr+1;
else addr=addr-1;
end
end
endmodule
the error here is that every clock cycle it start addressing from addr=0 for example and the output address is always 1 (for the +1) line
So what I understood from your question is that you want to design a ROM which will store coefficients.
Going by your question I assume that you have two types of coefficient viz type a & type b stored in the ROM, say the starting address for type a is 0 and for type b is 30. To go about accessing the ROM you would want two counters viz addr_ptr_a and addr_ptr_b which will act as address pointers, lets assume that the ROM has about 60 address locations then addr_ptr_a will count from 0 to 29 and addr_ptr_b will count from 30 to 60.
The GItype signal can be used to determine which counter to enable.
I am assuming a sequential read operation, for a random read operation you would need a separate logic to generate the read address.

Multiple Bi-directional buses in verilog

I am trying to simulate a CAN bus in a verilog test bench. I know I need 1 bi-directional bus for each node in the CAN network. What happens if many of the buses try to write a value in the bus at the same time? Will the dominant value of 0 win or will this produce some error? The code I am thinking of would go like this:
//First node
CAN_HIGH = (read) ? 'bz : DATA_NODE_A;
//Second node
CAN_HIGH = (read) ? 'bz : DATA_NODE_B;
If node A tries to write a 1 and node B tries to write a 0, will the value of CAN_HIGH be 0?
in general, if you just drive a net type, i.e. wire from multiple sources, with the same value, the result will be the value you drive. If values are different, the resut will be x. z is a special case and is the weakest value and will be overwritten.
wire bus;
assign bus = en1 ? val1 : `z;
assign bus = en2 ? val2 : `z;
if both, en1, en2 are down, the bus will have value of z;
if en1 or en2 , but not both are up, the bus will be assignd the corresponding value (1 or 2).
if both, en1 and en2 are high, then, if val1 == val2, the bus will get the value of val1/val2, otherwise it would be x.
Now, in verilog you can define such a thing as an assignment strength, which is non-synthesizable, but can be used to behavioral modeling of certain situations, or in testbench. This would tell the verilog which assignment should win in the competition. There are several levels of strengthness in verilog, you can find it in documentation. Here is an example:
wire bus;
assign (strong0, weak1) bus = en1 ? val1 : `z;
assign bus = en2 ? val2 : `z;
In the above example if both en1 and en2 are high, and values are different, the first assignment will have stronger '0' but weader '1', so that val1 will provide '0' in the resulting value and assignment2 will provide '1'. You can use different combinations of strength. However, if the strengths are the same, it will behave as in the first example.

How does the synthesizer decides on bitwdith for intermediate results?

Consider the following module:
module power(input [11-1:0] xi,xq,output [22-1:0] y);
assign y = xi*xi + xq*xq;
endmodule
I know that my single assignment is actually decomposed of 3 steps: 2 squares and one addition. My question is how would the synthesizer decides on the bitwidth of the intermediate steps xi*xi and xq*xq?
I noticed that when running logic equivelance circuit (lec) for the above code, it causes trouble and could only be solved by decomposing the single assignment into three assignments as follows:
module power(input [11-1:0] xi,xq,output [22-1:0] yy);
wire [21-1:0] pi,pq;
assign pi = xi*xi;
assign pq = xq*xq;
assign yy = pi+pq;
endmodule
Here's how your simulator decides on bitwdith for intermediate results.
Verilog Simulation
This expression - assign y = xi*xi + xq*xq; - is an example of a context determined expression. A Verilog simulator takes the widest of all the nets or variables in the expression and uses that. So, in your code, the widest is y at 22 bits wide, so Verilog will use 22 bits throughout.
VHDL Simulation
The behaviour of a VHDL simulator depends on the package used. If you use the numeric_std package, as is recommended, then you would need to obey the following rules:
The width of the sum should be the same as the wider of the two operands.
The width of the product should be the sum of the widths of the operands.
Therefore, your code would compile if translated directly into VHDL:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity power is
port (xi, xq : in signed(11-1 downto 0);
y : out signed(22-1 downto 0));
end entity power;
architecture A of power is
begin
y <= xi*xi + xq*xq;
end architecture A;
Shouldn't everything be signed?
Given the names of your module (power) and inputs (xi and xq) and having spent 25 years designing radio systems, shouldn't they be signed? Shouldn't your Verilog be:
module power(input signed [11-1:0] xi,xq,output signed [22-1:0] y);
assign y = xi*xi + xq*xq;
endmodule
That is why I chose the signed type from numeric_std, not the unsigned type.
Synthesis
Well, I've waffled on about simulators, but you asked about synthesis. And, to be frank, I don't know what a synthesiser would do. But, given the job of a synthesiser is to design a logic circuit that behaves exactly like the simulation, you would think that any self-respecting synthesiser would use the same bit-widths as the simulator. So, I'm pretty sure that's your answer.

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

Resources