Saturday, January 18, 2020

Spartan-6 distributed RAM confusion

Okay, I'm utterly confused.

According to the documentation. dual-port distributed RAM has one read/write port and one read-only port. It is is created by allocating twice as many LUTs as needed for single-port RAM; the write port writes both LUTs, but each read port addresses only one of the two LUTs. Thus one might expect a dual-port RAM to use twice as many LUTs as a single-port RAM.

Previously I created a test that instantiated one of the four dual-port 20x4-bit "registers" in an emulated i4002 RAM chip. Since the docs say a Spartan-6 LUT can be used either as a 64x1-bit RAM or as a 32x2-bit RAM, I expected XST to allocate two LUTs per port for a total of four LUTs per register. The "technology schematic" generated by ISE showed four RAM32X1D library primitives, yet the synthesis summary showed six LUTs allocated as dual-port RAM.

I could see four with things packed as I described above, or I could see eight if the synthesis used the 64x1 rather than the 32x2 configuration. But six LUTs made no sense. Changing the array size from 20 to 32 had no effect. So I created another test with the full complement of four registers.

With all four registers allocated, ISE reported 16 LUTs used as RAM. I'd only connected the second port of one of the "registers", so four were used as dual-port RAM. That would make sense using the 32x2 configuration. But why 12 as single-port RAM? Using a 32x2 configuration each single-port RAM should only occupy two LUTs for a total of six, not twelve.

For my next test I replaced the Verilog that inferred a dual-port distributed RAM with four explicit instantiations of the dual-port 32x1-bit RAM32X1D library primitive per "register". This produced exactly the same results as the inferred RAM: 4 LUTs as dual-port RAM and 12 LUTs as single-port RAM. At least now I know I didn't screw up the inferring code!

Still not seeing an explanation I created yet another test, this one with two explicit instantiations of the single-port 32x2-bit RAM32X2S library primitive per "register". Surely this one would allocate only eight LUTs? Nope: 16 LUTs allocated as single-port RAM.

I even tried fiddling with the ISE "strategy" configuration to encourage LUT combining. I can see various other details change, but never has the total number of LUTs allocated to RAM changed.

I give up. The Spartan-6 LX9 has 1440 LUTs that can be used as RAM, and my two i4002 emulations will require 32 of them, or 2.2%. Unless I run into resource limitations I'm going take my 32 LUTs and be happy.

No comments:

Post a Comment