Академический Документы
Профессиональный Документы
Культура Документы
Elementos de memoria
Un elemento de memoria es un componente que es capaz de guardar (memorizar) un
valor. Existen muchas maneras de modelar un elemento de memoria en VHDL, sin
embargo, dentro del subconjunto de VHDL sintetizable slo hay unas pocas maneras. El
subconjunto de VHDL sintetizable es un estndar del VHDL [14] que restringe el lenguaje
a un mnimo construcciones VHDL que los sintetizadores deben aceptar. Por tanto, no
todo el VHDL es aceptado para sintetizarlo e implementarlo en la FPGA. Esto se debe a
que el VHDL surgi para modelar y simular circuitos, y no para sintetizarlos. Por ello, el
VHDL es mucho ms amplio que lo que se puede sintetizar. En la prctica, cada
sintetizador acepta un conjunto determinado para sntesis, y por ello se debe consultar el
manual antes de empezar a usar un sintetizador nuevo [27].
A continuacin, mediante ejemplos, veremos cmo se realizan elementos de memoria.
K
0
1
0
1
Q(t+1)
Q(t)
0
1
Q(t)
BTN1
LD0
CLK
BTN0
Figura 5.1: Tabla de verdad del biestable J-K (izquierda) y circuito que queremos implementar (derecha)
Ahora crea un proyecto llamado biest_jk y una nueva fuente VHDL del mismo nombre.
Pon los puertos sealados en la figura 5.1, asignndole los pines que se muestran en la
figura. Usa cualquiera de los procesos de los cdigos 5 1 5 2. Implemntalo en la FPGA
y comprueba que funciona correctamente.
50
5. Elementos de memoria
51
El proceso debe tener una sentencia que indica si es un elemento de memoria activo
por nivel (latch) o por flanco (flip flop). En el cdigo 5 1, resaltado en negrita, indica que
es un flip flop activo por flanco de subida. los cuatro posibles casos son:
Si es un flip flop activo por flanco de subida la sentencia de reloj debe ser:
if clk'event and clk='1' then
Si es un flip flop activo por flanco de bajada la sentencia de reloj debe ser:
if clk'event and clk='0' then
El biestable puede tener inicializaciones asncronas (reset, clear, set, preset, ... o diversos
nombres). Esta inicializacin se debe poner antes de la sentencia de reloj. La sentencia
de reloj se pone con un elsif que sigue a la sentencia de inicializacin (cdigo 5 5).
Biest_proc: Process (Reset, Clk)
begin
if reset = '0' then
Q <= '0';
elsif clk'event and clk='1' then
-- ahora van sentencias sincronas
......
52
5. Elementos de memoria
En la lista de sensibilidad del proceso debe aparecer la seal de reloj y todas las seales
asncronas que se leen (las que estn antes de la seal de reloj). No es incorrecto incluir
las seales sncronas (las que estn despus de la sentencia de reloj), pero incluirlas
hace que la simulacin vaya ms lenta. El cdigo 5 9 muestra un ejemplo,. En l, la
seal Dato no se incluye por ser una seal sncrona: est dentro de la condicin de reloj.
Incluirla no es incorrecto, pero hace la simulacin ms lenta.
Biest_proc: Process (Reset, ValorInicial, Clk)
begin
if Reset = '0' then
Q <= ValorInicial; -- dato asincrono
elsif Clk'event and Clk='1' then
-- Aqui van las senales sincronas y no se ponen en la lista de sensibilidad
Q <= Dato;
end if;
end process;
Dentro de la condicin del reloj pueden ir todo tipo de sentencias. Estas sentencias son
secuenciales y s importa el orden de aparicin. Si se asigna valor a una seal ms de
una vez, la ltima asignacin es la que le dar valor. As, los cdigos 5 10 y 5 11 son
equivalentes. El cdigo 5 10 asigna Q<='0' cuando Inic='1'. Mientras que el cdigo 5
11 asigna Q<='0' siempre, pero es sobrescrito por Q<=Dato cuando Inic='0', por tanto,
asigna Q<='0' cuando Inic='1'.
Biest_proc: Process (Reset, Clk)
begin
if Reset = '0' then
Q <= '0';
elsif Clk'event and Clk='1' then
if Inic = '0' then
Q <= Dato;
else
Q <= '0';
end if;
end if;
end process;
Cuando en un camino no se asigna ningn valor al biestable, ste guarda el valor que
tena antes. Por ejemplo, en el cdigo 5 2, la seal Q no recibe valor cuando J='0' y
K='0', por tanto, la seal Q guarda su valor anterior. En consecuencia, el proceso del
cdigo 5 2 es equivalente al proceso del cdigo 5 1. Puesto que en el cdigo 5 1 se
asigna Q <= Q cuando J='0' y K='0'.
Esto ltimo es muy importante para evitar crear un elemento de memoria cuando no
queremos crearlo. Si queremos crear un proceso combinacional debemos incluir todas
las posibilidades, o terminar el proceso con un else o un when others". Otra
alternativa es incluir una asignacin por defecto al principio.
53
Por ejemplo, el cdigo 5 12 no genera latch, porque con el else se cubren todas las
posibilidades. Sin embargo, el proceso 5 13 s genera latch. Aunque la seal Select
nunca pudiera valer "11" se debe de poner segn el cdigo 5 12.
CombProc: Process(Select,Dato1,Dato2)
begin
if Select = "00" then
Q <= '0';
elsif Select = "01" then
Q <= Dato1;
else
Q <= Dato2;
end if;
end process;
LatchProc: Process(Select,Dato1,Dato2)
begin
if Select = "00" then
Q <= '0';
elsif Select = "01" then
Q <= Dato1;
elsif Select = "10" then
Q <= Dato2;
end if;
end process;
Incluso, aunque se cubran todas las posibilidades se debe terminar con un else porque
los tipos std_logic tienen ms valores posibles aparte de 0 y 1 . El cdigo 5 14 es el
recomendado frente al cdigo 5 15.
CombProc: Process(Select,Dato1,Dato2)
begin
if Select = "00" then
Q <= '0';
elsif Select = "01" then
Q <= Dato1;
elsif Select = "10" then
Q <= Dato2;
else
Q <= '1';
end if;
end process;
LatchProc: Process(Select,Dato1,Dato2)
begin
if Select = "00" then
Q <= '0';
elsif Select = "01" then
Q <= Dato1;
elsif Select = "10" then
Q <= Dato2;
elsif Select ="11" then
Q <= '1';
end if;
end process;
Otra manera de asegurarse de que no se genera latch es incluir una asignacin por
defecto al principio. Esto vendra a ser equivalente a un else. El cdigo 5 16 es
equivalente al cdigo 5 12, y el cdigo 5 17 es equivalente al 5 14.
CombProc: Process(Select,Dato1,Dato2)
begin
Q <= Dato2;
if Select = "00" then
Q <= '0';
elsif Select = "01" then
Q <= Dato1;
end if;
end process;
CombProc: Process(Select,Dato1,Dato2)
begin
Q <= '1';
if Select = "00" then
Q <= '0';
elsif Select = "01" then
Q <= Dato1;
elsif Select = "10" then
Q <= Dato2;
end if;
end process;
Por ltimo, se recomienda indentar (incluir espacios o tabuladores) con cada sentencia
anidada. Esto facilita mucho la comprensin del cdigo. Se recomienda indentar con dos
espacios. Para determinar la indentacin con el ISE WebPack, vete a Edit Preferences, y all
busca la categora ISE Text Editor. En ella pon Tab Width = 2. Y pon que cuando inserte un
tabulador (When You Press the Tab Key) se pongan espacios: Insert spaces.
54
5. Elementos de memoria
modo que si est apagado, cuando pulsemos se encienda; y si est encendido, al pulsar se
apague.
Sin mirar la solucin que se da a continuacin, intenta realizar el circuito t slo con la
informacin de la seccin 5.1.
5.3.1. Primera solucin
La primera aproximacin al problema sera realizar un biestable T, igual que como se hizo
en la prctica 17 de ED1 [12]. Para recordar, en la figura 5.3 se muestra la tabla de verdad
del biestable T y su esquema.
BTN0
T
0
1
Q(t+1)
Q(t)
Q(t)
CLK
LD0
Reset
BTN3
55
'1'
T='0'
Q
guarda valor
cambio en Q
BTN0-T
CLK
50 MHz
LED0-Q
Para evitar este efecto, lo que tenemos que hacer es un circuito detector de flancos, que
transformar nuestro pulso humano en pulso del periodo del reloj. Podramos pensar en
utilizar la expresin T'event and T='1' para detectar el flanco de subida. Y seguramente
funcione, sin embargo hemos visto que slo debemos utilizar dicha expresin para la
seal de reloj. Porque si no, estaremos usando la seal T como reloj del biestable, y en
diseos sncronos no es recomendable. As que tenemos que pensar en otra alternativa.
El detector de flanco se puede realizar con una mquina de estados que detecte la
secuencia 0 1 para flancos de subida y la secuencia 1 0 para flancos de bajada.
La mquina de estados podemos hacerla mediante diagrama de estados o bien mediante
registros de desplazamiento (usando biestables D). Ambos mtodos se han visto en clase.
Por ser una secuencia pequea, la haremos mediante registros de desplazamiento. No
usaremos directamente la entrada debido a que el pulsador es una entrada asncrona, sino
que la registraremos (la pasaremos por un biestable) para evitar metaestabilidad y para
evitar que el pulso resultante dure muy poco. El circuito detector de flanco sin registrar la
entrada se muestra en la figura 5.5 (realizado con registro de desplazamiento). Es una
mquina de Mealy porque la salida depende de la entrada (BTN0).
PULSO_BTN0
BTN0
BTN0_RG1
Clk
Figura 5.5: Circuito detector de flanco sin registrar la entrada (Mealy: no recomendado para este caso)
56
5. Elementos de memoria
clk
Clk
BTN0
BTN0_RG1
PULSO_BTN0
Si el pulso llega muy cerca del flanco de subida del
reloj el pulso resultante puede ser muy pequeo, o
lo que es peor: puede haber metaestabilidad
Figura 5.6: Cronograma del detector de flanco realizado por Mealy (no recomendado para este caso)
BTN0_RG1
BTN0_RG2
Clk
Figura 5.7: Circuito detector de flanco registrando la entrada (Moore: recomendado para este caso)
Ahora los pulsos resultantes siempre durarn un ciclo de reloj, como puedes ver en el
cronograma de la figura 5.8.
clk
Clk
BTN0
BTN0_RG1
BTN0_RG2
PULSO_BTN0
Ahora los pulsos siempre duran de un ciclo de reloj
Figura 5.8: Cronograma del detector de flanco realizado por Moore (recomendado para este caso)
As pues, el circuito que tenemos que hacer contendr el biestable T de la figura 5.3, pero
en vez de recibir el pulso directamente del pulsador, lo recibir filtrado por el detector de
flanco de la figura 5.7. El circuito final ser el mostrado en la figura 5.9.
57
detector de flanco
biestable T
PULSO_BTN0
BTN0
BTN0_RG1
BTN0_RG2
LD0
Reset
Reset
Reset
Clk
BTN3
Figura 5.9: Circuito que enciende y apaga un LED con el mismo pulsador
Este circuito se puede describir con el cdigo VHDL mostrado en la figura 5.10.
biest_D1: Process (Reset, Clk)
begin
if Reset = '1' then
BTN0_REG1 <= '0';
elsif Clk'event and Clk='1' then
BTN0_REG1 <= BTN0;
end if;
end process;
biest_D2: Process (Reset, Clk)
begin
if Reset = '1' then
BTN0_REG2 <= '0';
elsif Clk'event and Clk='1' then
BTN0_REG2 <= BTN0_REG1;
end if;
end process;
BTN0
Primer
biestable D
Reset
Clk
BTN0_RG1
Segundo
biestable D
BTN0_RG2
Reset
Clk
Deteccin de
flanco de subida
PULSO_BTN0 <= '1' when (BTN0_REG1 = '1' and BTN0_REG2='0') else '0';
biest_T: Process (Reset, Clk)
begin
if Reset = '1' then
Q_T <= '0';
elsif Clk'event and Clk='1' then
if PULSO_BTN0 = '1' then
Q_T <= NOT Q_T;
end if;
end if;
end process;
BTN0_RG1
biestable T cuya
entrada
PULSO_BTN0 se ha
transformado en
un pulso de un
ciclo de reloj
PULSO_BTN0
Q_T
Reset
Clk
Los dos primeros procesos de la figura 5.10 se pueden agrupar en uno, ya que en los
procesos el valor de las seales no se actualiza inmediatamente sino que se actualizan
al terminar el proceso. As, en el cdigo 5 20, la seal BTNO_REG1 no toma el valor
inmediatamente de BTN0, y por lo tanto, la seal BTN0_REG2 no recibe el valor que se le
acaba de asignar a BTN0_REG1 (el que le da BTN0) sino el valor que tena BTN0_REG1. En
consecuencia, al salir e proceso, BTN0_REG1 tendr el valor de BTN0 y BTN_REG2 tendr el
antiguo valor de BTN0_REG1 y no el que se le acaba de asignar. Por tanto, BTN0_REG2 est
retrasada un ciclo de reloj respecto de BTN0_REG1 (que es lo que queremos hacer).
58
5. Elementos de memoria
Ahora, crea un nuevo proyecto e implementa en la FPGA este circuito y comprueba que
funciona bien. En caso de que ests trabajando con la placa Basys, el diseo funcionar
mejor que el diseo de la figura 5.3, sin embargo, todava no funcionar del todo bien
porque los pulsadores de la Basys no tienen el circuito de eliminacin de rebotes (figura
3.2) que s est presente en la Pegasus (figura 3.1). Ms adelante, en el captulo 11 veremos
cmo solucionar este problema.
En cualquier caso qu pasa si en este circuito mantienes presionado el pulsador BTN0? se
comporta igual que antes?
5.4. Conclusiones
Los conceptos ms importantes de esta prctica:
No todas las maneras que tiene el VHDL para modelar elementos de memoria son
vlidas para sntesis.
En esta prctica se han establecido unas reglas para describir elementos de memoria
para sntesis.
Cuando describimos lgica combinacional, hay que tener cuidado de no crear latches
no deseados, para evitarlo, las seales se deben asignar en todas las condiciones
posibles. Las condiciones deben terminar en ELSE y no ELSIF.
En los procesos, las seales no se actualizan inmediatamente sino que se actualizan al
terminar el proceso.
Las entradas asncronas se deben registrar para evitar metaestabilidad.
Los detectores de flancos suelen ser necesarios para realiza interfaces humanos con
diseos sncronos
59