IF get_strength(result) < get_strength(s(i)) THEN result := s(i);
ELSIF get_strength(result) = get_strength(s(i)) THEN IF result /= s(i) THEN
result := x_tab(get_strength(result)); END IF; END IF; END LOOP; RETURN result; END resolve9; END ninepack;
The package ninepackdeclares a number of types used in this example, including some array types to make the resolution function easier to
implement. The basic algorithm of the function is the same as the fourval resolution function; however, the operations with nine values are a little more complex. Function resolve9still does a pairwise comparison of the input values to determine the resultant value. With a nine-value system, the comparison operation is more complicated, and therefore some constant arrays were declared to make the job easier.
The constant get_strengthreturns the driving strength of the driver value. The constant x_tab returns the appropriate unknown nine-state value, given the strength of the input. These constants could have been implemented as IFstatements or CASE statements, but constant arrays are much more efficient.
In the nine-value system, there are three values at the lowest strength level, so the variable result has to be initialized more carefully to predict correct results. If there are no drivers, the range attribute of argument s returns 0, and the default value (ZX) is returned.
Let’s look at a few examples of driver-input arguments and see what the resolution function predicts. An example of two drivers is shown in Figure 5-4.
This example contains two driver values,Z1and R0. Variable resultis initialized to the first driver value, and the loop executes as many times as there are drivers. The first time through the loop,resultequals Z1and the first driver equals Z1. Variable result remains at Z1 because the values are equal. The next time through the loop, variable resultcon- tains Z1, and the second driver contains R0. The constant get_strength returns strength R. The constant get_strengthfor variable resultreturns strength Z. Strength Ris lexically greater than strength Z. This is because value R has a higher position number than Z, because R is listed after Z in the type declaration for type strength. The fact that the new driver has
Driver Values Initial Value Z1 R0 Z1 Z1 R0 Resultant Value Figure 5-4
Nine State Resolution with Two Values.
a stronger strength value than variable resultcauses variable resultto be updated with the stronger value,R0.
Another example shows how the constant x_tab is used to predict the correct value for conflicting inputs. The driver values are shown in the array in Figure 5-5.
In this example, variable resultis initialized to F0. The first iteration of the loop does nothing because the first driver and the result- initialization value are the same value. The next iteration starts with variable resultcontaining the value F0, and the next driver value as R0. Because the value in variable resultis greater in strength than the value of the new driver, no action is implemented, except to advance the loop to the next driver.
The last driver contains the value F1. The strength of the value contained in variable resultand the new driver value are the same. Therefore, the IFstatement checking this condition is executed and succeeds. The next IFstatement checks to see if the logical values are the same for both vari- able resultand the new driver. Variable resultcontains an F0, and the new driver value contains an F1. The values are not the same, and the x_tabtable is used to return the correct unknown value for the strength of the driver values. The x_tabtable returns the value FX, which is returned as the resolved value.
A more efficient method to implement the loop would be to skip the first iteration where the first driver is compared to itself, because the value in variable resultis initialized to the first driver value. It is left as an exercise to the reader to write this new loop iteration mechanism.
Driver Values Initial Value F0 R0 F1 F0 F0 F0 FX Resultant Value Figure 5-5
Nine State Resolution with Three Values.
Although VHDL simulators can support any type of resolution that can be legally written in the language, synthesis tools can only support a subset. The reason stems from the fact that the synthesis tools must build actual hardware from the VHDL description. If the Resolution Function maps into a common hardware behavior such as wired-or or wired-and, then most synthesis tools allow the user the ability to tag the resolution function appropriately. For instance, a Resolution Function that performs a wired-or function is tagged with an attribute that tells the synthesis tools to connect the outputs together.
COMPOSITE TYPE RESOLUTION For simple signal values such as
the ninevaland fourvaltypes, it is easy to see how to create the resolu- tion function. But for signals of composite types, it is not so obvious. How can one value of a composite type be stronger than another?
The answer is that one value must be designated as weaker than all of the other values. Then the principle is the same as any other type being resolved. In the fourvaltype, the value Z was considered the weakest state, and any of the other values could overwrite this value. In the ninevaltype, all values with a strength of Zcould be overridden by val- ues with a strength of Ror F, and all values with strength Rcould be over- ridden by strength F.
To resolve a composite type, designate one value of the composite type as unusable except to indicate that the signal is not currently being driven. The resolution function checks how many drivers have this value and how many drivers have a driving value. If only one driving value exists, then the resolution function can return this value as the resolved value. If more than one driving value is present, then an error condition probably exists and the resolution function can announce the error.
A typical application for a composite type resolution function is shown in Figure 5-6.
Signal XBUScan be driven from a number of sources, but hopefully only one at a time. The resolution function must determine how many drivers are trying to drive XBUSand return the correct value for the signal.
Following is the type declarations and resolution function for a com- posite type used in such a circuit:
PACKAGE composite_res IS TYPE xtype IS
RECORD
addr : INTEGER; data : INTEGER;
MEMORY CPU IO_PORT DISK_CONTROL XBUS Figure 5-6 Block Diagram of Computer. END RECORD;
TYPE xtypevector IS ARRAY( natural RANGE <>) OF xtype; CONSTANT notdriven : xtype := (-1,-1);
FUNCTION cresolve( t : xtypevector) RETURN xtype; END composite_res;
PACKAGE BODY composite_res IS
FUNCTION cresolve( t : xtypevector) RETURN xtype IS VARIABLE result : xtype := notdriven;
VARIABLE drive_count : INTEGER := 0; BEGIN
IF t’LENGTH = 0 THEN RETURN notdriven; END IF;
FOR i IN t’RANGE LOOP