and or nand nor xor not
+ - * / mod rem abs ** (integer power)
+ - * / abs ** (integer power)
= /= work on any type < <= > >= any scalar type
& Note the deceptive meaning of this symbol!!!
Explicit type conversion is handled by
and is permitted when the types are said to be "closely related." This means approximately that they either are numeric types, or that they share the same base type if they are subtypes. Arrays must have the same dimensionality, but not necessarily the same dimensions.
Examples on numbers:
real'( intval ) converts an integer to real. integer'( x ) rounds the real value of x to the nearest integer. natural'( x ) checks to see that the value of x is non-negative (reporting the error if it occurs) and rounds to the nearest integerAn Application using type conversion on arrays:
signal databyte : byte_int ; signal accum : word_int ; - - - - accum <= databyte ; WRONG!! accum <= word_int ( databyte ) ; OK!!
When a slice is referenced, it is analogous to extracting data from a field of a register.
Example:
abus <= ax ( 15 downto 8 ); abus <= ax ( 7 downto 0 );Note: Behavioral models which involve multiplexing "wide" values onto "narrow" buses make this capability essential.
It is also useful for modelling shift and rotate operations.
Examples
AX <= AX ( 14 downto 0 ) & '0'; -- Left shift, zero fill on right end AX <= AX(0) & AX(15 downto 1); -- Right rotate
Used for checking setup and hold times. If T is the setup time, this will be true at the clocking time. It imposes a fairly high overhead, and should usually be avoided. See the use of S'LAST_EVENT below.
Used to model the clock transition in flipflops.
Example: Up_edge := S'event and S = '1'.
Can be used to compute time-varying values like capacitive dischange in a memory cell at refresh. Is the preferred way to check signal stabilization: J'last_event > Tsetup.
For example, if the evaluation of an OR expression produced a '1' for the new output value in response to input X changing to '1', that transaction would be queued for the simulator. However, the OR gate value may already be '1' (due to the Y input already being '1', or the signal may have other drivers that have forced the value to '1', so that when it comes time to update the signal no change occurs. At this point a transaction has occurred, but no event has occurred. Since no change occurred, this action will not trigger the execution of concurrent signal assignment statements or processes.
In most cases you should be using the EVENT based attributes discussed above, not the TRANSACTION based attributes discussed in this section. These attributes can be useful in studying how much signal activity there is in the design, and can be used to model such things as power use in switching devices.
Can be used to compute time-varying values like capacitive dischange in a memory cell at refresh. Also another way to check signal stabilization.
We may then choose to use the relational symbolsto describe (invoke) the new function. Replacing the function name with a quoted string (e.g. "<") creates an "overloaded" operator which can be used in the same syntactic way as the old or operation on bits and booleans.
Example: Declaration of Relational operation functions for bit_vectors.
function "<" ( x, y : bit_vector ) return boolean; function "<=" ( x, y : bit_vector ) return boolean;
VHDL uses the type of the operand to choose whether to use this function to perform the operation, one of the operations already defined on integers and reals, or still another user-defined function.
Building Functions using Operator Overloading and Constant Arrays
------------------------------------------------ -- local types TYPE stdlogic_1d IS ARRAY (std_ulogic) OF std_ulogic; TYPE stdlogic_table IS ARRAY(std_ulogic, std_ulogic) OF std_ulogic; -- truth table for "xor" function CONSTANT xor_table : stdlogic_table := ( -- -------------------------------------------- -- | U X 0 1 Z W L H - --| | -- -------------------------------------------- ('U','U','U','U','U','U','U','U','U'), --|U| ('U','X','X','X','X','X','X','X','X'), --|X| ('U','X','0','1','X','X','0','1','X'), --|0| ('U','X','1','0','X','X','1','0','X'), --|1| ('U','X','X','X','X','X','X','X','X'), --|Z| ('U','X','X','X','X','X','X','X','X'), --|W| ('U','X','0','1','X','X','0','1','X'), --|L| ('U','X','1','0','X','X','1','0','X'), --|H| ('U','X','X','X','X','X','X','X','X') --|-| ); -- truth table for "not" function CONSTANT not_table: stdlogic_1d := -- -------------------------------------------- -- | U X 0 1 Z W L H - | -- -------------------------------------------- ( 'U','X','1','0','X','X','1','0','X' ); ------------------------------------------------ -- overloaded logical operators ------------------------------------------------ FUNCTION "xor" (l : std_ulogic; r : std_ulogic ) RETURN UX01 IS BEGIN RETURN (xor_table(l, r)); END "xor"; FUNCTION "not" (l : std_ulogic ) RETURN UX01 IS BEGIN RETURN (not_table(l)); END "not";Quoted"xor" to name the function creates an "overloaded" operator which can be used in the same syntactic way as the old or operation on bits and booleans. VHDL checks the type of the operand to determine what function is to be used.
Bit strings, in binary, octal, and hex notation. The underscore is legal and purely cosmetic.
constant Zeros : bit_vector := B"0000_0000" ; constant empty: bit_vector := O"052"; constant restart: bit_vector:= X"0FC"; -- Character string constant Error_Msg : string := "System Fries!!"
Example: Since '0', '1', 'X', 'Z' are values for std_logic, we now can write string values for std_logic_vector.
constant ZZZs : std_logic_vector := "ZZZZ_ZZZZ" ;
Form
constant_name := (name1 => value1, name2 => value2,
. . . );
where names can be grouped A|B|C, and includes the reserved word OTHERS
Examples
type clock_level is (low,rising,high,falling); type ctable is array (clock_level) of bit; constant conversion_table : ctable := ('0','1','1','0'); constant conversion_table : ctable := (low=>'0', falling=>'0',high=>'1', rising=>'1'); constant conversion_table : ctable := (low | falling=>'0',high | rising=>'1'); constant conversion_table : ctable := "0110"; type cpureg is MVL_vector (rsize-1 downto 0); constant Zs : cpureg := (rsize-1 downto 0 => 'Z'); constant One : cpureg := (0 =>'1', others=>'0');Initializing a Record
constant CLEARAX : Instruction := (opcode=>xor, src_reg=>ax, dst_reg=>ax, src_mode=>reg, dst_mode=>reg); where type Instruction is record opcode : Operations; src_mode: Address_mode; src_reg : Wordreg; dst_mode: Address_mode; dst_reg : Wordreg; end record;and each of the types has been declared previously.
Rev. 2/20/98 B. Huey