Hot!Issue with entire dsPIC33Cx family with byte mode instructions? - resolved

Page: < 1234 > Showing page 3 of 4
Author
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/18 19:11:15 (permalink)
0
The high byte in w0 is shifted, and it is expected to increment across page boundaries.  As I said, I use different source/destination registers for RAM based lookups myself, but someone could actually use this code and expect it to work. 
 
I am thinking this is going to be something that affects all of the 16 bit core parts.
 
BTW, a couple of people have asked me to post the original "scare" response from Microchip (see below).  What concerns me is that it states "in some circumstances" when only one circumstance has been presented.  Are there others?
 
Created By: Matthew Robertson (3/11/2019 1:36 PM)
Hello Jim,

The product owner was out, but I talked with one of my colleagues from his team, and he was able to provide some input.

Basically, in some circumstances, when using byte mode instructions, it is possible for the data in the upper byte to be lost.

Since the part owner is out, I can't get more information right now. They may know which operations, or what patterns specifically cause the issue.

However the base suggestion is to stick with using only the lower byte when doing byte mode instructions, and assuming the upper byte is unreliable.

I will contact the part owner, and let you know as soon as I hear back. If you have any questions, please let me know I will answer them as best as I can.

Thank you,

Matthew
 
 
#41
Howard Long
Super Member
  • Total Posts : 641
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/19 02:56:33 (permalink)
0
JimDrew
The high byte in w0 is shifted, and it is expected to increment across page boundaries.  As I said, I use different source/destination registers for RAM based lookups myself, but someone could actually use this code and expect it to work. 

 
I'm not sure I understand by "The high byte in w0 is shifted". As far as I've been able to determine anecdotally on hardware, the high byte appears to be zeroed if you use a post increment on the same register that you're writing the byte to. In the simulator, it will increment if the low byte was to carry.
 
I'm still really struggling to figure out a real practical instance where you'd realistically ever need this.
 
As I suggested earlier, if the requirement to reproduce is as we currently understand, this to me straddles the boundary of assuming undefined behaviour, and contrivance or fabricated concern.
 
 
I am thinking this is going to be something that affects all of the 16 bit core parts.

 
As well as the earlier devices I checked, this morning I also reproduced it on the following silicon in real hardware:
 
dsPIC33EP256GP502
dsPIC33FJ128MC802
PIC24HJ128GP502
PIC24FJ64GA002
 

BTW, a couple of people have asked me to post the original "scare" response from Microchip (see below).  What concerns me is that it states "in some circumstances" when only one circumstance has been presented.  Are there others?

 
I fully agree that we need further clarity on what those circumstances are to make a reasonable risk analysis. 
 
Knowing that the scenario we have affects many other devices in the range (if not the entire range) does give us some degree of comfort.
#42
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/19 10:52:01 (permalink)
0
As far as I've been able to determine anecdotally on hardware, the high byte appears to be zeroed if you use a post increment on the same register that you're writing the byte to.

 
No, the upper byte is not zero'd.   Example:
 
w0 = 0x1234, memory at 0x1234 contains 0x55
 
mov.b [w0++],w0
 
w0 will now be = 0x1255 since only the lower byte is being affected.
 
The problem occurs in a case of crossing a page boundary.
 
w0 = 0x12FF, memory at 0x12FF contains 0xAA
 
mov.b [w0++],w0
 
w0 should be 0x13AA, but due to the discussed issue it is 0x12AA.
 
If you are relying on the upper byte for a future operation, it will be wrong.  I agree that this is a super remotely used condition, but nonetheless it is something that should work.  I think there just needs to be a note telling people not to do this.  :)
 
 
post edited by JimDrew - 2019/03/20 09:35:54
#43
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/19 11:13:36 (permalink)
0
One thing that I have not tried are different post and pre increment/decrement cases.  Such as:
 
w0 = 0x1200, memory at 0x1200 contains 0x4A
 
mov.b [w0--],w0
 
w0 = should be 0x114A, but I am guessing based on what the post increment does that it will end up being 0x124A.
 
I will have to test that.
 
post edited by JimDrew - 2019/03/19 11:16:07
#44
JPortici
Super Member
  • Total Posts : 623
  • Reward points : 0
  • Joined: 2012/11/17 06:27:45
  • Location: Grappaland
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/19 14:23:20 (permalink)
5 (2)
So it seems i still have troubles getting the issue.
I would expect the result to be 0x1249
->fetch memory at address [W0]
-> put the byte in the lower half of W0
-> decrement W0 (post decrement)
 
let's take the dsPIC programmer manual
http://ww1.microchip.com/downloads/en/DeviceDoc/70000157g.pdf
 
if the issue here is the order of execution of write back and operand increment/decrement, where can i find the expected order of execution?
#45
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/19 20:12:35 (permalink)
0
In the case of a post increment, the register is incremented *after* fetching the value.  Let's look at how this is handled when using different registers as a comparison:
 
w0 = 0x12FF, value pointed to is 0xAA
w1 = 0x2100
 
mov.b [w0++],w1
 
The result is:
 
w0 = 0x1300
w1 = 0x21AA
 
You can see that only the lower byte of w1 is affected and that w0 incremented from 0x12FF to 0x1300.  This should always be the case.  However, when using the same register, the upper byte of w0 retains the pre incremented value of 0x12, not 0x13 as you would expect.  THAT is the bug that occurs.
 
So, when doing the same thing as above, but using w0 as source and destination you get:
 
w0 = 0x12FF, value pointed to is 0xAA
 
mov.b [w0++],w0
 
The result is:
 
w0 = 0x12AA
 
There is some stage at the end of the microcode where when the same register is used, the original upper byte value is stored instead of the value that occurs after a pre or post increment/decrement.
 
post edited by JimDrew - 2019/03/20 09:36:35
#46
Howard Long
Super Member
  • Total Posts : 641
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 02:16:08 (permalink)
0
It doesn't matter whether you're on a page boundary or not, the high byte is always zeroed out on real hardware. The example below is on dsPIC33CH128MP508, but I also tested it on a PIC24F16FL402 with the same results (using an equally appropriate data address space).
 

#pragma config FNOSC = FRC // Oscillator Source Selection (Internal Fast RC (FRC))
#pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
#pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config FCKSM = CSECMD // Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled)
#pragma config PLLKEN = PLLKEN_OFF // PLLKEN (PLLKEN_OFF)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer operates in Window mode)
#pragma config FWDTEN = ON_SW // Watchdog Timer Enable bit (WDT controlled via SW, use WDTCON.ON bit)
#pragma config ICS = PGD2 // ICD Communication Channel Select bits (Communicate on PGC2 and PGD2)
#pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
#include <xc.h>
int main(void)
{
*(uint16_t *)0x1234=0xAA55;
*(uint16_t *)0x12FE=0xAA55;
// ____________________________ Hardware / Simulator
__asm("mov #0x1234,w0"); // w0 = 0x1234 / 0x1234
__asm("mov.b [w0++],w0"); // w0 = 0x0055 / 0x1255 **** High byte zeroed out on hardware
__asm("mov #0x12FF,w0"); // w0 = 0x12FF / 0x12FF
__asm("mov.b [w0++],w0"); // w0 = 0x00AA / 0x13AA **** High byte zeroed out on hardware
while (1)
{
Nop();
}
return 0;
}

 
 
#47
Howard Long
Super Member
  • Total Posts : 641
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 02:47:54 (permalink)
0
Jack_M
if the issue here is the order of execution of write back and operand increment/decrement, where can i find the expected order of execution?



That's certainly part of the issue, although there is a secondary issue in that the high byte is zeroed out on real hardware.
 
In practice, I would imagine that the pre/post increment and decrement operations are, by design, performed in-place on the registers themselves (i.e., not in the ALU) in parallel with the main operation.
 
Some pre increment/decrement examples below:
 

*(uint16_t *)0x1234=0xAA55;
*(uint16_t *)0x12FE=0xAA55;
 
// ____________________________ Hardware / Simulator
__asm("mov #0x1234,w0"); // w0 = 0x1234 / 0x1234 
__asm("mov.b [++w0],w0"); // w0 = 0x00AA / 0x12AA **** High byte zeroed out on hardware
__asm("mov #0x1300,w0"); // w0 = 0x1300 / 0x1300
__asm("mov.b [--w0],w0"); // w0 = 0x00AA / 0x12AA **** High byte zeroed out on hardware

#48
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 09:40:39 (permalink)
0
It doesn't matter whether you're on a page boundary or not, the high byte is always zeroed out on real hardware. The example below is on dsPIC33CH128MP508, but I also tested it on a PIC24F16FL402 with the same results (using an equally appropriate data address space).

 
Remember, this errata is for the '256 and '512 versions (not other versions).  I have not tried the '128 series myself.  I can tell you that the '512 for sure does not zero out the upper byte.  It does exactly as Microchip describes, and doesn't increment the upper byte like it is suppose to.  So, it seems that you have found another issue.  :)
 
I just tried this with a project using a dsPIC33CH512MP208 (80 pin version):
 
value at 0x12FF = 0x55
 
mov #0x12FF,w0
mov.b [w0++],w0
 
The simulator gets the correct result of 0x1355
 
Real hardware gets the incorrect result of 0x1255
 
::edit::
 
I just tried this on the dsPIC33CH512MP206 (64 pin version) and I DO get a 0x00 in the upper byte!
 
I am guessing that the information that Matthew gave me (see page 2 for message from Matthew describing the issue in detail) was based on the 80 pin part.  I will pass this info along to Microchip!
 
 
 
post edited by JimDrew - 2019/03/20 10:06:41
#49
Denge
Super Member
  • Total Posts : 76
  • Reward points : 0
  • Joined: 2016/03/03 07:23:12
  • Location: belgium
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 09:42:09 (permalink)
0
On a PIC24FJ64GA002 the reaction is the same as Howard described: the high byte is zeroed out.
I checked it for a few other W registers and they react all the same.
With this code, I would expect that the 0x0055 is 0x0056 at least
mov.b [w0++],w0 

But I can't still don't grasp what the advantage would be to use the same register
post edited by Denge - 2019/03/20 09:47:29
#50
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 10:04:07 (permalink)
0
The advantage to using the same register is saving an extra register.  I have projects where I am using all 14 registers (w15 is always reserved for the stack), and I could use a couple more free registers.
 
post edited by JimDrew - 2019/03/20 10:07:43
#51
NorthGuy
Super Member
  • Total Posts : 5309
  • Reward points : 0
  • Joined: 2014/02/23 14:23:23
  • Location: Northern Canada
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 11:12:34 (permalink)
5 (1)
An operation of incrementing a pointer and discarding the low byte of the result, how to put it, highly unusual. I tried, but I couldn't find any uses for it. In 99.9% of the cases, if you auto-increment a pointer this is because you want to fetch the next element at some point in the future. If you destroy the low byte, you give up any chance of it ever been used as a pointer. Perhaps, the high byte of the pointer might be of some use if you have a sophisticated system of tables at fixed memory addresses, but I cannot find any possible benefits of auto-increment in such situation.
 
This construct has never been used in 10+ years of PIC24 existence and the "bug" has never been discovered. There's no reason to dwell on it now. Unless there are other effects which we don't know of, whoever wrote this errata must be fired immediately.
 
BTW: It is in CK errata too.
#52
Denge
Super Member
  • Total Posts : 76
  • Reward points : 0
  • Joined: 2016/03/03 07:23:12
  • Location: belgium
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 11:52:02 (permalink)
5 (1)
@Jim

mov #0x12FF,w0
mov.b [w0++],w0


"The simulator gets the correct result of 0x1355"

Could you explain why the result should be 0x1355 iso 0x1255?
#53
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/20 18:36:40 (permalink)
0
This construct has never been used in 10+ years of PIC24 existence and the "bug" has never been discovered. There's no reason to dwell on it now. Unless there are other effects which we don't know of

 
I think maybe the issue here really is that everything (programmers and compilers) has expected the high byte to always be 0x00 (like what the ZE instruction does) in this case, and suddenly things were broken with the new larger parts were released.  To me, that makes way more sense.  I use ze [w0],w0 a LOT in my code, knowing that the upper byte is going to be cleared.  Who knows.. maybe the compiler "optimizes" a byte fetch and address increment into mov.b [wX++],wX ??  :)  I am still waiting for further info from Microchip.
 
@Denge, see post #46 for the explanation: https://www.microchip.com/forums/FindPost/1090928
 
#54
Howard Long
Super Member
  • Total Posts : 641
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/21 01:13:33 (permalink)
0
JimDrew
The advantage to using the same register is saving an extra register.  I have projects where I am using all 14 registers (w15 is always reserved for the stack), and I could use a couple more free registers.

 
That's only valid if you have a reason for needing the high byte of a post increment bearing in mind you're explicitly intentionally overwriting the low byte. What's the use case where you'd still have a reason to need that high byte?
 
To be clear, it works as expected if you don't use any pre/post inc/dec, i.e., the high byte is not overwritten.
 
#55
Howard Long
Super Member
  • Total Posts : 641
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/21 01:32:56 (permalink)
0
JimDrew
 
I just tried this with a project using a dsPIC33CH512MP208 (80 pin version):
 
value at 0x12FF = 0x55
 
mov #0x12FF,w0
mov.b [w0++],w0
 
The simulator gets the correct result of 0x1355
 
Real hardware gets the incorrect result of 0x1255
 
::edit::
 
I just tried this on the dsPIC33CH512MP206 (64 pin version) and I DO get a 0x00 in the upper byte!
 
I am guessing that the information that Matthew gave me (see page 2 for message from Matthew describing the issue in detail) was based on the 80 pin part.  I will pass this info along to Microchip!
 



I have just tried it on a high memory 80 pin part, the dsPIC33CH512MP508 on a PIM on an Explorer 16/32 board, and the high byte is zeroed, just as with all the other devices.
 
I have specifically included a number of exampes, including post increment, pre increment and decrement, and the Microchip example.
 

#pragma config FNOSC = FRC // Oscillator Source Selection (Internal Fast RC (FRC))
#pragma config IESO = OFF // Two-speed Oscillator Start-up Enable bit (Start up with user-selected oscillator source)
#pragma config POSCMD = NONE // Primary Oscillator Mode Select bits (Primary Oscillator disabled)
#pragma config OSCIOFNC = OFF // OSC2 Pin Function bit (OSC2 is clock output)
#pragma config FCKSM = CSECMD // Clock Switching Mode bits (Clock switching is enabled,Fail-safe Clock Monitor is disabled)
#pragma config PLLKEN = PLLKEN_OFF // PLLKEN (PLLKEN_OFF)
#pragma config WINDIS = OFF // Watchdog Timer Window Enable bit (Watchdog Timer operates in Window mode)
#pragma config FWDTEN = ON_SW // Watchdog Timer Enable bit (WDT controlled via SW, use WDTCON.ON bit)
#pragma config ICS = PGD2 // ICD Communication Channel Select bits (Communicate on PGC2 and PGD2)
#pragma config JTAGEN = OFF // JTAG Enable bit (JTAG is disabled)
 
#include <xc.h>
 
int main(void) 
{
*(uint16_t *)0x1234=0xAA55;
*(uint16_t *)0x12FE=0xAA55;
*(uint16_t *)0x74FE=0xF321;
 
// ______________________________ Hardware / Simulator
 
// Post-increment examples
__asm("mov #0x1234,w0"); // w0 = 0x1234 / 0x1234 
__asm("mov.b [w0++],w0"); // w0 = 0x0055 / 0x1255 ****
__asm("mov #0x12FF,w0"); // w0 = 0x12FF / 0x12FF
__asm("mov.b [w0++],w0"); // w0 = 0x00AA / 0x13AA ****
 
// Pre inc/dec examples
__asm("mov #0x1234,w0"); // w0 = 0x1234 / 0x1234 
__asm("mov.b [++w0],w0"); // w0 = 0x00AA / 0x12AA ****
__asm("mov #0x1300,w0"); // w0 = 0x1300 / 0x1300
__asm("mov.b [--w0],w0"); // w0 = 0x00AA / 0x12AA ****
 
// Microchip example
__asm("mov #0x74FF,w12"); // w12 = 0x74FF / 0x74FF
__asm("inc2.b [w12++],w12"); // w12 = 0x00F5 / 0x75F5 ****

while (1)
{
Nop();
}
return 0;
}
 

post edited by Howard Long - 2019/03/21 01:57:07
#56
JimDrew
Super Member
  • Total Posts : 342
  • Reward points : 0
  • Joined: 2003/11/07 12:37:26
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/21 13:20:56 (permalink)
0
I am using a dsPIC33CH512MP208 in a commercial product prototype and it doesn't clear the high byte.  It makes the upper byte one less than it should be, as per the Microchip example.  I don't have a 508 version here (we don't need CAN support), but I should probably order a few for testing in case we have to switch to the 508 due to a 208 shortage.  Maybe it's just the 208... or maybe the issue was fixed with newer date code parts?   I do have a few batches of parts.  I will look into that.
 
What's the use case where you'd still have a reason to need that high byte?

 
For maintaining the reference of the start of jump tables in a multi-jump lookup table.  For look up tables, I typically copy the program memory offsets into RAM and use that instead of table reads each time.  With the PIC24EP and dsPIC33EP parts (which I commonly use) it is faster to fetch data from RAM than it is from program memory.
 
 
 
post edited by JimDrew - 2019/03/21 13:23:45
#57
Denge
Super Member
  • Total Posts : 76
  • Reward points : 0
  • Joined: 2016/03/03 07:23:12
  • Location: belgium
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/21 15:43:20 (permalink)
0
Hi Jim,
JimDrew
In the case of a post increment, the register is incremented *after* fetching the value. 

 
Following the logic post #46 the result of
w0 = 0x12FF, value pointed to is 0xAA
mov.b [w0++],w0

should end up in 0x12AB and not 0x13AA
 
A pre-increment is getting the result 0x13AA, following the same logic.
In the simulator the pre-increment isn't correct either as it it pointing to the lower byte of 0x1300.
On hardware the post is zeroing the high byte, the pre is doing it correctly.
#58
Howard Long
Super Member
  • Total Posts : 641
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/21 16:59:24 (permalink)
0
JimDrew
What's the use case where you'd still have a reason to need that high byte?

 
For maintaining the reference of the start of jump tables in a multi-jump lookup table.  For look up tables, I typically copy the program memory offsets into RAM and use that instead of table reads each time.  With the PIC24EP and dsPIC33EP parts (which I commonly use) it is faster to fetch data from RAM than it is from program memory.

 
Then why would you use post/pre increment or decrement in that case? As I've stated twice before, there is no problem unless you're doing post/pre inc/dec.
#59
Howard Long
Super Member
  • Total Posts : 641
  • Reward points : 0
  • Joined: 2005/04/04 08:50:32
  • Status: offline
Re: Issue with entire dsPIC33Cx family with byte mode instructions? 2019/03/21 17:03:18 (permalink)
0
JimDrew
I am using a dsPIC33CH512MP208 in a commercial product prototype and it doesn't clear the high byte.  It makes the upper byte one less than it should be, as per the Microchip example.  I don't have a 508 version here (we don't need CAN support), but I should probably order a few for testing in case we have to switch to the 508 due to a 208 shortage.  Maybe it's just the 208... or maybe the issue was fixed with newer date code parts?   I do have a few batches of parts.  I will look into that.
 

 
I just checked, I do have some dsPIC33CH512MP208 in stock but they're still in tape, and it's now midnight here! I'll take a look over the weekend. 
#60
Page: < 1234 > Showing page 3 of 4
Jump to:
© 2019 APG vNext Commercial Version 4.5