-
Notifications
You must be signed in to change notification settings - Fork 198
Capítulo 28: Memoria RAM
Ejemplos de este capítulo en github
Las memorias RAM nos permiten almacenar datos y recuperarlos durante el funcionamiento del circuito. Son memorias donde podemos leer y escribir
Crearemos una memoria RAM genérica, síncrona, con una entrada de datos para escritura y una salida para lectura. Como ejemplo diseñaremos un buffer de almacenamiento de 16 bytes que cargue a través de datos provenientes del puerto serie, y una vez llenado, se vuelca su contenido también por el puerto serie.
La memoria RAM genérica la denominaremos genram
Los puertos y parámetros se muestran esta figura:
Los parámetros son los mismos que en la memoria ROM:
- DW (Data width): Anchura de los datos (en bits)
- AW (Address width): Anchura de las direcciones (en bits)
- ROMFILE: Fichero con el contenido inicial precargado de la ram
Los puertos son:
- data_in: Entrada de datos, para escritura
- data_out: Salida de datos, en la lectura
- addr: Dirección de acceso, tanto para escritura como para lectura
- rw: Modo de acceso: lectura (rw = 1) o escritura (rw = 0)
En este cronograma se muestran dos ciclos de lectura y uno de escritura intercalado:
Ciclo de lectura:
- Se coloca la dirección de lectura en addr
- Se pone la señal rw a 1 para indicar que se quiere leer
- En el siguiente flanco de subida se devolverá el dato por el puerto data_out
Ciclo de escritura:
- Se coloca la dirección de escritura en** addr**
- Se coloca el dato a escribir en el puerto data_in
- Se pone la señal rw a 0 para indicar escritura
- En el siguiente flanco de subida del reloj se escribirá el dato en la memoria
El código es similar al de la memoria rom pero añadiendo un proceso nuevo que se encarga de la escritura en cada flanco de subida del reloj, usando la señal rw como habilitación
module genram #( //-- Parametros
parameter AW = 5, //-- Bits de las direcciones (Adress width)
parameter DW = 4) //-- Bits de los datos (Data witdh)
( //-- Puertos
input clk, //-- Señal de reloj global
input wire [AW-1: 0] addr, //-- Direcciones
input wire rw, //-- Modo lectura (1) o escritura (0)
input wire [DW-1: 0] data_in, //-- Dato de entrada
output reg [DW-1: 0] data_out); //-- Dato a escribir
//-- Parametro: Nombre del fichero con el contenido de la RAM
parameter ROMFILE = "bufferini.list";
//-- Calcular el numero de posiciones totales de memoria
localparam NPOS = 2 ** AW;
//-- Memoria
reg [DW-1: 0] ram [0: NPOS-1];
//-- Lectura de la memoria
always @(posedge clk) begin
if (rw == 1)
data_out <= ram[addr];
end
//-- Escritura en la memoria
always @(posedge clk) begin
if (rw == 0)
ram[addr] <= data_in;
end
//-- Cargar en la memoria el fichero ROMFILE
//-- Los valores deben estan dados en hexadecimal
initial begin
$readmemh(ROMFILE, ram);
end
endmodule
TODO
0 You are leaving the privative sector (EN)
1 ¡Hola mundo! (EN) (RU)
2 De un bit a datos (EN)
3 Puerta NOT (EN)
4 Contador de 26 bits (EN)
5 Prescaler de N bits (EN)
6 Múltiples prescalers (EN)
7 Contador de 4 bits con prescaler (EN)
8 Registro de 4 bits (EN)
9 Inicializador (EN)
10 Registro de desplazamiento (EN)
11 Multiplexor de 2 a 1 (EN)
12 Multiplexor de M a 1 (EN)
13 Inicializando registros (EN)
14 Registro de N bits con reset síncrono
15 Divisor de frecuencias
16 Contador de segundos
17 Generando tonos audibles
18 Tocando notas
19 Secuenciando notas
20 Comunicaciones serie asíncronas
21 Baudios y transmisión
22 Reglas de diseño síncrono
23 Controladores y autómatas finitos
24 Unidad de transmisión serie asíncrona
25 Unidad de recepción serie asíncrona
26 Memoria ROM
27 Memoria ROM genérica
28 Memoria RAM
29 Puertas triestado
30 Hacia el microprocesador y más allá