Glad to hear it works. It's quite a nice solution I think.
Interrupts have been included in the XCore to allow us to support the migration of legacy code. XC uses events (rather than interrupts) exclusively and you will nearly always find that it is quicker to write an app written in XC. It will also be easier to support than the assembler you'll need to write to implement and integrate an interrupt.
Anyway, you get the message that if you're writing code with interrupts in assembler, you'll meet the same problems writing the code that you'd have on other processors (the problems Xmos avoids by using event driven, XC coding etc.). To answer your question directly now, the interrupts are described in the XS1 architecture manual (http://www.xmos.com/system/files/xs1_en.pdf) in the 'Events, Interrupts and Exceptions' chapter.
Edge triggering?
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
-
- XCore Addict
- Posts: 234
- Joined: Thu Dec 10, 2009 11:11 pm
- Location: Newcastle, UK
John, please post it. I'm sure there will be many others interested in seeing it.JohnR wrote:...
I still need clean up the code - I need to handle the case when there is no second pulse - as well as to tidy up the LCD display code. Then maybe I will post it in the projects section.
-
- Experienced Member
- Posts: 93
- Joined: Fri Dec 11, 2009 1:39 pm
Woody,
Thanks for your last message re using interrupts. I had thought that the latency responding to an input pulse might have been less with interrupts as compared to events. In any case, now I have two parallel threads for start and stop both with the same latency, this really does not matter any more.
I added another thread to handle the display code thus
Re usage of assembly - I have been coding in XC to start with and then looking at the generated assembler output. I have found that the assembler (even in 03 ?) mode seems to favour using a minimal number of registers that sometines require a lot of reloading from memory, fixed by adding some more registers at the start of the function. In some other cases the assembler seems not to look ahead, as in this code fragment,
As far as I can see the second and third ldw's are unnecessary?
TonyD,
Thanks for your encouragement. I still have to get the case of no stop pulse working.
Right now I am using the code below but it still needs debugging.
As soon as it is all working, I will post the code trivial though it is.
John
Thanks for your last message re using interrupts. I had thought that the latency responding to an input pulse might have been less with interrupts as compared to events. In any case, now I have two parallel threads for start and stop both with the same latency, this really does not matter any more.
I added another thread to handle the display code thus
Code: Select all
par {
start_channel(start, c_start);
stop_channel(c_stop, stop);
process(c_start, c_stop, c_data, test);
display(c_data);
}
Code: Select all
..L10:
mkmsk r2, 0x1
ldw r1, dp[start]
setd res[r1], r2
ldw r1, dp[start]
setc res[r1], 0x11
ldw r1, dp[start]
.L13:
in r1, res[r1]
ldw r1, dp[start]
getts r3, res[r1]
.L13:
As far as I can see the second and third ldw's are unnecessary?
TonyD,
Thanks for your encouragement. I still have to get the case of no stop pulse working.
Right now I am using the code below but it still needs debugging.
Code: Select all
case stop when pinseq(1) :> void @ tStop:
c_stop <: tStop;
break;
case t when timerafter(time) :> void :
c_stop <: time;
break;
}
t :> time;
time += 5000;
John
-
- Experienced Member
- Posts: 93
- Joined: Fri Dec 11, 2009 1:39 pm
Hi Woody,
Maybe you could help me again with a question on timed input ports. I have now implemented my delay measurement system using two threads to respond to the start and stop pulses.
I accumulate the delay value (c_stop - c_start) over a million pulses. If I plot the response for pulse delays between from about 15nsecs (the minimum delay I can generate) to about 140 nsecs, the delay value is given by
value = 200000 * delay + 24800000 where delay is in nsecs.
I am totally puzzled by the big offset value. I had expected that with the two inputs now on separate threads with identical code that there would be no offset as the time stamps would be, I thought, synchronous being generated from the same clock source. The reference frequency, as set up in the xml file, is 200Mhz. The input data rate is 1Mhz.
The offset really is no problem as I can simply subtract it in subsequent data processing but I am curious as to why it is occurring. Any help would again be appreciated.
John
Maybe you could help me again with a question on timed input ports. I have now implemented my delay measurement system using two threads to respond to the start and stop pulses.
Code: Select all
void start_channel(in port start, streaming chanend c_start)
{
int tStart;
while (1) {
if(peek(start)==0 ){
start when pinseq(1) :> void @ tStart;
c_start <: tStart;
}
}
}
void stop_channel(in port stop, streaming chanend c_stop)
{
int tStop;
while (1) {
if(peek(stop)==0) {
stop when pinseq(1) :> void @ tStop;
c_stop <: tStop;
}
}
}
I accumulate the delay value (c_stop - c_start) over a million pulses. If I plot the response for pulse delays between from about 15nsecs (the minimum delay I can generate) to about 140 nsecs, the delay value is given by
value = 200000 * delay + 24800000 where delay is in nsecs.
I am totally puzzled by the big offset value. I had expected that with the two inputs now on separate threads with identical code that there would be no offset as the time stamps would be, I thought, synchronous being generated from the same clock source. The reference frequency, as set up in the xml file, is 200Mhz. The input data rate is 1Mhz.
The offset really is no problem as I can simply subtract it in subsequent data processing but I am curious as to why it is occurring. Any help would again be appreciated.
John
-
- Experienced Member
- Posts: 93
- Joined: Fri Dec 11, 2009 1:39 pm
Hi,
I have added my current version of the timer code, warts and all, to the XCore project section.
Woody wrote earlier
I naiively thought originally that the timestamp associated with the 'in' instruction was somehow generated within the instruction itself, in fact the assembler code shows it as a separate and subsequent instruction.
John.
I have added my current version of the timer code, warts and all, to the XCore project section.
Woody wrote earlier
I think this is strictly true only when two separate cores are used. In the case of two threads on a single core, the input processing seems first to handle the start pulse, then process the second pulse. This minimum "processing" time seems to be of the order of 100 nsecs. It is really not a problem in practice since this time is constant and can be subtracted from the measured delays.Hi,
Quote:
The timestamping is performed by the hardware associated with the port circuitry. You need to have two threads to make sure that both ports are setup to look for the condition and store the timestamp. When the threads are setup like this the time it takes to read the timestamps is irrelevant.
I naiively thought originally that the timestamp associated with the 'in' instruction was somehow generated within the instruction itself, in fact the assembler code shows it as a separate and subsequent instruction.
John.
-
- Experienced Member
- Posts: 93
- Joined: Fri Dec 11, 2009 1:39 pm
Hi,
The table below shows the data from a set of delay measurements. The data in the output column is divided by a factor of 1000 from raw data accumulated over 1 sec measurement intervals at a 1 Mhz sampling rate.
Delay(ns) Output
16 15551
28 17557
32 18557
40 20054
50 22557
64 25060
78 27560
92 30070
104 32558
112 35052
128 37560
142 40043
John
The table below shows the data from a set of delay measurements. The data in the output column is divided by a factor of 1000 from raw data accumulated over 1 sec measurement intervals at a 1 Mhz sampling rate.
Delay(ns) Output
16 15551
28 17557
32 18557
40 20054
50 22557
64 25060
78 27560
92 30070
104 32558
112 35052
128 37560
142 40043
John
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
I can't work out what is represented by the equation. What do you mean by 'value' and what do you mean by 'delay'? Hopefully we'll be able to get to the bottom of this.JohnR wrote:I accumulate the delay value (c_stop - c_start) over a million pulses. If I plot the response for pulse delays between from about 15nsecs (the minimum delay I can generate) to about 140 nsecs, the delay value is given by
value = 200000 * delay + 24800000 where delay is in nsecs.
I am totally puzzled by the big offset value. I had expected that with the two inputs now on separate threads with identical code that there would be no offset as the time stamps would be, I thought, synchronous being generated from the same clock source. The reference frequency, as set up in the xml file, is 200Mhz. The input data rate is 1Mhz.
-
- Experienced Member
- Posts: 93
- Joined: Fri Dec 11, 2009 1:39 pm
Hi,
The 'value' is the output of the measurement system as shown on the HD44780 display. This is the accumulation of the differences in timestamps for 1 million start/stop pairs.
Hope this helps,
John.
I apologise for not being clearer. The 'delay' is the value of the delay between the start and stop pulses as measured by my logic analyser, with a resolution, I believe, of 2 nsecs or so.I can't work out what is represented by the equation. What do you mean by 'value' and what do you mean by 'delay'? Hopefully we'll be able to get to the bottom of this.
The 'value' is the output of the measurement system as shown on the HD44780 display. This is the accumulation of the differences in timestamps for 1 million start/stop pairs.
Hope this helps,
John.
-
- XCore Addict
- Posts: 165
- Joined: Wed Feb 10, 2010 2:32 pm
Hi John,JohnR wrote:I think this is strictly true only when two separate cores are used. In the case of two threads on a single core, the input processing seems first to handle the start pulse, then process the second pulse. This minimum "processing" time seems to be of the order of 100 nsecs. It is really not a problem in practice since this time is constant and can be subtracted from the measured delays.Woody wrote:The timestamping is performed by the hardware associated with the port circuitry. You need to have two threads to make sure that both ports are setup to look for the condition and store the timestamp. When the threads are setup like this the time it takes to read the timestamps is irrelevant.
I naiively thought originally that the timestamp associated with the 'in' instruction was somehow generated within the instruction itself, in fact the assembler code shows it as a separate and subsequent instruction.
John.
I must correct the statement I made above. This is a full description of the timestamping operation:
a) If an event is used to perform a timestamped input, then the time is stored and can be read at any time
b) If a timestamped input is performed without creating an event, then the time is not stored. Instead, the port time will be read soon after the input completes. Usually this port time will be the same as if the port time has been stored. However, when a high speed port clock is used (200MHz in your case), this may result in the time being read not corresponding to the time the condition occurred.
So to make sure you get the correct timestamp, you need to force an event to be taken. To force an event to be created for timestamped inputs replace your timestamped input that looks like this:
Code: Select all
// Timestamped input without event
start when pinseq(1) :> void @ tStart;
Code: Select all
// Timestamped input with event
select {
start when pinseq(1) :> void @ tStart:
break;
}
-
- Experienced Member
- Posts: 93
- Joined: Fri Dec 11, 2009 1:39 pm
Hi Woody,
The results are almost exactly the same with the same data offset
The logic analyser port, test0 , connected as shown below in the 'process' function shows a delay of 120 ns when the input delay is around 20 ns
[img]C:\XMos\pulser1.bmp
[/img]
It still seems to me that the single processor is reading time data in some sequential fashion rather than a hardware-generated time value?
John.
The results are almost exactly the same with the same data offset
The logic analyser port, test0 , connected as shown below in the 'process' function shows a delay of 120 ns when the input delay is around 20 ns
Code: Select all
void process(streaming chanend c_start, streaming chanend c_stop, streaming chanend c_data)
{
.....................
while(1){
select
{
case c_start :> start:
test0 <: 1;
temp = 0;
break;
case c_stop :> stop:
test0 <: 0;
temp = stop - start;
break;
default:
break;
}
/
[/img]
It still seems to me that the single processor is reading time data in some sequential fashion rather than a hardware-generated time value?
John.