2025-03-25 12:55 AM - edited 2025-03-25 12:57 AM
Hi,
I am using STM32H563ZI to design a new product, there is a SDRAM(W9825G6KH-6) connected to the MCU with 16bit width bus. The SDCLK is 125MHz while the MCU running at 250MHz. The read and write to SDRAM address space are both OK. But the read write performance is extremely slow, roughly 11MB/s for read and 14MB/s for write. I had configured the MPU and I-Cache/D-cache,
The speed is unsatisfied and unbelievable because I had a board with STM32H750 and the same SDRAM (SDCLK running at 100MHz, 16bit bus width), both read and write speed are around 100MB/s with cache on.
Could anyone give me some hints?
2025-03-25 1:24 AM
Hello,
1- STM32H750 is running at the same frequency as STM32H5: 250MHz?
2- Did you set the same SDRAM timing for both?
3- The SDRAM address region is located at 0xC000 0000 to 0xDFFF FFFF:
Which is a Non-cacheable region by default:
You said you configured the MPU, but did you set the SDRAM region as cacheable?
2025-03-25 4:49 AM
1- STM32H750 is running at the same frequency as STM32H5: 250MHz?
no, STM32H750 is running at 400Mhz, the STM32H5 running at 250MHz. Also I had changed the clock of STM32H5 to 200Mhz to make SDCLK at 100Mhz. The results are roughly the same. The SDRAM read write speed should not had so much differences.
2- Did you set the same SDRAM timing for both?
yes. Here is the timing data.
// SDRAM clk = 100MHz, 10ns
// Exit Self-Refresh Delay, TXSR = 72ns, 8clk
// Self-Refresh Time, TRAS = 42ns, 5clk
// Common Row Cycle Delay, TRC = 60ns, 6clk
// Common Row Precharge Delay, TRP = 15ns, 2clk
// Row to Column Delay, TRCD = 15ns, 2clk
// Write Recovery Time, TWR = 2
//
// 8192 rows, refresh rate = 64ms/8192 = 7.81us
// refresh counter = (7.81 * 100) - 20 = 761
3- The SDRAM address region is located at 0xC000 0000 to 0xDFFF FFFF:
I use SDRAM bank2 on STM32H5, I think the base address is 0xD000_0000.
-------------------------------------------------------------------------------------------------------------------
I tried to disable MPU, the SDRAM read/write speed looks boost to 21MB/s for read and 23MB/s for write. But it still not good enough.
while when MPU is enabled, the SDRAM read/write speed looks boost to 11MB/s for read and 11MB/s for write.
-------------------------------------------------------------------------------------------------------------------
Here is the MPU_Config(), I referred AN4838 Table 9 to set MPU regions for internal SRAM, internal Flash, and Peripherals. MPU region 4 and MPU attribute 3 are used for SDRAM (0xD000_0000 to 0xD1FFF_FFFF). The region is set to instruction disable, inner-sharable, normal-cachable, write-back, transit, and rw-allocate.
void MPU_Config(void)
{
MPU_Region_InitTypeDef MPU_InitStruct = {0};
MPU_Attributes_InitTypeDef MPU_AttributesInit = {0};
/* Disables the MPU */
HAL_MPU_Disable();
/** Initializes and configures the Region 0 and the memory to be protected
*/
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
MPU_InitStruct.BaseAddress = 0x20000000;
MPU_InitStruct.LimitAddress = 0x2009FFFF;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
MPU_InitStruct.AccessPermission = MPU_REGION_ALL_RW;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region 1 and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER1;
MPU_InitStruct.BaseAddress = 0x08000000;
MPU_InitStruct.LimitAddress = 0x081FFFFF;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER1;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region 2 and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER2;
MPU_InitStruct.BaseAddress = 0x40000000;
MPU_InitStruct.LimitAddress = 0x5FFFFFFF;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER2;
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region 3 and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER3;
MPU_InitStruct.BaseAddress = 0x80000000;
MPU_InitStruct.LimitAddress = 0x8FFFFFFF;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region 4 and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.BaseAddress = 0xD0000000;
MPU_InitStruct.LimitAddress = 0xD1FFFFFF;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER3;
MPU_InitStruct.IsShareable = MPU_ACCESS_INNER_SHAREABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Region 7 and the memory to be protected
*/
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER0;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
/** Initializes and configures the Attribute 0 and the memory to be protected
*/
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER0;
MPU_AttributesInit.Attributes = INNER_OUTER(MPU_NOT_CACHEABLE);
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);
/** Initializes and configures the Attribute 1 and the memory to be protected
*/
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER1;
MPU_AttributesInit.Attributes = INNER_OUTER(MPU_WRITE_THROUGH|MPU_TRANSIENT
|MPU_NO_ALLOCATE);
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);
/** Initializes and configures the Attribute 2 and the memory to be protected
*/
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER2;
MPU_AttributesInit.Attributes = MPU_DEVICE_nGnRE;
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);
/** Initializes and configures the Attribute 3 and the memory to be protected
*/
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER3;
MPU_AttributesInit.Attributes = INNER_OUTER(MPU_WRITE_BACK|MPU_TRANSIENT
|MPU_RW_ALLOCATE);
HAL_MPU_ConfigMemoryAttributes(&MPU_AttributesInit);
/* Enables the MPU */
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}
2025-03-25 5:40 AM - edited 2025-03-25 5:42 AM
1- For the performance comparison you need to set the system at the same config (compare like with like): same clock, same timings etc ..
2- As I can see, you didn't set the region 0xDxxx xxxx cacheable:
/** Initializes and configures the Region 4 and the memory to be protected
*/
MPU_InitStruct.Number = MPU_REGION_NUMBER4;
MPU_InitStruct.BaseAddress = 0xD0000000;
MPU_InitStruct.LimitAddress = 0xD1FFFFFF;
MPU_InitStruct.AttributesIndex = MPU_ATTRIBUTES_NUMBER3;
MPU_InitStruct.IsShareable = MPU_ACCESS_INNER_SHAREABLE;
HAL_MPU_ConfigRegion(&MPU_InitStruct);
You didn't set the parameter MPU_AttributesInit.Attributes for that region to be cacheable and you didn't set it before. So 0xDxxx xxxx still not cacheable.
2025-03-25 7:04 AM
Thank you for quick reply.
(1) I mentioned H750 doesn't mean I want to obtain the same performance. What I confused is why I cannot get considerable SDRAM performance, no one will thought 11-20MB/s read/write performance while d-cache enabled is reasonable, especially for H-class MCU .
(2) MPU_Config() was generated byCubeMx. MPU_AttributesInit.Attributes was set from line 93 to 96.
The MPU_REGION_NUMBER4 has the MPU_ATTRIBUTES_NUMBER3, The MPU_ATTRIBUTES_NUMBER3 is set to "normal cacheable, write back, transit, and rw allocate", as the code indicated.
MPU_AttributesInit.Number = MPU_ATTRIBUTES_NUMBER3;
MPU_AttributesInit.Attributes = INNER_OUTER(MPU_WRITE_BACK|MPU_TRANSIENT
|MPU_RW_ALLOCATE);
Do you mean MPU_ATTRIBUTES_NUMBER3 means no cacheable?
Or I should set MPU memory attributes beforce set MPU region? I think the order is irrelevant, just configure them before enable MPU is okay.
Could you please provide me with correct code to make SDRAM bank2 memory region cacheable?
2025-03-25 7:23 AM
I don't know how CubeMx generated that code but to me the region N3 was set after N4. So the attributes that was set to the region 3 was net set for the region 4.
So in your MPU region 4 config add manually the MPU attribute as for the region 3 and test.