IEEE P1164 Working Group - Change Proposal ID: CP-003 Proposer: Jim Lewis Status: Proposed (1-Jun-2001) Analyzed (17-Nov-2002) Resolved (17-May-2003) Summary: Add array/scalar logical operators Detail: Support logic operators: Array with Bit returning Array function "and" (L: std_logic_vector; R: std_logic) return std_logic_vector; function "and" (L: std_logic; R: std_logic_vector) return std_logic_vector; signal ASel, BSel : std_logic ; signal Y, A, B : std_logic_vector(7 downto 0) ; Y <= (A and ASel) or (B and BSel) ; Without these type of functions, the code is more cumbersome: signal vASel, vBSel : std_logic_vector(7 downto 0) ; vASel <= (others => ASel) ; vBSel <= (others => BSel) ; Y <= (A and vASel) or (B and vBSel) ; Or even better would be the following, but some tools seem to think it is ok and others don't: Y <= (A and (A'range => ASel)) or (B and (B'range => BSel)) ; Unfortunately most do not know the trick, give up with the first attempt and do the following: Y <= A when ASel = '1' else B when BSel = '1' else (others => '0') ; This results in priority select logic. For terms of 3 or more, priority select logic is inferior (Quality of Results) to Multiplexers or AND-Or logic. As a hardware designer interested in promoting quality of synthesis results, I would be more than happy to contribute implementations for all binary logic operators. The code for std_logic_1164 could be simply as follows: FUNCTION "and" ( l : std_logic_vector; r : std_logic ) RETURN std_logic_vector IS VARIABLE result : std_logic_vector ( l'Range ); BEGIN FOR i IN result'RANGE LOOP result(i) := and_table (l(i), r); END LOOP; RETURN result; END "and"; It would take less than one plane flight to provide the rest. Analysis: By Peter Ashenden , 17-Nov-2002 This proposal has come from a number of sources in addition to the above-named proposer. Furthermore, the P1076.3 working group is proposing similar functions for the numeric_bit and numeric_std packages. It would therefore be appropriate to include the proposed functions in std_logic_1164, in a manner compatible with numeric_std. Ultimately, similar functions for bit/bit_vector and boolean/boolean-vector operations should be included in the base VHDL standard, 1076. An issue to consider in the design of the function is the index range of the result. Alternatives are: 1. Same as the vector operand. This would be in keeping with the behavior of logical and shift operators defined in 1076. However, the existing logical operations in std_logic_1164 do not behave this way. 2. 1 to vector length. For std_ulogic_vector and std_logic_vector operands, this would be in keeping with the behavior of the two-vector logical operators currently defined in std_logic_1164. (See also CP-005.) If the proposed operations were also defined for bit/bit_vector and boolean/boolean-vector operands for ultimate inclusion in the base standard, this alternative would make the operations behave differently from the other logical and shift operators already defined in 1076. 3. Same as the result of the operator applied to two vectors. For std_ulogic_vector and std_logic_vector scalar/vector operations, the result would have an index range 1 to vector length. For bit_vector and boolean-vector scalar/vector operations in 1076, the result would have the same index range as the vector operand. In the interest of consistent behavior within the std_logic_1164 and std.standard packages, I suggest adopting alternative 3. Changes to 1164-1993: Add the following function declarations to the package declaration after the vectorized overloaded logical operators: ------------------------------------------------------------------- -- vector/scalar overloaded logical operators ------------------------------------------------------------------- FUNCTION "and" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector; FUNCTION "and" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector; FUNCTION "and" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector; FUNCTION "and" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector; FUNCTION "nand" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector; FUNCTION "nand" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector; FUNCTION "nand" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector; FUNCTION "nand" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector; FUNCTION "or" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector; FUNCTION "or" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector; FUNCTION "or" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector; FUNCTION "or" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector; FUNCTION "nor" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector; FUNCTION "nor" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector; FUNCTION "nor" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector; FUNCTION "nor" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector; FUNCTION "xor" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector; FUNCTION "xor" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector; FUNCTION "xor" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector; FUNCTION "xor" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector; FUNCTION "xnor" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector; FUNCTION "xnor" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector; FUNCTION "xnor" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector; FUNCTION "xnor" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector; Add the following function bodies to the package body after the vectorized overloaded logical operators: ------------------------------------------------------------------- -- vector/scalar overloaded logical operators ------------------------------------------------------------------- ------------------------------------------------------------------- -- and ------------------------------------------------------------------- FUNCTION "and" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := and_table (lv(i), r); END LOOP; RETURN result; END "and"; ------------------------------------------------------------------- FUNCTION "and" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := and_table (lv(i), r); END LOOP; RETURN result; END "and"; ------------------------------------------------------------------- FUNCTION "and" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector IS ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_logic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := and_table (l, rv(i)); END LOOP; RETURN result; END "and"; ------------------------------------------------------------------- FUNCTION "and" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector IS ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_ulogic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := and_table (l, rv(i)); END LOOP; RETURN result; END "and"; ------------------------------------------------------------------- -- nand ------------------------------------------------------------------- FUNCTION "nand" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(and_table (lv(i), r)); END LOOP; RETURN result; END "nand"; ------------------------------------------------------------------- FUNCTION "nand" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(and_table (lv(i), r)); END LOOP; RETURN result; END "nand"; ------------------------------------------------------------------- FUNCTION "nand" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector IS ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_logic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(and_table (l, rv(i))); END LOOP; RETURN result; END "nand"; ------------------------------------------------------------------- FUNCTION "nand" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector IS ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_ulogic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(and_table (l, rv(i))); END LOOP; RETURN result; END "nand"; ------------------------------------------------------------------- -- or ------------------------------------------------------------------- FUNCTION "or" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := or_table (lv(i), r); END LOOP; RETURN result; END "or"; ------------------------------------------------------------------- FUNCTION "or" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := or_table (lv(i), r); END LOOP; RETURN result; END "or"; ------------------------------------------------------------------- FUNCTION "or" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector IS ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_logic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := or_table (l, rv(i)); END LOOP; RETURN result; END "or"; ------------------------------------------------------------------- FUNCTION "or" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector IS ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_ulogic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := or_table (l, rv(i)); END LOOP; RETURN result; END "or"; ------------------------------------------------------------------- -- nor ------------------------------------------------------------------- FUNCTION "nor" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(or_table (lv(i), r)); END LOOP; RETURN result; END "nor"; ------------------------------------------------------------------- FUNCTION "nor" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(or_table (lv(i), r)); END LOOP; RETURN result; END "nor"; ------------------------------------------------------------------- FUNCTION "nor" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector IS ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_logic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(or_table (l, rv(i))); END LOOP; RETURN result; END "nor"; ------------------------------------------------------------------- FUNCTION "nor" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector IS ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_ulogic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(or_table (l, rv(i))); END LOOP; RETURN result; END "nor"; ------------------------------------------------------------------- -- xor ------------------------------------------------------------------- FUNCTION "xor" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := xor_table (lv(i), r); END LOOP; RETURN result; END "xor"; ------------------------------------------------------------------- FUNCTION "xor" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := xor_table (lv(i), r); END LOOP; RETURN result; END "xor"; ------------------------------------------------------------------- FUNCTION "xor" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector IS ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_logic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := xor_table (l, rv(i)); END LOOP; RETURN result; END "xor"; ------------------------------------------------------------------- FUNCTION "xor" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector IS ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_ulogic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := xor_table (l, rv(i)); END LOOP; RETURN result; END "xor"; ------------------------------------------------------------------- -- xnor ------------------------------------------------------------------- FUNCTION "xnor" ( l : std_logic_vector; r : std_ulogic ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(xor_table (lv(i), r)); END LOOP; RETURN result; END "xnor"; ------------------------------------------------------------------- FUNCTION "xnor" ( l : std_ulogic_vector; r : std_ulogic ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( 1 TO l'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(xor_table (lv(i), r)); END LOOP; RETURN result; END "xnor"; ------------------------------------------------------------------- FUNCTION "xnor" ( l : std_ulogic; r : std_logic_vector ) RETURN std_logic_vector IS ALIAS rv : std_logic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_logic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(xor_table (l, rv(i))); END LOOP; RETURN result; END "xnor"; ------------------------------------------------------------------- FUNCTION "xnor" ( l : std_ulogic; r : std_ulogic_vector ) RETURN std_ulogic_vector IS ALIAS rv : std_ulogic_vector ( 1 TO r'LENGTH ) IS r; VARIABLE result : std_ulogic_vector ( 1 TO r'LENGTH ); BEGIN FOR i IN result'RANGE LOOP result(i) := not_table(xor_table (l, rv(i))); END LOOP; RETURN result; END "xnor"; Resolution: The analysis is accepted.