mms-ok 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mms_ok-0.1.0/PKG-INFO +11 -0
- mms_ok-0.1.0/README.md +272 -0
- mms_ok-0.1.0/mms_ok/__init__.py +13 -0
- mms_ok-0.1.0/mms_ok/fpga.py +741 -0
- mms_ok-0.1.0/mms_ok/fpga_components.py +504 -0
- mms_ok-0.1.0/mms_ok/fpga_config.py +70 -0
- mms_ok-0.1.0/mms_ok/fpga_old.py +885 -0
- mms_ok-0.1.0/mms_ok/ok_setup.py +44 -0
- mms_ok-0.1.0/mms_ok/pipeoutdata.py +102 -0
- mms_ok-0.1.0/mms_ok/validation.py +20 -0
- mms_ok-0.1.0/mms_ok.egg-info/PKG-INFO +11 -0
- mms_ok-0.1.0/mms_ok.egg-info/SOURCES.txt +18 -0
- mms_ok-0.1.0/mms_ok.egg-info/dependency_links.txt +1 -0
- mms_ok-0.1.0/mms_ok.egg-info/requires.txt +2 -0
- mms_ok-0.1.0/mms_ok.egg-info/top_level.txt +2 -0
- mms_ok-0.1.0/setup.cfg +4 -0
- mms_ok-0.1.0/setup.py +19 -0
- mms_ok-0.1.0/tests/__init__.py +0 -0
- mms_ok-0.1.0/tests/test_conversion.py +183 -0
- mms_ok-0.1.0/tests/test_text_reordering.py +9 -0
mms_ok-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: mms_ok
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python package for interfacing with Opal Kelly FPGA boards
|
|
5
|
+
Author-email: juyoung.oh@snu.ac.kr
|
|
6
|
+
Classifier: Intended Audience :: Science/Research
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Topic :: Scientific/Engineering
|
|
9
|
+
Requires-Python: >=3.7
|
|
10
|
+
Requires-Dist: loog
|
|
11
|
+
Requires-Dist: numpy
|
mms_ok-0.1.0/README.md
ADDED
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
# MMS-OK: FPGA Interface Library
|
|
2
|
+
|
|
3
|
+
A Python library for interfacing with FPGA devices using the Opal Kelly FrontPanel API. This library provides a high-level interface for wire, trigger, and pipe operations with FPGA devices.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Wire-based I/O operations (setting/getting wire values)
|
|
8
|
+
- Trigger-based operations (activating triggers, checking trigger states)
|
|
9
|
+
- Pipe data transfer operations (reading/writing data through pipes)
|
|
10
|
+
- Block pipe operations for efficient large data transfers
|
|
11
|
+
- Comprehensive error handling and validation
|
|
12
|
+
- Utilities for data conversion and manipulation
|
|
13
|
+
- Support for XEM7310 and XEM7360 FPGA boards
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
### Prerequisites
|
|
18
|
+
|
|
19
|
+
- Python 3.7 or higher
|
|
20
|
+
- NumPy
|
|
21
|
+
- loog
|
|
22
|
+
- Opal Kelly FrontPanel API
|
|
23
|
+
- Install the Opal Kelly FrontPanel API according to the [official documentation](https://docs.opalkelly.com/fpsdk/frontpanel-api/).
|
|
24
|
+
|
|
25
|
+
### Install Guide
|
|
26
|
+
```bash
|
|
27
|
+
pip install mms_ok
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Quick Start
|
|
31
|
+
|
|
32
|
+
### Using the XEM Classes
|
|
33
|
+
|
|
34
|
+
```python
|
|
35
|
+
from mms_ok import XEM7310, XEM7360
|
|
36
|
+
|
|
37
|
+
# For XEM7310 boards
|
|
38
|
+
with XEM7310("path/to/bitstream.bit") as fpga:
|
|
39
|
+
# Reset the FPGA
|
|
40
|
+
fpga.reset(reset_address=0x00, reset_time=1.0, active_low=True)
|
|
41
|
+
|
|
42
|
+
# Control LEDs (8 LEDs on XEM7310)
|
|
43
|
+
fpga.SetLED(led_value=0xFF) # Turn on all LEDs
|
|
44
|
+
|
|
45
|
+
# Set wire values
|
|
46
|
+
fpga.SetWireInValue(0x00, 0x12345678)
|
|
47
|
+
fpga.UpdateWireIns()
|
|
48
|
+
|
|
49
|
+
# Read wire values
|
|
50
|
+
value = fpga.GetWireOutValue(0x20, auto_update=True)
|
|
51
|
+
print(f"Wire value: 0x{value:08X}")
|
|
52
|
+
|
|
53
|
+
# Activate a trigger
|
|
54
|
+
fpga.ActivateTriggerIn(0x40, 0)
|
|
55
|
+
|
|
56
|
+
# Check if a trigger is set
|
|
57
|
+
if fpga.IsTriggered(0x60, 0x01, auto_update=True):
|
|
58
|
+
print("Trigger is set!")
|
|
59
|
+
|
|
60
|
+
# Wait for a trigger with timeout
|
|
61
|
+
try:
|
|
62
|
+
fpga.CheckTriggered(0x60, 0x01, timeout=2.0)
|
|
63
|
+
print("Trigger condition met!")
|
|
64
|
+
except TimeoutError:
|
|
65
|
+
print("Trigger timeout!")
|
|
66
|
+
|
|
67
|
+
# Read data from a pipe
|
|
68
|
+
data = fpga.ReadFromPipeOut(0xA0, 1024, reorder_str=True)
|
|
69
|
+
print(f"Received data: {data.hex_data}")
|
|
70
|
+
print(f"Error code: {data.error_code}")
|
|
71
|
+
|
|
72
|
+
# Convert data to numpy array
|
|
73
|
+
import numpy as np
|
|
74
|
+
array_data = data.to_ndarray(dtype=np.uint16)
|
|
75
|
+
print(f"As array: {array_data}")
|
|
76
|
+
|
|
77
|
+
# For XEM7360 boards
|
|
78
|
+
fpga = XEM7360("path/to/bitstream.bit"):
|
|
79
|
+
|
|
80
|
+
# XEM7360 has 4 LEDs
|
|
81
|
+
fpga.SetLED(led_value=0x0F) # Turn on all 4 LEDs
|
|
82
|
+
|
|
83
|
+
# The rest of the API is the same as XEM7310
|
|
84
|
+
|
|
85
|
+
fpga.close()
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Automatic Updates
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from mms_ok import XEM7310
|
|
92
|
+
|
|
93
|
+
with XEM7310("path/to/bitstream.bit") as fpga:
|
|
94
|
+
# Enable automatic updates
|
|
95
|
+
fpga.SetAutoWireIn(True)
|
|
96
|
+
fpga.SetAutoWireOut(True)
|
|
97
|
+
fpga.SetAutoTriggerOut(True)
|
|
98
|
+
|
|
99
|
+
# Now you don't need to call update methods explicitly
|
|
100
|
+
fpga.SetWireInValue(0x00, 0x12345678) # Auto-updates
|
|
101
|
+
value = fpga.GetWireOutValue(0x20) # Auto-updates before reading
|
|
102
|
+
is_triggered = fpga.IsTriggered(0x60, 0x01) # Auto-updates before checking
|
|
103
|
+
|
|
104
|
+
# Disable automatic updates when needed
|
|
105
|
+
fpga.SetAutoWireIn(False)
|
|
106
|
+
fpga.SetAutoWireOut(False)
|
|
107
|
+
fpga.SetAutoTriggerOut(False)
|
|
108
|
+
|
|
109
|
+
# Now you need to call update methods explicitly
|
|
110
|
+
fpga.SetWireInValue(0x01, 0xABCDEF01)
|
|
111
|
+
fpga.SetWireInValue(0x02, 0x12345678)
|
|
112
|
+
fpga.UpdateWireIns() # Updates all wire-in values at once
|
|
113
|
+
|
|
114
|
+
fpga.UpdateWireOuts() # Explicitly update before reading
|
|
115
|
+
value = fpga.GetWireOutValue(0x21)
|
|
116
|
+
|
|
117
|
+
# You can also use auto_update parameter for one-time automatic updates
|
|
118
|
+
# without changing the global setting
|
|
119
|
+
fpga.SetWireInValue(0x03, 0x55AA55AA, auto_update=True) # One-time auto-update
|
|
120
|
+
value = fpga.GetWireOutValue(0x22, auto_update=True) # One-time auto-update
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Automatic updates are useful for simple operations, but disabling them can be more efficient when:
|
|
124
|
+
- Setting multiple wire values before updating them all at once
|
|
125
|
+
- Performing time-critical operations where explicit control is needed
|
|
126
|
+
- Optimizing performance for high-throughput applications
|
|
127
|
+
|
|
128
|
+
### Reading and Writing Data
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from mms_ok import XEM7310
|
|
132
|
+
import numpy as np
|
|
133
|
+
|
|
134
|
+
with XEM7310("path/to/bitstream.bit") as fpga:
|
|
135
|
+
# Write data to a pipe
|
|
136
|
+
# You can write string data (hex format)
|
|
137
|
+
fpga.WriteToPipeIn(0x80, "AABBCCDDEEFF0011", reorder_str=True)
|
|
138
|
+
|
|
139
|
+
# Or numpy arrays
|
|
140
|
+
data_array = np.array([1, 2, 3, 4], dtype=np.uint32)
|
|
141
|
+
fpga.WriteToPipeIn(0x80, data_array)
|
|
142
|
+
|
|
143
|
+
# Or raw bytearrays
|
|
144
|
+
raw_data = bytearray([0xAA, 0xBB, 0xCC, 0xDD] * 4)
|
|
145
|
+
fpga.WriteToPipeIn(0x80, raw_data)
|
|
146
|
+
|
|
147
|
+
# Read data from a pipe
|
|
148
|
+
# Specify buffer size in bytes
|
|
149
|
+
result = fpga.ReadFromPipeOut(0xA0, 16)
|
|
150
|
+
print(f"Hex data: {result.hex_data}")
|
|
151
|
+
print(f"Raw data: {result.raw_data}")
|
|
152
|
+
|
|
153
|
+
# For larger transfers, use block pipes
|
|
154
|
+
large_data = np.zeros(1024, dtype=np.uint32)
|
|
155
|
+
fpga.WriteToBlockPipeIn(0x80, large_data)
|
|
156
|
+
|
|
157
|
+
# Read large data blocks
|
|
158
|
+
large_result = fpga.ReadFromBlockPipeOut(0xA0, 4096) # 4096 bytes
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## API Documentation
|
|
162
|
+
|
|
163
|
+
### XEM Base Class
|
|
164
|
+
|
|
165
|
+
Abstract base class for Opal Kelly FPGA devices. Provides common functionality for all FPGA models.
|
|
166
|
+
|
|
167
|
+
#### Methods
|
|
168
|
+
|
|
169
|
+
- `reset(reset_address, reset_time, active_low)`: Reset the FPGA device
|
|
170
|
+
- `SetLED(led_value, led_address)`: Set LED values on the FPGA board
|
|
171
|
+
- `SetAutoWireIn(auto_update)`: Enable automatic update of wire-in values
|
|
172
|
+
- `SetAutoWireOut(auto_update)`: Enable automatic update of wire-out values
|
|
173
|
+
- `SetAutoTriggerOut(auto_update)`: Enable automatic update of trigger-out values
|
|
174
|
+
- `SetWireInValue(ep_addr, value, mask, auto_update)`: Set a value to be written to a wire-in endpoint
|
|
175
|
+
- `UpdateWireIns()`: Update all wire-in endpoints
|
|
176
|
+
- `UpdateWireOuts()`: Update all wire-out endpoints
|
|
177
|
+
- `GetWireOutValue(ep_addr, auto_update)`: Get the value of a wire-out endpoint
|
|
178
|
+
- `WriteToPipeIn(ep_addr, data, reorder_str)`: Write data to a pipe-in endpoint
|
|
179
|
+
- `ReadFromPipeOut(ep_addr, data, reorder_str)`: Read data from a pipe-out endpoint
|
|
180
|
+
- `WriteToBlockPipeIn(ep_addr, data, reorder_str)`: Write data to a block pipe-in endpoint
|
|
181
|
+
- `ReadFromBlockPipeOut(ep_addr, data, reorder_str)`: Read data from a block pipe-out endpoint
|
|
182
|
+
- `ActivateTriggerIn(ep_addr, bit)`: Activate a trigger-in endpoint
|
|
183
|
+
- `UpdateTriggerOuts()`: Update all trigger-out endpoints
|
|
184
|
+
- `IsTriggered(ep_addr, mask, auto_update)`: Check if specific trigger bits are set
|
|
185
|
+
- `CheckTriggered(ep_addr, mask, timeout)`: Check if a trigger condition is met within a specified timeout
|
|
186
|
+
|
|
187
|
+
### XEM7310 Class
|
|
188
|
+
|
|
189
|
+
Specific implementation for the XEM7310A75/A200 FPGA boards. Inherits from XEM base class.
|
|
190
|
+
|
|
191
|
+
#### Methods
|
|
192
|
+
|
|
193
|
+
All methods from XEM base class, plus:
|
|
194
|
+
- `SetLED(led_value, led_address)`: Control the 8 LEDs on the XEM7310 board
|
|
195
|
+
|
|
196
|
+
### XEM7360 Class
|
|
197
|
+
|
|
198
|
+
Specific implementation for the XEM7360K160T FPGA board. Inherits from XEM base class.
|
|
199
|
+
|
|
200
|
+
#### Methods
|
|
201
|
+
|
|
202
|
+
All methods from XEM base class, plus:
|
|
203
|
+
- `SetLED(led_value, led_address)`: Control the 4 LEDs on the XEM7360 board
|
|
204
|
+
|
|
205
|
+
### WireOperations
|
|
206
|
+
|
|
207
|
+
Interface for wire-based I/O operations on FPGA devices.
|
|
208
|
+
|
|
209
|
+
#### Methods
|
|
210
|
+
|
|
211
|
+
- `set_wire_in(ep_addr, value, mask)`: Set a value to be written to a wire-in endpoint
|
|
212
|
+
- `update_wire_ins()`: Update all wire-in endpoints
|
|
213
|
+
- `update_wire_outs()`: Update all wire-out endpoints
|
|
214
|
+
- `get_wire_out(ep_addr)`: Get the value of a wire-out endpoint
|
|
215
|
+
|
|
216
|
+
### TriggerOperations
|
|
217
|
+
|
|
218
|
+
Interface for trigger-based operations on FPGA devices.
|
|
219
|
+
|
|
220
|
+
#### Methods
|
|
221
|
+
|
|
222
|
+
- `activate_trigger_in(ep_addr, bit)`: Activate a trigger-in endpoint
|
|
223
|
+
- `update_trigger_outs()`: Update all trigger-out endpoints
|
|
224
|
+
- `is_triggered(ep_addr, mask)`: Check if specific trigger bits are set
|
|
225
|
+
|
|
226
|
+
### PipeOperations
|
|
227
|
+
|
|
228
|
+
Interface for pipe data transfer operations on FPGA devices.
|
|
229
|
+
|
|
230
|
+
#### Methods
|
|
231
|
+
|
|
232
|
+
- `write_to_pipe_in(ep_addr, data, reorder_str)`: Write data to a pipe-in endpoint
|
|
233
|
+
- `read_from_pipe_out(ep_addr, data, reorder_str)`: Read data from a pipe-out endpoint
|
|
234
|
+
- `reorder_hex_str(hex_str)`: Reorders a hexadecimal string by swapping positions
|
|
235
|
+
|
|
236
|
+
### BlockPipeOperations
|
|
237
|
+
|
|
238
|
+
Interface for block pipe data transfer operations on FPGA devices.
|
|
239
|
+
|
|
240
|
+
#### Methods
|
|
241
|
+
|
|
242
|
+
- `write_to_block_pipe_in(ep_addr, data, reorder_str)`: Write data to a block pipe-in endpoint
|
|
243
|
+
- `read_from_block_pipe_out(ep_addr, data, reorder_str)`: Read data from a block pipe-out endpoint
|
|
244
|
+
|
|
245
|
+
### PipeOutData
|
|
246
|
+
|
|
247
|
+
Represents data received from a pipe out interface.
|
|
248
|
+
|
|
249
|
+
#### Properties
|
|
250
|
+
|
|
251
|
+
- `error_code`: The error code associated with the data
|
|
252
|
+
- `raw_data`: The raw binary data received
|
|
253
|
+
- `hex_data`: Hexadecimal string representation of the data
|
|
254
|
+
- `transfer_byte`: The number of bytes transferred
|
|
255
|
+
|
|
256
|
+
#### Methods
|
|
257
|
+
|
|
258
|
+
- `to_ndarray(dtype)`: Convert the data to a numpy array with the specified dtype
|
|
259
|
+
|
|
260
|
+
## Endpoint Address Ranges
|
|
261
|
+
|
|
262
|
+
- Wire-in endpoints: `0x00 - 0x1F`
|
|
263
|
+
- Wire-out endpoints: `0x20 - 0x3F`
|
|
264
|
+
- Trigger-in endpoints: `0x40 - 0x5F`
|
|
265
|
+
- Trigger-out endpoints: `0x60 - 0x7F`
|
|
266
|
+
- Pipe-in endpoints: `0x80 - 0x9F`
|
|
267
|
+
- Pipe-out endpoints: `0xA0 - 0xBF`
|
|
268
|
+
|
|
269
|
+
# Contact
|
|
270
|
+
For questions, bug reports, or feature requests, please contact:
|
|
271
|
+
|
|
272
|
+
juyoung.oh@snu.ac.kr
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from loog import log
|
|
2
|
+
|
|
3
|
+
from .ok_setup import copy_frontpanel_files
|
|
4
|
+
|
|
5
|
+
copy_frontpanel_files()
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
import ok
|
|
9
|
+
except ImportError:
|
|
10
|
+
log("Please manually setup FrontPanel SDK!", level="critical")
|
|
11
|
+
raise ImportError("Import ok failed")
|
|
12
|
+
|
|
13
|
+
from .fpga import XEM7310, XEM7360
|