Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
9 years ago

Data transfer from hardware Modules to Nios

Hello,

As I have described in a previous post http://www.alteraforum.com/forum/showthread.php?t=52808&p=217155&highlight=#post217155 I want to implement a DAQ system using NIOS and W5300. The communication problem between NIOS and W5300 has been solved and I am able now to transfer data through TCP/IP. Now I am dealing with a different problem that has to do with transfer data between hardware module (implemented in verilog) and NIOS.

To give you a short description my system consists of 36 hardware modules each of them transferring 64 bits of data every 462us. The goal is to grab this data and send them through Ethernet to a pc, so my required data rate is about 5 Mbits/s. Ethernet communication itself doesn't seem to be a problem cause can achieve much higher speeds. The problem is how fast the cpu grabs the data for the modules. In the beginning I thought using just PIOs wouldn't be a problem. So NIOS collects the data from the modules and then transfer them again to W5300 fifo, but using counters I found that my maximum data rate is only about 4Mbit/s. Is there any alternative way to go? I thought using DMA but it sounds bit complicated for me at the moment and I don't know if at the end would be enough.

Any suggestions??

15 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    In your project settings, change the optimization level from "None" to -O3. Your software might break, or it might be fine.

    Your code boils down to:

    
    void IINCHIP_WRITE(uint32 addr, uint16 data) {
    	(*((vuint16*) addr)) = data;
    }
    uint32 wiz_write_buf(SOCKET s, uint8* buf, uint32 len) {
    	uint32 idx = 0;
    	// M_08082008
    	IINCHIP_CRITICAL_SECTION_ENTER();
    	for (idx = 0; idx < len; idx += 2)
    		IINCHIP_WRITE(Sn_TX_FIFOR(s), *((uint16*) (buf + idx)));
    	// M_08082008
    	IINCHIP_CRITICAL_SECTION_EXIT();
    }
    

    The compiler can do some improvements by itself when you have enabled the optimizer, but as an example, changing to a macro and using the 'register' keyword probably will bring some improvement:

    
    #define IINCHIP_WRITE(addr, data)   ((*((vuint16*) addr)) = data)
    uint32 wiz_write_buf(SOCKET s, uint8* buf, uint32 len) {
    	register uint32 idx = 0;
            register uint32 fifo_addr = Sn_TX_FIFOR(s);
    	// M_08082008
    	IINCHIP_CRITICAL_SECTION_ENTER();
    	for (idx = 0; idx < len; idx += 2)
    		IINCHIP_WRITE(fifo_addr, *((uint16*) (buf + idx)));
    	// M_08082008
    	IINCHIP_CRITICAL_SECTION_EXIT();
    }
    

    The simple above edits eliminated 2 x 16 = 32 function call overheads from your loop. The math in the loop also isn't great, but deal with the function calls first.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've made code optimization but this didn't bring any improvement. The changes in the code above also didn't work in contrary bring more trouble cause by changing the code I stared to lose some packets (I've tested the changes separately....).

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    I've made code optimization but this didn't bring any improvement. The changes in the code above also didn't work in contrary bring more trouble cause by changing the code I stared to lose some packets (I've tested the changes separately....).

    --- Quote End ---

    "losing packets" could simply be a side effect of your code not waiting for the transmit to complete before issuing the next request.

    After you've sped things up as fast as you can, just add a simple wait loop to delay between packet transmits and see if that affects at all your lost packets.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    No its just that the code runs slower and it doesn't return fast enough to catch the next data. I've added a delay and the behavior is the same.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    No its just that the code runs slower and it doesn't return fast enough to catch the next data. I've added a delay and the behavior is the same.

    --- Quote End ---

    Sorry, I don't understand the problem: each of those code improvements should have resulted in faster execution time for wiz_write_buf().

    If they somehow made it operate slower, I guess make changes one at a time and figure out why it got slower?