Sunteți pe pagina 1din 14

UNIVERSIDAD POLITCNICA DE VICTORIA

MAESTRA EN INGENIERA

ESPECIALIDAD: MECATRNICA

ASIGNATURA: PROCESADORES DIGITALES

CATEDRTICO: DR. MARCO AURELIO NUO MAGANDA

ALUMNO: JOSU HEL JIMNEZ ARTEAGA

REPORTE DE PRCTICA: 04

SUMADOR DE NMEROS DE PUNTO FLOTANTE


INTRODUCCIN Se implementar un circuito sumador de nmeros de punto flotante. Para comprobar su funcionamiento se utilizar una precisin sencilla La representacin en punto flotante est basada en la notacin cientfica: El punto decimal no se halla en una posicin fija dentro de la secuencia de bits, sino que su posicin se indica como una potencia de la base:

Figura 1. Representacin en punto flotante

En todo nmero de punto flotante se distinguen tres componentes: Signo: indica el signo del nmero (0 = positivo, 1 = negativo) Mantisa: contiene la magnitud del nmero (en binario puro) Exponente: contiene el valor de la potencia de la base (sesgado) La base queda implcita y es comn a todos los nmeros, la ms usada es 2. Dado que un mismo nmero puede tener varias representaciones, los nmeros suelen estar normalizados. Un nmero est normalizado si tiene la forma 1.xx2xx. Los nmeros normalizados en base 2 tienen siempre un 1 a la izquierda, ste suele quedar implcito. (1) El estndar IEEE 754 especifica tres formatos de precisin:
SIGNO 1 BIT

PRECISIN SENCILLA (32 BITS)


EXPONENTE 8 BITS MANTISA 23 BITS

SIGNO 1 BIT

EXPONENTE 11 BITS

PRECISIN DOBLE (64 BITS)

MANTISA 52 BITS

SIGNO 1 BIT

EXPONENTE 15 BITS

PRECISIN CUDRUPLE (128 BITS)

MANTISA 112 BITS

DESARROLLO Para llevar a cabo la suma de dos nmeros de punto flotante se siguen los pasos enlistados a continuacin: 1. Se comparan los exponentes de los dos nmeros y realizan operaciones de corrimiento hacia la derecha del menor, incrementando en 1 a su exponente, hasta que sea igual que el mayor. 2. Se suman las fracciones. 3. Se normaliza el resultado de la suma, haciendo los corrimientos necesarios a la mantisa e incrementando el exponente de la suma, esto en caso necesario. 4. Se redondea la suma en caso de que los dgitos sean diferentes a los bits utilizados por los operandos originales. La comparacin de los exponentes se lleva a cabo mediante una resta, por lo que fue necesario implementar una ALU (figura 2).

Figura 2. Diagrama a bloques de una ALU de 4 Bits

El funcionamiento de la ALU se describe por medio de las siguientes tablas:


Tabla 1. Tabla de funcionamiento de la ALU

S2 0 0 0 0 1 1 1 1

S1 0 0 1 1 0 0 1 1

S0 0 1 0 1 0 1 0 1

OPERACIN PASSTHROUGH A AND B A OR B NOT A A+B AB A+1 A1

X(LE) A A AND B A OR B A A A A A

Y(AE) 0 0 0 0 B B 0 1

C0(CE) 0 0 0 0 0 1 1 0

Para el primer paso, se realiza una resta de los exponentes, utilizando la diferencia como sumando para el menor exponente y como el nmero de corrimientos hechos a la mantisa para tener ahora dos cantidades normalizadas con el mismo exponente. Al hacer los corrimientos, se toma en cuenta el bit oculto, el cual qued implcito en la primera normalizacin para el nmero de punto flotante y ahora pasar a tomar el valor de 0. En caso de que los exponentes originalmente sean iguales, no se realizar corrimiento en las mantisas, ni suma en los exponentes. La seleccin del nmero con menor mantisa se hizo mediante un multiplexor genrico 2 a 1, de 8 bits para el exponente y 23 bits para la mantisa. En el segundo paso, se suman las mantisas (que ahora tienen el mismo exponente). Si se generara overflow en esta suma, se hara un nuevo corrimiento para normalizar el resultado de la suma, tomando en cuenta el bit implcito de la mantisa para introducirlo como primer bit del corrimiento hacia la derecha; adems, se incrementara el exponente en 1. Dentro del diseo que realiza los corrimientos, se implement una comparacin la cual revisa que el nmero de corrimientos sea menor que el nmero de bits de la mantisa, y en caso contrario hace un redondeo, poniendo el bit menos significativo en 1. RESULTADOS Una vez realizado el diseo completo, se comprob su funcionalidad utilizando un testbench, en el que se guardan los dos operandos de punto flotante para ser sumados. Como primera prueba se hizo la suma de los nmeros 0.25 y 100, los cuales en notacin de punto flotante (precisin sencilla) se representan respectivamente de la siguiente manera:
SIGNO 0 SIGNO 0 EXPONENTE 0111 1101 EXPONENTE 1000 0101 MANTISA 00000000000000000000000 MANTISA 10010000000000000000000

La diferencia entre los exponentes es de 8, por lo que al exponente menor se le sumar 8, y se harn 8 corrimientos a la mantisa. Quedando la siguiente suma: +
= SIGNO 0 0 0 EXPONENTE 1000 0101 1000 0101 1000 0101 MANTISA 00000001000000000000000 10010000000000000000000 10010001000000000000000

El exponente del resultado qued igual ya que no fue necesario volver a normalizar el resultado. El resultado final es mostrado en la figura 3.

Figura 3a. Exponente del resultado

Figura 3b. Mantisa del resultado

Prueba de otra suma: 9.75 + 22.4375 9.7510 = 1001.112 x 20 = 1.001112 x 23 Exponente: 3 + 127 = 13010 = 100000102 22.437510 = 10110.01112 x 20 = 1.011001112 x 24 Exponente: 4 + 127 = 13110 = 100000112

SIGNO 0 SIGNO 0

EXPONENTE 1000 0010 EXPONENTE 1000 0011

MANTISA 00111000000000000000000 MANTISA 01100111000000000000000

Al restar los exponentes, la diferencia es 1, por lo que se suma 1 al exponente menor y se hace un corrimiento a la mantisa correspondiente; quedando la siguiente suma: +
= SIGNO 0 0 0 EXPONENTE 1000 0011 1000 0011 1000 0011 MANTISA 10011100000000000000000 01100111000000000000000 00000011000000000000000

En la mantisa del resultado hubo un overflow, por lo que al resultado se le hace un corrimiento y se incrementa el exponente, quedando como resultado normalizado:
SIGNO 0 EXPONENTE 1000 0100 MANTISA 00000001100000000000000

Agrupando los bits del resultado en conjuntos de 4 bits: 0100 0010 0000 0000 1100 0000 0000 0000 Que equivale en hexadecimal: 4 2 0 0 C 0 0 0 El resultado de la suma en punto flotante es: 1.0000000112 x 2132, que al regresarlo a notacin de nmero real, se obtiene: 1.0000000112 x 25 = 100000.00112 x 20 = 32.187510, el cual es el resultado de la suma. 9.75 + 22.4375 = 32.1875 Utilizando otro testbench en el que se agruparon el bit de signo, exponente y mantisa en un vector de 32 bits, se obtiene la forma de onda mostrada en la figura 4, en la cual se puede apreciar el valor del resultado en hexadecimal obtenido anteriormente (4200C000h)

Figura 4. Resultado de la suma de punto flotante

CONCLUSIONES El diseo se facilit al haber definido claramente los pasos a seguir, programando as un bloque o grupo de bloques que se encargaran de las funciones necesarias en cada paso. Esta implementacin se realiz tambin tomando en cuenta la caracterstica de flexibilidad en lo que se refiere al nmero de bits utilizados para mantisa y exponente, en otras palabras, para usar otro tipo de precisin. El enfoque utilizado fue seleccionado a conveniencia y facilidad segn el circuito diseado, tomando como recurso final el enfoque estructural, y definiendo cada bloque utilizado de ambas maneras, estructural y comportamental. REFERENCIAS
(1)

B. Parhami: Computer Arithmetic: Algorithms and Hardware Design, Ed. Oxford. (Diapositivas: http://www.fdi.ucm.es/profesor/mozos/AEC/aritm_pf.PDF)

ANEXOS Cdigo fuente del diseo Archivo: AE.vhd


library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity AE is port( -- DECLARACION DE PUERTOS S : in STD_LOGIC_VECTOR(2 downto 0); Bi : in STD_LOGIC; Yi : out STD_LOGIC ); end AE; architecture AE_arq of AE is begin -- BLOQUE AE (ARITHMETIC EXTENDER) PARA ALU Yi <= '1' when (S = "100" and Bi = '1') else '1' when (S = "101" and Bi = '0') else '1' when (S = "111") else '0'; end AE_arq;

Archivo: LE.vhd
library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity LE is port( -- DECLARACION DE PUERTOS S : in STD_LOGIC_VECTOR(2 downto 0); ai : in STD_LOGIC; bi : in STD_LOGIC; Xi : out STD_LOGIC );

end LE;

architecture LE_arq of LE is begin -- BLOQUE LE (LOGIC EXTENDER) PARA ALU Xi <= ai when (S = "000") else (ai and bi) when (S = "001") else (ai or bi) when (S = "010") else not(ai) when (S = "011") else ai; end LE_arq;

Archivo: CE.vhd
library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity CE is port( -- DECLARACION DE PUERTOS S : in STD_LOGIC_VECTOR(2 downto 0); C0 : out STD_LOGIC );

end CE;

architecture CE_arq of CE is begin C0 <= '1' when (S = "101" or S = "110") else '0'; -- BLOQUE DE ACARREO DE ENTRADA PARA ALU end CE_arq;

Archivo: FA.vhd
library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity FA is port( -- DECLARACION DE PUERTOS Xi : in STD_LOGIC; Yi : in STD_LOGIC; Ci : in STD_LOGIC; Co : out STD_LOGIC; Sum : out STD_LOGIC );

end FA;

architecture FA_arq of FA is begin -- BLOQUE FA (FULL ADDER) PARA ALU Sum <= Xi xor Yi xor Ci; Co <= (Xi and Yi) or (Ci and (Xi xor Yi)); end FA_arq;

Archivo: ALU1BIT.vhd

library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity ALU1BIT is port( -- DECLARACION DE PUERTOS S : in STD_LOGIC_VECTOR(2 downto 0); ai : in STD_LOGIC; bi : in STD_LOGIC; ci : in STD_LOGIC; co : out STD_LOGIC; f : out STD_LOGIC ); end ALU1BIT; architecture ALU1BIT_arq of ALU1BIT is -- SEALES INTERMEDIAS signal xi, yi: std_logic; begin -- BLOQUE DE 1 BIT PARA LA ALU LE01: entity work.LE (LE_arq) port map (S, ai, bi, xi); AE01: entity work.AE (AE_arq) port map (S, bi, yi); FA01: entity work.FA (FA_arq) port map (xi, yi, ci, co, f); end ALU1BIT_arq;

Archivo: ALU.vhd

library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity ALU is generic( LONGITUD: positive := 8 -- AQUI SE DEFINE LA CANTIDAD DE BITS DE LA ALU ); port( -- DECLARACION DE PUERTOS S : in STD_LOGIC_VECTOR(2 downto 0); A : in STD_LOGIC_VECTOR(LONGITUD-1 downto 0); B : in STD_LOGIC_VECTOR(LONGITUD-1 downto 0); OvF : out STD_LOGIC; F : out STD_LOGIC_VECTOR(LONGITUD-1 downto 0) ); end ALU; architecture ALU_arq of ALU is -- SEALES INTERMEDIAS signal C: std_logic_vector(LONGITUD downto 0); begin -- BLOQUE DE ACARREO DE ENTRADA (CE) CE01: entity work.CE (CE_arq) port map (S, C(0)); BLOQUE_GEN: for I in 0 to LONGITUD-1 generate -- GENERA LOS BLOQUES DE LA ALU POR CADA BIT ALU1: entity work.ALU1BIT (ALU1BIT_arq) port map (S, A(I),B(I),C(I),C(I+1),F(I)); end generate BLOQUE_GEN; -- SEAL DE OVERFLOW OvF <= C(LONGITUD); end ALU_arq;

Archivo: MUX.vhd

library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity MUX is generic( LONGITUD: positive := 8 -- CANTIDAD DE BITS DEL MUX 2 A 1 ); port( -- DECLARACION DE PUERTOS s : in STD_LOGIC; A : in STD_LOGIC_VECTOR(LONGITUD-1 downto 0); B : in STD_LOGIC_VECTOR(LONGITUD-1 downto 0); Y : out STD_LOGIC_VECTOR(LONGITUD-1 downto 0) ); end MUX; architecture MUX_arq of MUX is begin Y <= A when (s = '0') else -- MULTIPLEXOR 2 A 1 B when (s = '1'); end MUX_arq;

Archivo: RSHIFT.vhd

library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIAS UTILIZADAS use IEEE.STD_LOGIC_UNSIGNED.all; use ieee.std_logic_arith.all; entity RSHIFT is generic( BITS: integer := 8 -- CANTIDAD DE BITS DEL DATO ); port( -- DECLARACION DE PUERTOS entrada : in STD_LOGIC_VECTOR(BITS-1 downto 0); shift: in STD_LOGIC_VECTOR(BITS-1 downto 0); -- CANTIDAD DE CORRIMIENTOS b0: in STD_LOGIC; salida : out STD_LOGIC_VECTOR(BITS-1 downto 0) ); end RSHIFT; architecture RSHIFT_arq of RSHIFT is signal temp,temp2: STD_LOGIC_VECTOR(BITS-1 downto 0); signal int: integer range 0 to 255; begin -- AGREGA UNA SERIE DE ...000b0 temp <= (entrada and (not(entrada))) + b0; -- CONVIERTE A ENTERO EL DATO DE ENTRADA PARA EL CORRIMIENTO int <= (conv_integer(shift)); -- CONCATENA LOS DATOS PARA HACER UN CORRIMIENTO -- Y REVISA SI HAY UNDERFLOW PARA HACER UN REDONDEO temp2 <= temp(int-1 downto 0) & entrada(BITS-1 downto int) when (int > 1 and int<BITS) else temp(BITS-1 downto 0); -- ASIGNA EL VALOR DE LA SALIDA -- SI SE HACE SOLO 1 CORRIMIENTO, SE CONCATENA EL BIT DE ENTRADA EN LA PARTE ALTA -- SI SE HACEN 0 CORRIMIENTOS, LA SALIDA ES IGUAL A LA ENTRADA salida <= temp2 when (int > 1) else b0&entrada(BITS-1 downto 1) when (int = 1) else entrada when (int = 0); end RSHIFT_arq;;

Archivo: RESTAEXP.vhd

library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity RESTAEXP is generic( LONG: integer := 8 -- CANTIDAD DE BITS DEL DATO ); port( -- DECLARACION DE PUERTOS A : in STD_LOGIC_VECTOR(LONG-1 downto 0); B : in STD_LOGIC_VECTOR(LONG-1 downto 0); C : out STD_LOGIC_VECTOR(LONG-1 downto 0); SEL1: out STD_LOGIC ); end RESTAEXP; architecture RESTAEXP_arq of RESTAEXP is signal ov1, ov2: std_logic; signal f1,f2: std_logic_vector(LONG-1 downto 0); begin -- RESTA USANDO ALU. S = 101 -- SE HACE LA RESTA A-B Y B-A, Y SELECCIONA EL VALOR ABSOLUTO DE LA DIFERENCIA SUB1: entity work.ALU (ALU_arq) port map ("101",A,B,ov1,f1); SUB2: entity work.ALU (ALU_arq) port map ("101",B,A,ov2,f2); C <= f1 when (ov1 = '1') else f2 when (ov2 = '1'); SEL1 <= ov1; end RESTAEXP_arq;

Archivo: PASO1.vhd

library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity PASO1 is generic( BFRA: positive := 23 -- BITS DE LA FRACCION ); port( -- DECLARACION DE PUERTOS mant1a : in STD_LOGIC_VECTOR(BFRA-1 downto 0); mant2a : in STD_LOGIC_VECTOR(BFRA-1 downto 0); exp1a : in STD_LOGIC_VECTOR(7 downto 0); exp2a : in STD_LOGIC_VECTOR(7 downto 0); expo : out STD_LOGIC_VECTOR(7 downto 0); mantisa : out STD_LOGIC_VECTOR(BFRA-1 downto 0) ); end PASO1; architecture PASO1_arq of PASO1 is -- SEALES INTERMEDIAS signal diferencia,expaa,expb0,expa0,expa1: std_logic_vector(7 downto 0); signal mantaa,mantb0,manta0,mants,diferencib,shf2: std_logic_vector(BFRA-1 downto 0); signal sel1,ov1,ov2,ov3,ov4,ov5,ov6,na,nb: std_logic; signal na1, nb1, nc1, shf1,ov2a,ov3a,ov4a,b0: std_logic_vector(7 downto 0); begin

-- PASO 1: -- RESTA DE EXPONENTES RE01: entity work.RESTAEXP (RESTAEXP_arq) port map (exp1a, exp2a, diferencia, sel1); -- SELECCION DEL MENOR EXPONENTE, LO GUARDA EN expaa. AL EXPONENTE MAYOR LO GUARDA EN expb0 -- A LA MANTISA DE MENOR EXPONENTE LA GUARDA EN mantaa, LA MAYOR EN mantb0 SE01: entity work.MUX (MUX_arq) generic map (LONGITUD => 8) port map (sel1,exp1a,exp2a,expaa); SE02: entity work.MUX (MUX_arq) generic map (LONGITUD => 8) port map (sel1,exp2a,exp1a,expb0); SE03: entity work.MUX (MUX_arq) generic map (LONGITUD => BFRA) port map (sel1,mant1a,mant2a,mantaa); SE04: entity work.MUX (MUX_arq) generic map (LONGITUD => BFRA) port map (sel1,mant2a,mant1a,mantb0); -- SUMA. MENOR EXPONENTE + DIFERENCIA Y LO GUARDA EN expa0. (S = 100) AD01: entity work.ALU (ALU_arq) port map ("100",expaa,diferencia,ov1,expa0); -- REALIZA CORRIMIENTO AL NUMERO CON MENOR EXPONENTE Y LO GUARDA EN manta0 diferencib <= "000000000000000"&diferencia; SH01: entity work.RSHIFT (RSHIFT_arq) generic map (BITS => BFRA) port map (mantaa,diferencib,'1',manta0); -- LO SIGUIENTE SE UTILIZARA AL NORMALIZAR LA SUMA DE MANTISAS na <= '1'; nb <= '1' when (diferencia = "00000000") else '0'; na1 <= "0000000"&na; nb1 <= "0000000"&nb; -- PASO 2: -- SUMA LAS MANTISAS NORMALIZADAS CON EL MISMO EXPONENTE Y GUARDA EN mants. (S = 100) AD02: entity work.ALU (ALU_arq) generic map (LONGITUD => BFRA) port map ("100",manta0,mantb0,ov2,mants); ov2a <= "0000000"&ov2; -- PASO 3: -- SUMA LAS N PARA HACER LA NORMALIZACION DE LA SUMA AD03: entity work.ALU (ALU_arq) port map ("100",na1,nb1,ov3,nc1); AD04: entity work.ALU (ALU_arq) port map ("100",nc1,ov2a,ov4,b0); ov3a <= "0000000"&nc1(1); ov4a <= "0000000"&b0(1); AD05: entity work.ALU (ALU_arq) port map ("100",ov3a,ov4a,ov5,shf1); -- CORRIMIENTO PARA NORMALIZAR (EL PASO 4 SE HACE DENTRO DEL CORRIMIENTO) shf2 <= "000000000000000"&shf1; SH02: entity work.RSHIFT (RSHIFT_arq) generic map (BITS => BFRA) port map (mants,shf2,b0(0),mantisa); -- AJUSTA EL NUEVO EXPONENTE AD06: entity work.ALU (ALU_arq) port map ("100",expa0,"00000001",ov6,expa1); expo <= expa1 when (shf1 = "00000001") else expa0; end PASO1_arq;;

Archivo: Testbench.vhd
library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity Testbench is port( -- DECLARACION DE PUERTOS exponente : out STD_LOGIC_VECTOR(7 downto 0); mantisa : out STD_LOGIC_VECTOR(22 downto 0) ); end Testbench; architecture Testbench_arq of Testbench is signal a, b: std_logic_vector(31 downto 0); begin -- DEFINICION DE LOS SUMANDOS EN NOTACION DE PUNTO FLOTANTE -- PRECISION SENCILLA (1 BIT SIGNO, 8 BITS EXPONENTE, 23 BITS MANTISA) a <= '0'&"01111101"&"00000000000000000000000"; b <= '0'&"10000101"&"10010000000000000000000"; -- INSTANCIA DEL SUMADOR DE NUMEROS DE PUNTO FLOTANTE SUMA: entity work.PASO1 (PASO1_arq) port map (a(22 downto 0),b(22 downto 0),a(30 downto 23), b(30 downto 23), exponente, mantisa); end Testbench_arq;

Archivo: Testbench2.vhd
library IEEE; use IEEE.STD_LOGIC_1164.all; -- LIBRERIA UTILIZADA entity Testbench is port( -- DECLARACION DE PUERTOS resultado : out STD_LOGIC_VECTOR(31 downto 0) ); end Testbench; architecture Testbench_arq of Testbench is signal a, b: std_logic_vector(31 downto 0); signal exponente: std_logic_vector(7 downto 0); signal mantisa: std_logic_vector(22 downto 0); begin -- DEFINICION DE LOS SUMANDOS EN NOTACION DE PUNTO FLOTANTE -- PRECISION SENCILLA (1 BIT SIGNO, 8 BITS EXPONENTE, 23 BITS MANTISA) a <= '0'&"10000010"&"00111000000000000000000"; b <= '0'&" 10000011"&"01100111000000000000000"; -- INSTANCIA DEL SUMADOR DE NUMEROS DE PUNTO FLOTANTE SUMA: entity work.PASO1 (PASO1_arq) port map (a(22 downto 0),b(22 downto 0),a(30 downto 23), b(30 downto 23), exponente, mantisa); resultado <= '0'&exponente&mantisa; end Testbench_arq;

S-ar putea să vă placă și