Одноразрядная синхронная RAM на Verilog: подробное руководство
Проект
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, we, oe
);
reg [DATA_WIDTH-1:0] tmp_data;
reg [DATA_WIDTH-1:0] mem [DEPTH];
always @(posedge clk)
if (cs & we) mem[addr] <= data;
always @(posedge clk)
if (cs & !we) tmp_data <= mem[addr];
assign data = (cs & oe & !we) ? tmp_data : 'hz;
endmodule
Тестбенч
module tb;
parameter ADDR_WIDTH = 4, DATA_WIDTH = 16, DEPTH = 16;
reg clk, cs, we, 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
Verilog
- Освоение Verilog: полное руководство по проектированию цифровых схем
- Освоение конкатенации в Verilog: практическое руководство
- Понимание назначений в Verilog: типы, синтаксис и лучшие практики
- Блокирующие и неблокирующие назначения в Verilog: ключевые различия
- Мастерство функций в Verilog для эффективного RTL дизайна
- Понимание задач (Tasks) в Verilog: отличия от функций, синтаксис и применение
- Генератор тактового сигнала в Verilog: проектирование и реализация
- Мастерство математических функций Verilog для эффективного аппаратного дизайна
- Мастерство $timeformat в Verilog: точность и контроль отображения времени
- Понимание и печать timescale в Verilog в любой области видимости