Bird
Raised Fist0
Verilogprogramming~5 mins

Dual-port RAM design in Verilog

Choose your learning style10 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.

Practice

(1/5)
1. What is the main advantage of using a dual-port RAM in hardware design?
easy
A. It allows two independent read/write operations simultaneously.
B. It reduces the size of the memory.
C. It makes the RAM slower but cheaper.
D. It only supports read operations.

Solution

  1. Step 1: Understand dual-port RAM functionality

    Dual-port RAM has two ports that can access memory independently at the same time.
  2. Step 2: Identify the main benefit

    This allows simultaneous read/write operations, improving performance.
  3. Final Answer:

    It allows two independent read/write operations simultaneously. -> Option A
  4. Quick Check:

    Dual-port RAM = two simultaneous accesses [OK]
Hint: Dual-port RAM means two ports can access memory at once [OK]
Common Mistakes:
  • Thinking it reduces memory size
  • Assuming it only supports reads
  • Believing it slows down RAM
2. Which of the following is the correct Verilog port declaration for a dual-port RAM with separate read and write ports?
easy
A. input clk, input [7:0] addr_a, output [7:0] data_out_a, input [7:0] addr_b, output [7:0] data_out_b;
B. input clk, input [7:0] addr, input [7:0] data_in, output [7:0] data_out, input we;
C. input clk, input [7:0] addr, output [7:0] data_out, input we, input re;
D. input clk, input [7:0] addr_a, input [7:0] data_in_a, output [7:0] data_out_a, input we_a, input [7:0] addr_b, input [7:0] data_in_b, output [7:0] data_out_b, input we_b;

Solution

  1. Step 1: Identify dual-port RAM ports

    Dual-port RAM needs separate address, data, and write enable signals for each port.
  2. Step 2: Match correct declaration

    input clk, input [7:0] addr_a, input [7:0] data_in_a, output [7:0] data_out_a, input we_a, input [7:0] addr_b, input [7:0] data_in_b, output [7:0] data_out_b, input we_b; declares separate addr, data_in, data_out, and we signals for ports A and B, matching dual-port RAM design.
  3. Final Answer:

    input clk, input [7:0] addr_a, input [7:0] data_in_a, output [7:0] data_out_a, input we_a, input [7:0] addr_b, input [7:0] data_in_b, output [7:0] data_out_b, input we_b; -> Option D
  4. Quick Check:

    Separate signals per port = input clk, input [7:0] addr_a, input [7:0] data_in_a, output [7:0] data_out_a, input we_a, input [7:0] addr_b, input [7:0] data_in_b, output [7:0] data_out_b, input we_b; [OK]
Hint: Dual-port RAM needs separate signals for each port [OK]
Common Mistakes:
  • Using single address and data signals for both ports
  • Missing write enable signals
  • Confusing read and write signals
3. Given the following Verilog snippet for a dual-port RAM, what will be the value of data_out_b after the clock edge if we_b is 0 and addr_b is 3?
reg [7:0] ram [0:7];
always @(posedge clk) begin
  if (we_a) ram[addr_a] <= data_in_a;
  if (we_b) ram[addr_b] <= data_in_b;
  data_out_a <= ram[addr_a];
  data_out_b <= ram[addr_b];
end
medium
A. The value of data_in_b.
B. The value stored at address 3 before the clock edge.
C. Zero, because we_b is 0.
D. Undefined, because data_out_b is not assigned.

Solution

  1. Step 1: Understand write enable effect

    Since we_b is 0, no write occurs at addr_b on this clock edge.
  2. Step 2: Determine data_out_b value

    data_out_b reads the RAM at addr_b, so it outputs the stored value at address 3 before the clock edge.
  3. Final Answer:

    The value stored at address 3 before the clock edge. -> Option B
  4. Quick Check:

    we_b=0 means no write; output = stored value [OK]
Hint: If write enable is 0, output shows stored memory value [OK]
Common Mistakes:
  • Assuming data_out_b equals data_in_b always
  • Thinking output is zero when no write
  • Ignoring read operation on clock edge
4. Identify the error in this dual-port RAM Verilog code snippet:
reg [7:0] ram [0:15];
always @(posedge clk) begin
  if (we_a) ram[addr_a] <= data_in_a;
  if (we_b) ram[addr_b] <= data_in_b;
  data_out_a <= ram[addr_a];
  data_out_b <= ram[addr_b];
end

assign data_out_a = ram[addr_a];
medium
A. Conflicting assignments to data_out_a: both procedural and continuous.
B. Missing clock signal in sensitivity list.
C. Incorrect RAM size declaration.
D. No write enable signals declared.

Solution

  1. Step 1: Check assignments to data_out_a

    Data_out_a is assigned inside the always block and also by continuous assign statement, causing conflict.
  2. Step 2: Understand Verilog rules

    A signal cannot be driven by both procedural and continuous assignments simultaneously.
  3. Final Answer:

    Conflicting assignments to data_out_a: both procedural and continuous. -> Option A
  4. Quick Check:

    Signal driven twice = conflict error [OK]
Hint: Avoid assigning same signal in always block and assign statement [OK]
Common Mistakes:
  • Ignoring multiple drivers on one signal
  • Thinking sensitivity list needs clock and addr
  • Misunderstanding RAM size syntax
5. You want to design a dual-port RAM where Port A is write-only and Port B is read-only. Which modification correctly implements this behavior in Verilog?
hard
A. Disable clock on Port B to make it read-only.
B. Use write enable on both ports and read data from both ports.
C. Use write enable only on Port A and never write on Port B; read data only from Port B.
D. Use a single write enable for both ports.

Solution

  1. Step 1: Define port roles

    Port A should only write data, so it needs a write enable and no read output.
  2. Step 2: Configure Port B as read-only

    Port B should not write, so write enable is never asserted; it only reads data from RAM.
  3. Final Answer:

    Use write enable only on Port A and never write on Port B; read data only from Port B. -> Option C
  4. Quick Check:

    Write-only Port A + Read-only Port B = Use write enable only on Port A and never write on Port B; read data only from Port B. [OK]
Hint: Assign write enable only to write port, read from the other [OK]
Common Mistakes:
  • Trying to write on both ports
  • Disabling clock to control read/write
  • Using single write enable for both ports
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard