Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
17255 Discussions

Auto RAM Block Balancing Failure

Altera_Forum
Honored Contributor II
1,632 Views

Hi All, 

 

I have an interesting situation that I am unable to explain and is causing me some grief.  

 

The design targets the Stratix 3 family and instantiates many large memories using an inferred memory style of Verilog coding. Enough memories are instantiated that the design uses all of the M144K blocks and most of the M9K blocks. Until recently, Quartus built the project with no problem. It would choose to build the inferred memories from M144K blocks until they were all used up, then it would build the rest with M9K blocks, which is the behavior I both would expect and want. 

 

Now I have a need for all the memories to double in size. The device size will increase accordingly. The design is parameterized, so it would seem to be no problem. However, now Quartus wants to build all the memories from M144K blocks. A Fitter error naturally follows when it tries to fit more M144Ks than exist. 

 

It appears that I have crossed some memory size threshold where Synthesis no longer is willing to consider building the inferred memory from M9K blocks. By the way, the synthesis setting "Auto RAM Block Balancing" is turned on. Changing the setting for "Maximum Number of M-RAM/M144K Memory Blocks" to a value less than the number in the device does not help either, the fit failure still occurs but now references the new lower limit. 

 

I can work around the problem by making separate modules for the memories that use the "ramstyle" attribute to specify use of either M144K or M9K memory. If I then instantiate the right amount of each, the project builds and fits just fine. But this fix requires adjustment any time the target device is changed and also has other shortcomings. 

 

The memory in question is inferred using the code given below. It is a true dual port RAM with single clock and equal size ports. The inference is fairly plain and pretty much follows the Altera template. When it is instantiated with parameters of DATA_SIZE = 32, ADDR_SIZE = 15, Quartus seems to force it to be M144K no matter what. If ADDR_SIZE is reduced to 14, then Quartus uses the memory resources intelligently.  

 

Does anybody have any insight into this issue? Am I missing some setting that will make Quartus behave with the larger memories?  

 

Thanks in advance. 

 

 

////////////////////////////////////////////////////////////////////////////////// // True Dual Port RAM with single clock, same size ports. (both ports are R/W) // Follows Quartus II template for inferring RAM. // Single port read-during-write gives new data. // Mixed port read-during-write gives old data. // Simultaneous writes on both ports are not allowed. // That behavior is supported by M9K and M144K memory blocks in Stratix III. ////////////////////////////////////////////////////////////////////////////////// module true_dual_port_ram_single_clock# ( parameter DATA_SIZE=8, parameter ADDR_SIZE=6 ) ( input clk, input we_a, input we_b, input data_a, input data_b, input addr_a, input addr_b, output reg q_a, output reg q_b ); // Declare the RAM variable reg ram ; // Port A always @ (posedge clk) begin if (we_a) begin ram <= data_a; q_a <= data_a; end else begin q_a <= ram; end end // Port B always @ (posedge clk) begin if (we_b) begin ram <= data_b; q_b <= data_b; end else begin q_b <= ram; end end endmodule
0 Kudos
1 Reply
Altera_Forum
Honored Contributor II
878 Views

A follow-up: 

 

I still have no optimal solution, so if anybody has info, I would still be happy to hear it. 

 

However, I do have a more tolerable workaround. If a memory with ADDR_SIZE>14 is specified, the module instantiates an array of memories with ADDR_SIZE=14 and adds extra address decoding and output selecting logic. In this case, Quartus balances the block types properly even though the total number of bits instantiated is the same as before.
0 Kudos
Reply