pulp_soc icon indicating copy to clipboard operation
pulp_soc copied to clipboard

Hardcoded uDMA memory address width reduction

Open heavySea opened this issue 3 years ago • 0 comments

I encountered a problem with the reduction of the memory addresses in the uDMA subsystem. I noticed it on the SPI peripheral so I will describe it with this example.

Whenever a memory address is needed to be stored (e.g. the start address of a TX buffer) only the relevant bits should be stored not the whole 32 bit address to save some resources. The number of bits is given as L2_AWIDTH_NOAL in udma_subsystem.sv . Currently it is defined as L2_AWIDTH_NOAL = L2_ADDR_WIDTH + 2;. L2_ADDR_WIDTH is passed from in pulp_soc.sv through soc_peripherals.sv as L2_MEM_ADDR_WIDTH = $clog2(L2_BANK_SIZE * NB_L2_BANKS) (actually L2_MEM_ADDR_WIDTH = $clog2(L2_BANK_SIZE * NB_L2_BANKS) - $clog2(NB_L2_BANKS);, but $clog2(NB_L2_BANKS) is added back again when passed to soc_peripherals)

The problem lies in the hardcoded L2_AWIDTH_NOAL = L2_ADDR_WIDTH + 2; which is only valid for the preset memory configuration. It is wrong when using following memory configuration for example:

Two shared memory banks of 1024 lines/32b-words and two private memory banks of 1024 lines L2_MEM_ADDR_WIDTH becomes 11 bits. Therefore L2_AWIDTH_NOAL becomes 13 bits. But the highest possible Address 0x4000 requires 14 bits, thus the peripheral can not access half of the memory.

I suggest defining L2_AWIDTH_NOAL as
$clog2(L2_BANK_SIZE * NB_L2_BANKS * 4 + L2_BANK_SIZE_PRI * NB_L2_BANKS_PRI * 4), which calculates the required bits for the highest memory address.

This could be done directly in pulp_soc, since all this localparam L2_BANK_SIZE = 29184; // in 32-bit words localparam L2_MEM_ADDR_WIDTH = $clog2(L2_BANK_SIZE * NB_L2_BANKS) - $clog2(NB_L2_BANKS); localparam NB_L2_BANKS_PRI = 2;

is there only for the uDMA anyway..

heavySea avatar Dec 18 '20 13:12 heavySea