Port B thoughts - Do we need INB/OUTB/DIRB ?
Cluso99
Posts: 18,069
I have wondered if Port B needs its own registers?
By this I mean, does a cog require access to all 64 I/O pins at the same time, or would a swap instruction/mechanism be acceptable?
By utilising a swap instruction, we would only have access to a single 32bit I/O bank per cog. This would remove the requirement to use the WC modifier on the WAITPEQ/PNE instructions (simplifies obex objects). Perhaps the coginit/cognew could add a bit to select the I/O bank for the cog, meaning all existing objects would work without change, and access either bank at start time.
This also frees those 3 special registers for other use - such as the MUL instruction(s) or uart/etc extensions.
Your thoughts ???
By this I mean, does a cog require access to all 64 I/O pins at the same time, or would a swap instruction/mechanism be acceptable?
By utilising a swap instruction, we would only have access to a single 32bit I/O bank per cog. This would remove the requirement to use the WC modifier on the WAITPEQ/PNE instructions (simplifies obex objects). Perhaps the coginit/cognew could add a bit to select the I/O bank for the cog, meaning all existing objects would work without change, and access either bank at start time.
This also frees those 3 special registers for other use - such as the MUL instruction(s) or uart/etc extensions.
Your thoughts ???
Comments
INA/INB could utilise the shadow register to be used as a mask when reading INA/INB.
A write to INA of a mask value would cause any subsequent read of INA to be masked with the shadow INA.
Regularly we need to mask the read bits, so this would save an instruction, but more importantly speed up bit reading.
The implementation would be a MOV INA,<mask> where the mask would be ANDed with INA for any subsequent INA reads.
That's a really good idea!
Now once we go beyond 64 I/O's, I'd make it assignable - so two ports out out N accessible without having to map ports.
Imagine a big FPGA with 256 I/O's
MAPIO A|B, Port0|...|Port7
I was more thinking about just a P1B (a real IC, not FPGA) where compatibility is the prime objective, and there would not be more than 64 I/O.
Does this change your thinking???
pik33,
Again, only 64 I/O for what I am thinking. I think your work is for a more specific case using an FPGA.
Does this therefore make sense???
All,
I can see other uses for the free'd up INB/OUTB/DIRB while keeping P1 compatibility. The removal of VGA also free's up a few registers too.
These could be used to add general purpose UARTs, more Counters, etc. I mentioned these ideas in rogloh's push/pop thread.
Love it! I do masking all the time to kill unwanted bits from I/O and it does waste cycles in those tight loops. The DIRA register gives you output masking, but we don't have any input masking.
Actually we could probably have both variants, using WC, WZ, NR modifiers. Using NR might make a nice choice in conjunction with WZ and WC combinations to allow 4 different possible destinations for the write to INA. Non NR forms of writing to INA just result in regular shadow RAM behaviour so DJNZ loops using INA as the temporary counter still work. NR forms of INA writes would indicate new behavior.
I also like the idea of having an inbuilt shifter, so we could choose which nibble(s), byte(s) or word of the long we return. The ALU might be leveraged to allow this. One of the 4 combinations of destinations of INA writes might choose the shifter/byte selector.
eg. How about this?
PS. the last reserved case MOV INA, xxx NR WC WZ could actually be used as an OR mask if you needed any input bits setup as 1 instead of cleared to 0. So an example after configuring an AND mask and an OR mask for INA would be:
Tthis is an excellent idea that should be implemented regardless of the INB question.
Having said that... I like the idea of masking inputs, and the shadow INA is a great place for the AND mask... and I don't think this would break existing software.
Fantastic extension and by not using the shadow register, these registers can be held in logic rather than the cog ram which requires clock cycles (ie extend the instructions) to access.
It so means that we can initially preset the AND register to all F's and the OR register to all 0's.
I suggest the shifter S register be in the form..
0000_sssss
sssss = ROR shift count
A read of INA would then...
1. ROR
2. AND
3. OR
return the result.
We could leverage the upper 0000 bits to select the 32-bit port block.
The same could apply to OUTA NR xx,xx
And the INA and OUTA/DIRA ports could now be separate 32-bit port blocks. eg INA (read) is port A and write is port B, etc.
Bill,
Absolutely, we need to retain separate INx/DIRx/OUTx registers. But with the above scheme, why do we require INB/DIRB/OUTB registers???
Since there is really no compatibility issues, anything current objects would work with less changes to address different ports using just INA/DIRA/OUTA registers remapped to any 32-bit port. Potentially this could give us 3 freed registers for either more special functions (uart, counter, etc) or SP, PC, LR ???
The result of a simple suggestion to use the write to INA for a mask has resulted in a
ROR/AND/OR within a read INA and write INA with no clock penalties.
How often do we do this for I/O? Almost always!!!
It will be a biggie speed improvement and also some code/space reduction.
Collaboration at Work (tm)
Can you sneak in a USB style Differential-IN as well ?
LOL. It's actually not beyond the realms of possibility....
We have up to 4 longs we can configure for controlling INA settings using NR, WC, WZ approaches mentioned above.
The AND mask needs 32 bits.
The OR mask needs 32 bits.
The proposed INA shifter only needs 5 bits, so there are 27 bits remaining in that same configuration long which we can use for different purposes such as source port bank selection and possibly the USB thing too. Bank selection might only need a small number of bits, e.g, another 5. That would then give us up to 32 banks or 1024 pins!
For convenience we should probably try to align the various configuration fields to traditional I/D/S bit field positions within the long to simplify its construction dynamically. Not essential but handy that way.
We could readily use these extra bits remaining to optionally nominate 2 INA pin bits (adjacent or potentially even arbitrary for full flexibility) for computing a differential result and copying this into some final INA bit position allowing the Prop to read it. That's simple enough on its own, but we can actually go quite a bit further have one of the source port banks we can map to INA be a "USB decoder" bank. And this is what feeds our INA, even doing the serial to parallel & bit destuffing for us so the prop just has to work at the byte rate instead :cool:. There's more to it of course, this is just a basic idea for teasing our minds with...I am feeling generous today.
Hoping we don't get too sidetracked by USB right now, but if there is a basic plan for allowing it to interoperate with this general scheme down the line that would be a good thing.
There is still another potential configuration long free with INA we can reserve for unknown future extensions. Plus more again available for DIRA/OUTA output port settings using the same programming methods with NR. There's heaps of scope for us to play here.
I think I have come up with a reasonable use for the 4th available INA configuration long mentioned previously. We can use it to hold an address we write such that the next read(s) from INA gets the result of reading from that address in some peripheral address space used within the FPGA. This gives us a nice simple and consistent way to expand to a much larger number of internal registers/external addresses via indirect addressing. It would also be a great way for addressing external SRAM using up to 32 bit addresses in just two instructions.
So we could ultimately allow for something like this:
For example, to read SRAM attached to the FPGA, you just setup the address and then just read INA back again, really simple.
or to read from some internal known I/O peripheral addresses you could use smaller range using immediate constant so you don't burn extra COG registers
We could use similar technique for addressing the output data writes to OUTA, or use this same configured address in INA for both purposes, reads and writes.
One potential definition of this so called source_bank_shift configuration register could be something like this... (just an example)
BBBBSSSSS_xxxx_xxxxPPPPP_xxxKKKKKK
where
BBBB = I/O source bank selection (see below for example)
SSSSS = shift amount in bits before you AND & OR with masks
PPPPP = I/O source pin
KKKKKK = serial clock source pin/counter/secondary input pin for differential use
x = reserved bits, could be useful for other features such as nominating word size, endianess etc
BBBB
0 = normal INA pin group of 32 bits
1 = secondary INA pin group of 32 bits
2 = tertiary " " " "
..
12 = serial to parallel conversion data source, inputting the defined pin and accumulating, bit 31 of INA read could indicate new serial data byte/word has been latched and is ready
13 = USB data source (differential input mode, may do destuffing etc)
14 = external bus data source (no address autoincrement)
15 = external bus data source (with address autoincrement, allows 32 bit memory reads on every clock!)
Anyone else got some ideas on this...?
Sounds good, the default (0000?) is the standard Port, and being able to MAP i/o to FPGA resource is going to be an an important feature of P1V.
certainly some good ideas there. Need to think about it further.