Diseño de RAM de puerto único en Verilog: Guía completa
Diseño del módulo
module single_port_sync_ram #(
parameter ADDR_WIDTH = 4,
parameter DATA_WIDTH = 32,
parameter DEPTH = 16
)(
input clk,
input [ADDR_WIDTH-1:0] addr,
inout [DATA_WIDTH-1:0] data,
input cs,
input we,
input oe
);
reg [DATA_WIDTH-1:0] tmp_data;
reg [DATA_WIDTH-1:0] mem [DEPTH];
always @(posedge clk) begin
if (cs & we)
mem[addr] <= data;
end
always @(posedge clk) begin
if (cs & !we)
tmp_data <= mem[addr];
end
assign data = (cs & oe & !we) ? tmp_data : 'hz;
endmodule
Banco de pruebas (Testbench)
module tb;
parameter ADDR_WIDTH = 4;
parameter DATA_WIDTH = 16;
parameter DEPTH = 16;
reg clk;
reg cs;
reg we;
reg oe;
reg [ADDR_WIDTH-1:0] addr;
wire [DATA_WIDTH-1:0] data;
reg [DATA_WIDTH-1:0] tb_data;
single_port_sync_ram #(.DATA_WIDTH(DATA_WIDTH)) u0 (
.clk(clk),
.addr(addr),
.data(data),
.cs(cs),
.we(we),
.oe(oe)
);
always #10 clk = ~clk;
assign data = !oe ? tb_data : 'hz;
initial begin
{clk, cs, we, addr, tb_data, oe} <= 0;
repeat (2) @(posedge clk);
for (integer i = 0; i < 2**ADDR_WIDTH; i = i + 1) begin
repeat (1) @(posedge clk)
addr <= i;
we <= 1;
cs <= 1;
oe <= 0;
tb_data <= $random;
end
for (integer i = 0; i < 2**ADDR_WIDTH; i = i + 1) begin
repeat (1) @(posedge clk)
addr <= i;
we <= 0;
cs <= 1;
oe <= 1;
end
#20 $finish;
end
endmodule
Esta implementación describe una memoria RAM síncrona de puerto único con interfaz de bus bidireccional. El módulo acepta parámetros configurables para ancho de dirección, ancho de datos y profundidad. La escritura y lectura ocurren en flanco positivo de reloj cuando el chip select (cs) está activo. La salida de datos se habilita mediante output enable (oe) y se pone en alta impedancia ('hz) cuando no se lee.
Verilog
- Dominar Verilog: Tutorial completo para diseño de circuitos digitales
- Dominar la concatenación en Verilog: Guía práctica
- Comprender las asignaciones en Verilog: tipos, sintaxis y mejores prácticas
- Bloqueante vs. No bloqueante en Verilog: Diferencias clave explicadas
- Dominar las funciones en Verilog para diseño RTL eficiente
- Comprender las Tasks en Verilog: Funciones vs Tasks, sintaxis y uso
- Generador de reloj en Verilog: Guía de diseño e implementación
- Dominar las funciones matemáticas en Verilog para diseño de hardware eficiente
- Dominar $timeformat en Verilog: Control de precisión y visualización
- Comprender e imprimir timescales de Verilog en cualquier alcance
- Dominando la E/S de Archivos en Verilog: Abrir, Leer, Escribir y Cerrar