How can I make a 16-bit shift register without UDBs?
This Knowledge Base Article (KBA) is an extension of KBA219861 for an 8-bit shift register.
Many PSoC® 4 and PSoC 6 devices implement a Smart IO block. The Smart IO block includes eight LUTs and data unit (DU). Each LUT can be configured as combinatorial or registered logic. The DU can implement many functions: counters, data matching, and shift register. The DU is shown in PSoC Creator version 4.1 and later; it is not enabled in earlier versions.
The following steps illustrate an example of an externally supplied 20 kHz square wave being delayed by a fixed amount of 16 µsec:
1. Create a new project in PSoC Creator and place the source, Smart IO Components, and clock. Set the clock to 1.0 MHz.
2. Enable Smart IO. By default, Smart IO is not configured; inputs and outputs on the block are not displayed. When the Smart IO configuration screen opens, the General tab appears by default; In this tab, connections and all parameters are blank. Change any one of the input fields of the DU to enable the configuration.
Now, the DU is highlighted indicating that it is in use and the Data Unit tab is enabled.
3. Go to the Data Unit tab. The default logical block in schematic appears on the lower right.
4. Click the Opcode drop-down arrow, select Shift Right, and click Apply. The Shift Right block appears on the lower right.
5. Set the length (size) of the shift register and click Apply.
6. Go to the General tab. Click the Clock drop-down arrow and select Divided clock (Active) from the drop-down list.
7. Select inputs to the Shift Right function:
This is the Asynchronous load function and must be set to 0. Set TR0 by selecting Constant 0 from the drop-down list.
This is the Enable function and must be set to 1. Set TR1 by selecting Constant 1 from the drop-down list.
This is the input data to the shift register. The input to TR2 should be the output from one of the LUTs. TR2 cannot be directly connected to a data input or GPIO.
8. Select a suitable LUT. In this example, select LUT0.
An error code indicates that the input is undefined.
The input to LUT0 can be any of the data lines or half of the GPIOs. In this example, select gpio2 for each LUT0 Input. Then, click the connect bubble, on the lines, to set all three LUT0 inputs gpio2. Here, you select GPIO2 because GPIO0 and GPIO1 are used for programming and debugging and are unavailable for Smart IO connection.
An error is displayed because the GPIO is not configured.
9. Set GPIO2 to Input (Async).
The shift register input connections are now configured.
10. In this example, LUT0 must now be programmed as a follower or buffer. Go to the LUT0 tab. Select Combinatorial from the Mode drop-down list.
Inputs 0, 1, and 2 are connected to the same source, GPIO0, so the Out encoding could follow any one of the inputs - 1, 1, 1 is convenient.
11. Route the DU output to a GPIO. The DU output does not connect directly to a GPIO, so it must be routed through another LUT. Each LUT output is connected to a single GPIO. Since GPIO0 and GPIO1 are used by debug and programming pins and GPIO2 is already used as the input, the next available pin is GPIO3. Select Output from the GPIO3 drop-down list.
12. Select LUT3, the only LUT that routes to GPIO3. The DU output connects only to Input 0 of each of the LUTs. Set LUT3 Input 0 to DU. LUT3 Input 1 and Input 2 must be connected. Since GPIO2 is already in use, it can be used for the connection.
13. Program LUT3 as a follower, but not in the same manner as LUT0. The DU connects only to Input0 of any of the LUTs, so the combinatorial logic must follow Input0.
Click OK. The General tab appears. Note that the Smart IO routing is complete.
14. Complete Smart IO connections. Click OK again. The schematic view returns. Adjust the position of the external pins to line with the GPIOs used. Adjust clock connection to utilize the same source as the PWM. For this test example, set PWM period to 49 and compare with 24.
15. Generate code. The source code is simple:
Build and program.
16. Test the shift register by providing an input and measure the output.
Connect Source_Out on P1.0 to SR_In on P0.2 (This is done here with a jumper wire on a dev kit):
Trace 1 is Source_Out -- SR_In
Trace 2 is SR_Out
The cursors tell the tale; the waveform is delayed by 8 µsec.
The above implements the first half of the 16-bit shift register, the remaining implementation will be in LUTs. The LUTs can be configured into two different registered forms.
In the input-registered form, the output can follow Input 0 and Input 1, even though Input 2 is registered. Since there is no easy way to hold Input 0 and Input 1 to a fixed value, it is more direct to use the output-registered form. Inputs 0, 1, and 2 are set to form a follower as done with the 8-bit shift register example.
17. Configure LUT0. The input from GPIO is into LUT0. For LUT0, select Registered output from the Mode drop-down list. The combinatorial decode remains the same. The look in the General tab and the connections do not change.
18. Build and program. The scope now shows a 9 µsec delay, 8 µsec from the DU and 1 µsec each from LUT0. The trace references are the same as in the 8-bit shift register example.
19. Connect the LUTs in sequence.
The signal chain (with all of that trace crossing) is:
LUT7 then back to
and out on GPIO3.
All LUTs except LUT1 are set in the same way: Registered output and output high when Input 0, 1, and 2 are all logic 1. Input 0 of LUT1 is the only one that can be connected to DU. So, the logic must follow Input 0.
Many routings are possible. This routing is chosen to preserve the input and output on GPIO2 and GPIO3 respectively, as done in the 8-bit shift register example.
20. Click Hide routing matrix to view a simplified routing with lesser distraction.
21. Build and program using the same two-line code segment.
22. Measure the result. The scope shows a 16 µsec delay. Trace references are the same as in the 8-bit and 10-bit shift register examples.