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

Error (276003): Cannot convert all sets of registers into RAM megafunctions when creating nodes.

SparkyNZ
New Contributor III
572 Views

 

 

Error (276003): Cannot convert all sets of registers into RAM megafunctions when creating nodes. The resulting number of registers remaining in design exceeds the number of registers in the device or the number specified by the assignment max_number_of_registers_from_uninferred_rams. This can cause longer compilation time or result in insufficient memory to complete Analysis and Synthesis

 

 

I started doing some overhaul on the logic in my project today and I got this error. I've made too many changes to incrementally back-step to see what caused this.

How can I identify what the offending code, logic or register usage actually is?

SparkyNZ_0-1739590620599.png

 

I can't see what my total register usage is yet. I'm using my trusty Cyclone IV EP4CE6 FPGA. I know I have been close to exhausting resources on this device for a while. I have the below array which has usually been a problem, but even when I reduce the size right down it isn't making any difference so it must be something else.

 

bit[2:0]  frameBuffer[49920];

 

I have been trying to work through resolving all of my truncation warnings etc today but still no joy.

I did however see this in the log:

 

Info (276014): Found 1 instances of uninferred RAM logic
	Info (276007): RAM logic "frameBuffer" is uninferred due to asynchronous read logic

What does this mean? I am only reading frameBuffer in one place as far as I can tell:

bit[16:0] frameBufferReadIndex;
bit [3:0] frameBufferByte;

bit       vgaReading;
assign frameBufferByte = vgaReading ? frameBuffer[ frameBufferReadIndex ] : 4'h0;

Ignore the 'byte' reference - I have been making the 'byte' smaller and smaller since I began running out of resources.

 

Labels (1)
0 Kudos
1 Solution
FvM
Honored Contributor II
522 Views

Internal FPGA block RAM is synchronous, using a clock. If your code doesn't register at least frameBufferReadIndex, it can't infer RAM. Best to follow RAM code template in Quartus.

 

For maximum memory size, you also need to look at RAM block organization. RAM capacity of EP4CE6 is 30k x 9bit, thus you can't implement more than 30k 4-bit array elements.

View solution in original post

5 Replies
FvM
Honored Contributor II
523 Views

Internal FPGA block RAM is synchronous, using a clock. If your code doesn't register at least frameBufferReadIndex, it can't infer RAM. Best to follow RAM code template in Quartus.

 

For maximum memory size, you also need to look at RAM block organization. RAM capacity of EP4CE6 is 30k x 9bit, thus you can't implement more than 30k 4-bit array elements.

SparkyNZ
New Contributor III
486 Views

I don't understand this at all. Using the same frameBuffer definition, I made my top level module fill the frame buffer with values as a test. The entire screen was filled with colour as I expected. In fact, I used to have frameBuffer defined like this:

 

 

bit[3:0]  frameBuffer[33792];

 

 

This worked perfectly fine. I had an entirely working screen - and that was 4bits.

I have a 3-bit frameBuffer now (as shown in the original post) and even reducing this to 16k results in the same problem:

 

 

bit[2:0]  frameBuffer[16384];

 

 

If your code doesn't register at least frameBufferReadIndex, it can't infer RAM. Best to follow RAM code template in Quartus.

I don't understand what you are saying, sorry. What do you mean by "code doesn't register"? Is there something wrong with the below definition?

 

 

bit[16:0] frameBufferReadIndex;

 

 

Why did it work before I changed my logic around? I really don't understand why a design can work fine for ages and then it won't compile when some things are reorganised. I have had a frame buffer like this in other projects too. Maybe I have had that "Info (276007): RAM logic "frameBuffer" is uninferred due to asynchronous read logic" warning all along but it has still worked?

 

Update: I just checked the compiler output for the previous version that works. It has this to say about frameBuffer instead:

 

 

Warning (276027): Inferred dual-clock RAM node "frameBuffer_rtl_0" from synchronous design logic.  The read-during-write behavior of a dual-clock RAM is undefined and may not match the behavior of the original design.

 

 

 

Just a bit of additional info - I have frameBuffer being read by a 25MHz VGA clock. At various times, it will be written to using a 28MHz clock. I was worried about this from the start and I originally tried using the same 28MHz clock for VGA but that wouldn't work. So is there now an issue with async read and write because the logic has changed - and therefore the timing? I'm not sure how to get around this. Was I just lucky when it worked and generated the above warning? Why is it not inferring a dual-clock RAM node this time around?

Can I force usage of a dual-clock RAM node somehow?

Is it simply a matter of making a module as described here: https://www.intel.com/content/www/us/en/docs/programmable/683082/22-1/simple-dual-port-dual-clock-synchronous-ram.html ?

0 Kudos
SparkyNZ
New Contributor III
474 Views

Well.. I implemented my frameBuffer as a separate module as suggested here: https://www.intel.com/content/www/us/en/docs/programmable/683082/22-1/simple-dual-port-dual-clock-synchronous-ram.html

 

..and that is compiling and "working" once again. Now I have this warning, so I assume all is OK and back to normal?

 

Warning (276027): Inferred dual-clock RAM node "FrameBuffer:frameBuffer|ram_rtl_0" from synchronous design logic.  The read-during-write behavior of a dual-clock RAM is undefined and may not match the behavior of the original design.

 

0 Kudos
FvM
Honored Contributor II
464 Views
Hi,
good that it works. It's impossible to understand the problem without seeing the full code.
Regarding above warning, it depends on read/write sequence if it's an actual problem. Quartus can't see it. It just tells the fact that dual clock RAM can involve inconsistent read during write behaviour. If the same address is written and read simultaneously, the read data word may be a mixture of old and new data bits.
0 Kudos
SparkyNZ
New Contributor III
455 Views

I am always happy to share full code but there's always the danger of losing IP when publicly shared. Thank you. I'll accept your answer as the solution since it has pointed me in the right direction and made me learn a bit more.

0 Kudos
Reply