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.
Dual-port RAM design in 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.
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)
);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
endalways @(posedge clk) begin
if (we_b) ram[addr_b] <= din_b; // Write on port B
dout_b <= ram[addr_b]; // Read on port B
endThis 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.
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
endmoduleIf 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.
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
dual-port RAM in hardware design?Solution
Step 1: Understand dual-port RAM functionality
Dual-port RAM has two ports that can access memory independently at the same time.Step 2: Identify the main benefit
This allows simultaneous read/write operations, improving performance.Final Answer:
It allows two independent read/write operations simultaneously. -> Option AQuick Check:
Dual-port RAM = two simultaneous accesses [OK]
- Thinking it reduces memory size
- Assuming it only supports reads
- Believing it slows down RAM
Solution
Step 1: Identify dual-port RAM ports
Dual-port RAM needs separate address, data, and write enable signals for each port.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.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 DQuick 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]
- Using single address and data signals for both ports
- Missing write enable signals
- Confusing read and write signals
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
Solution
Step 1: Understand write enable effect
Sincewe_bis 0, no write occurs ataddr_bon this clock edge.Step 2: Determine data_out_b value
data_out_breads the RAM ataddr_b, so it outputs the stored value at address 3 before the clock edge.Final Answer:
The value stored at address 3 before the clock edge. -> Option BQuick Check:
we_b=0 means no write; output = stored value [OK]
- Assuming data_out_b equals data_in_b always
- Thinking output is zero when no write
- Ignoring read operation on clock edge
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];
Solution
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.Step 2: Understand Verilog rules
A signal cannot be driven by both procedural and continuous assignments simultaneously.Final Answer:
Conflicting assignments to data_out_a: both procedural and continuous. -> Option AQuick Check:
Signal driven twice = conflict error [OK]
- Ignoring multiple drivers on one signal
- Thinking sensitivity list needs clock and addr
- Misunderstanding RAM size syntax
Solution
Step 1: Define port roles
Port A should only write data, so it needs a write enable and no read output.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.Final Answer:
Use write enable only on Port A and never write on Port B; read data only from Port B. -> Option CQuick 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]
- Trying to write on both ports
- Disabling clock to control read/write
- Using single write enable for both ports
Ready to prove it?
Pass the test and this pattern moves unknown
