0% found this document useful (0 votes)
29 views8 pages

Single Port RAM Fix

The document outlines improvements to a single-port RAM Verilog code, addressing issues with read operations, filename extensions for dump files, and the need for delays in read verification. It provides corrected code for both the single-port RAM module and its testbench, ensuring proper functionality and synchronization. Additionally, it introduces a dual-port RAM design with separate read/write ports, detailing its features and providing a testbench for simulation.

Uploaded by

Siddharth Doshi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
29 views8 pages

Single Port RAM Fix

The document outlines improvements to a single-port RAM Verilog code, addressing issues with read operations, filename extensions for dump files, and the need for delays in read verification. It provides corrected code for both the single-port RAM module and its testbench, ensuring proper functionality and synchronization. Additionally, it introduces a dual-port RAM design with separate read/write ports, detailing its features and providing a testbench for simulation.

Uploaded by

Siddharth Doshi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

Single Port RAM Fix

Your single-port RAM Verilog code is logically structured but has a few areas for improvement:

Issues & Improvements:

1. Read Operation Issue:


The way `addr_reg` is assigned in the `else` condition makes the read operation not
work as expected.
The read should happen asynchronously or should use the same clocking mechanism
as the write.
2. `$dumpfile` Filename Issue:
The filename should have `.vcd` extension: `wave_single_port_ram.vcd`.
3. Missing Delay for Read Verification:
After setting `we = 0`, a small delay should be added before reading the stored values.

Corrected Code:

Here’s an improved and fully functional version of your code:

Updated `single_port_ram` Module

verilog

module single_port_ram (
input [7:0] data,
input [5:0] addr,
input we, clock,
output reg [7:0] q
);

reg [7:0] ram [63:0];

always @ (posedge clock) begin


if (we)
ram[addr] <= data; // Write Operation
else
q <= ram[addr]; // Read Operation (Fixed)
end

endmodule

Updated `single_port_ram_tb` Testbench

verilog

module single_port_ram_tb ();

reg [7:0] data;

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 1/8
reg [5:0] addr;
reg we;
reg clock;
wire [7:0] q;

single_port_ram dut (data, addr, we, clock, q);

initial clock = 1;
always #5 clock = ~clock; // Clock Toggle Every 5 Time Units

initial begin
$dumpfile("wave_single_port_ram.vcd"); // Added .vcd Extension
$dumpvars(0, single_port_ram_tb);
end

initial begin
$monitor(" time=%3t | data=%h | addr=%d | we=%b | clock=%b | q=%h ", $time, data, addr,
end

initial begin
// Write Cycle
we = 1;
data = 8'h01; addr = 6'd0; #10;
data = 8'h02; addr = 6'd1; #10;
data = 8'h03; addr = 6'd2; #10;

// Read Cycle
we = 0;
#5; addr = 6'd0; #10; // Small Delay Added
#5; addr = 6'd1; #10;
#5; addr = 6'd2; #10;

$finish;
end

endmodule

Fixes & Enhancements in the Testbench

1. `$dumpfile` Filename Fix:


Changed `"wave_single_port_ram"` → `"wave_single_port_ram.vcd"`.
2. Fixed Read Operation:
The original design stored the address in `addr_reg`, which was unnecessary.
Now, `q` is directly updated from `ram[addr]` during the clocked read.
3. Added Small Delays Before Reads:
To properly observe values stored in RAM.

Expected Waveform Output

When you run the simulation, the RAM should behave as follows:

Time (ns) `we` `addr` `data` (Written) `q` (Read Data)

0 1 0 0x01 -
10 1 1 0x02 -
20 1 2 0x03 -
30 0 0 - 0x01

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 2/8
Time (ns) `we` `addr` `data` (Written) `q` (Read Data)

40 0 1 - 0x02
50 0 2 - 0x03

This corrected version ensures: ✅


Correct Read/Write Operations
✅ Proper Clock Synchronization
✅ Correct Testbench Execution
Try running this updated code, and let me know if you have any further issues! 🚀
Here is the Verilog RTL code for a Synchronous Dual-Port RAM that satisfies all the given
specifications.

Key Features Implemented

✅ Dual-Port Design: Two ports ( and ) for independent read/write operations.


✅ Single Clock Synchronization: All operations happen on the same clock edge.
`port_0` `port_1`

✅ Same Port for Read/Write: Each port ( and


`data_0` ) is bidirectional for both read and
`data_1`
write.
✅ Simultaneous Read & Write to Different Ports: Reads and writes can happen simultaneously
to different ports, but not to the same port at the same time.
✅ Same Address Read/Write: The same address can be accessed by both ports simultaneously.
✅ Reset Handling:
If `we_x = 1` during reset → RAM is cleared to `0`.
If `we_x = 0` & `oe_x = 1` during reset → Outputs are `0`.

Verilog Code: Dual-Port RAM

verilog

module dual_port_ram (
input clk, reset,

// PORT 0
input [5:0] address_0,
inout [7:0] data_0,
input cs_0, we_0, oe_0,

// PORT 1
input [5:0] address_1,
inout [7:0] data_1,
input cs_1, we_1, oe_1
);

reg [7:0] ram [63:0]; // 64x8-bit Memory


reg [7:0] data_out_0, data_out_1;

assign data_0 = (cs_0 && oe_0 && !we_0) ? data_out_0 : 8'bz; // Output only when OE is enab
assign data_1 = (cs_1 && oe_1 && !we_1) ? data_out_1 : 8'bz;

always @(posedge clk) begin


if (reset) begin
integer i;

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 3/8
if (we_0 || we_1) begin
for (i = 0; i < 64; i = i + 1)
ram[i] <= 8'b0; // Clear memory on reset if write enabled
end
end
else begin
// PORT 0 Operation
if (cs_0) begin
if (we_0)
ram[address_0] <= data_0; // Write Operation
else if (oe_0)
data_out_0 <= ram[address_0]; // Read Operation
end

// PORT 1 Operation
if (cs_1) begin
if (we_1)
ram[address_1] <= data_1; // Write Operation
else if (oe_1)
data_out_1 <= ram[address_1]; // Read Operation
end
end
end

endmodule

Testbench: dual_port_ram_tb

verilog

module dual_port_ram_tb;

reg clk, reset;


reg [5:0] address_0, address_1;
wire [7:0] data_0, data_1;
reg cs_0, we_0, oe_0;
reg cs_1, we_1, oe_1;
reg [7:0] temp_data_0, temp_data_1;

assign data_0 = (!we_0) ? 8'bz : temp_data_0;


assign data_1 = (!we_1) ? 8'bz : temp_data_1;

dual_port_ram dut (
.clk(clk),
.reset(reset),
.address_0(address_0),
.data_0(data_0),
.cs_0(cs_0),
.we_0(we_0),
.oe_0(oe_0),
.address_1(address_1),
.data_1(data_1),
.cs_1(cs_1),
.we_1(we_1),
.oe_1(oe_1)
);

initial clk = 0;
always #5 clk = ~clk;

initial begin
$dumpfile("dual_port_ram.vcd");
$dumpvars(0, dual_port_ram_tb);

reset = 1;
cs_0 = 0; we_0 = 0; oe_0 = 0;
cs_1 = 0; we_1 = 0; oe_1 = 0;

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 4/8
#10 reset = 0; // De-assert reset

// Writing to port 0 and 1 at different addresses


cs_0 = 1; we_0 = 1; address_0 = 6'd5; temp_data_0 = 8'hAA;
cs_1 = 1; we_1 = 1; address_1 = 6'd10; temp_data_1 = 8'h55;
#10 we_0 = 0; we_1 = 0;

// Reading from port 0 and 1


oe_0 = 1; address_0 = 6'd5;
oe_1 = 1; address_1 = 6'd10;
#10;

// Simultaneous read/write test


we_0 = 1; temp_data_0 = 8'hCC; address_0 = 6'd5; // Writing to address 5
we_1 = 1; temp_data_1 = 8'h33; address_1 = 6'd10; // Writing to address 10
#10 we_0 = 0; we_1 = 0;

// Read updated values


oe_0 = 1; address_0 = 6'd5;
oe_1 = 1; address_1 = 6'd10;
#10;

$finish;
end

endmodule

Expected Simulation Results

Time (ns) Port Address WE OE Data (Written) Data (Read)


10 0 5 1 0 0xAA -
10 1 10 1 0 0x55 -
20 0 5 0 1 - 0xAA
20 1 10 0 1 - 0x55
30 0 5 1 0 0xCC -
30 1 10 1 0 0x33 -

40 0 5 0 1 - 0xCC
40 1 10 0 1 - 0x33

Key Enhancements

✔ Bi-directional Data Bus ( )


✔ Uses
`inout`
for proper tri-state behavior
✔ Simultaneous read/write across different ports
`assign`

✔ Prevents same port read/write at the same time


✔ Resets RAM if on reset
`we_x = 1`

This RTL Design is ready for synthesis and FPGA implementation. 🚀 Let me know if you need
any modifications!

Here is the Verilog RTL design for a Synchronous Dual-Port RAM with Separate Read/Write
Ports that meets your specifications.

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 5/8
Key Features Implemented

✅ Dual-Port Design: Separate read ( ) and write (


`port_rd` ) ports for independent
`port_wr`
operations.
✅ Single Clock Synchronization: All read/write operations occur on the same clock edge.
✅ Different Ports for Read/Write:
`address_wr` & `data_wr` → Write operations.
`address_rd` & `data_rd` → Read operations.
✅ Simultaneous Read/Write at the Same Address: Possible without conflicts.
✅ Reset Handling:
If `we = 1` during reset → RAM is cleared to 0.
If `re = 1` during reset → `data_rd` output is set to `0`.

Verilog Code: Dual-Port RAM (Separate Read/Write Ports)

verilog

module dual_port_ram (
input clk, reset,
input [5:0] address_rd, address_wr,
input [7:0] data_wr,
output reg [7:0] data_rd,
input cs, we, re
);

reg [7:0] ram [63:0]; // 64x8-bit Memory

always @(posedge clk) begin


if (reset) begin
integer i;
if (we) begin
for (i = 0; i < 64; i = i + 1)
ram[i] <= 8'b0; // Reset memory to 0
end
if (re) begin
data_rd <= 8'b0; // Reset output to 0
end
end
else begin
if (cs) begin
// Write Operation
if (we)
ram[address_wr] <= data_wr;

// Read Operation
if (re)
data_rd <= ram[address_rd];
end
end
end

endmodule

Testbench: dual_port_ram_tb

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 6/8
verilog

module dual_port_ram_tb;

reg clk, reset;


reg [5:0] address_rd, address_wr;
reg [7:0] data_wr;
wire [7:0] data_rd;
reg cs, we, re;

dual_port_ram dut (
.clk(clk),
.reset(reset),
.address_rd(address_rd),
.address_wr(address_wr),
.data_wr(data_wr),
.data_rd(data_rd),
.cs(cs),
.we(we),
.re(re)
);

initial clk = 0;
always #5 clk = ~clk; // Clock Toggle Every 5 Time Units

initial begin
$dumpfile("dual_port_ram.vcd");
$dumpvars(0, dual_port_ram_tb);

reset = 1; cs = 0; we = 0; re = 0;
#10 reset = 0; // De-assert reset

// Write Data at address 5


cs = 1; we = 1; address_wr = 6'd5; data_wr = 8'hAA;
#10 we = 0;

// Read Data from address 5


re = 1; address_rd = 6'd5;
#10;

// Write and Read Simultaneously


we = 1; address_wr = 6'd10; data_wr = 8'h55;
re = 1; address_rd = 6'd5;
#10 we = 0; re = 0;

// Read New Data


re = 1; address_rd = 6'd10;
#10;

$finish;
end

endmodule

Expected Simulation Results

Time (ns) `we` `re` `address_wr` `data_wr` `address_rd` `data_rd`

10 1 0 5 0xAA - -
20 0 1 - - 5 0xAA

30 1 1 10 0x55 5 0xAA
40 0 1 - - 10 0x55

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 7/8
Key Enhancements

✔ Separate Read & Write Ports ( , )


✔ Simultaneous Read/Write to the Same Address
`address_wr` `address_rd`

✔ Resets RAM when on reset


✔ Clears Output Data when
`we = 1`
`re = 1`on reset
This RTL Design is ready for FPGA/ASIC synthesis 🚀. Let me know if you need modifications! 🚀

Printed using ChatGPT to PDF, powered by PDFCrowd HTML to PDF API. 8/8

You might also like