0
0
Verilogprogramming~5 mins

Dual-port RAM design in Verilog

Choose your learning style9 modes available
Introduction

Dual-port RAM lets you read and write data at the same time using two separate ports. This helps make your designs faster and more flexible.

When you want to read data from memory while writing new data at the same time.
In video processing where one part updates pixels and another reads them simultaneously.
For communication buffers where data is written by one device and read by another without waiting.
In CPU designs where instruction fetch and data access happen at the same time.
Syntax
Verilog
module dual_port_ram #(
    parameter DATA_WIDTH = 8,
    parameter ADDR_WIDTH = 4
) (
    input wire clk,
    input wire we_a, // write enable for port A
    input wire [ADDR_WIDTH-1:0] addr_a,
    input wire [DATA_WIDTH-1:0] din_a,
    output reg [DATA_WIDTH-1:0] dout_a,
    input wire we_b, // write enable for port B
    input wire [ADDR_WIDTH-1:0] addr_b,
    input wire [DATA_WIDTH-1:0] din_b,
    output reg [DATA_WIDTH-1:0] dout_b
);

    reg [DATA_WIDTH-1:0] ram [0:(1<<ADDR_WIDTH)-1];

    always @(posedge clk) begin
        if (we_a) ram[addr_a] <= din_a;
        dout_a <= ram[addr_a];
    end

    always @(posedge clk) begin
        if (we_b) ram[addr_b] <= din_b;
        dout_b <= ram[addr_b];
    end

endmodule

The module has two ports (A and B), each can read or write independently.

Both ports share the same memory array but have separate address, data, and control signals.

Examples
Instantiates the dual-port RAM with 8-bit data and 4-bit address width.
Verilog
dual_port_ram #(8, 4) ram_inst (
    .clk(clk),
    .we_a(we_a),
    .addr_a(addr_a),
    .din_a(data_in_a),
    .dout_a(data_out_a),
    .we_b(we_b),
    .addr_b(addr_b),
    .din_b(data_in_b),
    .dout_b(data_out_b)
);
Shows how port A writes and reads data on clock edge.
Verilog
always @(posedge clk) begin
    if (we_a) ram[addr_a] <= din_a; // Write on port A
    dout_a <= ram[addr_a];         // Read on port A
end
Shows how port B writes and reads data on clock edge.
Verilog
always @(posedge clk) begin
    if (we_b) ram[addr_b] <= din_b; // Write on port B
    dout_b <= ram[addr_b];         // Read on port B
end
Sample Program

This testbench writes values to two different addresses using both ports at the same time. Then it reads back the values to show that both ports work independently.

Verilog
module testbench;
    reg clk = 0;
    always #5 clk = ~clk; // 10 time units clock period

    reg we_a, we_b;
    reg [3:0] addr_a, addr_b;
    reg [7:0] din_a, din_b;
    wire [7:0] dout_a, dout_b;

    dual_port_ram #(8,4) ram (
        .clk(clk),
        .we_a(we_a),
        .addr_a(addr_a),
        .din_a(din_a),
        .dout_a(dout_a),
        .we_b(we_b),
        .addr_b(addr_b),
        .din_b(din_b),
        .dout_b(dout_b)
    );

    initial begin
        // Write 42 to address 3 on port A
        we_a = 1; addr_a = 4'd3; din_a = 8'd42;
        // Write 99 to address 5 on port B
        we_b = 1; addr_b = 4'd5; din_b = 8'd99;
        #10;

        // Disable write, read from both addresses
        we_a = 0; we_b = 0;
        addr_a = 4'd3; addr_b = 4'd5;
        #10;

        $display("Port A read from addr 3: %d", dout_a);
        $display("Port B read from addr 5: %d", dout_b);

        $finish;
    end
endmodule
OutputSuccess
Important Notes

If both ports write to the same address at the same time, the result depends on your FPGA or synthesis tool and may cause conflicts.

Dual-port RAM is useful to increase memory access speed by allowing two operations simultaneously.

Summary

Dual-port RAM allows two independent read/write operations at the same time.

Each port has its own address, data, and write enable signals.

This design helps improve performance in many hardware applications.