Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
Intel Support hours are Monday-Fridays, 8am-5pm PST, except Holidays. Thanks to our community members who provide support during our down time or before we get to your questions. We appreciate you!

Need Forum Guidance? Click here
Search our FPGA Knowledge Articles here.
15468 Discussions

How to implement a module for accessing single block of on-chip memory in systemverilog?


Let say I want to model a 8 x 1024 bits Ram.

I can generate a Single Port Ram Module from IP Catalog.

I can access the on-chip memory via a single instance of this "Single Port Ram" module.

However, I have multiple modules which may access this single block of on-chip memory.

By creating multiple instances of "Single Port Ram", it actually instantiate duplicated blocks of on-chip memory per "Single Port Ram" module.


So, I am look for a real example in systemverilog on how to model a module for accessing a single block of on-chip memory by multiple instances of modules.


Please kindly help.

0 Kudos
2 Replies
New Contributor II

You need an arbiter. With multiple masters for a single ram, you need some logic to decide who gets to access the ram in any given cycle.


for example:

always @(posedge clk) begin if (we(0) ) begin mem_we <= we[0]; mem_din <= din[0]; end else begin mem_we <= we[1]; mem_din <= din[1]; end end

Here, channel 0 has priority over channel 1. With several masters, arbitration schemes can get more complicated - modes like round-robin or lowest port priority are pretty common.


Sorry about that if I didn't clearly state the issue here. The real problem is : I cannot instantiate two modules for accessing single block of memory.


Let say I have a single port ram module:

module single_port_ram ( input [15:0] data, input [7:0] addr, input we, clk, output [15:0] q );   // Declare the RAM variable reg [15:0] ram[63:0]; // Variable to hold the registered read address reg [7:0] addr_reg; always @ (posedge clk) begin // Write if (we) ram[addr] <= data; addr_reg <= addr; end // Continuous assignment implies read returns NEW data. // This is the natural behavior of the TriMatrix memory // blocks in Single Port mode. assign q = ram[addr_reg]; endmodule


I have a top module which connect to two single_port_ram modules for reading 16 bits data at addr1 and addr2 respectively.

logic[15:0] data1, data2; logic[7:0] addr1, addr2; logic[15:0] out1, out2;   single_port_ram ram1 ( data(data1), addr(addr1), we(0), clk(clk), q(out1) );   single_port_ram ram2 ( data(data2), addr(addr2), we(0), clk(clk), q(out2) );

You can see ram1 and ram2 are actually TWO separated ram blocks (which is not my intent) as I declare the single_port_ram module twice.


What I want to do is : to have a single module (probably with port interface?) for accessing SINGLE block of memory so that I can create multiple instances of this module in different top modules for accessing same block of memory.


A stackoverflow user had the same issue and someone suggest to create port interface.


Since I am new to systemverilog, I am looking for a real example which can illustrate how it works.