Meaning of strong and weak drive in VHDL?
The ieee.std_logic_1164
package allows two drive strengths.
(0,1) are normal drive strength and used for all normal purposes. (L,H) are weak drivers, they are normally used to model pull-up and pull-down resistors.
Formally, ieee.std_logic_1164
distinguishes between the std_ulogic
and std_logic
types, even though they share the same set of values (U,L,H,0,1,X,Z etc).
The difference between them is this : std_ulogic
is an unresolved type. It is an error for a std_ulogic
signal to be driven by two signal sources (like short circuiting 2 wires together - it's usually a mistake) - such errors will be caught (by the compiler) and fixed (by you!) even before you get to simulation.
On the other hand, std_logic
is a resolved type. It is legal to have two or more drivers on a signal. The result is determined by a "resolution function" which looks at all the driving values and combines them into the value you will see on the signal. For example, 0
and '1' combine to produce X
(the Unknown state) , and X
and anything else produces X
so that once Unknowns happen, they propagate through the design to show there's a problem.
But '0' and 'H' combine to produce '0' (because H
is weak) and similarly, '1' and 'L' combine to produce '1'. So a strong driver can legally overpower a weak one : no harm done.
Let's look at the 'Z' state : it signifies Undriven, or High Impedance (High-Z). Now Z
and H
combine to produce H
because H
, though weak, is still stronger than no driver at all.
This is just a brief summary : for all details see a good VHDL book or even the ieee.std_logic_1164 package source code.
So one use of a weak H
is in the so-called "wired-or" configuration, as used in I2C buses.
SDA <= `H`; -- permanent pullup resistor
SDA <= `0` when I2C_Master_SDA = '0' else `Z`;
SDA <= `0` when I2C_Slave1_SDA = '0' else `Z`;
SDA <= `0` when I2C_Slave2_SDA = '0' else `Z`;
We are safely combining 4 drivers on the same signal : one I2C master, two slaves, and a permanent weak pullup.