Examen Escrito Extraordinario 2022 - Solucion

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 13

APELLIDOS:

UNIVERSIDAD
NOMBRE: DNI:
POLITÉCNICA

DE MADRID ASIGNATURA: Diseño Digital 2 Diseño (escrito)

E.T.S.I.S. de Telecomunicación TITULACIÓN: ELECTRÓNICA DE COMUNICACIONES

Fecha Curso Grupo Notas Parciales Nota Final

01 07 2022 Tercero

ADVERTENCIAS PARA LA REALIZACIÓN


DE ESTA PARTE DEL EXAMEN

 Rellene AHORA los datos personales que deben figurar en esta hoja.
 Mientras dure el examen deberá exponer su D.N.I. encima de la mesa.
 NO SE ADMITIRÁN exámenes escritos a lapicero ni con tinta roja o verde.
 COMPRUEBE que su ejemplar del examen consta de 1 ejercicio en 9 páginas
numeradas.
 En este examen NO PUEDEN UTILIZARSE CALCULADORAS, LIBROS,
APUNTES NI DISPOSITIVOS DE TELECOMUNICACIÓN. Retírelos ahora de la
mesa.
 La duración de esta parte del examen es de 60 minutos.
 La calificación de esta parte del examen tendrá un peso del 50% sobre la calificación
total

1
Esta hoja se ha dejado en blanco intencionadamente

2
Ejercicio 1 Máster SPI a tres hilos
10 puntos 60 minutos

El código adjunto corresponde al modelo de un circuito que resuelve un problema similar


al que habrá tenido que solucionar para realizar el diseño del NIVEL ELECTRONICO
PLUS. Se trata del modelo correspondiente a un Máster SPI a tres hilos, con unas
especificaciones de funcionamiento equivalentes a las del diseño extraordinario.

Nota: en el entregable de la parte escrita encontrará el datasheet del acelerómetro.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity master_spi_3_hilos is
port(nRst: in std_logic;
clk: in std_logic; -- 50 MHz

-- Ctrl_SPI
start: in std_logic; -- Orden de ejecucion
nWR_RD: in std_logic; -- Escritura (0) o lectura (1)
dir_reg: in std_logic_vector(6 downto 0); -- autoinc - direccion de acceso;
dato_wr: in std_logic_vector(7 downto 0); -- dato a escribir (solo
-- escrituras de 1 bit
dato_rd: buffer std_logic_vector(7 downto 0); -- valor del byte leido
ena_rd: buffer std_logic; -- valida a nivel alto a dato_rd
rdy: buffer std_logic; -- unidad preparada para aceptar start

-- bus SPI
nCS: buffer std_logic; -- chip select
SPC: buffer std_logic; -- clock SPI (5 MHz)
SDI_O: inout std_logic); -- Data Input/Output

end entity;

architecture rtl of master_spi_3_hilos is


--Reloj del bus
signal cnt_SPC: std_logic_vector(2 downto 0);
signal fdc_cnt_SPC: std_logic;
signal SPC_posedge: std_logic;
signal SPC_negedge: std_logic;

constant SPC_LH: natural := 5;

-- Contador de bits y bytes transmitidos


signal cnt_bits_SPC: std_logic_vector(5 downto 0);

-- Sincro SDI y Registro de transmision y recepcion


signal SDI_syn: std_logic;
signal reg_SPI: std_logic_vector(16 downto 0);

-- Para el control
signal no_bytes: std_logic_vector(2 downto 0);
signal fin: std_logic;

--Control buffer Z
signal ctrl_SDI_O: std_logic;
signal op_nWR: std_logic;

begin

3
-- Generacion de nCS:
process(nRst, clk)
begin
if nRst = '0' then
nCS <= '1';
op_nWR <= '0';

elsif clk'event and clk = '1' then


if start = '1' and nCS = '1' then
nCS <= '0';
op_nWR <= nWR_RD;

elsif fin = '1' then


nCS <= '1';

end if;
end if;
end process;

rdy <= nCS;

-- Generacion de SPC:
process(nRst, clk)
begin
if nRst = '0' then
cnt_SPC <= (1 => '1', others => '0');
SPC <= '1';

elsif clk'event and clk = '1' then


if nCS = '1' then
cnt_SPC <= (1 => '1', others => '0');
SPC <= '1';

elsif fdc_cnt_SPC = '1' then


SPC <= not SPC;
cnt_SPC <= (0 => '1', others => '0');

else
cnt_SPC <= cnt_SPC + 1;

end if;
end if;
end process;

fdc_cnt_SPC <= '1' when cnt_SPC = SPC_LH else


'0';

SPC_posedge <= SPC when cnt_SPC = 1 else


'0';

SPC_negedge <= not SPC when cnt_SPC = 1 else


'0';

-- Cuenta bits y bytes:


process(nRst, clk)
begin
if nRst = '0' then
cnt_bits_SPC <= (others => '0');

elsif clk'event and clk = '1' then


if SPC_posedge = '1' then
cnt_bits_SPC <= cnt_bits_SPC + 1;

elsif nCS = '1' then


cnt_bits_SPC <= (others => '0');

end if;
end if;
end process;

4
-- Registro
process(nRst, clk)
begin
if nRst = '0' then
reg_SPI <= (others => '0');
SDI_syn <= '0';

elsif clk'event and clk = '1' then


SDI_syn <= SDI_O;

if start = '1' and nCS = '1' then


reg_SPI <= '0'& nWR_RD & dir_reg & dato_wr;

elsif SPC_negedge = '1' then


reg_SPI(16 downto 1) <= reg_SPI(15 downto 0);

elsif SPC_posedge = '1' then


reg_SPI(0) <= SDI_syn;

end if;
end if;
end process;

ena_rd <= (not nCS and fin) when cnt_bits_SPC(5 downto 3) = 7 else
SPC_negedge when cnt_bits_SPC(5 downto 3) > 1 and
cnt_bits_SPC(2 downto 0) = 0 else
'0';

dato_rd <= reg_SPI(7 downto 0);

process(nRst, clk)
begin
if nRst = '0' then
ctrl_SDI_O <= '0';

elsif clk'event and clk = '1' then


if nCS='0' and cnt_bits_SPC(5 downto 3)=1 and op_nWR='1' and fdc_cnt_SPC='1' then
ctrl_SDI_O <= '1';

elsif nCS = '1' then


ctrl_SDI_O <= '0';

end if;
end if;
end process;

SDI_O <= reg_SPI(16) when ctrl_SDI_O = '0' else


'Z';

-- Control heuristico
process(nRst, clk)
begin
if nRst = '0' then
no_bytes <= (others => '0');

elsif clk'event and clk = '1' then


if start = '1' and nCS = '1' then
if nWR_RD = '0' then
no_bytes <= "010";

else
no_bytes <= "111";

end if;
end if;
end if;
end process;

fin <= '1' when cnt_bits_SPC(5 downto 3) = no_bytes else


'0';

end rtl;

5
1.- Conteste a las siguientes cuestiones:

a) Indique el significado y cómo deben ser utilizados los siguientes parámetros de la


especificación de tiempos de la interfaz SPI del acelerómetro que ha usado en el
diseño (2 puntos)

 Tsu(CS)

Tiempo de setup de CS. Es el mínimo tiempo que debe transcurrir desde


la activación de la señal CS hasta el primer flanco de bajada en la señal
SPC. Este tiempo es de 5ns.

 Th(CS)

Tiempo de hold de CS. Es el mínimo tiempo que debe transcurrir desde el


último flanco de subida en la señal SPC hasta la desactivación de la señal
CS. Este tiempo es de 20ns.

 Tsu(SI)

Tiempo de setup de datos en SDI. Es el mínimo tiempo que debe


permanecer estable el dato en la línea SDI previamente del flanco de
subida en la señal SPC. Este tiempo es de 5ns.

 Th(SI)

Tiempo de hold de datos en SDI. Es el mínimo tiempo que debe


permanecer estable el dato en la línea SDI posteriormente al flanco de
subida en la señal SPC. Este tiempo es de 15ns.

6
b) Analice el código del modelo del circuito para explicar detalladamente cómo se
garantiza el cumplimiento de los tiempos descritos en el apartado anterior. (2
puntos)

Tsu(CS):

Cuando se activa la señal nCS la señal SPC se encuentra a nivel alto. Desde ese instante
el contador cnt_SPC contará desde 1 hasta el valor SPC_LH (5) antes de bajar la línea
SPC. Por lo tanto transcurren 5*20ns = 100 ns.

Th(CS):

La señal nCS se activa un ciclo después de la activación de la señal “fin”, la cual se


activa cuando cnt_bits_SPC(5:3) iguala el número de bytes que deben transmitirse. Este
contador se incrementa el ciclo de reloj posterior a la activación de la señal
SPC_posedge, la cual se activa de manera simultánea a la subida de la señal SPC. Por
lo tanto, transcurren 2 ciclos de reloj entre ambos eventos, es decir, 40ns.

Tsu(SI):

La señal SDI toma el valor del bit de mayor peso del registro reg_SPI. Este registro se
desplaza cuando la señal SPC_negedge se activa, lo cual se produce cuando cnt_SP toma
el valor 1. Así pues, hay cuatro ciclos de reloj entre la puesta del dato y la subida de SPC,
es decir, 80ns.

Th(SI):

Siguiendo la explicación anterior, hay 6 ciclos de reloj entre el flanco de subida de SPC
y la puesta del nuevo dato en SDI. Es decir, 120ns.

7
c) De acuerdo con la especificación de tiempos del acelerómetro:

 Indique el valor máximo de tiempo que debe transcurrir, después del


flanco de bajada del reloj SPC, antes de que el máster escriba un nuevo
bit, de forma que se respete el tiempo de setup de datos en el esclavo.
Justifique detalladamente su respuesta (0.5 puntos)

Puesto que debe respetarse el tiempo de setup de datos en el esclavo, el


tiempo en el que el master debe poner el dato dependerá del tiempo a nivel
bajo de SPC. Siendo tLOW – tSU(SI)

 Indique la anchura mínima que deben tener el nivel alto y el nivel bajo de
la señal de reloj SPC. Justifique detalladamente su respuesta (1.5 puntos)

El tiempo a nivel bajo debe permitir que se respeten los tiempos de setup
de datos tSU(SI) y el tiempo de dato válido en SDO tV(SO). Así pues será
el mayor de estos valores. En nuestro caso, 50ns.

El tiempo a nivel alto debe permitir que se respete el tiempo de hold de


datos th(SI), es decir 20nS.

De manera conjunta, el periodo mínimo de la señal SPC es de 100ns,


tc(SPC)

d) Analice el código del modelo del circuito para explicar detalladamente la función
que realizan las señales op_nWR y ctrl_SDI_O y el modo en el que el circuito
maneja su valor para conseguir que la interfaz a 3 hilos funcione correctamente:

 ctrl_SDI_O: (1.5 puntos)

Esta señal controla cuando la señal SDI_O debe funcionar como entrada (1)
o como salida (0). Cuando esta señal vale 1 el master se desconecta de la
línea, poniéndola en alta impedancia (Z). Esto sucede en las transferencias
de lectura (op_nWR = ‘1’), cuando se ha transmitido el primer byte
(cnt_bits_SPC(5 downto 3) = 1 y fdc_cnt_SPC = '1').

8
 op_nWR: (1.5 puntos)

Esta señal indica si la transferencia es de escritura (0) o de lectura (1). Esta


señal está involucrada en la generación de la señal ctrl_SDI, como ya ha sido
explicado con anterioridad.

e) La siguiente sentencia concurrente modela el funcionamiento del puerto de datos


bidireccional de la interfaz SPI.

SDI_O <= reg_SPI(16) when ctrl_SDI_O = '0' else


'Z';

Indique, justificando su respuesta, si la sentencia modela una salida en colector


abierto, una salida con control de alta impedancia u otro tipo de salida (1 punto)

Esta sentencia modela una salida con control de alta impedancia. Si la señal
ctrl_SDI toma el valor 1, esta señal SDI_O toma el valor Z, es decir, permanece
en alta impedancia. En caso contrario toma el valor 1 o 0 según sea el valor de
reg_SPI(16)

9
library work;
use work.auxiliar.all; -- Funcion ceil_log

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;

entity estimador is
generic(N: in positive := 16); -- numero de registros del banco (potencia de 2)

port(nRst: in std_logic;
clk: in std_logic;

X_out_bias: in std_logic_vector(10 downto 0);


Y_out_bias: in std_logic_vector(10 downto 0);
Z_out_bias: in std_logic_vector(10 downto 0);
muestra_bias_rdy: in std_logic;

X_media: buffer std_logic_vector(11 downto 0);


Y_media: buffer std_logic_vector(11 downto 0);
Z_media: buffer std_logic_vector(11 downto 0));

end entity;

architecture rtl of estimador is


type reg_file is array (NATURAL RANGE <>) of std_logic_vector(32 downto 0);
signal reg_muestra: reg_file(N-1 downto 0);
signal reg_file_aux: std_logic_vector(32 downto 0);
signal reg_file_aux_2: std_logic_vector(32 downto 0);

signal dif_X_muestra_N: std_logic_vector(11 downto 0);


signal dif_Y_muestra_N: std_logic_vector(11 downto 0);
signal dif_Z_muestra_N: std_logic_vector(11 downto 0);
signal dif_X_muestra_N_2: std_logic_vector(11 downto 0);
signal dif_Y_muestra_N_2: std_logic_vector(11 downto 0);
signal dif_Z_muestra_N_2: std_logic_vector(11 downto 0);

signal X_media_N: std_logic_vector(11+ceil_log(N) downto 0);


signal Y_media_N: std_logic_vector(11+ceil_log(N) downto 0);
signal Z_media_N: std_logic_vector(11+ceil_log(N) downto 0);
signal X_media_N_2: std_logic_vector(11+ceil_log(N/2) downto 0);
signal Y_media_N_2: std_logic_vector(11+ceil_log(N/2) downto 0);
signal Z_media_N_2: std_logic_vector(11+ceil_log(N/2) downto 0);

signal X_media_1: std_logic_vector(11 downto 0);


signal Y_media_1: std_logic_vector(11 downto 0);
signal Z_media_1: std_logic_vector(11 downto 0);
signal X_media_2: std_logic_vector(10 downto 0);
signal Y_media_2: std_logic_vector(10 downto 0);
signal Z_media_2: std_logic_vector(10 downto 0);

signal X_media_agreg: std_logic_vector(12 downto 0);


signal Y_media_agreg: std_logic_vector(12 downto 0);
signal Y_media_agreg: std_logic_vector(12 downto 0);

begin
-- Banco de registros
process(clk, nRst)
begin
if nRst = '0' then
for i in reg_muestra'range loop
reg_muestra(i) <= (others => '0');

end loop;

elsif clk'event and clk = '1' then


if muestra_bias_rdy = '1' then
reg_muestra(0) <= X_out_bias & Y_out_bias & Z_out_bias;

-1-
for i in 1 to N-1 loop
reg_muestra(i) <= reg_muestra(i-1);

end loop;
end if;
end if;
end process;

reg_file_aux <= reg_muestra(N-1);

reg_file_aux_2 <= reg_muestra((N/2)-1);

-- Delta de acumulacion
dif_X_muestra_N <= X_out_bias(10)&X_out_bias - reg_file_aux(32 downto 22);
dif_Y_muestra_N <= Y_out_bias(10)&Y_out_bias - reg_file_aux(21 downto 11);
dif_Z_muestra_N <= Z_out_bias(10)&Z_out_bias - reg_file_aux(10 downto 0);
dif_X_muestra_N_2 <= X_out_bias(10)&X_out_bias - reg_file_aux_2(32 downto 22);
dif_Y_muestra_N_2 <= Y_out_bias(10)&Y_out_bias - reg_file_aux_2(21 downto 11);
dif_Z_muestra_N_2 <= Z_out_bias(10)&Z_out_bias - reg_file_aux_2(10 downto 0);

-- Acumulador
process(nRst, clk)
begin
if nRst = '0' then
X_media_N <= (others => '0') ;
Y_media_N <= (others => '0') ;
Z_media_N <= (others => '0') ;
X_media_N_2 <= (others => '0') ;
Y_media_N_2 <= (others => '0') ;
Z_media_N_2 <= (others => '0') ;

elsif clk'event and clk = '1' then


if muestra_bias_rdy = '1' then
X_media_N <= X_media_N + dif_X_muestra_N;
Y_media_N <= Y_media_N + dif_Y_muestra_N;
Z_media_N <= Z_media_N + dif_Z_muestra_N;
X_media_N_2 <= X_media_N_2 + dif_X_muestra_N_2;
Y_media_N_2 <= Y_media_N_2 + dif_Y_muestra_N_2;
Z_media_N_2 <= Z_media_N_2 + dif_Z_muestra_N_2;

end if;
end if;
end process;

-- Valor medio de las ultimas N muestras


X_media_1 <= X_media_N(11+ceil_log(N) downto ceil_log(N));
Y_media_1 <= Y_media_N(11+ceil_log(N) downto ceil_log(N));
Z_media_1 <= Z_media_N(11+ceil_log(N) downto ceil_log(N));

-- Valor medio de las ultimas N/2 muestras


X_media_2 <= X_media_N_2(11+ceil_log(N/2) downto ceil_log(N/2));
Y_media_2 <= Y_media_N_2(11+ceil_log(N/2) downto ceil_log(N/2));
Z_media_2 <= Z_media_N_2(11+ceil_log(N/2) downto ceil_log(N/2));

-- Calculo media final

X_media_agreg <= ('0'&X_media_1) + X_media_2;


Y_media_agreg <= ('0'&Y_media_1) + Y_media_2;
Z_media_agreg <= ('0'&Z_media_1) + Z_media_2;

X_media <= X_media_agreg(12 downto 1);


Y_media <= Y_media_agreg(12 downto 1);
Z_media <= Z_media_agreg(12 downto 1);
end architecture;

-2-
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity sensor_driver is
port(nRst: in std_logic;
clk: in std_logic; -- 50 MHz
tic: in std_logic;
-- Ctrl_SPI
rdy: in std_logic; -- unidad preparada para aceptar start
start: buffer std_logic; -- Orden de ejecucion
nWR_RD: buffer std_logic; -- Escritura (0) o lectura (1)
repeat_conf: in std_logic;
dir_reg: buffer std_logic_vector(6 downto 0); -- autoincremento + direccion de
acceso;
dato_wr: buffer std_logic_vector(7 downto 0)); -- dato a escribir

end entity;

architecture rtl of sensor_driver is


type t_estado is (wait_5ms, wait_10ms, assert_start, release_start);
signal estado: t_estado;

constant num_op_conf: natural := 6;


signal cnt_op_conf: std_logic_vector(2 downto 0);

constant dir_reg1 : std_logic_vector(6 downto 0):= "0100000";


constant dir_reg2 : std_logic_vector(6 downto 0):= "0100001";
constant dir_reg3 : std_logic_vector(6 downto 0):= "0100010";
constant dir_reg4 : std_logic_vector(6 downto 0):= "0100011";
constant dir_reg5 : std_logic_vector(6 downto 0):= "0100100";
constant dir_reg6 : std_logic_vector(6 downto 0):= "0100101";

constant valor_reg1 : std_logic_vector(7 downto 0):= X"67";


constant valor_reg2 : std_logic_vector(7 downto 0):= X"80";
constant valor_reg3 : std_logic_vector(7 downto 0):= X"00";
constant valor_reg4 : std_logic_vector(7 downto 0):= X"81";
constant valor_reg5 : std_logic_vector(7 downto 0):= X"00";
constant valor_reg6 : std_logic_vector(7 downto 0):= X"00";

constant dir_reg_rd: std_logic_vector(6 downto 0) := "1101000";

begin
process(nRst, clk)
begin
if nRst = '0' then
start <= '0';
nWR_RD <= '0';
dir_reg <= (others => '0');
dato_wr <= (others => '0');
estado <= wait_5ms;
cnt_op_conf <= (0 => '1', others => '0');

elsif clk'event and clk = '1' then


case estado is
when wait_5ms =>
if tic = '1' then
estado <= wait_10ms;

end if;

when wait_10ms =>


if tic = '1' then
estado <= assert_start;

end if;

-1-
when assert_start =>
if cnt_op_conf <= num_op_conf and rdy = '1' then
start <= '1';
nWR_RD <= '0';

case cnt_op_conf is
when "001" =>
dir_reg <= dir_reg2;
dato_wr <= valor_reg2;

when "010" =>


dir_reg <= dir_reg3;
dato_wr <= valor_reg3;

when "011" =>


dir_reg <= dir_reg4;
dato_wr <= valor_reg4;

when "100" =>


dir_reg <= dir_reg5;
dato_wr <= valor_reg5;

when "101" =>


dir_reg <= dir_reg6;
dato_wr <= valor_reg6;

when "110" =>


dir_reg <= dir_reg1;
dato_wr <= valor_reg1;

when others => null;


end case;

estado <= release_start;

elsif tic = '1' and cnt_op_conf > num_op_conf and rdy = '1' then
start <= '1';
nWR_RD <= '1';
dir_reg <= dir_reg_rd;
estado <= release_start;

end if;

when release_start =>


start <= '0';
estado <= assert_start;

if nWR_RD = '0' then


cnt_op_conf <= cnt_op_conf + 1;

elsif repeat_conf = '1' then


cnt_op_conf <= (0 => '1', others => '0');

end if;
end case;
end if;
end process;
end rtl;

-2-

También podría gustarte