mention page number of vgbbd
[libreriscv.git] / docs / pinmux.mdwn
index 0a6b4197163f5b854eba99773d9635d099989f13..40f4e9097795801901fde45b11d0a5a4218845cb 100644 (file)
@@ -7,8 +7,11 @@ Links:
 * <https://ftp.libre-soc.org/Pin_Control_Subsystem_Overview.pdf>
 * <https://bugs.libre-soc.org/show_bug.cgi?id=50>
 * <https://bugs.libre-soc.org/show_bug.cgi?id=750>
+* <https://bugs.libre-soc.org/show_bug.cgi?id=762>
 * <https://git.libre-soc.org/?p=c4m-jtag.git;a=tree;hb=HEAD>
 * Extra info: [[/docs/pinmux/temp_pinmux_info]]
+* <https://git.libre-soc.org/?p=pinmux.git;a=blob;f=src/stage2.py> - Latest
+manual demo of pinmux generation
 
 Managing IO on an ASIC is nowhere near as simple as on an FPGA.
 An FPGA has built-in IO Pads, the wires terminate inside an
@@ -382,7 +385,7 @@ Signal, but the external peripheral (known as a PHY in Hardware terminology)
 
 Firstly: note that the Clock will, obviously, also need to be routed
 through JTAG Boundary Scan, because, after all, it is being received
-through just another ordinary IO Pad, after all.  Secondly: note thst
+through just another ordinary IO Pad, after all.  Secondly: note that
 if it didn't, then clock skew would occur for that peripheral because
 although the Data Wires went through JTAG Boundary Scan MUXes, the
 clock did not.  Clearly this would be a problem.
@@ -415,72 +418,136 @@ there will be a lag on the output data compared to the incoming
 (external) clock
 
 # Pinmux GPIO Block
-The following diagram is an example of a GPIO block with switchable banks and comes from the Ericson presentation on a GPIO architecture.
+
+The following diagram is an example of a mux'd GPIO block that comes from the
+Ericson presentation on a GPIO architecture.
 
 [[!img gpio-block.svg size="800x"]]
 
-The block we are developing is very similar, but is lacking some of configuration of the former (due to complexity and time constraints).
+## Our Pinmux Block
 
-## Diagram
-[[!img banked_gpio_block.jpg size="600x"]]
+The block we are developing is very similar, but is lacking some of
+configuration of the former (due to complexity and time constraints).
 
-*(Diagram is missing the "ie" signal as part of the bundle of signals given to the peripherals, will be updated later)*
+The implemented pinmux uses two sub-blocks:
 
-## 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.
+1. A Wishbone controlled N-GPIO block.
 
-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.
+1. N-port I/O multiplexer (for current usecase set to 4
+ports).
 
-### 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/ie (Not
-fully specified how this should be arranged yet)
+### Terminology
 
-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/ie 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)*
+For clearer explanation, the following definitions will be used in the text.
+As the documentation is actively being written, the experimental code may not
+adhere to these all the time.
+
+* Bank - A group of contiguous pins under a common name.
+* Pin - Bi-directional wire connecting to the chip's pads.
+* Function (pin) - A signal used by the peripheral.
+* Port - Bi-directional signal on the peripheral and pad sides of the
+multiplexer.
+* Muxwidth - Number of input ports to the multiplexers
+* PinMux - Multiplexer for connecting multiple peripheral functions to one IO
+pad.
+
+For example:
+
+A 128-pin chip has 4 banks N/S/E/W corresponding to the 4 sides of the chip.
+Each bank has 32 pins. Each pin can have up to 4 multiplexed functions, thus
+the multiplexer width for each pin is 4.
+
+### PinSpec Class
+
+* <https://git.libre-soc.org/?p=pinmux.git;a=blob;f=src/spec/base.py;h=c8fa2b09d650b1b7cfdb499bfe711a3ebaf5848b;hb=HEAD> PinSpec class
+defined here.
+
+PinSpec is a powerful construct designed to hold all the necessary information
+about the chip's banks. This includes:
+
+1. Number of banks
+1. Number of pins per each bank
+1. Peripherals present (UART, GPIO, I2C, etc.)
+1. Mux configuration for every pin (mux0: gpio, mux1: uart tx, etc.)
+1. Peripheral function signal type (out/in/bi)
+
+### Pinouts
+
+* <https://git.libre-soc.org/?p=pinmux.git;a=blob;f=src/spec/interfaces.py;h=f5ecf4817ba439b607a1909a4fcb6aa2589e2afd;hb=HEAD> Pinouts class
+defined here.
+
+The Pinspec class inherits from the Pinouts class, which allows to view the
+dictionaries containing bank names and pin information.
+
+* keys() - returns dict_key object of all the pins (summing all the banks) which
+is iterable
+* items() - a dict_key of pins, with each pin's mux information
+
+For example, PinSpec object 'ps' has one bank 'A' with 4 pins
+ps.keys() returns dict_keys([0, 1, 2, 3])
+ps.items() returns
+dict_items([(0, {0: ('GPIOA_A0', 'A'), 1: ('UART0_TX', 'A'),
+                                2: ('TWI0_SDA', 'A')}),
+                   (1, {0: ('GPIOA_A1', 'A'), 1: ('UART0_RX', 'A'),
+                                2: ('TWI0_SCL', 'A')}),
+                       (2, {0: ('GPIOA_A2', 'A')}), (3, {0: ('GPIOA_A3', 'A')})])
+
+### PinGen
+
+pinfunctions.py contains the "pinspec" list containing the Python functions
+which generate the necessary signals for gpio, uart, i2c, etc. (with IOType
+information). PinGen class uses "__call__" and "pinspec" to effectively create a
+Lambda function for generating specified peripheral signals.
+
+## The GPIO block 
+
+*NOTE !* - Need to change 'bank' terminology for the GPIO block in doc and code!
+
+[[!img n-gpio.svg size="600x"]]
+
+The 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.
+
+### Configuration Word
 
-## Configuration Word
 After a discussion with Luke on IRC (14th January 2022), new layout of the
-8-bit data word for configuring the GPIO (through CSR):
+8-bit data word for configuring the GPIO (through WB):
 
 * oe - Output Enable (see the Ericson presentation for the GPIO diagram)
-* ie - Input Enable
+* ie - Input Enable *(Not used, as IOPad only supports i/o/oe)*
 * 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)
+* bank[2:0] - Bank Select *(only 4 banks used, bank[2] used for JTAG chain)*
 
 ### 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.
+one data word. The number of GPIOs in one "row" is dependent on the WB data bus
+*width* and *granuality* (see Wishbone B4 spec, section 3.5 Data Organization
+for more details).
 
-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).
+If for example, the data bus is 64-bits wide and granuality is 8, eight GPIO
+configuration bytes - and thus eight GPIOs - can be configured in one go.
+To configure only certain GPIOs, the WB sel signal can be used (see next
+section).
 
-The diagram below shows the layout of the configuration byte, and how it fits
-within a 64-bit data word.
+*(NOTE: Currently the code doesn't support granuality higher than 8)*
 
-[[!img gpio_csr_example.jpg size="600x"]]
+The diagram below shows the layout of the configuration byte.
+
+[[!img gpio-config-word.jpg 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 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?)
+0-7 are accessed via address 0, whereas GPIOs 8-15 are accessed by address 1.
+
+### Example Memory Map
 
-## Example Memory Map
-[[!img gpio_memory_example.jpg size="600x"]]
+[[!img gpio-mem-layout.jpg 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.
@@ -500,51 +567,113 @@ The 32-bit on the other hand has four address rows, and so will take four write
 * 0x02 - Configure GPIOs  8-11 - requires 4-bit `sel` one bit per GPIO
 * 0x03 - Configure GPIOs 12-15 - requires 4-bit `sel` one bit per GPIO
 
-## Combining JTAG BS Chain and Pinmux (In Progress)
-[[!img io_mux_bank_planning.JPG size="600x"]]
+Here is the pseudocode for reading the GPIO
+data structs:
+
+    read_bytes = []
+    for i in range(len(sel)):
+        GPIO_num = adr*len(sel)+i
+        if sel[i]:
+            read_bytes.append(GPIO[GPIO_num])
+        else:
+            read_bytes.append(Const(0, 8))
+    if not wen:
+        dat_r.eq(Cat(read_bytes))
+
+and for writing, slightly different style:
+
+    if wen:
+        write_bytes = []
+        for i in range(len(sel)):
+            GPIO_num = adr*len(sel)+i
+            write_byte = dat_w.bit_select(i*8, 8)
+            if sel[i]:
+                GPIO[GPIO_num].eq(write_byte)
+
+As explained in this video <https://m.youtube.com/watch?v=Pf6gmDQnw_4>
+if each GPIO is mapped to one single byte, and it is assumed that
+the `sel` lines are enough to **always** give byte-level read/write
+then the GPIO number *becomes* the Memory-mapped byte number, hence
+the use of `len(sel)` above.  `len(dat_r)//8` would do as well
+because these should be equal.
+
+
+## The IO Mux block
+
+[[!img iomux-4bank.svg size="600x"]]
+
+This block is an N-to-1 (4-port shown above) mux and it simultaneously connects:
+
+* o/oe signals from one of N peripheral ports, to the pad output port
+
+* i pad port signal to one of N peripheral ports (the rest being set to 0).
+
+The block is then used in a higher-level pinmux block, and instantiated for each
+pin.
+
+## Combined Block
+
+*NOTE !* - Need to change 'bank' terminology for the GPIO block in doc and code!
+
+[[!img pinmux-1pin.svg size="600x"]]
+
+The GPIO and IOMux blocks are combined in a single block called the
+Pinmux block.
+
+By default, bank 0 is hard-wired to the 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.
+
+Bank select, allows to switch over the control of the IO pad 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)*
+
+### 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
+(whether ie should be routed out is not finalised yet)
+
+
+### Adding JTAG BS Chain to the Pinmux block (In Progress)
 
 The JTAG BS chain need to have access to the bank select bits, to allow
 selecting different peripherals during testing. At the same time, JTAG may
 also require access to the WB bus to access GPIO configuration options
 not available to bank 1/2/3 peripherals.
 
-### Proposal
-TODO: REWORK BASED ON GPIO JTAG DIAGRAMS BELOW
 The proposed JTAG BS chain is as follows:
 
-* Between each peripheral and GPIO block, add a JTAG BS chain. For example
-the I2C SDA line will have core o/oe/i/ie, and from JTAG the pad o/oe/i/ie will
-connect to the GPIO block's ports 1-3.
-* Provide a test port for the GPIO block that gives full access to configuration
-(o/oe/i/ie/puen/pden) and bank select. Only allow full JTAG configuration *IF*
-ban select bit 2 is set!
-* No JTAG chain between WB bus and GPIO port 0 input *(not sure what to do for
-this, or whether it is even needed)*.
+* Connect puen/pden/bank from GPIO block to the IOMux through JTAG BS chain.
+* Connect the i/o/oe pad port from IOMux via JTAG BS chain.
+* (?) Test port for configuring GPIO without WB? - utilising bank bit 2?
+* (?) Way to drive WB via JTAG?
 
 Such a setup would allow the JTAG chain to control the bank select when testing
 connectivity of the peripherals, as well as give full control to the GPIO
 configuration when bank select bit 2 is set.
 
-For the purposes of muxing peripherals, bank select bit 2 is ignored. This means
-that even if JTAG is handed over full control, the peripheral is still connected
-to the GPIO block (via the BS chain).
+For the purposes of muxing peripherals, bank select bit 2 is ignored. This
+means that even if JTAG is handed over full control, the peripheral is
+still connected to the GPIO block (via the BS chain).
 
 Signals for various ports:
 
-* WB bus or Periph0: WB data read, data write, address, cyc, stb, ack
-* Periph1/2/3: o,oe,i,ie (puen/pden are only controlled by WB, test port, or
-fixed by functionality)
-* Test port: bank_select[2:0], o,oe,i,ie,puen,pden. In addition, internal
+* WB bus or Periph0: WB data read, data write, address, sel, cyc, stb, ack
+* Periph1/2/3: o,oe,i (puen/pden are only controlled by WB, test port, or
+fixed by functionality; ie not used yet)
+* (?) Test port: bank[2:0], o,oe,i,ie,puen,pden. In addition, internal
 address to access individual GPIOs will be available (this will consist of a
 few bits, as more than 16 GPIOs per block is likely to be to big).
 
-As you can see by the above list, the GPIO block is becoming quite a complex
+As you can see by the above list, the pinmux block is becoming quite a complex
 beast. If there are suggestions to simplify or reduce some of the signals,
-that will be helpful.*
-
-The diagrams below show 1-bit GPIO connectivity, as well as the 4-bit case.
+that will be helpful.
 
-[[!img gpio_jtag_1bit.jpg size="600x"]]
+The diagrams above showed 1-bit GPIO connectivity. Below you'll find the
+4-bit case *(NOT IMPLEMENTED YET)*.
 
 [[!img gpio_jtag_4bit.jpg size="600x"]]