Skip to content

Commit 15abbe0

Browse files
committed
Added software API documentation
1 parent 6367aae commit 15abbe0

File tree

7 files changed

+374
-0
lines changed

7 files changed

+374
-0
lines changed

API/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
_build
2+

API/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# PHANTOM Linux Userland IP Interface
2+
3+
This documentation describes the interface that software applications in the PHANTOM Linux distribution can use to interact with IP cores that are programmed on the FPGA.
4+
5+
6+
7+
## Building
8+
9+
To build the documentation you should first install [Sphinx](http://www.sphinx-doc.org/en/stable/). Then execute:
10+
11+
./build.sh

API/build.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#!/bin/sh
2+
3+
sphinx-build -M latexpdf . _build
4+
5+
cp _build/latex/PHANTOM.pdf ./phantom_software_ip_api.pdf

API/conf.py

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
4+
5+
extensions = ['sphinx.ext.autodoc']
6+
7+
8+
templates_path = ['_templates']
9+
source_suffix = '.rst'
10+
master_doc = 'index'
11+
12+
# General information about the project.
13+
project = 'PHANTOM Linux API'
14+
copyright = '2017, Ian Gray'
15+
author = 'University of York'
16+
17+
18+
version = '1.0'
19+
release = '1.0'
20+
language = None
21+
22+
23+
# List of patterns, relative to source directory, that match files and
24+
# directories to ignore when looking for source files.
25+
# This patterns also effect to html_static_path and html_extra_path
26+
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
27+
28+
# The name of the Pygments (syntax highlighting) style to use.
29+
pygments_style = 'sphinx'
30+
31+
# If true, `todo` and `todoList` produce output, else they produce nothing.
32+
todo_include_todos = False
33+
34+
primary_domain = "c"
35+
36+
37+
# -- Options for HTML output ----------------------------------------------
38+
39+
# The theme to use for HTML and HTML Help pages. See the documentation for
40+
# a list of builtin themes.
41+
#
42+
html_theme = 'alabaster'
43+
html_theme_options = {}
44+
html_static_path = ['_static']
45+
46+
47+
# -- Options for HTMLHelp output ------------------------------------------
48+
49+
# Output file base name for HTML help builder.
50+
htmlhelp_basename = 'PHANTOMdoc'
51+
52+
53+
# -- Options for LaTeX output ---------------------------------------------
54+
55+
latex_elements = {
56+
'papersize': 'a4paper',
57+
'pointsize': '10pt',
58+
59+
# Additional stuff for the LaTeX preamble.
60+
#
61+
# 'preamble': '',
62+
63+
# Latex figure (float) alignment
64+
#
65+
# 'figure_align': 'htbp',
66+
}
67+
68+
# Grouping the document tree into LaTeX files. List of tuples
69+
# (source start file, target name, title,
70+
# author, documentclass [howto, manual, or own class]).
71+
latex_documents = [
72+
(master_doc, 'PHANTOM.tex', 'PHANTOM Documentation',
73+
'University of York', 'manual'),
74+
]
75+
76+
77+
# -- Options for manual page output ---------------------------------------
78+
79+
# One entry per manual page. List of tuples
80+
# (source start file, name, description, authors, manual section).
81+
man_pages = [
82+
(master_doc, 'phantom', 'PHANTOM Documentation',
83+
[author], 1)
84+
]
85+
86+
87+
# -- Options for Texinfo output -------------------------------------------
88+
89+
# Grouping the document tree into Texinfo files. List of tuples
90+
# (source start file, target name, title, author,
91+
# dir menu entry, description, category)
92+
texinfo_documents = [
93+
(master_doc, 'PHANTOM', 'PHANTOM Documentation',
94+
author, 'PHANTOM', 'One line description of project.',
95+
'Miscellaneous'),
96+
]
97+
98+
99+

API/index.rst

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
.. PHANTOM documentation master file, created by
2+
sphinx-quickstart on Thu May 4 10:49:08 2017.
3+
You can adapt this file completely to your liking, but it should at least
4+
contain the root `toctree` directive.
5+
6+
7+
PHANTOM API
8+
=================
9+
10+
.. toctree::
11+
:maxdepth: 2
12+
:caption: Contents:
13+
14+
ipcores
15+
16+
.. Indices and tables
17+
==================
18+
19+
* :ref:`genindex`
20+
* :ref:`search`

API/ipcores.rst

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
Accessing IP Cores from Linux
2+
=============================
3+
4+
PHANTOM FPGA IP cores are accessed by Linux userland software through the following API.
5+
6+
7+
Common Definitions
8+
------------------------
9+
10+
.. macro:: PHANTOM_OK
11+
12+
Returned by functions to indicate no error.
13+
14+
.. macro:: PHANTOM_FALSE
15+
16+
Returned by functions to indicate false.
17+
18+
.. macro:: PHANTOM_ERROR
19+
20+
Returned by functions to indicate an otherwise unspecified error.
21+
22+
.. macro:: PHANTOM_NOT_FOUND
23+
24+
Returned by functions to indicate something was not found.
25+
26+
.. type:: phantom_data_t
27+
28+
A type guaranteed to be wide enough to store an entire word. On Zynq systems this is `uint32_t`, and on a Zynq UltraScale+ device it is `uint64_t`.
29+
30+
.. type:: phantom_address_t
31+
32+
A type guaranteed to be wide enough to store an entire system address. On Zynq systems this is `uint32_t`, and on a Zynq UltraScale+ device it is `uint64_t`.
33+
34+
.. macro:: PHANTOM_DMA_TO_IP
35+
36+
Specify a DMA transfer from main memory into an IP core.
37+
38+
.. macro:: PHANTOM_DMA_FROM_IP
39+
40+
Specify a DMA transfer from an IP core's address space into main memory.
41+
42+
43+
44+
Configuring the FPGA
45+
---------------------
46+
47+
.. function:: int phantom_fpga_is_done()
48+
49+
Check the FPGA's `done` pin, which is asserted when the FPGA is successfully programmed with a bitfile.
50+
51+
:return:
52+
* :macro:`PHANTOM_OK` if the FPGA has been configured with a compatible bitfile
53+
* :macro:`PHANTOM_FALSE` if the DONE pin is not asserted.
54+
55+
56+
.. function:: int phantom_fpga_configure(FILE *bitfile)
57+
58+
Configure the FPGA fabric with the specified bitfile. bitfile is a configuration file as generated by the Xilinx tools for the appropriate FPGA part. This function assumes that the FPGA is not currently programmed. Note that this function does not block until programming is complete. :func:`phantom_fpga_is_done()` should be called to determine that programming has completed successfully before the FPGA is used.
59+
60+
:param FILE* bitfile: A FILE pointer to a compatible bitfile, opened in binary mode.
61+
62+
:return:
63+
* :macro:`PHANTOM_OK` if configuration started successfully
64+
* :macro:`PHANTOM_ERROR` if the bitfile could not be sent to the FPGA.
65+
66+
67+
68+
The `phantom_ip_t` structure
69+
----------------------------
70+
71+
The PHANTOM IP cores in the current design are represented by instances of the `phantom_ip_t` structure which are obtained by calling :func:`phantom_fpga_get_ips()`.
72+
73+
74+
.. type:: typedef struct {...} phantom_ip_t;
75+
76+
The structure contains at least the following members:
77+
78+
.. member:: char *idstring
79+
80+
An identifying string.
81+
82+
.. member:: uint32_t id
83+
84+
A unique identifier for the IP.
85+
86+
.. member:: uint8_t num_masters
87+
88+
The number of AXI Masters in the IP.
89+
90+
.. member:: phantom_address_t base_address
91+
92+
The base memory address of the IP core's AXI Slave.
93+
94+
.. member:: phantom_address_t address_size
95+
96+
The size in bytes on the IP core's AXI Slave memory space.
97+
98+
..
99+
100+
101+
Reading IP Core Information
102+
---------------------------
103+
104+
.. function:: int phantom_fpga_get_num_ips()
105+
106+
If the FPGA is currently programmed, this gives the number of PHANTOM IP cores in the current design.
107+
108+
:return: the number of IP cores that are currently configured onto the FPGA. -1 if a problem is encountered.
109+
110+
111+
.. function:: phantom_ip_t *phantom_fpga_get_ips()
112+
113+
If the FPGA is currently programmed, this fetches an array of `phantom_ip_t` that describe the PHANTOM IP cores in the design, as in the following example::
114+
115+
phantom_ip_t *ips = phantom_fpga_get_ips();
116+
117+
for(int i = 0; i < phantom_fpga_get_num_ips(); i++) {
118+
printf("%d: %s\n", i, ips[i].idstring);
119+
}
120+
121+
:return: An array of the PHANTOM IPs in the currently-programmed design, or `NULL` if none exist.
122+
123+
124+
.. function:: int phantom_fpga_ip_initialise(phantom_ip_t *ip, const char *idstring)
125+
126+
If the FPGA is currently programmed, search for the PHANTOM IP core with the provided `idstring`. The `ip` struct is then initialised.
127+
128+
:param phantom_ip_t* ip: A `phantom_ip_t` struct to be initialised.
129+
:param char* idstring: The identifier string of the IP.
130+
131+
:return:
132+
* :macro:`PHANTOM_OK` if the IP is successfully initialised.
133+
* :macro:`PHANTOM_NOT_FOUND` if the FPGA is correctly programmed, but the requested core cannot be found.
134+
* :macro:`PHANTOM_ERROR` if another error occurs.
135+
136+
137+
.. function:: int phantom_fpga_ip_initialise_by_id(phantom_ip_t *ip, uint32_t id)
138+
139+
As :func:`phantom_fpga_ip_initialise()`, but initialises a core based on its unique id. This is useful for when multiple copies of the same IP core are present. These can be queried through the use of :func:`phantom_fpga_get_ips()`.
140+
141+
:param phantom_ip_t* ip: A `phantom_ip_t` struct to be initialised.
142+
:param uint32_t id: The unique identifier of the IP.
143+
144+
:return:
145+
* :macro:`PHANTOM_OK` if the IP is successfully initialised.
146+
* :macro:`PHANTOM_NOT_FOUND` if the FPGA is correctly programmed, but the requested core cannot be found.
147+
* :macro:`PHANTOM_ERROR` if another error occurs.
148+
149+
150+
151+
152+
153+
154+
155+
IP Control
156+
----------
157+
158+
.. function:: int phantom_fpga_ip_start(phantom_ip_t* ip)
159+
160+
Starts the specified IP. Has no effect if the core is already started.
161+
162+
:param phantom_ip_t* ip: The IP core to control.
163+
164+
:return: :macro:`PHANTOM_OK` if the core started successfully, or :macro:`PHANTOM_ERROR` if not.
165+
166+
167+
.. function:: int phantom_fpga_ip_is_done(phantom_ip_t* ip)
168+
169+
Checks if the specified IP has completed its execution.
170+
171+
:param phantom_ip_t* ip: The IP core to query.
172+
173+
:return: :macro:`PHANTOM_OK` if the core stopped successfully, or :macro:`PHANTOM_FALSE` if not.
174+
175+
176+
.. function:: int phantom_fpga_ip_is_idle(phantom_ip_t* ip)
177+
178+
Checks if the specified IP is idle and ready for I/O or to be started.
179+
180+
:param phantom_ip_t* ip: The IP core to query.
181+
182+
:return: :macro:`PHANTOM_OK` if the core is idle, or :macro:`PHANTOM_FALSE` if not.
183+
184+
185+
186+
187+
IP Data I/O
188+
-----------
189+
190+
PHANTOM IPs are presented to the Linux kernel as Userland IO (UIO) devices, and so the entire address space can be mapped and accessed using simple get and set functions. This is not the most efficient way to move large volumes of data however. The IP core itself can read and write from main system memory through an AXI master interface. Therefore the UIO interface should be used to pass parameters and configuration data, and the device itself should fetch input data as required using AXI burst transfers.
191+
192+
It is also possible for the hardware design to include an AXI DMA controller to support automatic bulk data movement. This core can be controlled through the UIO interface through the simple helper functions provided here. More complex DMA transfers can be coded directly.
193+
194+
195+
.. function:: int phantom_fpga_ip_set(phantom_ip_t* ip, phantom_address_t addr, phantom_data_t val)
196+
197+
Set a value inside the AXI Slave address space of the IP. `addr` is based from 0 and will be automatically offset to the appropriate base address (`phantom_ip_t.base_address`).
198+
199+
:param phantom_ip_t* ip: The IP core to query.
200+
:param phantom_address_t addr: The address, based at 0, inside the address space of the IP core.
201+
:param phantom_data_t val: The value to set.
202+
203+
:return: :macro:`PHANTOM_OK` if the value was set, or :macro:`PHANTOM_ERROR` if not.
204+
205+
206+
.. function:: phantom_data_t phantom_fpga_ip_get(phantom_ip_t* ip, phantom_address_t addr)
207+
208+
Get a value from the AXI Slave address space of the IP. `addr` is based from 0 and will be automatically offset to the appropriate base address (`phantom_ip_t.base_address`).
209+
210+
:param phantom_ip_t* ip: The IP core to query.
211+
:param phantom_address_t addr: The address, based at 0, inside the address space of the IP core.
212+
213+
:return: The value of the argument specified by `addr`.
214+
215+
216+
.. function:: int phantom_fpga_dma_transfer(phantom_ip_t* ip, phantom_address_t dma_core, phantom_address_t buffaddr, phantom_address_t length, int direction)
217+
218+
Cause a DMA core in the specified IP core to initiate a DMA transfer. This function assumes that an AXI DMA IP core is located at the appropriate address in the memory space of the target IP. This function returns immediately and the transfer will begin a time after this. For more details consult the Xilinx DMA Core driver.
219+
220+
:param phantom_ip_t* ip: The IP core to query.
221+
:param phantom_address_t dma_core: The offset, starting at 0, of the DMA core inside the address space of the IP.
222+
:param phantom_address_t buffaddr: The address in main memory to start the transfer from.
223+
:param phantom_address_t length: The length in bytes of the transfer.
224+
:param int direction: The direction of the transfer. Valid values are `PHANTOM_DMA_TO_IP` or `PHANTOM_DMA_FROM_IP`
225+
226+
:return: :macro:`PHANTOM_OK` if the transfer was started, or :macro:`PHANTOM_FALSE` if not.
227+
228+
229+
.. function:: int phantom_fpga_dma_is_idle(phantom_ip_t* ip, phantom_address_t dma_core, int direction)
230+
231+
Check if the DMA core in the specified IP core is idle in the given direction. Because the Xilinx AXI DMA core is bidirectional, it is possible for a transfer to be proceeding in one direction whilst the other is idle.
232+
233+
:param phantom_ip_t* ip: The IP core to query.
234+
:param phantom_address_t dma_core: The offset, starting at 0, of the DMA core inside the address space of the IP.
235+
:param int direction: The direction of the transfer. Valid values are `PHANTOM_DMA_TO_IP` or `PHANTOM_DMA_FROM_IP`
236+
237+
:return: :macro:`PHANTOM_OK` if the core is idle, or :macro:`PHANTOM_FALSE` if not.

API/phantom_software_ip_api.pdf

117 KB
Binary file not shown.

0 commit comments

Comments
 (0)