Addizione tra numeri binari A=a n-1 a n-2...a i...a 0 B=b n-1 b n-2...b i...b 0 s i =a i b i c in c out =a i b i + a i c in + b i c in a i b i FA c out c in S=s n s n-1 s n-2...s i...s 0 s i a n 1 b n 1 a n 2 b n 2 a 1 b 1 a 0 b 0 FA FA FA FA c out c in c out c in c out c in c out c in s n carry out s n 1 s n 2 s 1 s 0 A,B [0,2 n -1] S [0,2 n+1-1] 1
Numeri con il segno (complemento a 2) A=a n-1 a n-2...a i...a 0 con a i {0,1} rappresenta un numero tra 0 e 2 n -1 def.: B=-A è un numero tale che A+B=0 (A - A = 0) Al posto della definizione di sopra utilizziamo la seguente def.: B=-A è un numero tale che A+B=2 n dove 2 n in binario viene rappresentato da S=s n s n-1 s n-2...s i...s 0 con s n =1, s i =0 i [0,n-1]. th.: B=-A, B=b n-1 b n-2...b i...b 0 => B=( a n-1 a n-2...a i...a 0 ) +1 Dim.: (a n-1 a n-2...a i...a 0 )+ (a n-1 a n-2...a i...a 0 )= 11...1...1 (11...1...1=2 n -1) (a n-1 a n-2...a i...a 0 )+ (a n-1 a n-2...a i...a 0 +1) = 2 n -A Trascurando l'ultimo bit del sommatore possiamo quindi utilizzare la stessa struttura vista prima per fare le addizioni tra numeri con il segno. 2
Numeri con il segno (complemento a 2) Quindi un vettore di n bits puo rappresentare: un numero senza segno compreso tra 0 e 2 n -1 un numero con il segno compreso tra -2 n-1 e 2 n-1-1 N.B.: tutti i numeri negativi hanno il bit più significativo ad 1, tutti quelli positivi hanno il bit più significativo a 0 N.M.B.: questo non vuol dire che cambiando l'ultimo bit passo da A a -A Per la somma di due vettori di bit si usa il sommatore descritto in precedenza. E' l' utilizzatore del sommatore che sa se i vettori rappresentano numeri con il segno o senza. BIT SIGNED UNSIGNED A B S=A+B A B S=A+B A B S=A+B 1001 0100 1101-7 4-3 9 4 13 3
Aritmetica in VHDL package std_logic_1164 is type std_logic_vector is array ( NATURAL range <>) of STD_LOGIC; Il package std_logic_1164 definisce il tipo di dato std_logic_vector package std_logic_arith is type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; type SIGNED is array (NATURAL range <>) of STD_LOGIC; function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: SIGNED) return SIGNED; Il package std_logic_arith definisce due tipi corrispondenti ai numeri interi con il segno e senza il segno. Inoltre il VHDL contiene tra i tipi predefiniti il tipo INTEGER Su questi quattro tipi di dato si possono effettuare le operazioni aritmetiche 4
Operazioni Aritmetiche sintetizzabili in VHDL Addizione, + Sottrazione, - Confronti, >, >=, <, <= Moltiplicazione, * Divisione per una potenza di 2 (equivale a un right shift) Shift per una costante, (SHL, SHR) 5
Operazioni aritmetiche utilizzando std_logic_arith... LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_arith.all ; LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_arith.all ; Signal A, B: UNSIGNED(7 DOWNTO 0) ; Signal S: UNSIGNED(7 DOWNTO 0) ; S <= A+B; Signal A, B: SIGNED(7 DOWNTO 0) ; Signal S: SIGNED(7 DOWNTO 0) ; S <= A+B; 6
... utilizzando std_logic_unsigned e std_logic_signed... LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_unsigned.all ; LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_signed.all ; Signal A, B: STD_LOGIC_VECTOR (7 DOWNTO 0) ; Signal S: STD_LOGIC_VECTOR (7 DOWNTO 0) ; S <= A+B; Signal A, B: STD_LOGIC_VECTOR(7 DOWNTO 0) ; Signal S: STD_LOGIC_VECTOR(7 DOWNTO 0) ; S <= A+B; 7
... e utilizzando gli integer LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_arith.all ; LIBRARY ieee ; USE ieee.std_logic_1164.all ; USE ieee.std_logic_arith.all ; Signal A, B,C: INTEGER; Signal S: UNSIGNED (7 downto 0); C<=A+B; S <= CONV_UNSIGNED(C,8); Signal A, B,C: INTEGER; Signal S: SIGNED (7 downto 0); C<=A+B; S <= CONV_SIGNED(C,8); 8
library ieee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity signed_resize_larger is port(a : in signed(7 downto 0); z : out signed(15 downto 0) ); architecture behavior of signed_resize_larger is begin z <= conv_signed(a, 16); msb lsb
library ieee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity signed_resize_larger is port(a : in signed(7 downto 0); z : out signed(15 downto 0) ); architecture behavior of signed_resize_larger is begin z <= conv_signed(a, z length); msb lsb
library ieee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity unsigned_resize_larger is port(a : in unsigned(7 downto 0); z : out unsigned(15 downto 0) ); architecture behavior of unsigned_resize_larger is begin z <= conv_unsigned(a, 16); 0 0 0 0 0 0 0 0 msb lsb
library ieee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity signed_resize_smaller is port(a : in signed(15 downto 0); z : out signed(7 downto 0) ); architecture behavior of signed_resize_smaller is begin z <= conv_signed(a, 8); msb lsb
Library iee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity unsigned_resize_smaller is port(a : in unsigned(15 downto 0); z : out unsigned(7 downto 0) ); architecture behavior of unsigned_resize_smaller is begin z <= conv_unsigned(a, 8); msb lsb
Library iee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity unsigned_slice is port(a : in unsigned(15 downto 0); z : out unsigned(7 downto 0) ); architecture behavior of unsigned_slice is begin z <= a(7 downto 0); msb lsb
Shift functions: std_logic_arith signed and unsigned Shift left logical 4 bit msb lsb 0 0 0 0
Unsigned Shift right functions 0 0 0 0 msb lsb Signed Shift Right Functions msb lsb
Type Conversions Type conversion function: conv_type type:integer, signed, unsigned, std_logic_vector asig:integer, signed, unsigned, std_logic_vector conv_integer(asig): convert asig to integer conv_integer(aint, n): convert aint to n bit integer conv_unsigned(asig,n): convert asig to n bit unsigned conv_signed(asig,n): convert asig to n bit signed conv_std_logic_vector(asig,n):convert asig to n bit std_logic_vector
Type Conversions library iee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity conversion_demo is port(value : in natural range 0 to 255; result : out unsigned(7 downto 0) ); architecture behavior of conversion_demo is begin result <= conv_signed(value,result length);
Type Conversions std_logic_vector ==> signed or unsigned library iee; use ieee.std_logic_arith.all; use ieee.std_logc_1164.all; entity conversion_demo is port(value : in std_logic_vector(7 downto 0); result : out unsigned(7 downto 0) ); architecture behavior of conversion_demo is begin result <= unsigned(value);
std_logic_arith library IEEE; use IEEE.std_logic_1164.ALL; PACKAGE std_logic_arith is type UNSIGNED is array (NATURAL range <>) of STD_LOGIC; type SIGNED is array (NATURAL range <>) of STD_LOGIC; subtype SMALL_INT is INTEGER range 0 to 1; function "+"(L: UNSIGNED; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: SIGNED) return SIGNED; function "+"(L: UNSIGNED; R: SIGNED) return SIGNED; function "+"(L: SIGNED; R: UNSIGNED) return SIGNED; function "+"(L: UNSIGNED; R: INTEGER) return UNSIGNED; function "+"(L: INTEGER; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: INTEGER) return SIGNED; function "+"(L: INTEGER; R: SIGNED) return SIGNED; function "+"(L: UNSIGNED; R: STD_ULOGIC) return UNSIGNED; function "+"(L: STD_ULOGIC; R: UNSIGNED) return UNSIGNED; function "+"(L: SIGNED; R: STD_ULOGIC) return SIGNED; function "+"(L: STD_ULOGIC; R: SIGNED) return SIGNED; u, v, w: unsigned( n DOWTO 0); s, r, t: signed( n DOWTO 0); i, j, k: integer; u <= v + w; s <= r + t; s <= u + r; s <= r + u; u <= v + j; u <= j + v; s <= r + j;