Universidad Nacional de Asunción Facultad de Ingeniería DIGITAL: CUADERNO DE EJERCICIOS - I MATERIA Sistemas Digitales I & II Diseño Lógico Digital I & II AUTORES Ing. Miguel A. Benitez A. Prof. Sistemas Digitales I & II Ing. Francisco Delgado Prof. Diseño Lógico Digital I & II Año 2013 INTRODUCCION Esta serie de ejercicios fueron seleccionados teniendo en cuenta que el entendimiento y modelado de los mismos es transversal a los conceptos requeridos para el conocimiento del lenguaje VHDL a nivel RTL y del diseño lógico. Si bien no abarca la totalidad del lenguaje, que en realidad nunca fue el propósito por parte de los autores, este solucionario es una primera entrega de una serie de ejercicios que serán pertinentes a las materias de diseño lógico y diseño de sistemas digitales (arquitecturas específicas y arquitecturas comerciales). Finalmente damos las gracias a los alumnos que en su momento contribuyeron a la solución de ciertos ejercicios, los nombres de los mismos fueron incluidos al principio de cada ejercicio según hayan colaborado. EJERCICIO 1 Modelar un circuito comparador con señales de entrada de 2 bits cada una, la librería disponible es: ieee.std_logic_1164.all. Utilizar el tipo de datos adecuado y modelar con el estilo estructural. Solución --Comparador de 2 bit library ieee; use ieee.std_logic_1164.all; entity comparador is port( a, b : in std_logic_vector(0 to 1); salida : out std_logic); end comparador; --use work.componentes.all; architecture estructural of comparador is signal cterm : std_logic_vector(0 to 1); begin U0: entity work.pxnor port map(a(0), b(0), cterm (0)); U1: entity work.pxnor port map(a(1), b(1), cterm (1)); U3: entity work.pand port map(cterm (0), cterm (1), salida); end estructural; -----------------------------PXNOR---------------------------------library ieee; use ieee.std_logic_1164.all; entity PXNOR is port (A, B: in std_logic; C: out std_logic); end entity; -architecture FlujoDatos of PXNOR is begin C<=A xnor B; end architecture; ------------------------------PAND---------------------------------library ieee; use ieee.std_logic_1164.all; entity PAND is port (A, B: in std_logic; C: out std_logic); end entity; -architecture FlujoDatos of PAND is begin C<=A and B; end architecture; EJERCICIO 2 Modelar una unidad aritmética lógica que contenga las siguientes operaciones: suma, resta, and lógica y or lógica. Para el efecto utilizar la sentencia concurrente with_select: (a) sin función de conversión y (b) con función de conversión. Además, para cada uno de los casos especificar librerías. Solución (a) library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -entity ALU_1 is port( operando1, operando2: in std_logic_vector(7 downto 0); operacion: in std_logic_vector(2 downto 0); resultado_operando: out std_logic_vector(8 downto 0)); end entity; ----------------------------------------------------------------------------architecture f_ALU OF ALU_1 IS signal aritmetica, logica: std_logic_vector(8 downto 0); begin --------------UNIDAD ARITMETICA--------------------------------with operacion(1 downto 0) select aritmetica<= '0'&operando1 + operando2 when "00", '0'&operando1 - operando2 when "01", '0'&operando1 WHEN OTHERS; --------------UNIDAD LOGICA------------------------------------- with operacion(1 downto 0) select logica<= '0'&operando1 AND '0'&operando2 when "00", '0'&operando1 OR '0'&operando2 when "01", '0'&operando2 wheN others; ---------------MULTIPLEXOR-------------------------------------with operacion(2) select resultado_operando<= aritmetica when '0', logica when others; end architecture; (b) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity ALU_2 is port( operando1, operando2: in std_logic_vector(7 downto 0); operacion: in std_logic_vector(2 downto 0); resultado_operando: out std_logic_vector(8 downto 0)); end entity; ----------------------------------------------------------------------------architecture f_ALU OF ALU_2 IS signal aritmetica, logica: std_logic_vector(8 downto 0); begin --------------UNIDAD ARITMETICA--------------------------------with operacion(1 downto 0) select aritmetica<= std_logic_vector(to_unsigned(to_integer(unsigned(operando1)) +to_integer(unsigned(operando2)), 9)) when "00", std_logic_vector(to_unsigned(to_integer(unsigned(operando1))to_integer(unsigned(operando2)), 9)) when "01", '0'&operando1 WHEN OTHERS; --------------UNIDAD LOGICA------------------------------------with operacion(1 downto 0) select logica<= '0'&operando1 AND '0'&operando2 when "00", '0'&operando1 OR '0'&operando2 when "01", '0'&operando2 wheN others; ---------------MULTIPLEXOR-------------------------------------with operacion(2) select resultado_operando<= aritmetica when '0', logica when others; end architecture; EJERCICIO 3 Modelar un paquete llamado funciones que contenga las operaciones de suma, resta y multiplicación como funciones. Tipo de datos que deberá retornar: natural. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --declara paquete package geometria is function area_circ(radio: natural) return natural; function area_cuadrado(lado: natural) return natural; end package; ---------------------------cuerpo del paquete-----------------------------package body geometria is -------------------descripción de la función que calcula el área de un círculo---------function area_circ(radio: natural) return natural is constant pi: natural:=3; begin return(pi*(radio**2)); end function; ----------------------------------------------------------------------function area_cuadrado(lado: natural) return natural is begin return(lado**2); end function; end package body; EJERCICIO 4 Modelar un paquete llamado funciones que contenga las operaciones de suma, resta y multiplicación como funciones. A partir del modelado de las funciones, describir un circuito (top level) secuencial cuyas entradas sean del tipo entero para decodificar la operación, del tipo natural para los datos a calcular y del tipo std_logic para el reloj. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; --declara paquete package funciones is function suma(a,b: natural) return natural; function resta(a,b: natural) return natural; function multi(a,b:natural) return natural; end package; --cuerpo del paquete package body funciones is --descripción de la función que calcula la suma, resta y multiplicación de números naturales function suma(a,b: natural) return natural is begin return(a+b); end function; -function resta(a,b: natural) return natural is begin return(a-b); end function; -function multi(a,b: natural) return natural is begin return(a*b); end function; end package body; --top level operaciones, llama al archivo funciones library ieee; use ieee.std_logic_1164.all; --use ieee.numeric_std.all; use work.funciones.all; --declara la entidad entity operaciones is port( reloj: in bit; cod_op: in integer range 0 to 2; a,b: in natural; resultado: out natural); end entity; --arquitectura architecture comportamental of operaciones is begin process(reloj) begin if reloj ='1' then case cod_op is when 0 =>resultado<=suma(a,b); when 1 =>resultado<=resta(a,b); when 2 =>resultado<=multi(a,b); end case; end if; end process; end architecture; ---- EJERCICIO 5 Modelar un sumador de dos vectores de entrada con signo de cuatro elementos cada uno, utilizar los paquetes std_logic_1164 y numeric_std, así como, funciones de conversión. library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity suma is port( a: in std_logic_vector(3 downto 0); b: in std_logic_vector(3 downto 0); s: out std_logic_vector(3 downto 0)); end entity; -architecture flujo of suma is begin s<=std_logic_vector(signed(a)+signed(b)); end architecture; EJERCICIO 6 Modelar un sumador completo de dos entradas de dos elementos cada una utilizando tipo de datos: matriz definido por un arreglo de dos dimensiones. -----------------sumador completo------------------------------------------library ieee; use ieee.std_logic_1164.all; entity fa is port (x, y, Cin: in std_logic; Sum, Cout: out std_logic); end entity; -architecture estructural of fa is -- red interna: signal cterm: std_logic_vector(1 to 10); type MATRIZ is array(1 to 5) of std_logic_vector(1 to 2); signal Puerta: MATRIZ; -- defino las entradas de las 10 puertas begin Puerta(1) <= (x, y); Puerta(2) <= (cterm(1), Cin); Puerta(3)<= (cterm(2), Cin); Puerta(4)<= (x, y); Puerta(5)<= (cterm(3), cterm(4)); P_XOR : for I in 1 to 2 generate ET_1 : entity WORK.PXOR port map (Puerta(I)(1), Puerta(I)(2), cterm(I)); end generate P_XOR; P_AND : for I in 3 to 4 generate ET_2 : entity WORK.PAND port map (Puerta(I)(1), Puerta(I)(2), cterm(I)); end generate P_AND; P_OR : for I in 5 to 5 generate ET_2 : entity WORK.POR port map (Puerta(I)(1), Puerta(I)(2), cterm(I)); end generate P_OR; Sum <= cterm(2); Cout <= cterm(5); end architecture; ------------------------------PXOR---------------------------------library ieee; use ieee.std_logic_1164.all; entity PXOR is port (A, B: in std_logic; C: out std_logic); end entity; -architecture FlujoDatos of PXOR is begin C<=A xor B; end architecture; ------------------------------PAND---------------------------------library ieee; use ieee.std_logic_1164.all; entity PAND is port (A, B: in std_logic; C: out std_logic); end entity; -architecture FlujoDatos of PAND is begin C<=A and B; end architecture; -----------------------------POR-----------------------------------library ieee; use ieee.std_logic_1164.all; entity POR is port (A, B: in std_logic; C: out std_logic); end entity; -architecture FlujoDatos of POR is begin C<=A or B; end architecture; EJERCICIO 7 Un circuito procesador de datos esta diseñado para recibir un conjunto de datos y colocar a la salida el mayor dato que aparece en un grupo. La maquina tiene una entrada datain de 8-bit, una entrada sirve de un-bit, un-bit de salida listo y una salida de 8-bit mayor. Todos los datos son considerados números positivos de 8-bits. La maquina recibe datos mientras sirve es ‘1’ y hace que en mayor esté disponible el mayor dato tan pronto como un grupo de datos esté disponible. Bytes síncronos de grupos de datos aparecen en datain mientras sirve es ‘1’. Un grupo de datos comienza cuando sirve llega a ser ‘1’ y continua mientras esta entrada es ‘1’. La terminación de un grupo de datos es indicada por sirve igual a ‘0’, el mayor dato del último grupo de datos aparece en la salida mayor después de un periodo de reloj y listo es ‘1’. library ieee; use ieee.std_logic_1164.all; entity TopLevel is port( sirve,clock: in std_logic; datain: in std_logic_vector (7 downto 0); mayor: out std_logic_vector (7 downto 0); listo : out std_logic); end entity; -architecture tl of TopLevel is --------------------------------------------------------------component UnidadDatos is port( datain: in std_logic_vector(7 downto 0); datain_on_bus, ld_t, ld_m, ld_ac, t_on_bus: in std_logic; sirve, clock: in std_logic; listo : out std_logic; mayor : out std_logic_vector(7 downto 0)); end component; --------------------------------------------------------------component UnidadControl is port( sirve, clock: in std_logic; datain_on_bus, ld_t, ld_m, ld_ac, t_on_bus: out std_logic); end component; --------------------------------------------------------------signal datain_on_bus, ld_t, ld_m, ld_ac, t_on_bus: std_logic; begin U1: UnidadDatos port map (datain=> datain, datain_on_bus=>datain_on_bus, ld_t=> ld_t, ld_m=> ld_m, ld_ac=> ld_ac, t_on_bus=> t_on_bus, sirve => sirve, clock=> clock, listo => listo, mayor => mayor); U2: UnidadControl port map( sirve => sirve, clock=>clock, datain_on_bus=>datain_on_bus, ld_t=> ld_t, ld_m=> ld_m, ld_ac=> ld_ac, t_on_bus=> t_on_bus); end architecture; ---------------------------------Unidad de Datos del núcleo-----------------------------------------------library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity UnidadDatos is port( datain: in std_logic_vector(7 downto 0); datain_on_bus, ld_t, ld_m, ld_ac, t_on_bus: in std_logic; sirve, clock: in std_logic; listo : out std_logic; mayor : out std_logic_vector(7 downto 0)); end entity; -----------------------------------------------------------------------------------------------architecture tl of UnidadDatos is signal acum, acumT, max: std_logic_vector(7 downto 0); begin process(clock, sirve, datain, datain_on_bus, ld_t, ld_m, ld_ac, t_on_bus) begin if (clock='1' and clock'event) then if(sirve='1') then listo<='0'; if(datain_on_bus='1' and ld_ac='1') then acum <= datain; acumT <= acum; elsif (datain_on_bus='1' and ld_t='1') then if (acum >= datain) then acumT <= acum; else acumT <= datain; end if; elsif (sirve='0' and ld_ac='1' and t_on_bus='1') then acum <= acumT; end if; elsif (ld_m='1' and t_on_bus='1') then max <= acumT; listo <='1'; end if; end if; end process; mayor <= max; end architecture; -----------------------------------------------------------------------------------------------------------------Unidad de Control del núcleo-------------------------library ieee; use ieee.std_logic_1164.all; entity UnidadControl is port( sirve, clock: in std_logic; datain_on_bus, ld_t, ld_m, ld_ac, t_on_bus: out std_logic); end entity; -architecture tl of ucontrol is type estados is (s0, s1, s2, s3); signal EstadoP, EstadoF: estados; begin fsm: process(sirve, EstadoP) begin EstadoF <= EstadoP; case estado is when s0 => datain_on_bus <= '1'; ld_ac <='1'; ld_t <='0'; ld_m <='0'; t_on_bus <= '0'; if (sirve ='1') then EstadoF <= s1; else EstadoF <= s3; end if; when s1 => datain_on_bus <= '1'; ld_ac <='0'; ld_t <='1'; ld_m <='0'; t_on_bus <= '0'; if (sirve ='1') then EstadoF <= s2; else EstadoF <= s3; end if; when s2 => datain_on_bus <= '0'; ld_ac <='1'; ld_t <='0'; ld_m <='0'; t_on_bus <= '1'; if (sirve ='1') then EstadoF <= s1; else EstadoF <= s3; end if; when s3 => datain_on_bus <= '0'; ld_ac <='0'; ld_t <='0'; ld_m <='1'; t_on_bus <= '1'; if (sirve ='1') then EstadoF <= s0; else EstadoF <= s3; end if; end case; end process; -clockd: process (clock) begin if (clock='1' and clock'event) then EstadoP<= EstadoF; end if; end process; end architecture; EJERCICIO 8 Sumador completo estilo flujo de datos, generalizado a N = 32 con estilo estructural. El gráfico esta sintetizado para N=4, para poder visualizar el sumador. -- Guido José Valenzano Tocaimasa library ieee; use ieee.std_logic_1164.all; -entity SumadorCompleto is port( OperadorA : in std_logic; OperadorB : in std_logic; AcEntrada : in std_logic; Resultado : out std_logic; AcSalida : out std_logic ); end entity; -architecture flujo of SumadorCompleto is begin Resultado <= OperadorA xor OperadorB xor AcEntrada; AcSalida <= (OperadorA and OperadorB) or (OperadorA and AcEntrada) or (OperadorB and AcEntrada); end architecture; – library ieee; use ieee.std_logic_1164.all; entity SumadorN is generic (N: positive := 32); port ( A : in std_logic_vector(0 to N-1); B : in std_logic_vector(0 to N-1); Cin : in std_logic; Cout : out std_logic; S : out std_logic_vector(0 to N-1)); end entity; -architecture estructural of SumadorN is type matrix is array (0 to N-1) of std_logic_vector(0 to 2); signal cterm : std_logic_vector(0 to N-1); signal m: matrix; component SumadorCompleto is port( OperadorA : in std_logic; OperadorB : in std_logic; AcEntrada : in std_logic; Resultado : out std_logic; AcSalida : out std_logic); end component; begin -- De modo a asignar las conexiones con un ciclo for, se utiliza un process sensible a cambios de -- las señales de entrada: A, B y Cin. process(A,B,Cin) begin m(N-1) <= ( A(N-1), B(N-1), Cin ); for i in 0 to N-2 loop m(i) <= ( A(i), B(i), cterm(i+1) ); end loop; end process; -- Aquí se hace el mapeo de cada sumador a las señales establecidas. c_sum31 : SumadorCompleto port map ( m(N-1)(0), m(N-1)(1), m(N-1)(2), S(N-1), cterm(N-1) ); c_sum : for i in 0 to N-2 generate comp1: SumadorCompleto port map ( m(i)(0), m(i)(1), m(i)(2), S(i), cterm(i) ); end generate c_sum; -- El acarreo final todavía no está mapeado, por lo que se realiza aquí. Cout <= cterm(0); end architecture; EJERCICIO 9 -- Guido José Valenzano Tocaimasa library ieee; use ieee.std_logic_1164.all; entity circuito is port (x, y, z : in std_logic; f1, f2: out std_logic); end circuito; -----------------------------------------------------architecture funcional of circuito is signal ct: std_logic_vector (1 to 5); -----------------------------------------------------component anda is port ( a, b : in std_logic; c: out std_logic); end component; -----------------------------------------------------component ora is port ( a, b: in std_logic; c: out std_logic); end component; -----------------------------------------------------type matriz is array (1 to 5) of std_logic_vector (1 to 2); signal m: matriz; -----------------------------------------------------begin m(1) <= (x,z); m(2) <= (y,z); m(3) <= ( x, z); m(4) <= (ct(1), ct(2)); m(5) <= (ct(2), ct(3)); p_and: ET_1: for i in 1 to 3 generate anda port map(m(i)(1),m(i)(2),ct(i)); end generate p_and; p_or: for i in 4 to 5 generate ET_2: ora port map(m(i)(1),m(i)(2),ct(i)); end generate p_or; f1 <= ct(4); f2 <= ct(5); end architecture; ------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; -entity anda is port ( a, b: in std_logic; c: out std_logic); end entity; -architecture and2 of anda is begin c <= a and b; end architecture; ------------------------------------------------------------------------library ieee; use ieee.std_logic_1164.all; -entity ora is port ( a, b: in std_logic; c: out std_logic); end entity; -architecture arq_or of ora is begin c <= a or b; end architecture; EJERCICIO 10 Un circuito procesador de datos recibe a través del puerto de entrada md de 3-bit el modo en que será procesado el dato ingresado por el puerto salin de 8-bits. Si la señal reset es ‘0’ todas las salidas de la máquina son puesta a ‘0’, caso contrario se procesa el dato según md. Considerar que la máquina es síncrona. Cuando md es 111 y rdy es 1, y el dato es capturado en el puerto salin. Para los casos, md = 000 la maquina no realiza ninguna acción sobre el dato, md = 001 el dato se desplaza a la derecha un-bit, md = 010 el dato se desplaza a la izquierda, md = 011 el dato se incrementa en 1, md = 100 dato se decrementa en 1, md = 101 dato se complementa, md = 110 los 4-bit MSB se invierten con los 4-bit LSB. library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; -entity ProcDato is port ( md: in std_logic_vector(2 downto 0); reset, rdy, clk: in std_logic; salin: inout std_logic_vector(7 downto 0) ); end entity; ---------------------------------------------------------architecture funcional of ProcDato is signal cterm: std_logic_vector( 7 downto 0); begin process(clk) begin if reset = '0' then salin <= (others => '0'); elsif clk = '1' and clk'event then if rdy = '0' then case md is when "001" => salin <= '0'&cterm(7 downto 1); when "010" => salin <= cterm(6 downto 0)&'0'; when "011" => salin <= cterm+1; when "100" => salin <= cterm-1; when "101" => salin <= not cterm; when "110" => salin <= cterm(3 downto 0)&cterm(7 downto 4); when others => null; end case; elsif md = "111" then cterm <= salin; end if; end if; end process; end architecture; BIBLIOGRAFIA http://hdl-fpga.blogspot.com/2011/06/ieeenumericstdall-funciones-de.html Ll. Teres; Y. Torroja; S. Olcoz; E. Villar: VHDL Lenguaje Estándar de Diseño Electrónico, 1era. Edición en español, 1998, McGraw-Hill, ISBN: 84-481-1196-6. J.F. Wakerly: Diseño Digital Principios y Prácticas, 3era. Edición, 2001, Prentice Hall, ISBN: 970-17-0404-5. IEEE: The IEEE standard VHDL Language Reference Manual. IEEE Std. - 1076 - 1987, 1988. Zainalabedin Navabi: VHDL:Modular Design and Synthesis of Cores and Systems, Third Edition, 2010, McGraw-Hill Education (India) Pvt Limited. J. Alcala; D.G. Maxinez: VHDL El Arte de Programar Sistemas Digitales, 1era. Reimpresión, 2003, Compañía Editorial Continental, ISBN: 970-24-0259-X.