# Ayuda con memoria ram diseñada en vhdl



## electronacho (Feb 17, 2011)

Hola colegas, primero les quiero contar que es mi primer tema aca, asi que tengan piedad.
Paso a contarles, estoy diseñando una alarma en este codigo, y encontre en la web una memoria ram diseñada tamien en este lenguaje, que me puede servir. esta es la pagina (http://www.dacya.ucm.es/marcos/intvhdl.pdf)
les paso el codigo

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
-- El paquete debe contener la función que pasa de std_logic_vector a
-- natural, para poder acceder al array (ver sección 6)

entity SRAM is
generic( w: integer:=4; -- ancho de palabra
d: integer:=4; -- nº de palabras
a: integer:=2); -- ancho dirección
port( Clock: in std_logic;
Enable: in std_logic;
Read : in std_logic;
Write: in std_logic;
Read_Addr: in std_logic_vector(a-1 downto 0);
Write_Addr: in std_logic_vector(a-1 downto 0);
Data_in: in std_logic_vector(w-1 downto 0);
Data_out: out std_logic_vector(w-1 downto 0)
);
end SRAM;

architecture behav of SRAM is
-- Utilizamos un array para guardar los valores de la memoria
type ram_type is array (0 to d-1) of std_logic_vector(w-1 downto 0);
signal tmp_ram: ram_type;
begin
-- Lectura
process(Clock, Read)
begin
if (Clock'event and Clock='1') then
if Enable='1' then
if Read='1' then
Data_out <= tmp_ram(std2n(Read_Addr));
else
Data_out <= (Data_out'range => 'Z');
-- Todos los bits de Data_out se ponen a 'Z'
end if;
end if;
end if;
end process;
-- Escritura
process(Clock, Write)
begin
if (Clock'event and Clock='1') then
if Enable='1' then
if Write='1' then
tmp_ram(std2n(Write_Addr)) <= Data_in;
end if;
end if;
end if;
end process;
end behav;

La cuestion es que me da error en donde dice std2n, me dice que no esta declarado.
en mi opinion la falta una libreria o un package que pasa de un vector de bit a numero natural, que tamine lo dice el propio codigo como nota, y el tema es que no encuentro nada de eso, y ni idea como se puede diseñar. Les agradecere infinitamente su ayuda. desde ya muchas gracias


----------



## electronacho (Feb 17, 2011)

A lo mejor saben como diseñar una memoria en vhdl (otra forma a la que yo propongo), para implementarla en un cpld. Si pudieran decirme como hacerla o pasarme el codigo para poder verlo. Estoy abierto a cualquier propuestas. Muchas gracias.


----------



## Ferny (Feb 17, 2011)

Comentario que aparece al principio:

-- El paquete debe contener la función que pasa de std_logic_vector a
-- natural, para poder acceder al array (ver sección 6)

Ésa es la función std2n...

Prueba cambiando std2n por conv_integer, debería funcionar igual y no darte problemas.

Data_out <= tmp_ram(conv_integer(Read_Addr));
tmp_ram(conv_integer(Write_Addr)) <= Data_in;



> A lo mejor saben como diseñar una memoria en vhdl (otra forma a la que yo propongo), para implementarla en un cpld.


Dependiendo de qué cpld uses es posible que no puedas implementar una RAM, ten cuidado con eso. Los CPLD no están pensados para implementar memorias, para eso son más las FPGAs...

La RAM que pones es una implementación típica, pero cuidado ya que permite operaciones de lectura y escritura simultáneas sobre la misma dirección de memoria... podría mejorarse utilizando una sola señal que sustituya a las read/write y que sea por ejemplo '1' para read y '0' para write, así evitas ese problema.

Saludos


----------



## electronacho (Feb 17, 2011)

Amigo ferny, te agradezco tu ayuda. primero te cuento que la solución que me diste anduvo barbaro, sin problemas, y tuve encuenta lo de las señales read/write. Ahora la cuestion es que al simular me tira error, (la simulacion aparece en rojo y con letras U), pienso que es un error en las señales y/o frecuencias; te explico algo, ya que pareces idoneo en el tema, lo que tengo que hacer es una alarma con codigo, en la cual una de las caracteristicas de esta sea que el usuario pueda cambiar este codigo la veces que quiera. Lo que estoy pensando es que a lo mejor me convenga mas pensarlo a nivel hardware, (como se debe pensar al trajar con vhdl), pero pensando mas en registros y flip-flop. vos que opinas? ire bien encaminado con el uso de esta memoria que propuise anteriormente? o me conviene pensarlo mas por el lado de registros? que me propondrias vos?
Un poco largo todo esto jaja, perdon si te arte. Desde ya te agradezco tu ayudo.
Saludos


----------



## Ferny (Feb 17, 2011)

Que salga U es normal, eso sucede cuando el estado inicial no está definido, como este caso. Lo correcto sería inicializar la memoria (todos los bits a '1' por ejemplo), de todas formas tampoco es algo muy necesario. Lo más que puede pasar es que si lees la memoria sin haberla escrito antes, lea cualquier cosa (en simulación saldrán las U, pero en una implementación real probablemente leas todos los bits a '1').

Sobre la implementación, depende de la cantidad de cosas que necesites guardar. Si son pocas cosas, unos registros son más sencillos de implementar, pero si quieres guardar gran cantidad de datos entonces sin duda una memoria es lo más óptimo en área. Tienes que tener en cuenta que los registros se hacen a base de flip-flops (un bit = un flip-flop), que es un recurso bastante más escaso que la RAM en el caso de las FPGAs (fácil te puedes encontrar una FPGA que tenga por ejemplo 20000 flip-flops pero más de 2Mbits de RAM).

El caso de los CPLD es otro, éstos están pensados más para realizar funciones lógicas, por ello la cantidad de flip-flops y ram que tienen puede ser escasa o incluso nula dependiendo del dispositivo.

Saludos


----------



## electronacho (Feb 17, 2011)

gracias de nuevo ferny, lo que tengo que guardar son dos codigos, uno para desactivar/armar la alarma y otro que desactivar/armar pero en forma silenciosa. el caso es que son dos codigos. Lo que voy a hacer es probar con este codigo a ver que pasa y sino lo pensare de otra manera, por lo menos hasta ver el modelo del cpld. Ahora me di cuenta que las sentencias Data_out <= tmp_ram(conv_integer(Read_Addr)); y tmp_ram(conv_integer(Write_Addr)) <= Data_in; no termino de entender, no entiendo que poner el las entradas Read_Addr y Write_Addr. digamos que para un codigo deberia guardar 4 palabras de 4 bits. pero esas entradas no se que son. Me podrias explicar eso... y no te jodo mas. gracias


----------



## Ferny (Feb 18, 2011)

Read_Addr y Write_Addr son buses de datos de 2 bits, pueden tomar los valores 00 - 01 - 10 - 11. Son cada una de las 4 direcciones de memoria que tiene tu RAM, por tanto puedes almacenar 4 valores distintos de 4 bits (el ancho del bus de datos es 4). Con esas entradas le estás indicando a la RAM qué posición quieres leer o escribir.

conv_integer lo que hace es convertir a entero un bus de datos binario, es decir convertiría los anteriores valores respectivamente a 0 - 1 - 2 - 3

finalmente tmp_ram(x) es un array, para acceder a los elementos del array tienes que pasarle el valor entero del elemento al que quieres acceder, que es esa x que puse (x = 0 - 1 - 2 - 3)


----------



## felipeyeah (Feb 19, 2011)

o*y*e amigo, que programa *h*-usas para programar en vhdl, yo siempre he querido hacer algún circuito y descargue uno pero no se pudo..:S

emm.. *Qu*e 'cosas' *h-*usas para programar y diseñar circuitos? 
te agrade*c*ería que me dijeras para que yo me iniciara en esto..

saludos!


----------



## electronacho (Feb 26, 2011)

yo uso el xilinx 10.1, y para simular uso el que trae ese programa

Ferny, te queria agradecer tu ayuda, me fue muy util. te cuento que no pude hacerla al final, no se porque; y como me acortan los tiempos opte por hacer la memoria en hardware, ya que no es un circuito muy complcado ni muy grande. Cuando tenga un poco mas de tiempo pienso resolver el problema porque me quede con la pica.
Desde ya muchas gracias


----------

