IEEE P1164 Working Group - Change Proposal ID: CP-002 Proposer: Peter Ashenden (Based on input from requirements gathering.) Status: Proposed (1-Jun-2001) Analyzed (17-Nov-2002) Resovled (17-Feb-2003) Summary: Add shift operators for vector types Detail: The revision of IEEE Std 1076 in 1993 added shift operators for operands whose type is a one-dimensional array of bit or boolean. It is proposed to add overloaded declarations of the shift operators to P1164 for operands of type std_ulogic_vector and std_logic_vector. The following declarations should be added to the package declaration of std_logic_1164: ------------------------------------------------------------------- -- overloaded shift operators ------------------------------------------------------------------- function "sll" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector; function "sll" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector; function "srl" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector; function "srl" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector; function "sla" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector; function "sla" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector; function "sra" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector; function "sra" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector; function "rol" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector; function "rol" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector; function "ror" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector; function "ror" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector; The declarations should be added to the package body of std_logic_1164: ------------------------------------------------------------------- -- overloaded shift operators ------------------------------------------------------------------- ------------------------------------------------------------------- -- sll ------------------------------------------------------------------- FUNCTION "sll" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( l'RANGE ) := (OTHERS => '0'); ALIAS resultv : std_logic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(1 TO l'LENGTH - r) := lv(r+1 TO l'LENGTH); END IF; RETURN result; ELSE RETURN l SRL (-r); END IF; END "sll"; ------------------------------------------------------------------- FUNCTION "sll" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( l'RANGE ) := (OTHERS => '0'); ALIAS resultv : std_ulogic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(1 TO l'LENGTH - r) := lv(r+1 TO l'LENGTH); END IF; RETURN result; ELSE RETURN l SRL (-r); END IF; END "sll"; ------------------------------------------------------------------- -- srl ------------------------------------------------------------------- FUNCTION "srl" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( l'RANGE ) := (OTHERS => '0'); ALIAS resultv : std_logic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(r+1 TO l'LENGTH) := lv(1 TO l'LENGTH - r); END IF; RETURN result; ELSE RETURN l SLL (-r); END IF; END "srl"; ------------------------------------------------------------------- FUNCTION "srl" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( l'RANGE ) := (OTHERS => '0'); ALIAS resultv : std_ulogic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(r+1 TO l'LENGTH) := lv(1 TO l'LENGTH - r); END IF; RETURN result; ELSE RETURN l SLL (-r); END IF; END "srl"; ------------------------------------------------------------------- -- sla ------------------------------------------------------------------- FUNCTION "sla" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( l'RANGE ) := (OTHERS => l(l'RIGHT)); ALIAS resultv : std_logic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(1 TO l'LENGTH - r) := lv(r+1 TO l'LENGTH); END IF; RETURN result; ELSE RETURN l SRA (-r); END IF; END "sla"; ------------------------------------------------------------------- FUNCTION "sla" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( l'RANGE ) := (OTHERS => l(l'RIGHT)); ALIAS resultv : std_ulogic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(1 TO l'LENGTH - r) := lv(r+1 TO l'LENGTH); END IF; RETURN result; ELSE RETURN l SRA (-r); END IF; END "sla"; ------------------------------------------------------------------- -- sra ------------------------------------------------------------------- FUNCTION "sra" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( l'RANGE ) := (OTHERS => l(l'LEFT)); ALIAS resultv : std_logic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(r+1 TO l'LENGTH) := lv(1 TO l'LENGTH - r); END IF; RETURN result; ELSE RETURN l SLA (-r); END IF; END "sra"; ------------------------------------------------------------------- FUNCTION "sra" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( l'RANGE ) := (OTHERS => l(l'LEFT)); ALIAS resultv : std_ulogic_vector ( 1 TO l'LENGTH ) IS result; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN IF r < l'LENGTH THEN resultv(r+1 TO l'LENGTH) := lv(1 TO l'LENGTH - r); END IF; RETURN result; ELSE RETURN l SLA (-r); END IF; END "sra"; ------------------------------------------------------------------- -- rol ------------------------------------------------------------------- FUNCTION "rol" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( l'RANGE ); ALIAS resultv : std_logic_vector ( 1 TO l'LENGTH ) IS result; VARIABLE rv : integer; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN rv := r MOD l'length; resultv(1 TO l'LENGTH - rv ) := lv(rv+1 TO l'LENGTH); resultv(l'LENGTH - rv + 1 TO l'length) := lv(1 TO rv); RETURN result; ELSE RETURN l ROR (-r); END IF; END "rol"; ------------------------------------------------------------------- FUNCTION "rol" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( l'RANGE ); ALIAS resultv : std_ulogic_vector ( 1 TO l'LENGTH ) IS result; VARIABLE rv : integer; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN rv := r MOD l'length; resultv(1 TO l'LENGTH - rv ) := lv(rv+1 TO l'LENGTH); resultv(l'LENGTH - rv + 1 TO l'LENGTH) := lv(1 TO rv); RETURN result; ELSE RETURN l ROR (-r); END IF; END "rol"; ------------------------------------------------------------------- -- ror ------------------------------------------------------------------- FUNCTION "ror" ( l : std_logic_vector; r : integer ) RETURN std_logic_vector IS ALIAS lv : std_logic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_logic_vector ( l'RANGE ); ALIAS resultv : std_logic_vector ( 1 TO l'LENGTH ) IS result; VARIABLE rv : integer; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN rv := r MOD l'length; resultv(rv+1 TO l'LENGTH) := lv(1 TO l'LENGTH - rv); resultv(1 TO rv) := lv(l'LENGTH - rv + 1 TO l'LENGTH); RETURN result; ELSE RETURN l ROL (-r); END IF; END "ror"; ------------------------------------------------------------------- FUNCTION "ror" ( l : std_ulogic_vector; r : integer ) RETURN std_ulogic_vector IS ALIAS lv : std_ulogic_vector ( 1 TO l'LENGTH ) IS l; VARIABLE result : std_ulogic_vector ( l'RANGE ); ALIAS resultv : std_ulogic_vector ( 1 TO l'LENGTH ) IS result; VARIABLE rv : integer; BEGIN IF r = 0 OR l'LENGTH = 0 THEN RETURN l; ELSIF r > 0 THEN rv := r MOD l'length; resultv(rv+1 TO l'LENGTH) := lv(1 TO l'LENGTH - rv); resultv(1 TO rv) := lv(l'LENGTH - rv + 1 TO l'LENGTH); RETURN result; ELSE RETURN l ROL (-r); END IF; END "ror"; Analysis: By Peter Ashenden , 17-Nov-2002 The implementations of the operators are based on the specifications in IEEE Std 1076 for the corresponding operators on vectors of bits and booleans. The package ieee.numeric_std defines overloaded version of the shift operators for operands of type signed and unsigned, but they cannot be applied to operands of type std_logic_vector or std_ulogic_vector without type conversion. Furthermore, an implementation that supports std_logic_1164 need not necessarily support numeric_std, so the operations may not be available. Changes to 1164-1993: - Insert the function declarations in the package declaration between the overloaded logical operators and the conversion functions. - Insert the function bodies in the package body between the overloaded logical operators and the conversion table declarations. Resolution: Analysis accepted Member votes: Accept 13 (100%) Reject 0 (0%) Abstain 0 (0%) All votes: Accept 15 (100%) Reject 0 (0%) Abstain 0 (0%) From Jose Torres I would suggest to add a comment in each function to indicate how the shift is done and what happens to the n bit.