vector. The TDO and TDI data is compared using asserts.
NOTE: Currently the last test case's TDO data does not match the actual
-core/pad signal values. Not sure why the returned TDO is icorrect, however
+core/pad signal values. Not sure why the returned TDO is incorrect, however
the signals are correct.
-# Simple GPIO extension
-## Explanation
-The code from soc repo was taken and is being extended to support full gpio
-capability.
-
-The simple GPIO module has a parameter specifying the number of I/O lines.
-For configuration, oe and bank select (capped at 4-bits or 16 banks, probably
-plenty for now) are available.
+# Pinmux GPIO Block
+## Diagram
+[[!img banked_gpio_block.png size="600x"]]
-For simplicity, only one bank select parameter for the *WHOLE* GPIO block was
-implemented (I wasn't able to get an array of signals working with the list()
-function).
+## Explanation
+The simple GPIO module is multi-GPIO block integral to the pinmux system.
+To make the block flexible, it has a variable number of of I/Os based on an
+input parameter.
-For separate access of outputs or input registers, the two bits of the second
-byte of the address have been used.
-As a result this simple block is limited to 256 GPIOs (which is probably fine).
+By default, the block is memory-mapped WB bus GPIO. The CPU
+core can just write the configuration word to the GPIO row address. From this
+perspective, it is no different to a conventional GPIO block.
-## Address map
+### Bank Select Options
+* bank 0 - WB bus has full control (GPIO peripheral)
+* bank 1,2,3 - WB bus only controls puen/pden, periphal gets o/oe/i (Not fully
+specified how this should be arranged yet)
-* 0x0Y - Access (R/W) CSR of GPIO #Y
+Bank select however, allows to switch over the control of the GPIO block to
+another peripheral. The peripheral will be given sole connectivity to the
+o/oe/i signals, while additional parameters such as pull up/down will either
+be automatically configured (as the case for I2C), or will be configurable
+via the WB bus. *(This has not been implemented yet, so open to discussion)*
## Configuration Word
After a discussion with Luke on IRC (14th January 21), new layout of the 8-bit
data word for configuring the GPIO (through CSR):
-* bank_select[2:0] IO | PDEN PUEN IE OE
+* oe - Output Enable (see the Ericson presentation for the GPIO diagram)
+* ie - Input Enable
+* puen - Pull-Up resistor enable
+* pden - Pull-Down resistor enable
+* i/o - When configured as output (oe set), this bit sets/clears output. When
+configured as input, shows the current state of input (read-only)
+* bank_sel[2:0] - Bank Select (only 4 banks used)
-(This layout is not fixed in stone, and is trivial to update if there are
-better proposals.)
+### Simultaneous/Packed Configuration
+To make the configuration more efficient, multiple GPIOs can be configured with
+one data word. The number of GPIOs in one "row" is dependent on the width of the
+WB data bus.
-* Bank select switches the peripheral that gets to control the GPIO block.
-By default, bank 0 allows full configuration through the Wishbone Bus (from the CPU looks like memory-mapped IO).
-<--- TODO: create table of bank select options!
-* PDEN and PUEN are pull-up/down enables.
-* IE and OE are input/output path enables respectively (see the Ericson
-presentation for the GPIO diagram).
-* IO either shows the output state (if OE set), or the value of the input
-(IE set). To change the output value, write to this bit.
+If for example, the data bus is 64-bits wide, eight GPIO configuration bytes -
+and thus eight GPIOs - are configured in one go. There is no way to specify
+which GPIO in a row is configured, so the programmer has to keep the current
+state of the configuration as part of the code (essentially a shadow register).
-## Planned Improvement
-A planned improvement is to fit multiple GPIO configurations within a single
-WB transaction. For a 64-bit wide data bus, 8 GPIOs could be configured
-simultaneously.
+The diagram below shows the layout of the configuration byte, and how it fits
+within a 64-bit data word.
+
+[[!img gpio_csr_example.png size="600x"]]
If the block is created with more GPIOs than can fit in a single data word,
the next set of GPIOs can be accessed by incrementing the address.
-For example, if 16 GPIOs are instantiated, GPIOs 0-7 are accessed via
-address 0, whereas GPIOs 8-15 are accessed by address 8
+For example, if 16 GPIOs are instantiated and 64-bit data bus is used, GPIOs
+0-7 are accessed via address 0, whereas GPIOs 8-15 are accessed by address 8
(TODO: DOES ADDRESS COUNT WORDS OR BYTES?)
-## Sim commands for single GPIO
-* gpio_configure - Set the CSR (only oe and bank select at the moment).
-* gpio_rd_csr - Read the current CSR state and parse (TODO).
+## Example Memory Map
+[[!img gpio_memory_example.png size="600x"]]
+
+The diagrams above show the difference in memory layout between 16-GPIO block implemented with 64-bit and 32-bit WB data buses. The 64-bit case shows there are two rows with eight GPIOs in each, and it will take two writes (assuming simple WB write) to completely configure all 16 GPIOs. The 32-bit on the other hand has four address rows, and so will take four write transactions.
+
+64-bit:
+
+* 0x00 - Configure GPIOs 0-7
+* 0x01 - Configure GPIOs 8-15
+
+32-bit:
+
+* 0x00 - Configure GPIOs 0-3
+* 0x01 - Configure GPIOs 4-7
+* 0x02 - Configure GPIOs 8-11
+* 0x03 - Configure GPIOs 12-15
+
+## Sim commands for single GPIO - IN PROGRESS
+* gpio_config - Set the CSR (only the first GPIO is currently configured).
+* gpio_rd_csr - Read the current CSR state and parse (only first GPIO).
* gpio_rd_input - Read the current input.
* gpio_set_out - Set the output to given value.
* gpio_set_in_pad - Set the input signals for the block (external,
* Set GPIO outputs sequentially
* Set external GPIO inputs sequentially and clear
-No asserts have been added yet as I was still developing the logic and the sim
-functions.