====== Operators ====== ===== Overview ===== ^ logical | and | or | nand | nor | xor | xnor | not | | ^ relational | = | /= | < | <= | >= | > | | | ^ shift | sll | srl | sla | sra | rol | ror | | | ^ arithmetic | + | - | * | / | mod | rem | ** | abs | sorted on order of increasing precedence (top ⇒ down) VHDL’93: New operators: xnor, shift operators === Notes === The VHDL operators are rather self-explanatory. While relational operators are available for all predefined data types, the logical, shift and arithmetical operators may only be used with bit and numerical values, respectively. ===== Logical Operators ===== entity LOGIC_OP is port (A, B, C, D : in bit; Z1 : out bit; EQUAL : out boolean); end LOGIC_OP; architecture EXAMPLE of LOGIC_OP is begin Z1 <= A and (B or (not C xor D)); EQUAL <= A xor B; -- wrong end EXAMPLE; * Priority * not (top priority) * and, or, nand, nor. xor, xnor (equal priority) * Predefined for * bit, bit_vector * boolean * Data types have to match Brackets must be used to define the order of evaluation === Notes === Logical operations with arrays require operands of the same length. The operation is carried out element by element, then. This requirement does not exist for comparison operations with arrays. The arrays are left-aligned prior to comparison instead. Therefore it is recommended to adjust the length of the operands with the help of the concatenation operator. ===== Logical Operators with Arrays ===== architecture EXAMPLE of LOGICAL_OP is signal A_BUS : bit_vector (3 downto 0); signal B_BUS : bit_vector (3 downto 0); signal Z_BUS : bit_vector (4 to 7); begin Z_BUS <= A_BUS and B_BUS; end EXAMPLE; * Operands of the same length and type * Assignment via the position of the elements (according to range definition) **Exercise: Insert Indexes** {{:courses:system_design:vhdl_language_and_syntax:folie140_logicaloperatorswitharrays.svg?nolink&500|Example}} === Notes === A_BUS(0) and B_BUS(0) ➔ ist auf Z_BUS(7) geklemmt, usw. ===== Shift Operators: Examples ===== VHDL’93: Defined only for one-dimensional arrays of a bit of boolean! signal A_BUS, B_BUS, Z_BUS : bit_vector (3 downto 0); Z_BUS <= A_BUS sll 2; -- At the end, the first value of the type is used for filling up Z_BUS <= B_BUS sra 1; Z_BUS <= A_BUS ror 3; **Logical shift** {{:courses:system_design:vhdl_language_and_syntax:folie142_logicalshift.svg?nolink&700|Logical shift}} **Arithmetic shift** {{:courses:system_design:vhdl_language_and_syntax:folie142_arithmeticshift.svg?nolink&700|Arithmetic shift}} **Rotation** {{:courses:system_design:vhdl_language_and_syntax:folie142_rotation.svg?nolink&700|Rotation}} === Notes === Shift and rotation operations on arrays were introduced with the VHDL’93 standard. Rotation means that none of the element values is lost as the value that is rotated out of the array on one side will be used for the vacant spot on the other side. This is different from the shift operations where the value is discarded. During so called arithmetic shift operations the vacant spot receives its previous value; in case of logical shift operations the default value of the signal, i.e. the left-most value from the type declaration, will be used. ===== Relational Operators ===== architecture EXAMPLE of RELATIONAL_OP is signal NR_A, NR_B : integer; signal A_EQ_B1, A_EQ_B2 : bit; signal A_LT_B : boolean; begin -- A,B may be of any standard data type process (A, B) begin if (A = B) then A_EQ_B1 <= '1'; else A_EQ_B1 <= '0'; end if; end process; A_EQ_B2 <= A = B; -- wrong A_LT_B <= B <= A; end EXAMPLE; * Predefined for all standard data types * Result: boolean type (true, false) * less than < * less or equal <= * equal = * unequal /= * greater or equal >= * greater > === Notes === A_EQ_B2: wrong, since (A=B) is boolean, A_EQ_B2 is bit! A_LT_B („A larger than B“): ok, since (B less then or equal A) is boolean, A_LT_B also! ===== Comparison Operations with Arrays ===== architecture EXAMPLE of COMPARISON is signal NIBBLE : bit_vector(3 downto 0); signal BYTE : bit_vector(0 to 7); begin NIBBLE <= "1001"; BYTE <= "00001111"; COMPARE : process (NIBBLE, BYTE) begin if (NIBBLE < BYTE) then -- e.g. evaluated as: -- if (NIBBLE(3) < BYTE(0)) or -- ((NIBBLE(3) = BYTE(0)) and -- (NIBBLE(2) < BYTE(1))) or -- ((NIBBLE(3) = BYTE(0)) and -- (NIBBLE(2) = BYTE(1)) and -- (NIBBLE(1) < BYTE(2))) or ... -- better: if (("0000"&NIBBLE) <= BYTE) ... end process COMPARE; end EXAMPLE; Adjust the length of arrays prior to comparison! * Operands of the same type * Arrays: * May differ in length * Left-alignment prior to comparison * Are compared element after element **according to their position from left to right** * **No numerical interpretation (unsigned, 2-complement etc.)** Stops at first position evaluated TRUE === Notes === When comparing array types it must be considerd that the comparison is carried out from the left side to the right. That means for arrays of varying length that "111" is greater than "1001", for example. If it is not desired, hence shall be compared right-aligned, then the arrays will have to be brought upon the equal length by hand, e.g. by means of concatenation: '0'&"111" is then smaller than "1001". ===== Arithmetic Operators ===== * addition + * subtraction - * multiplication * * exponentiation ** * division / * modulo **mod** * absolut value **abs** * remainder **rem** * **Operands of the same type** * **Predefined for** * **integer** * **real** (except mod and rem) * **physical types** (e.g. time) * **Not defined for bit_vector** (undefined number format: unsigned, 2-complement, etc.) * **Conventional mathematical meaning and priority** ... signal A, B, C : integer; signal RESULT : integer; ... RESULT <= -A + B * C; -- unary operator ’-’ before A ... * **‘+’ and ’-’ may also be used as unary operators (only one operand)** === Notes === Please note, that two operations to calculate the remainder of an integer division are defined. The modulo operation finds the remainder of division of one number by another. The sign of the result of ’**rem**’ and ’**mod**’ operations is equal to the sign of the first and second operand, respectively. Unary operations have only one operand ===== Quiz ===== signal BOOL: boolean; signal A_INT, B_INT, Z_INT: integer range 0 to 15; signal Z_BIT: bit; signal A_VEC, B_VEC, Z_VEC: bit_vector (3 downto 0); signal A_VEC2, B_VEC2, Z_VEC2: bit_vector (7 downto 0); ...Logic-operators| ...Arithmetic-operators| ...Comparison-operators ...according to their position.| ...from left to right. ... automatically, according to their position.| ... specifically, via the index (e.g.: Z_BUS(1) <= `3`;) ...by pairs of elements, according to their position.| ...by pairs of elements, according to their index. Z_BIT <= A_INT = B_INT;| BOOL <= A_INT > B_VEC;| Z_INT <= A_INT + B_INT;| Z_INT <= A_INT = "0001";| Z_BIT <= A_VEC AND B_INT;| Z_VEC <= A_VEC2 AND B_VEC2;