Back Midas Rome Roody Rootana
  Midas DAQ System  Not logged in ELOG logo
Entry  13 Feb 2020, Marius Koeppel, Forum, Writting Midas Events via FPGAs 
    Reply  13 Feb 2020, Stefan Ritt, Forum, Writting Midas Events via FPGAs 
       Reply  14 Feb 2020, Konrad Briggl, Forum, Writting Midas Events via FPGAs 
          Reply  14 Feb 2020, Stefan Ritt, Forum, Writting Midas Events via FPGAs 
             Reply  20 Feb 2020, Konstantin Olchanski, Forum, Writting Midas Events via FPGAs 
                Reply  20 Feb 2020, Marius Koeppel, Forum, Writting Midas Events via FPGAs 
                   Reply  20 Feb 2020, Stefan Ritt, Forum, Writting Midas Events via FPGAs 
                      Reply  21 Feb 2020, Konstantin Olchanski, Forum, Writting Midas Events via FPGAs 
                         Reply  21 Feb 2020, Stefan Ritt, Forum, Writting Midas Events via FPGAs 
                   Reply  21 Feb 2020, Konstantin Olchanski, Forum, Writting Midas Events via FPGAs 
Message ID: 1829     Entry time: 13 Feb 2020     Reply to this: 1830   1831
Author: Marius Koeppel 
Topic: Forum 
Subject: Writting Midas Events via FPGAs 
Dear all,

we creating Midas events directly inside a FPGA and send them off via DMA into the PC RAM. For reading out this RAM via Midas the FPGA sends as a pointer where it has written the last 4kB of data. We use this pointer for telling the ring buffer of midas where the new events are. The buffer looks something like:

// event 1
dma_buf[0] = 0x00000001; // Trigger and Event ID
dma_buf[1] = 0x00000001; // Serial number
dma_buf[2] = TIME; // time
dma_buf[3] = 18*4-4*4; // event size
dma_buf[4] = 18*4-6*4; // all bank size
dma_buf[5] = 0x11; // flags
// bank 0
dma_buf[6] = 0x46454230; // bank name
dma_buf[7] = 0x6; // bank type TID_DWORD
dma_buf[8] = 0x3*4; // data size
dma_buf[9] = 0xAFFEAFFE; // data
dma_buf[10] = 0xAFFEAFFE; // data
dma_buf[11] = 0xAFFEAFFE; // data
// bank 1
dma_buf[12] = 0x1; // bank name
dma_buf[12] = 0x46454231; // bank name
dma_buf[13] = 0x6; // bank type TID_DWORD
dma_buf[14] = 0x3*4; // data size
dma_buf[15] = 0xAFFEAFFE; // data
dma_buf[16] = 0xAFFEAFFE; // data
dma_buf[17] = 0xAFFEAFFE; // data

// event 2
.....

dma_buf[fpga_pointer] = 0xXXXXXXXX;


And we do something like:

while{true}
   // obtain buffer space
   status = rb_get_wp(rbh, (void **)&pdata, 10);
   fpga_pointer = fpga.read_last_data_add();

   wlen = last_fpga_pointer - fpga_pointer; \\ in 32 bit words
   copy_n(&dma_buf[last_fpga_pointer], wlen, pdata);
   rb_status = rb_increment_wp(rbh, wlen * 4); \\ in byte

   last_fpga_pointer = fpga_pointer;

Leaving the case out where the dma_buf wrap around this works fine for a small data rate. But if we increase the rate the fpga_pointer also increases really fast and wlen gets quite big. Actually it gets bigger then max_event_size which is checked in rb_increment_wp leading to an error. 

The problem now is that the event size is actually not to big but since we have multi events in the buffer which are read by midas in one step. So we think in this case the function rb_increment_wp is comparing actually the wrong thing. Also increasing the max_event_size does not help.

Remark: dma_buf is volatile so memcpy is not possible here.

Cheers,
Marius
ELOG V3.1.4-2e1708b5