Problem with LOCLONG instruction
ozpropdev
Posts: 2,793
Hi All
I'm having a problem with the LOCLONG instruction.
If the instruction sits in certain address spaces it fails.
The code below looks up a long in a table and flashes a LED representing the value. (DE2-115 FPGA)
If I insert spacer NOP's or any other instruction to move the LOCLONG away from those addresses it works.
I kept inserting spacers and a pattern emerged in the bad addresses.
The bad addresses were $E18,$E38,$E58. In another program (Toolbox) I got similar patterns $2338,$2358,$2378.
The common pattern seems to be bites 3 and 4 set in the absolute address.
Am I missing something?
Cheers
Brian
I'm having a problem with the LOCLONG instruction.
If the instruction sits in certain address spaces it fails.
The code below looks up a long in a table and flashes a LED representing the value. (DE2-115 FPGA)
If I insert spacer NOP's or any other instruction to move the LOCLONG away from those addresses it works.
I kept inserting spacers and a pattern emerged in the bad addresses.
The bad addresses were $E18,$E38,$E58. In another program (Toolbox) I got similar patterns $2338,$2358,$2378.
The common pattern seems to be bites 3 and 4 set in the absolute address.
dat orgh $e00/4 'F11 to run from PNUT org jmp @hub_code bx long 0 timer long 0 delay long 40_000_000 orgh hub_code mov bx,#2 'set item index = 4 nop 'fail bug address = $e18 nop 'ok nop 'ok nop 'ok nop 'ok nop 'ok nop 'ok nop 'ok nop 'fail bug address = $e38 nop 'ok nop 'ok nop 'ok nop 'ok nop 'ok nop 'ok nop 'ok nop 'fail bug address = $e58 nop 'ok bug loclong bx,@list rdlong bx,bx getcnt timer add timer,delay waitcnt timer,delay :loop setp #32 waitcnt timer,delay clrp #32 waitcnt timer,delay djnz bx,@:loop jmp #$ list long 3 'index 0 long 1 'index 1 long 4 'index 2 long 1 'index 3 long 5 'index 4 long 9 'index 5If Ok LED flashes 4 times, a fail flashes more than I can be bothered to count!
Am I missing something?
Cheers
Brian
Comments
I just went back to the previous FPGA Build (6 Feb 2014) and the problem is still there.
Cheers
Brian
I forced the locptra to start out at $400 ($1000 byte address)
then I added nops to test all 8 longs in the cache line $400-$407
locptra worked in every slot.
Why don't you snag the bit-banged tx (verified working in cog and hubexec) then you won't have to count blinking lights... which are still very helpful tools!
With pre fetch on (Cog start up default) the code works ok on first pass then fails thereafter.
With pre fetch off the first pass fails and every other pass works.
This is with the LOCLONG aligned to hub addresses with bits 3 and 4 set. (As described in first post above)
I'll keep digging.... Brian
I wonder if the related LOCWORD LOCBYTE LOCINST have the same issue?
Bill
Identical fault for LOCWORD and LOCBYTE.
I'm looking at LOCINST now...
LOCBASE is also part of the same group...
As expected LOCBASE is the same as the others.
BTW What is LOCINST supposed to do? Wasn't in the last Docs.
I see the same behavior.
I like the number sequence, makes me hungry for pie...
C.W.
I have a nano so I modified the original example so that it saves a couple of test values to the hub and then launches the monitor so I they can be reviewed.
It looks like in the cases where LOCLONG fails it is using the index value from D and the relative offset from S but is failing to include the absolute address of the instruction itself.
Examples:
When label bug is at address $e54 the value returned by the LOCLONG is $e70 which points at the correct value in the list.
When label bug is at address $e58 the value returned by the LOCLONG is $1C which is $e74 - $e58. ($e74 is the expected value)
The error pattern repeats as shown by Brian and the error value is always off by the address of the LOCLONG.
C.W.
Nice work. That explains the results nicely.
I have been testing on DE2 and DE0 with the same results.
The tests I am doing at the moment also seem to show the results being affected by what type
of instruction preceed the LOCLONG instruction. Still working on that one.
Regarding my earlier question on LOCINST it appears to return the offset from the current PC to the @label instruction.
Cheers
Brian
Post Edit: I wondered if anyone would notice the number sequence!
If pre fetch is turn off same result as before. Hopefully this makes sense to Chip and he has a "Aha" moment.
I'm glad you guys found this problem. I'll be on it tomorrow morning.
I've been thinking that for the JMP #addresslabel(>>2) issue, I'll have the assembler return >>2 values for labels in the cases of operand use. I'll see in the morning how this will work, but that would be the proper way to handle things. That way, JMP #constant would still be what you'd expect. JMP #addresslabel would also force a long-address check, which is important.
It turns out that no '>>2' was ever needed. I didn't realize that I already had the assembler handing this properly. Sorry for all the confusion on this >>2 matter. Now, to find what's wrong with LOCLONG...
If there is a JMP directly after the LOCLONG the error does not occur.
It does not matter if the jump is to a COG or HUB address.
If the line with the label 'buggy' is commented out to insert a NOP between the LOCLONG and the JMP the error occurs.
Question: Do the cache lines always load from a WIDE boundary such as $00, $20, $40, etc.?
C.W.
Good sleuthing, ctwardell!
I was running tests of my own and I remembered that someone said this about the address of the instruction being missing. I did the math and, sure enough, that was the problem, all right.
I had accidentally omitted the pipeline-stage-advance signal from a flop clock gate, so when the cache was reloading, it clocked more than once, and after the first time, the data became errant. I fixed it and now I'm checking for any other such omissions.
I'll do a recompile soon and post new files.
GOOD JOB DISCOVERING THIS, GUYS!!!
http://forums.parallax.com/showthread.php/125543-Propeller-II-update-BLOG?p=1251927&viewfull=1#post1251927
This fixes the LOCxxxx bug.
Unfortunately it is not possible to use all the routines! For instance, tx_string calls the cog routine rdstring (which of course is not present).
It is ok to call tx_crlf though. It is also possible to use the text strings such as hello, hitspace and error.
Note that the compiler requires the address in an EQU (ie in a CON block) to be shifted >>2. This is both for jmp/call and for locptra/b/etc. The shift is not required when referencing labels for data/instructions within a DAT. It is a pnut inconsistency that can be looked at later.
So here is an example... Note: I have a LED and resistor across P0-P1.
Andyway here is what I have found yet:
1) Delayed jumps do not work correct if one of the delayed instructions is a WAITVID, and tasks are enabled.
2) In the Monitor: If you want to start a cog from hubmemory with 0+addr, the addr must be entered as hubaddr/4, which is a bit strange.
I think the monitor should calculate that for us (shr value,#2 before cogrun).
Andy
I think that would be by design since waitvid jumps to itself instead of stalling the pipeline when in multitasking mode.
All of the instructions listed below would likely be in the same category.
This is one of those cases where we will need good documentation.
From the 20Mar2014 Prop2_Docs.txt:
C.W.
Yes that explains it. I try to port an old code from a time when this was possible, but if I think about it, it was not very efficient because the task stalled until the waitvid was done. So I should have used POLLVID, and then it's the same as we have now.
Andy
Andy, this is a hard thing to decide. With hub execution now, things are a little different, since the cog uses a 16-bit address (ignores the two LSBs) for instructions in hub memory, which are longs. Have you noticed the 'X' mode in the ROM Monitor yet? I put it there to help orient people to a cog's execution perspective. In that mode, you see and manipulate the hub memory in this 16-bit-address/long perspective. If you see what the cog sees, it becomes very simple again.