'Could have been accomplished in the few cases that needed it with getoutx instructions.
-Phil
That doesn't address the problem of compiling from high level languages. If you don't want to make a special case of this register in the compiler code generator, it's not going to be compiled to use that instruction.
I guess I don't understand what the big deal is with making special cases in the compiler. I should think that would have to be done all the time to handle architectural quirks. At its worst, the P2 is still more regular than, say, an Atmel AVR.
IOW, a compiler writer's job is supposed to be hard if it makes code-wirters' jobs easier or yields more efficient object code. Right?
I guess I don't understand what the big deal is with making special cases in the compiler. I should think that would have to be done all the time to handle architectural quirks. At its worst, the P2 is still more regular than, say, an Atmel AVR.
IOW, a compiler writer's job is supposed to be hard if it makes code-wirters' jobs easier or yields more efficient object code. Right?
-Phil
An AVR has also separated registers for the output state and the input read. All modern microprocessors do that, I only know the Intel 8051 which had a single port register which caused a lot of problems.
The combined PINx worked different if you do:
OR PINA,#$FF
or if you do:
MOV tmp,PINA
OR tmp,#$FF
MOV PINA,tmp
That is really hard for compilers because this can change depending of the optimization level.
If something is "hard" for compilers (but not impossible), I still say, "So what?" It only has to be done once. Exceptions are what if statements are for.
Besides, if INx and OUTx are separated and thereby no longer fit in the SFR space, then every access becomes an exception. OTOH, if the separated registers do fit in the SFR space, then this discussion is moot -- depending on what, if anything, had to be kicked out to accommodate them.
There are always trade-offs, and the costs/benefits of any decision depend on what compromises have to be made. I do not, however, consider moderately increased compiler complexity to be a sufficiently inflluential negative to affect architecture.
Phil,
P2 has less that 16 SFRs even with in and out split. P2 doesn't have any of the counter/etc regs in SFR space. It only has the INDEX/IN/OUT/DIR registers (total of 14).
That being the case, this discussion is moot, although I would love to have seen the PHSx and FRQx registers remain in SFR space at the expense of leaving INx and OUTx conjoined.
(My comments about compiler exceptions still stand, however.)
I guess I don't understand what the big deal is with making special cases in the compiler. I should think that would have to be done all the time to handle architectural quirks. At its worst, the P2 is still more regular than, say, an Atmel AVR.
IOW, a compiler writer's job is supposed to be hard if it makes code-wirters' jobs easier or yields more efficient object code. Right?
-Phil
True in theory but Parallax doesn't necessarily have an infinite amount of money to pay for compiler development.
I had been of the opinion that INx and OUTx should be separate registers because of the ability to perform the AND/OR/XOR/... functions on the output pins and achieve the correct result.
However, if
AND/OR/XOR/... PINx,[#]MASK
works correctly (by reading the shadow register or whatever - by reading what has been effectively written to PINx as an OUTx instruction) then why cannot the combined PINx register work?
IOW if PINx is used as the D (destination) in a read-modify-write type instruction, then PINx yields the OUTx value rather than the actual value on the pins (they may be different).
When Pinx is used as the S (source) it correctly yields the INx which is the actual value on the pins.
This seems to work for me. If so, then perhaps the following will solve this issue with assembler/compiler warnings...
PINx/OUTx/INx all refer to the same register, but their usage in an instruction is as follows (anything else gives a warning, just like I believe JMP/CALL XXX should give a warning 'missing #')
MOV/... OUTx,VALUE 'sets output pins to value
AND/OR/XOR/... OUTx,MASK 'read-modify-write uses OUTx (not actual INx)
MOV/... VALUE,INx 'reads actual value on the pins
So, OUTx is for Destination, and INx is for Source. Other use is flagged with a warning/error by the assemblers/compilers.
This does mean that you cannot actually read the OUTx values. Is this a problem in the above scenario?
If it is, then surely we can solve this by a GETOUTx set of instructions ??
Another solution is to move the Peripheral Registers so they do not consume the very valuable COG RAM space.
That means there is no cost to adding more and easier access.
Another solution is to move the Peripheral Registers so they do not consume the very valuable COG RAM space.
That means there is no cost to adding more and easier access.
But then you lose all the valuable instructions that operate on these Peripheral Registers (PINx or INx & OUTx, and DIRx). Instructions like AND, ANDN, OR, XOR, SHR, SHL, ROR, ROL, RCR, RCL, etc. There are so many tricks we do use already on the INA & OUTA registers in particular, and DIRA too, in the P1, that to lose these IMHO is not on the books.
I think usually you're usually just trying to update pins you already have setup as outputs using DIRx.
I have several projects that tri-state the output buffers then AND/OR into pins so they are "pre-set" before re-enabling them as outputs. In most cases you are right, but combining IN/OUT registers seems like asking for trouble.
Having special instructions to access the SFRs is very undesirable to me. Besides, it seems like Chip has already filled up all of the instruction OPcodes and is still trying to figure out how to stuff a few more instructions.
I have several projects that tri-state the output buffers then AND/OR into pins so they are "pre-set" before re-enabling them as outputs. In most cases you are right, but combining IN/OUT registers seems like asking for trouble.
I'm conflicted about accessing the INx/OUTx through special instructions. My gut feeling is that I think it's a good idea. Had this been the way it was done from the beginning, we would never have had the debate (twice now) about PINx. On the other hand, I agree with Cluso99 that we would lose the convenience of using standard instructions. At the very least, maybe DIRx access could be moved to special instructions. Apart from half-duplex protocols (like I2C, which is fairly slow), is there a need to regularly modify DIRx?
Edit: just to add a thought, special instructions would potentially allow simultaneous setting of pins across multiple output registers, which can't be done right now. I'm not sure if that's valuable or not.
Just for clarity, can someone confirm if this is the current interpretation of INx and OUTx?
INx[y] = (DIRx[y] AND OUTx[y]) OR (NOT DIRx[y] AND (input from pin OR output from all other cogs whose same DIRx[y] is set))
OUTx[y] = whatever was previously written to OUTx[y]
Just for clarity, can someone confirm if this is the current interpretation of INx and OUTx?
INx[y] = (DIRx[y] AND OUTx[y]) OR (NOT DIRx[y] AND (input from pin OR output from all other cogs whose same DIRx[y] is set))
OUTx[y] = whatever was previously written to OUTx[y]
INx[y] just reads the state of the pin. If the voltage at the pin is lower than the threshold it reads a 0 otherwise a 1. The threshold is configurable and can also be a schmitt trigger or the difference to a second pin or an ADC bitstream. But there is no logical combination with the DIRx[y] or with the output of other cogs.
For sure the voltage level at the pin depends on the OUTx[y] if DIRx[y] is set in any cog. But the connected hardware at the pin can overdrive the OUTx[y] state, there are now very weak output modes configurable.
Phil,
"...a compiler writer's job is supposed to be hard..."
CPU designers have assumed that philosophy may times in the past. "Let's make the architecture and instruction set super wizzy and leave the complexity to the compiler". That is what lead to the down fall of the Intel i860 and the Itanium, oh and the Intel 432 before that. In some of those cases (i860 for example) it was not only impossible for the compiler but very hard for the asembler programmer as well.
Watching the history of these things unfold over the years I all ways had be wondering why CPU designers and compiler writers don't talk to each other more. We might have had better optimized more efficient systems a long time ago if they did.
BTW, guys, I have no real objection to keeping INA and OUTA separate, per se. It does make things easier, after all. Where it bothers me, though, is that other SFRs (e.g. certain counter registers) get shunted out of SFR address space as a result, making them less efficient to use than before. Combining INx and OUTx still allows them to be used normally in most cases, with the exceptions handlable with special accessing instructions (e.g. getoutx). If doing so allows other SFRs to re-enter SFR space, then it's a Good Thing, in my mind at least. IOW, this discussion is not just about the I/O registers; it's about finding a balance and making a home for as many SFRs as possible in the top sixteen longs of cog RAM.
I have a friend who's fond of saying, once the hardware has been built, "The rest is just software!" Indeed.
Totally off topic here but I once worked on a portable military device that included a processor and a special ASIC modem. The idea was that the ASIC would wake up the processor from it's low power sleep mode when some wireless singal arrived. The hardware guys had put the CPU and ASIC together such that the sync pattern in that signal, that should wake everything up, was to be detected in software. Which meant the CPU had to be awake all the time. Which meant there would be no battery life. Which meant the whole project was pointless. Took me a big long argument to convince everyone that we needed a hardware change...
...On the other hand, I agree with Cluso99 that we would lose the convenience of using standard instructions.
Being able to use regular instructions on OUTx and DIRx allows multitasking to work, as long as everybody does atomic read-modify-write operations, like AND/OR/XOR/ADD/SUB/etc, and especially the new SETNIB/SETBYTE/SETWORD. If every task had to do a GETOUTx instruction, followed by something like SETOUTx, different tasks would wind up with different snapshots of the states, in time, and a big mess would occur. Having the pins mapped into register space is critical for multitasking to work.
Just for clarity, can someone confirm if this is the current interpretation of INx and OUTx?
INx[y] = (DIRx[y] AND OUTx[y]) OR (NOT DIRx[y] AND (input from pin OR output from all other cogs whose same DIRx[y] is set))
OUTx[y] = whatever was previously written to OUTx[y]
INx is simply what is being seen at the pins, regardless of any states anyone's attempting to drive them to. It's the actual measured pin states.
Chip (refer my post #140)
Is there any reason we cannot use the same reg for PINx (INx/OUTx) with INx when used as the Source, and OUTx used as the Destination. Then all read-modify-write instructions would correctly (provided the P2 used this) use the OUTx register and not the pins.
Am Imissingsomething here ?
Chip (refer my post #140)
Is there any reason we cannot use the same reg for PINx (INx/OUTx) with INx when used as the Source, and OUTx used as the Destination. Then all read-modify-write instructions would correctly (provided the P2 used this) use the OUTx register and not the pins.
Am Imissingsomething here ?
Comments
IOW, a compiler writer's job is supposed to be hard if it makes code-wirters' jobs easier or yields more efficient object code. Right?
-Phil
An AVR has also separated registers for the output state and the input read. All modern microprocessors do that, I only know the Intel 8051 which had a single port register which caused a lot of problems.
The combined PINx worked different if you do: or if you do: That is really hard for compilers because this can change depending of the optimization level.
Andy
Besides, if INx and OUTx are separated and thereby no longer fit in the SFR space, then every access becomes an exception. OTOH, if the separated registers do fit in the SFR space, then this discussion is moot -- depending on what, if anything, had to be kicked out to accommodate them.
There are always trade-offs, and the costs/benefits of any decision depend on what compromises have to be made. I do not, however, consider moderately increased compiler complexity to be a sufficiently inflluential negative to affect architecture.
-Phil
P2 has less that 16 SFRs even with in and out split. P2 doesn't have any of the counter/etc regs in SFR space. It only has the INDEX/IN/OUT/DIR registers (total of 14).
That being the case, this discussion is moot, although I would love to have seen the PHSx and FRQx registers remain in SFR space at the expense of leaving INx and OUTx conjoined.
(My comments about compiler exceptions still stand, however.)
-Phil
However, if
AND/OR/XOR/... PINx,[#]MASK
works correctly (by reading the shadow register or whatever - by reading what has been effectively written to PINx as an OUTx instruction) then why cannot the combined PINx register work?
IOW if PINx is used as the D (destination) in a read-modify-write type instruction, then PINx yields the OUTx value rather than the actual value on the pins (they may be different).
When Pinx is used as the S (source) it correctly yields the INx which is the actual value on the pins.
This seems to work for me. If so, then perhaps the following will solve this issue with assembler/compiler warnings...
PINx/OUTx/INx all refer to the same register, but their usage in an instruction is as follows (anything else gives a warning, just like I believe JMP/CALL XXX should give a warning 'missing #')
MOV/... OUTx,VALUE 'sets output pins to value
AND/OR/XOR/... OUTx,MASK 'read-modify-write uses OUTx (not actual INx)
MOV/... VALUE,INx 'reads actual value on the pins
So, OUTx is for Destination, and INx is for Source. Other use is flagged with a warning/error by the assemblers/compilers.
This does mean that you cannot actually read the OUTx values. Is this a problem in the above scenario?
If it is, then surely we can solve this by a GETOUTx set of instructions ??
That means there is no cost to adding more and easier access.
I have several projects that tri-state the output buffers then AND/OR into pins so they are "pre-set" before re-enabling them as outputs. In most cases you are right, but combining IN/OUT registers seems like asking for trouble.
Having special instructions to access the SFRs is very undesirable to me. Besides, it seems like Chip has already filled up all of the instruction OPcodes and is still trying to figure out how to stuff a few more instructions.
Edit: just to add a thought, special instructions would potentially allow simultaneous setting of pins across multiple output registers, which can't be done right now. I'm not sure if that's valuable or not.
INx[y] = (DIRx[y] AND OUTx[y]) OR (NOT DIRx[y] AND (input from pin OR output from all other cogs whose same DIRx[y] is set))
OUTx[y] = whatever was previously written to OUTx[y]
These are fairly basic operations on the pins.
INx[y] just reads the state of the pin. If the voltage at the pin is lower than the threshold it reads a 0 otherwise a 1. The threshold is configurable and can also be a schmitt trigger or the difference to a second pin or an ADC bitstream. But there is no logical combination with the DIRx[y] or with the output of other cogs.
For sure the voltage level at the pin depends on the OUTx[y] if DIRx[y] is set in any cog. But the connected hardware at the pin can overdrive the OUTx[y] state, there are now very weak output modes configurable.
Andy
"...a compiler writer's job is supposed to be hard..."
CPU designers have assumed that philosophy may times in the past. "Let's make the architecture and instruction set super wizzy and leave the complexity to the compiler". That is what lead to the down fall of the Intel i860 and the Itanium, oh and the Intel 432 before that. In some of those cases (i860 for example) it was not only impossible for the compiler but very hard for the asembler programmer as well.
Watching the history of these things unfold over the years I all ways had be wondering why CPU designers and compiler writers don't talk to each other more. We might have had better optimized more efficient systems a long time ago if they did.
I have a friend who's fond of saying, once the hardware has been built, "The rest is just software!" Indeed.
-Phil
-Phil
Being able to use regular instructions on OUTx and DIRx allows multitasking to work, as long as everybody does atomic read-modify-write operations, like AND/OR/XOR/ADD/SUB/etc, and especially the new SETNIB/SETBYTE/SETWORD. If every task had to do a GETOUTx instruction, followed by something like SETOUTx, different tasks would wind up with different snapshots of the states, in time, and a big mess would occur. Having the pins mapped into register space is critical for multitasking to work.
INx is simply what is being seen at the pins, regardless of any states anyone's attempting to drive them to. It's the actual measured pin states.
Is there any reason we cannot use the same reg for PINx (INx/OUTx) with INx when used as the Source, and OUTx used as the Destination. Then all read-modify-write instructions would correctly (provided the P2 used this) use the OUTx register and not the pins.
Am Imissingsomething here ?
What if you want OUTx to be the source?