No, you don't need a PLL to decode manchester. That's only one way. In fact a PLL doesn't by itself decode anything, it only provides a clock at which you can reliably sample the manchester half-bits. If the bit rate of the manchester stream can vary, then something like a PLL that can adjust to the incoming frequency may be useful.
I have done several manchester decoders and none of them used a PLL. The first time I did this, my thought was to measure the time between edges by capturing a timer, and then decode the bitstream from there. That worked fine, but in subsequent projects I used a different scheme that allowed for higher manchester bit rate relative to the instruction rate. In these projects I simply sampled the incoming stream at regular intervals. The periodic interrupt counts how many successive samples the input is high or low and passes that to the next level up decoding logic. That then classifies each level as long, short, or invalid, which is then decoded up the protocol chain usually ending in fully received and validated packets.
Since manchester is usually used because data needs to be transmitted accross some analog medium (it's a bit silly to use manchester between two digital chips on the same board, for example), the raw input signal is often analog. Above I mentioned that I now usually sample the manchester signal at some multiple (like 8-12) of the expected bit rate. This is actually usually done with a A/D. By doing this you eliminate the need for analog data slicers.
Digital data slicers can easily be quite a bit better than analog ones of reasonable complexity. All you need to do externally is to low pass filter the signal to prevent aliasing at the fast sample rate. Since the manchester signal is being sampled around 8-12 times faster than the bit rate, such a filter won't cut into the real signal much at all. Usually two poles of R-C is good enough.
My digital data slicers work by keeping the last two bit times of samples in memory. For example, if the manchester data is being sampled 8x the bit rate, then this would mean the last 16 samples are kept in a rolling buffer. The reason for two whole bit times is that this is the minimum time for two full successive levels of opposite polarity (imagine a 101010... pattern). The data slicer computes the average of the max and min values in the buffer, and uses that as the high/low comparison threshold.
Another trick is to do a little low pass filtering on the string of A/D samples before data slicing. This is one of the few cases where a box filter is actually a good answer, as apposed to the usual knee jerk reaction of those that didn't pay attention in signal processing class. The convolution window width is simply the number of samples in a half-bit. Think of the case where the input is a perfectly clean digital signal. This signal will always have levels lasting either 1/2 bit or 1 bit time. The box filter ("moving average" for the knee jerkers) will turn the edges into ramps lasting 1/2 bit time each. A signal with a sequence of short levels therefore becomes a triangle wave. A sequence of long levels therefore a trapezoid with ramps last 1/2 bit time and solid levels between also 1/2 bit time long. Note that data slicing this signal to the average of its max and min value yields the same resulting stream as doing it on the unfiltered input.
So why filter? Because you get better noise immunity. As described above, a perfect signal isn't effected by this filter. However, a noisy signal is. The effect on the resulting 1s and 0s stream out of the data slicer from random noise added to the input samples is less with the filtering. I have implemented this algorithm in a dsPIC sampling at 9x the bit rate with a 12 bit A/D right from a analog RF receiver. This system was able to decode valid packets from RF transmissions that I could barely see on a scope by looking at the same signal going into the A/D. "Valid" packet means that no manchester violations were found, the bit stream decoded, and a 20 bit CRC checksum test passed. This stuff really works.
The d
and a
bits are fields in the instruction encoding, but not part of the 8-bit address field in the instruction. If we want to be academic about it, we could say that the a
bit is an addressing mode field in the instruction. The d
bit can be analyzed as a destination addressing mode or as part of the opcode, but the 00
you start by quoting are not part of addressing at all; they are simply the last two bits of the MOVF opcode.
The 12-bit effective address used is constructed as the 8 address bits from the instruction, prepended by 4 bits that either come from the BSR or are derived from the first few of the explicit address bits, as selected by the a
field. But the value of the a
bit itself doesn't become part of the address.
Finally (but I may be misreading the documentation I could find here), the ,A
in the assembler syntax seems to stand for "use the Access bank", so when (upper-case) A
is present in the assembler instruction, it means that (lower-case) a
in the binary instruction encoding is zero and the BSR is not used.
Best Answer
Let's start by labelling some bits of the diagram for easy reference:
Now we can define what the different labels mean.
So we can make some boolean expressions now:
Expanded:
Since CS is always active LOW you are interested in the FALSE values of those expressions - the values that make the expression result in an answer of FALSE.
So if any of A8-A15 are true then A must be true, ergo to get A to be false NONE of A8 to A15 can be HIGH. So A will be LOW for address range 0b00000000XXXXXXXX (or 0x0000 - 0x00FF)
If either B or E are true then C is true. Therefore B and E both have to be false for C to be false. E is A15, so we know now that A15 must be LOW to ensure that C can be false. A has to be true since it is negated to form B. So one of A8-A14 must be high to make A true and thus B false.
That leads us to the address 0b0YYYYYYYXXXXXXXX where at least one of Y must be high and we don't care about X. That is, anywhere between 0b00000001XXXXXXXX and 0b01111111XXXXXXX, or in hex: 0x0100 to 0x7FFF.
D is the same as C except for the fact that E is inverted. That means that A15 must be HIGH to make D able to be false. Since A15 is high we have the ability to set A8-A14 low and still be valid for this range. So we get 0b1YYYYYYYXXXXXXX, or 0b10000000XXXXXXXX to 0b11111111XXXXXXXX, or in hex: 0x8000 to 0xFFFF.
To put those address ranges in context let's build a full memory map: