@@ -27,150 +27,14 @@ framework.
2727 Glasgow's embeddable APIs, they may change underneath you in future
2828 versions of Glasgow!
2929
30- Getting started with Assemblies
31- -------------------------------
30+ This section documents Glasgow's embeddable APIs in a tutorial fashion.
3231
33- The core concept of the Glasgow embeddable API is the Assembly, accessible
34- through the ``glasgow.hardware.assembly.HardwareAssembly `` class
35- [#other_assemblies ]_. An Assembly represents a configuration of gateware
36- for a specific Glasgow, including all gateware necessary to interface with
37- the host software, and including all pipes and registers that the gateware
38- has access to.
32+ .. toctree ::
3933
40- Because each Assembly object is associated with a specific Glasgow, in order
41- to begin working with an Assembly, you will need to instantiate it with
42- reference to an attached device; you can use
43- ``HardwareAssembly.find_device() `` to locate a device, and build an Assembly
44- based on it. An Assembly has ``.start() `` and ``.stop() `` methods to
45- synthesize it and download it to the device, but for convenience, it also
46- implements the async context manager protocol to connect to the device.
47- `The following skeleton of a program
48- <../_static/examples/assembly-skeleton.py> `_ will search for a Glasgow,
49- create an empty Assembly targetted to it, and then download it to the
50- attached Glasgow:
34+ getting-started-with-assemblies
35+ adding-an-applet
36+ adding-your-own-logic
37+ using-registers
38+ using-pins
39+ using-pipes
5140
52- .. literalinclude :: ../_static/examples/assembly-skeleton.py
53- :language: python
54-
55- .. note ::
56-
57- Most users that have `followed the recommended installation instructions
58- <initial-setup> `__ will have Glasgow already installed via ``pipx ``.
59- Usually, this is an important part of making Glasgow easy-to-install --
60- but ``pipx `` is designed for standalone packages that are not meant to
61- be imported! Installing Glasgow outside of ``pipx `` in your own
62- environment is outside of the scope of this document, but to run these
63- samples, you might consider running inside of the Glasgow venv that
64- ``pipx `` already set up for you. For many users, doing so will take the
65- form:
66-
67- .. code :: console
68-
69- $ ~/.local/pipx/venvs/glasgow/bin/python3 assembly-skeleton.py
70-
71- Glasgow should respond:
72-
73- .. code :: console
74-
75- DEBUG:asyncio:Using selector: EpollSelector
76- DEBUG:glasgow.hardware.device:found revC3 device with serial C3-20240518T200308Z
77- DEBUG:glasgow.hardware.toolchain:using toolchain 'builtin' (yosys 0.61.0.0.post1073, nextpnr-ice40 0.9.0.0.post686, icepack 0.9.0.0.post686)
78- INFO:glasgow.hardware.device:generating bitstream ID ae08e17ee60fe32bc1165e0c59410d57
79- DEBUG:glasgow.hardware.build_plan:bitstream ID ae08e17ee60fe32bc1165e0c59410d57 is not cached, executing build
80- INFO:root:Glasgow is alive!
81-
82- Adding an applet to an Assembly
83- -------------------------------
84-
85- The most common straightforward of an Assembly is to add `existing Glasgow
86- applets <../applets> `_ to it. (Indeed, internally, the "new-style" Glasgow
87- ``AppletV2 `` subsystem is based on Assemblies.) Many Glasgow applets were
88- designed to be used with :ref: `the REPL <repl-script >`, and expose a
89- programmatic interface to be used interactively; you can also use these from
90- your own programs. In this section, we will instantiate a pair of UARTs,
91- with the interface as described in :ref: `the UART REPL example <repl-uart >`.
92-
93- .. note ::
94-
95- Not all Glasgow applets have been ported to the "new-style" API yet.
96- (Applets that haven't instead derive from ``GlasgowApplet ``.) If
97- you find one that hasn't yet been ported, the Glasgow project will
98- gladly accept your help!
99-
100- Most "new-style" applets include an ``Interface `` module that encapsulates
101- their digital logic, and host-side logic to act on it. The UART is no
102- exception; it is implemented as
103- ``glasgow.applet.interface.uart.UARTInterface ``. In this example, we
104- instantiate two ``UARTInterface ``\s , and use them to talk to each other
105- through Glasgow's external I/O pins. Most of the example is relatively
106- self-explanatory, but it is worth considering:
107-
108- * Instantiating the ``Interface `` -- and, indeed, any module that adds logic
109- into the Assembly -- must be done before the Assembly is started. In our
110- examples, as described above, the Assembly is started implicitly by the
111- ``async with `` block, so we attach the ``UARTInterface `` to the Assembly
112- before we enter that block.
113- * Conversely, interacting with the ``Interface `` can happen only after
114- synthesis is complete and the gateware is running to Glasgow. Many
115- applets will implement configuration settings (in this example, setting
116- the baud rate on the UART peripheral) as dynamic register writes; these
117- qualify as interactions, for our purposes! So we ``set_baud `` on each of
118- the ``UARTInterface ``\s inside of the ``async with `` block, after the
119- Assembly has been started.
120- * In this example, we want to run the transmit and receive tasks in parallel
121- (the Glasgow system has enough buffer for this trivial case, even if we do
122- not, but it is educational to demonstrate how to do it!). Many
123- applications will want to operate in a "straight line" -- there is no
124- inherent requirement that ``uart_b.read(...) `` must be wrapped in an
125- ``asyncio.create_task ``, and indeed, you could just as well do something
126- like ``result = await uart_b.read(...) `` to immediately block on an
127- interaction with an ``Interface ``. (This is also demonstrated in the
128- ``.set_baud `` calls.)
129-
130- `Below, we give a program <../_static/examples/assembly-applets.py >`_ that
131- instantiates two unidirectional UARTs, sets them each to 115200 baud, and
132- transmits some bytes from one to the other. In order to run this program,
133- remember to connect a flying lead from pin A0 to pin B0!
134-
135- .. literalinclude :: ../_static/examples/assembly-applets.py
136- :language: python
137-
138- Glasgow should respond:
139-
140- .. code :: console
141-
142- DEBUG:asyncio:Using selector: EpollSelector
143- DEBUG:glasgow.hardware.device:found revC3 device with serial C3-20240518T200308Z
144- DEBUG:glasgow.hardware.assembly:setting port A voltage to 3.30 V
145- DEBUG:glasgow.hardware.assembly:setting port B voltage to 3.30 V
146- DEBUG:glasgow.hardware.assembly:assigning pin tx[0] to A0
147- DEBUG:glasgow.hardware.assembly:assigning pin rx[0] to B0
148- DEBUG:glasgow.hardware.assembly:pulling pin B0 high
149- DEBUG:glasgow.hardware.toolchain:using toolchain 'builtin' (yosys 0.61.0.0.post1073, nextpnr-ice40 0.9.0.0.post686, icepack 0.9.0.0.post686)
150- INFO:glasgow.hardware.device:device already has bitstream ID 083ca04cc3edb43de9ba63d35bec38fc
151- INFO:glasgow.hardware.assembly:port A voltage set to 3.3 V
152- INFO:glasgow.hardware.assembly:port B voltage set to 3.3 V
153- INFO:root:assembly has started
154- INFO:root:uart_a transmitted data, waiting for received data
155- INFO:root:uart_b received data b'Hello, Glasgow!'
156-
157- Putting your own logic into an Assembly
158- ---------------------------------------
159-
160- Using registers to connect to logic
161- -----------------------------------
162-
163- Connecting to pins
164- ------------------
165-
166- Using pipes to transfer data
167- ----------------------------
168-
169- .. [#other_assemblies ]
170-
171- There are other Assemblies in Glasgow; for instance, if you
172- wish to develop gateware without hardware on your desk at all, you might
173- consider a ``SimulationAssembly ``. All Assemblies derive from the
174- ``AbstractAssembly `` base class, which is the type that you will most
175- commonly find passed around in Glasgow's internals. These types of
176- Assemblies are out of scope for this document!
0 commit comments