I have the following problem - my embedded system has four fifos consisting of 64-byte chunks of data. These fifo's and the corresponding data chunks are represented in the diagram below. Once all 4 fifo's have been popped, I need to interleave the data chunks. I can do a simple loop but I am concerned this might be too processor intensive. Does anyone have a smarter way that is less processor intensive in which I can rapidly interleave the different chunks of memory?
Asked
Active
Viewed 84 times
0
-
1Is there a DMA which you can setup to do this for you? – Yunnosch May 20 '22 at 15:06
-
Yeah, I had this thought too @Yunnosch but I am not sure where to look in this case. I am using DesignWare IP from synopsis for the DMAC. It's not clear to me what I need to be looking at or for... – cirrusio May 20 '22 at 15:09
-
OK @Yunnosch - I think that what I am looking for is to enable the controller to scatter the data. – cirrusio May 20 '22 at 16:02
-
Unless you tell us what the controller is no one can help you with a hardware specific solution. Why do you think the simple solution will be processor intensive? Have you tried it and measured it? Have you tested what the compiler optimiser might do to improve it? – Clifford May 20 '22 at 22:15
-
Clifford - I was responding to the above comment concerning the DMA. In this case I referring to scatter-gather capabilities of a DMA controller. I don't know if this functionality is available on all controllers but it is not specific to the particular DMAC I am using (but I do very specifically call out the IP I am using). At present, we have plenty of computational room, but this processor will be driving a lot so tying it up with moving data around using a simple for loop will not be optimal if there is something that can be done in DMA... – cirrusio May 20 '22 at 23:06
2 Answers
1
Use an array of FIFO pointers:
#define FIFO_COUNT 4
fifo *fifos[FIFO_COUNT] = {&fifo0, &fifo1, &fifo2, &fifo3];
int cur_fifo = 0;
Then when you read from a FIFO read from the one referenced by cur_fifo
, then increment it with wraparound:
next_block = fifo_read(fifos[cur_fifo]);
cur_fifo = (cur_fifo + 1) % FIFO_COUNT;
0
#define FIFO1 (volatile uint64_t *)FIFO1_ADDRESS
#define FIFO2 (volatile uint64_t *)FIFO2_ADDRESS
#define FIFO3 (volatile uint64_t *)FIFO3_ADDRESS
#define FIFO4 (volatile uint64_t *)FIFO4_ADDRESS
static inline uint64_t *popfifos(uint64_t *data)
{
data[0] = *FIFO1;
data[1] = *FIFO2;
data[2] = *FIFO3;
data[3] = *FIFO4;
return data + 4;
}
void readFIFOS(uint64_t *buff, size_t nreads)
{
while(nreads--)
{
if(fifosReady()) buff = popfifos(buff);
}
}
fifosReady reads some hardware registers waiting for data to be ready.

0___________
- 60,014
- 4
- 34
- 74