FPGA designs and registers¶
Load a matching pair¶
The .bit file programs the FPGA; the .hwh file describes the design. Both paths are local to your computer. Use files built together for your target and compatible with the NOA target services.
Inside a connected async with Noa(...) as device: block:
await device.load_bitstream("design.bit", "design.hwh")
Loading replaces the FPGA configuration currently running. After a compatible design is loaded or attached, the client exposes daq, stream_in, DA, DB and analog-output objects. Their availability in the actual hardware/design must be checked; the current client creates these names for its reference design.
Register example¶
The repository's registers design adds two signed 32-bit values. Addresses below belong to that example, not to every design. Run from the cloned repository root:
import asyncio
from noa.noa import Noa
async def main():
async with Noa("arch1-00001.local") as device:
await device.load_bitstream(
"examples/registers/design_1_wrapper.bit",
"examples/registers/design_1.hwh",
)
result_received = asyncio.Event()
async def on_sum(name, value):
print(name, value)
if value == 220:
result_received.set()
await device.setup_write_register("A", 0x104, dtype="int32")
await device.setup_write_register("B", 0x108, dtype="int32")
await device.setup_read_register("sum", 0x10C, dtype="int32", cb=on_sum)
await device.write_register("A", 100)
await device.write_register("B", 120)
await asyncio.wait_for(result_received.wait(), timeout=5)
print("Latest sum:", device.read_register("sum"))
if __name__ == "__main__":
asyncio.run(main())
Read registers update asynchronously. read_register() returns the latest cached value, not a fresh network read. Use an asynchronous callback or another completion condition when an operation depends on a new value. A successful write does not mean its corresponding read update has arrived.
Match dtype to the design's signal representation. See data types and the original example.