480 likes | 493 Views
ECE 545 Lecture 7. Modeling of Arithmetic Circuits. Adders. 16-bit Unsigned Adder. 16. 16. X. Y. Cout. Cin. S. 16. Comparators. 4-bit Number Comparator. 4. A. AeqB. AgtB. 4. B. AltB. Operators in standard VHDL. Unsigned and Signed Data Types. Signed and Unsigned Types.
E N D
ECE 545 Lecture 7 Modeling of Arithmetic Circuits
Adders ECE 448 – FPGA and ASIC Design with VHDL
16-bit Unsigned Adder 16 16 X Y Cout Cin S 16
Comparators ECE 448 – FPGA and ASIC Design with VHDL
4-bit Number Comparator 4 A AeqB AgtB 4 B AltB
Operators in standard VHDL Chapter 3
Unsigned and Signed Data Types ECE 448 – FPGA and ASIC Design with VHDL
Signed and Unsigned Types Behave exactly like STD_LOGIC_VECTOR plus, they determine whether a given vector should be treated as a signed or unsigned number. Require USE ieee.numeric_std.all;
Arithmetic operations Synthesizable arithmetic operations: • Addition, + • Subtraction, - • Comparisons, >, >=, <, <= • Multiplication, * • Division by a power of 2, /2**6(equivalent to right shift) • Shifts by a constant, SHL, SHR
Operations on Unsigned Numbers For operations on unsigned numbers USE ieee.numeric_std.all and signals of the type UNSIGNED and conversion functions: std_logic_vector(), unsigned() OR USE ieee.std_logic_unsigned.all and signals of the type STD_LOGIC_VECTOR (recommended) (permitted)
Operations on Signed Numbers For operations on signed numbers USE ieee.numeric_std.all, signals of the type SIGNED, and conversion functions: std_logic_vector(), signed() OR USE ieee.std_logic_signed.all and signals of the type STD_LOGIC_VECTOR (recommended) (permitted)
Integer Types Operations on signals (variables) of the integer types: INTEGER, NATURAL, and their sybtypes, such as TYPE day_of_month IS RANGE 1 TO 31; are synthesizable in the range -(231-1) .. 231 -1 for INTEGERs and their subtypes 0 .. 231 -1 for NATURALs and their subtypes
Integer Types Operations on signals (variables) of the integer types: INTEGER, NATURAL, are less flexible and more difficult to control than operations on signals (variables) of the type STD_LOGIC_VECTOR UNSIGNED SIGNED, and thus are recommened to be avoided by beginners.
Addition of Unsigned Numbers (1) LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.numeric_std.all ; ENTITY adder16 IS PORT ( Cin : IN STD_LOGIC ; X, Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ; S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) ; Cout : OUT STD_LOGIC ) ; END adder16 ;
Addition of Unsigned Numbers (2) ARCHITECTURE Behavior OF adder16 IS SIGNAL Xs : UNSIGNED(15 DOWNTO 0); SIGNAL Ys : UNSIGNED(15 DOWNTO 0); SIGNAL Sum : UNSIGNED(16 DOWNTO 0) ; BEGIN Xs <= unsigned(X); Ys <= unsigned(Y); Sum <= ('0' & X) + Y + Cin ; S <= std_logic_vector(Sum(15 DOWNTO 0)) ; Cout <= Sum(16) ; END Behavior ;
Addition of Unsigned Numbers (3) LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_unsigned.all ; ENTITY adder16 IS PORT ( Cin : IN STD_LOGIC ; X, Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ; S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) ; Cout : OUT STD_LOGIC ) ; END adder16 ; ARCHITECTURE Behavior OF adder16 IS SIGNAL Sum : STD_LOGIC_VECTOR(16 DOWNTO 0) ; BEGIN Sum <= ('0' & X) + Y + Cin ; S <= Sum(15 DOWNTO 0) ; Cout <= Sum(16) ; END Behavior ;
Addition of Signed Numbers (1) LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.numeric_std.all ; ENTITY adder16 IS PORT ( Cin : IN STD_LOGIC ; X, Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ; S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) ; Overflow : OUT STD_LOGIC ) ; END adder16 ;
Addition of Signed Numbers (2) ARCHITECTURE Behavior OF adder16 IS SIGNAL Xs : SIGNED(15 DOWNTO 0); SIGNAL Ys : SIGNED(15 DOWNTO 0); SIGNAL Sum : SIGNED(16 DOWNTO 0) ; BEGIN Xs <= signed(X); Ys <= signed(Y); Sum <= ('0' & X) + Y + Cin ; S <= std_logic_vector(Sum(15 DOWNTO 0)) ; Overflow <= Sum(16) XOR X(15) XOR Y(15) XOR Sum(15) ; END Behavior ;
Addition of Signed Numbers (3) LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_signed.all ; ENTITY adder16 IS PORT ( Cin : IN STD_LOGIC ; X, Y : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ; S : OUT STD_LOGIC_VECTOR(15 DOWNTO 0) ; Overflow : OUT STD_LOGIC ) ; END adder16 ; ARCHITECTURE Behavior OF adder16 IS SIGNAL Sum : STD_LOGIC_VECTOR(16 DOWNTO 0) ; BEGIN Sum <= ('0' & X) + Y + Cin ; S <= Sum(15 DOWNTO 0) ; Overflow <= Sum(16) XOR X(15) XOR Y(15) XOR Sum(15) ; END Behavior ;
Addition of Signed Numbers (4) ENTITY adder16 IS PORT ( X, Y : IN INTEGER RANGE -32768 TO 32767 ; S : OUT INTEGER RANGE -32768 TO 32767 ) ; END adder16 ; ARCHITECTURE Behavior OF adder16 IS BEGIN S <= X + Y ; END Behavior ;
Multiplication of signed and unsigned numbers (1) LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all ; entity multiply is port( a : in STD_LOGIC_VECTOR(7 downto 0); b : in STD_LOGIC_VECTOR(7 downto 0); cu : out STD_LOGIC_VECTOR(15 downto 0); cs : out STD_LOGIC_VECTOR(15 downto 0) ); end multiply; architecture dataflow of multiply is SIGNAL sa: SIGNED(7 downto 0); SIGNAL sb: SIGNED(7 downto 0); SIGNAL sc: SIGNED(15 downto 0); SIGNAL ua: UNSIGNED(7 downto 0); SIGNAL ub: UNSIGNED(7 downto 0); SIGNAL uc: UNSIGNED(15 downto 0);
Multiplication of signed and unsigned numbers (2) begin -- signed multiplication sa <= SIGNED(a); sb <= SIGNED(b); sc <= sa * sb; cs <= STD_LOGIC_VECTOR(sc); -- unsigned multiplication ua <= UNSIGNED(a); ub <= UNSIGNED(b); uc <= ua * ub; cu <= STD_LOGIC_VECTOR(uc); end dataflow;
Arithmetic operations The result of synthesis of an arithmetic operation is a - combinational circuit - without pipelining. The exact internal architecture used (and thus delay and area of the circuit) may depend on the timing constraints specified during synthesis (e.g., the requested maximum clock frequency).
IEEE numeric_std package • How to infer arithmetic operators? • In standard VHDL: signal a, b, sum: integer; . . . sum <= a + b; • What’s wrong with integer data type? Chapter 3
IEEE numeric_std package: define integer as a an array of elements of std_logic • Two new data types: unsigned, signed • The array interpreted as an unsigned or signed binary number • E.g., signal x, y: signed(15 downto 0); • Need invoke package to use the data type library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; Chapter 3
E.g., Chapter 3
Type conversion • Std_logic_vector, unsigned, signed are defined as an array of element of std_logic • They considered as three different data types in VHDL • Type conversion between data types: • type conversion function • Type casting (for “closely related” data types) Chapter 3
E.g. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; . . . signal s1, s2, s3, s4, s5, s6: std_logic_vector(3 downto 0); signal u1, u2, u3, u4, u6, u7: unsigned(3 downto 0); signal sg: signed(3 downto 0); Chapter 3
E.g. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; . . . signal s1, s2, s3, s4, s5, s6: std_logic_vector(3 downto 0); signal u1, u2, u3, u4, u6, u7: unsigned(3 downto 0); signal sg: signed(3 downto 0); Chapter 3
Ok u3 <= u2 + u1; --- ok, both operands unsigned u4 <= u2 + 1; --- ok, operands unsigned and natural • Wrong u5 <= sg; -- type mismatch u6 <= 5; -- type mismatch • Fix u5 <= unsigned(sg); -- type casting u6 <= to_unsigned(5,4); -- conversion function Chapter 3
Wrong u7 <= sg + u1; -- + undefined over the types • Fix u7 <= unsigned(sg) + u1; -- ok, but be careful • Wrong s3 <= u3; -- type mismatch s4 <= 5; -- type mismatch • Fix s3 <= std_logic_vector(u3); -- type casting s4 <= std_logic_vector(to_unsigned(5,4)); Chapter 3
Wrong s5 <= s2 + s1; + undefined over std_logic_vector s6 <= s2 + 1; + undefined • Fix s5 <= std_logic_vector(unsigned(s2) + unsigned(s1)); s6 <= std_logic_vector(unsigned(s2) + 1); Chapter 3
Non-IEEE package • Packagea by Synopsys • std_logic_arith: • Similar to numeric_std • New data types: unsigned, signed • Details are different • std_logic_unsigned/ std_logic_signed • Treat std_logic_vector as unsigned and signed numbers • i.e., overload std_logic_vector with arith operations Chapter 3
Software vendors frequently store them in ieee library: • E.g., library ieee; use ieee.std_logic_1164.all; use ieee.std_arith_unsigned.all; . . . signal s1, s2, s3, s4, s5, s6: std_logic_vector(3 downto 0); . . . s5 <= s2 + s1; -- ok, + overloaded with std_logic_vector s6 <= s2 + 1; -- ok, + overloaded with std_logic_vector Chapter 3
Only one of the std_logic_unsigned and std_logic_signed packages can be used • The std_logic_unsigned/std_logic_signed packages beat the motivation behind a strongly-typed language • Numeric_std is preferred Chapter 3
IEEE Packages for Arithmetic • std_logic_1164 • Official IEEE standard • Defines std_logic and std_logic_vector • example: std_logic_vector(7 downto 0) • These are for logic operations (AND, OR) not for arithmetic operations (+, *) • std_logic_arith • Not official IEEE standard (created by Synopsys) • Defines unsigned and signed data types, example: unsigned(7 downto 0) • These are for arithmetic (+,*) not for logic (AND, OR) • std_logic_unsigned • Not official IEEE standard (created by Synopsys) • Including this library tells compiler to treat std_logic_vector like unsigned type in certain cases • For example, can perform addition on std_logic_vector • Used as a helper to avoid explicit conversion functions • std_logic_signed • Not official IEEE standard (created by Synopsys) • Same functionality as std_logic_unsigned except tells compiler to treat std_logic_vector like signed type in certain cases • Do not use both std_logic_unsigned and std_logic_signed at the same time! • If need to do both signed and unsigned arithmetic in same entity, do not use std_logic_unsigned or std_logic_signed packages do all conversions explicitly
Library inclusion • When dealing with unsigned arithmetic use: LIBRARY IEEE; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; needed for using unsigned data type USE ieee.std_logic_unsigned.all; • When dealing with signed arithmetic use: LIBRARY IEEE; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; need for using signed data type USE ieee.std_logic_signed.all; • When dealing with both unsigned and signed arithmetic use: LIBRARY IEEE; USE ieee.std_logic_1164.all; USE ieee.std_logic_arith.all; Then do all type conversions explicitly
History: std_logic_arith versus numeric_std • History • Package std_logic_arith created by Synopsys as a stop-gap measure • Eventually, the IEEE created their own official “version” of std_logic_arith called numeric_std • numeric_std • Official IEEE standard • Defines unsigned and signed • These are for arithmetic (+,*) not for logic (AND, OR) • example: unsigned(7 downto 0) • Use either numeric_std or std_logic_arith, not both! • When dealing with unsigned and/or signed types using numeric_std, use: LIBRARY IEEE; USE ieee.std_logic_1164.all; USE ieee.numeric_std.all; • Since different CAD vendors may implement std_logic_arith differently, you can use numeric_std to be safe • However … many legacy designs and companies use std_logic_arith in combination with std_logic_unsigned or std_logic_signed • Examples in class may occasionally use std_logic_arith or std_logic_unsigned/signed • If you use numeric_std, make sure to declare it properly so all code compiles
Example: std_logic_arith versus numeric_std UNSIGNED ADDER WITH NO CARRYOUT library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.std_logic_arith.all; -- not needed but keep for style use IEEE.std_logic_unsigned.all; entity adder is port( a : in STD_LOGIC_VECTOR(2 downto 0); b : in STD_LOGIC_VECTOR(2 downto 0); c : out STD_LOGIC_VECTOR(2 downto 0) ); end adder; architecture adder_arch of adder is begin c <= a + b; end adder_arch; library IEEE; use IEEE.STD_LOGIC_1164.all; use IEEE.numeric_std.all; entity adder is port( a : in STD_LOGIC_VECTOR(2 downto 0); b : in STD_LOGIC_VECTOR(2 downto 0); c : out STD_LOGIC_VECTOR(2 downto 0) ); end adder; architecture adder_arch of adder is begin c <= std_logic_vector(unsigned(a) + unsigned(b)); end adder_arch; Tells compiler totreat std_logic_vectorlike unsigned type
Conversion functions From: http://dz.ee.ethz.ch/support/ic/vhdl/vhdlsources.en.html
More information? • Go to: • http://dz.ee.ethz.ch/support/ic/vhdl/vhdlsources.en.html • Download • std_logic_arith.vhd • std_logic_unsigned.vhd • std_logic_signed.vhd • numeric_std • …and compare them