XC 3.4 Transactions

Archived XCore tutorials.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Not sure what your question is Mika

Code: Select all

transaction in_char_array ( chanend c, char src[], unsigned size) 
transaction out_char_array ( chanend c, const char src[], unsigned size) 
If these are in the XC libs (you haven't given me a reference or link?) Then I would imagine they are simply convenience functions for transactional array transfers and would be used in the following sort of way:

Code: Select all

void tx(chanend c){
  char msg[] = "Message1";
  master in_char_array(c,msg,9);
}

void rx(chanend c){
  char msg[9];
  select {
    case slave { in_char_array ( c, msg, 9) } :
    process(msg,9);
    break;
  }
}

main(void){
  par {
   tx(c);
  rx(c);
  }
}
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

Not sure what your question is Mika
Like: You can use

unsigned inuint ( chanend c ) / void outuint ( chanend c, unsigned val )

that I believe is the same as using the :> and <: !?
even thought, quote:
"The protocol used is incompatible with the protocol used by the input (:>) and ouput (<:) operators. "

In this case I guess it means that both ways generates the same asm code, but the compiler cannot understand a mix of inuint to a :> operator.

My problem is all the guess - it might be the case, but I'm never sure of it.
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
lilltroll
XCore Expert
Posts: 956
Joined: Fri Dec 11, 2009 3:53 am
Location: Sweden, Eskilstuna

Post by lilltroll »

I found an example in the SDRAM module implementet with inline asm instead:
Good as an general understanding of the reduction of overhead.
I post it here so other can have benefit of it:
(For the newbies reading this, things like this is often not neccesary on a L1 chip, since all avilable channels can be static streaming channels, but on a chip with several cores, the Switch has a limited amount of links, and you cannot just keep it simple by using streaming channels everywhere for interchip communication)
As usual correct me if I'm misstaken

Code: Select all

* Module:  app_sdram_burst_example
 * Version: 1v1
 * Build:   eb5cce73e7f7b93b19b9fbd609ded15dc3c5cb05
 * File:    client.c
 *
 * The copyrights, all other intellectual and industrial 
 * property rights are retained by XMOS and/or its licensors. 
 * Terms and conditions covering the use of this code can
 * be found in the Xmos End User License Agreement.
 *
 * Copyright XMOS Ltd 2010
 *
 * In the case where this code is a modification of existing code
 * under a separate license, the separate license terms are shown
 * below. The modifications to the code are still covered by the 
 * copyright notice above.
 *
 **/                                   
#include <xs1.h>
#include <xccompat.h>

// In order to use negative indexing and get a 4 instruction loop, we need pointer arithmetics
// Hence C (rather than XC)
#define OUT(c, x) asm("out res[%0], %1" : : "r"(c), "r"(x))
#define IN(c, x) asm("in %0, res[%1]" : "=r"(x) : "r"(c))
#define OUTCT_END(c) asm("outct res[%0], %1" : : "r"(c), "i"(XS1_CT_END))
#define CHKCT_END(c) asm("chkct res[%0], %1" : : "r"(c), "i"(XS1_CT_END))

// LLVM canonical loop transformations (XMOS bug 6253) produce 5 instructions
// Assembly required to get 4
#ifdef __llvm__
#define BRBT(x, off) asm("bt %0, %1" : : "r"(x), "i"(off))
#define INC(x) asm("add %0, %1, 1" : "=r"(x) : "r"(x))
#define LOAD(word, base, off) asm("ldw %0, %1[%2]" : "=r"(word) : "r"(base), "r"(off))
#define STORE(word, base, off) asm("stw %0, %1[%2]" : : "r"(word), "r"(base), "r"(off))
#endif

void sdram_write(chanend c, int bank, int row, int col, const unsigned words[], int nwords)
{
	const unsigned *ptr;
	int index;
	unsigned word;
   
	// Output write command
	OUTCT_END(c);
	CHKCT_END(c);
	OUT(c, 3);
	OUTCT_END(c);
	CHKCT_END(c);

	// Init slave output
	CHKCT_END(c);

	// Out bank row col nwords
	OUT(c, bank);
	OUT(c, row);
	OUT(c, col);
	OUT(c, nwords);

	ptr = words + nwords;
	index = -nwords - 1; 

  // See comment above
	while (index != 0)
	{
#ifndef __llvm__
		index++;
		word = ptr[index];
#else
    INC(index);
    LOAD(word, ptr, index);
#endif
		OUT(c, word);
	}

	// End slave
	OUTCT_END(c);
	CHKCT_END(c);
}

void sdram_read(chanend c, int bank, int row, int col, unsigned words[], int nwords)
{
	unsigned *ptr;
	int index;
	unsigned word;

	// Output read command
	OUTCT_END(c);
	CHKCT_END(c);
	OUT(c, 4);
	OUTCT_END(c);
	CHKCT_END(c);

	// Init slave input
	CHKCT_END(c);

	// Out bank row col nwords
	OUT(c, bank);
	OUT(c, row);
	OUT(c, col);
	OUT(c, nwords);

	// Output a END token for ABI
	OUTCT_END(c);

#ifdef SERVER_NOT_UNROLLED
	// Dummy input
	IN(c, word);
#endif

	ptr = words + nwords;
	index = -nwords;

  // See comment above
	while (index != 0)
	{
		IN(c, word);
#ifndef __llvm__
		ptr[index] = word;
		index++;
#else
    STORE(word, ptr, index);
    INC(index);
#endif
	}

	// End slave
	OUTCT_END(c);
	CHKCT_END(c);
}
:shock: "(XMOS bug 6253)" which are the 6252 other bugs ?? :lol:
Probably not the most confused programmer anymore on the XCORE forum.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

Well I would like to know what the overall benefit adds up within the benchmarks, But frankly I think this kind of Voodoo pixie magic like code should be avoided unless there is a very good reason to use it. It will likely lead to difficult to manage, unreadable and unstructured code. Quite frankly this kind of ugliness should be fixed by the compiler rather than resorting to these desperate and somewhat unerving ASM hacks ;-)
:shock: "(XMOS bug 6253)" which are the 6252 other bugs ?? :lol:
Or which ones are fixed/unfixed? wishing there was a bug database online for looking up such things..