I have already explored all the "low hanging fruits" I have found but I'll need more time to come up with a proper perspective and theory. However, practical implementations have some coding constraints that I will address in this log.

Let's have a look at this revised dependency graph, which I revised to consider the aspects covered here:

I tried to minimise the total number of operations. This would probably be adapted for a hardware implementation, of course, but let's first design a first working software version.

The first thing to consider is the last one, usually called the "Finish" step, where the final result is handled. Already, X, Y and C contain the whole state for the system but

- C is usually discarded, so should be better combined with the remaining bits
- X could be OK by itself but adding it to Y should increase the Hamming distance in the case of an alteration that hits the last word and/or the checksum.

So the Finish contains a simple addition with carry in, and no carry out.

- If you only require 16 bits of signature, this sum is all you need.
- However if you desire 32 bits, you can concatenate X and Y.

Going up from there, we have the loop body. The X-Y swap has been moved up but this doesn't change much here.

Then we have the Start step where the variables are initialised. As we have learned, the carry must be set to a value that is coherent with Y, in order to prevent a "stuck state". So in fact, any value is OK except { Y=FFFF, C=1} and { Y=0, C=0}. I have used 0x1234 to prove my point but you may choose another non-forbidden value.

One input value is pre-loaded into X and the pointer can be pre-incremented in the loop to save one instruction and prevent an off-by-one access (and/or TLB lookup for a block that will not be used).

From there, writing the code is quiet like a walk in the woods...

```
#include <stdint.h>
#include <inttypes.h>
#define PISANO_WIDTH (16)
#define SIZE (1<<PISANO_WIDTH)
#define MASK (SIZE-1)
uint32_t Pisano_Checksum(
uint16_t *buffer, // points to the data to scan
int size // number of 16-bit WORDS to scan
) {
uint32_t
// Start
X = *buffer,
Y = 0x1234, // anything except 0 or FFFF
C = 1,
t;
// Loop
while (size) {
size--;
buffer++;
t = X + Y + C; X = Y ^ *buffer;
C = t >> PISANO_WIDTH; Y = t & MASK;
}
// Finish
return C+Y+(X << PISANO_WIDTH);
}
```

*Aaaand* that's it.

I provided a tiny **main()** to verify the basics.

gcc -Wall test_Pisano16x2.c -o test_pisano && ./test_pisano Checksum: 8573B7DA

What remains now to be done ?

## Discussions

## Become a Hackaday.io Member

Create an account to leave a comment. Already have an account? Log In.