Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
NanoSoC Tech
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
SoCLabs
NanoSoC Tech
Commits
a076f472
Commit
a076f472
authored
2 years ago
by
dwf1m12
Browse files
Options
Downloads
Patches
Plain Diff
add baseline nanosoc test jupyter notebook example
parent
9386e4a4
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz104/jupyter_notebooks/soclabs/nanosoc-iotest.ipynb
+708
-0
708 additions, 0 deletions
...port/pz104/jupyter_notebooks/soclabs/nanosoc-iotest.ipynb
with
708 additions
and
0 deletions
Cortex-M0/nanosoc/systems/mcu/fpga_imp/pynq_export/pz104/jupyter_notebooks/soclabs/nanosoc-iotest.ipynb
0 → 100755
+
708
−
0
View file @
a076f472
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Downloading Overlays\n",
"\n",
"This notebook demonstrates how to download an FPGA overlay and examine programmable logic state. \n",
"\n",
"## 1. Instantiating an overlay\n",
"With the following overlay bundle present in the `overlays` folder, users can instantiate the overlay easily.\n",
"\n",
"* A bitstream file (\\*.bit).\n",
"* An hwh file (\\*.hwh).\n",
"* A python class (\\*.py).\n",
"\n",
"For example, an overlay called `base` can be loaded by:\n",
"```python\n",
"from pynq.overlays.base import BaseOverlay\n",
"overlay = BaseOverlay(\"base.bit\")\n",
"```\n",
"Users can also use the absolute file path of the bitstream to instantiate the overlay.\n",
"\n",
"In this notebook, we get the current bitstream loaded on PL, and try to download it multiple times."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
"try {\n",
"require(['notebook/js/codecell'], function(codecell) {\n",
" codecell.CodeCell.options_default.highlight_modes[\n",
" 'magic_text/x-csrc'] = {'reg':[/^%%microblaze/]};\n",
" Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n",
" Jupyter.notebook.get_cells().map(function(cell){\n",
" if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n",
" });\n",
"});\n",
"} catch (e) {};\n"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
"try {\n",
"require(['notebook/js/codecell'], function(codecell) {\n",
" codecell.CodeCell.options_default.highlight_modes[\n",
" 'magic_text/x-csrc'] = {'reg':[/^%%pybind11/]};\n",
" Jupyter.notebook.events.one('kernel_ready.Kernel', function(){\n",
" Jupyter.notebook.get_cells().map(function(cell){\n",
" if (cell.cell_type == 'code'){ cell.auto_highlight(); } }) ;\n",
" });\n",
"});\n",
"} catch (e) {};\n"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import os, warnings\n",
"from pynq import PL\n",
"from pynq import Overlay\n",
"\n",
"ol = Overlay(\"/home/xilinx/pynq/overlays/soclabs/design_1.bit\")\n",
"\n",
"if not os.path.exists(PL.bitfile_name):\n",
" warnings.warn('There is no overlay loaded after boot.', UserWarning)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**Note**: If you see a warning message in the above cell, it means that no overlay\n",
"has been loaded after boot, hence the PL server is not aware of the \n",
"current status of the PL. In that case you won't be able to run this notebook\n",
"until you manually load an overlay at least once using:\n",
"\n",
"```python\n",
"from pynq import Overlay\n",
"ol = Overlay('your_overlay.bit')\n",
"```\n",
"\n",
"If you do not see any warning message, you can safely proceed."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"ol = Overlay(PL.bitfile_name)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now we can check the download timestamp for this overlay."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'2023/2/20 17:44:40 +479858'"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ol.download()\n",
"ol.timestamp"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": []
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [],
"source": [
"from pynq import Overlay\n",
"from pynq import MMIO\n",
"import time\n",
"from time import sleep, time\n",
"\n",
"#ADP_address = 0x80020000 # nanosoc FT1248 com channel\n",
"#ADP_address = 0x80030000 # streamio TX/RX loopback (unbuffered)\n",
"#ADP_address = 0x80040000 # streamio TX/RX loopback (FIFO buffered)\n",
"ADP_address = 0x80050000 # local test ADP controller COM channel\n",
"UART2_address = 0x80060000 # nanosoc UART2 com serial (9600 baud?)\n",
"#ADP_address = 0x80070000 # uart TX/RX loopback\n",
"\n",
"# HARDWARE CONSTANTS\n",
"RX_FIFO = 0x00\n",
"TX_FIFO = 0x04\n",
"# Status Reg\n",
"STAT_REG = 0x08\n",
"RX_VALID = 0\n",
"RX_FULL = 1\n",
"TX_EMPTY = 2\n",
"TX_FULL = 3\n",
"IS_INTR = 4\n",
"\n",
"# Ctrl Reg\n",
"CTRL_REG = 0x0C\n",
"RST_TX = 0\n",
"RST_RX = 1\n",
"INTR_EN = 4\n",
"\n",
"class ADPIO:\n",
" def __init__(self, address):\n",
" # Setup axi core\n",
" self.uart = MMIO(address, 0x10000, debug=False)\n",
" self.address = address\n",
"\n",
" def setupCtrlReg(self):\n",
"# # Reset FIFOs, disable interrupts\n",
"# self.uart.write(CTRL_REG, 1 << RST_TX | 1 << RST_RX)\n",
"# sleep(1)\n",
" self.uart.write(CTRL_REG, 0)\n",
" sleep(1)\n",
" self.uart.write(TX_FIFO, 0x1b)\n",
" sleep(1)\n",
"\n",
" def read(self, count, timeout=1):\n",
" # status = currentStatus(uart) bad idea\n",
" buf = \"\"\n",
" stop_time = time() + timeout\n",
" for i in range(count):\n",
" # Wait till RX fifo has valid data, stop waiting if timeoutpasses\n",
" while (not (self.uart.read(STAT_REG) & 1 << RX_VALID)) and (time() < stop_time):\n",
" pass\n",
" if time() >= stop_time:\n",
" break\n",
" buf += chr(self.uart.read(RX_FIFO))\n",
" return buf\n",
" \n",
" def write(self, buf, timeout=1):\n",
" # Write bytes via UART\n",
" stop_time = time() + timeout\n",
" wr_count = 0\n",
" for i in buf:\n",
" # Wait while TX FIFO is Full, stop waiting if timeout passes\n",
" while (self.uart.read(STAT_REG) & 1 << TX_FULL) and (time() < stop_time):\n",
" pass\n",
" # Check timeout\n",
" if time() > stop_time:\n",
" wr_count = -1\n",
" break\n",
" self.uart.write(TX_FIFO, ord(i))\n",
" wr_count += 1\n",
" return wr_count\n",
"\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Inspect the ADP banner after reset (0x50CLAB02 expected)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"' 0x50c1ab02\\n\\r\\n\\r]'"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp = ADPIO(ADP_address)\n",
"# Setup AXI UART register\n",
"adp.setupCtrlReg()\n",
"adp.read(20)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Also check the UART2 RX channel for any boot message"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"''"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"uart = ADPIO(UART2_address)\n",
"# Setup AXI UART register\n",
"uart.setupCtrlReg()\n",
"uart.read(50)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now check adp Address pointer reets to zero"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'A 0x00000000\\n\\r]'"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('A\\n')\n",
"adp.read(20)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And do a couple of 32-bit reads"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'R 0x00000000\\n\\r]'"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('R\\n')\n",
"adp.read(15)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'R 0x00000000\\n\\r]'"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('R\\n')\n",
"adp.read(15)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Verify the address pointer has auto-incremented two words"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'A 0x00000008\\n\\r]'"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('A\\n')\n",
"adp.read(15)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now set adp address to high memory and write a couple of patterns"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'A 0xc0000000\\n\\r]'"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('A c0000000\\n')\n",
"adp.read(20)"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'W 0x11111111\\n\\r]'"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('W 111111111\\n')\n",
"adp.read(15)"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'W 0x22222222\\n\\r]'"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('W 22222222\\n')\n",
"adp.read(15)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Reset the address pointer and verify same patterns read back"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'A 0xc0000000\\n\\r]'"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('A c0000000\\n')\n",
"adp.read(20)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'R 0x11111111\\n\\r]'"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('R\\n')\n",
"adp.read(15)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'R 0x22222222\\n\\r]'"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adp.write('R\\n')\n",
"adp.read(15)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"## ol.download()\n",
"ol.timestamp\n",
"ol.reset()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ip_info = {'trace_cntrl':\"ft1248tb_i/ila_0\"}\n",
"class pynq.logictools.trace_analyzer.TraceAnalyzer(ip_info)\n",
"\n",
" "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#PL.ip_dict"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"gpio_0.register_map\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 2. Examining the PL state\n",
"\n",
"While there can be multiple overlay instances in Python, there is only one bitstream that is currently loaded onto the programmable logic (PL). \n",
"\n",
"This bitstream state is held in the singleton class, PL, and is available for user queries."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"PL.bitfile_name"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"PL.timestamp\n",
"\n",
"PL.ip_dict\n",
"\n",
"leds_address = PL.ip_dict['led_4bits']['phys_addr']\n",
" \n",
"from pynq import MMIO\n",
"mmio_buttons = MMIO(0xa0000000, 16)\n",
"help (mmio_buttons)\n",
"\n",
"#print(hex(mmio_buttons))\n",
"#print(hex(mmio_buttons.read(0)))\n",
"\n",
"hex(pl.ip_dict[\"axi_gpio_1\"][\"phys_addr\"])\n",
"\n",
"\n",
"#buttons_address = ssc_dpram.ip_dict['push_button_4bits']['phys_addr']\n",
"#switches_address = ssc_dpram.ip_dict['dip_switch_4bits']['phys_addr']\n",
"#leds_address = ssc_dpram.ip_dict['led_4bitss']['phys_addr']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Users can verify whether an overlay instance is currently loaded using the Overlay is_loaded() method"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"ol.is_loaded()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## 3. Overlay downloading overhead\n",
"\n",
"Finally, using Python, we can see the bitstream download time over 50 downloads. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import time\n",
"import matplotlib.pyplot as plt\n",
"\n",
"length = 50\n",
"time_log = []\n",
"for i in range(length):\n",
" start = time.time()\n",
" ol.download()\n",
" end = time.time()\n",
" time_log.append((end-start)*1000)\n",
"\n",
"%matplotlib inline\n",
"plt.plot(range(length), time_log, 'ro')\n",
"plt.title('Bitstream loading time (ms)')\n",
"plt.axis([0, length, 0, 1000])\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 1
}
%% Cell type:markdown id: tags:
# Downloading Overlays
This notebook demonstrates how to download an FPGA overlay and examine programmable logic state.
## 1. Instantiating an overlay
With the following overlay bundle present in the
`overlays`
folder, users can instantiate the overlay easily.
*
A bitstream file (
\*
.bit).
*
An hwh file (
\*
.hwh).
*
A python class (
\*
.py).
For example, an overlay called
`base`
can be loaded by:
```
python
from
pynq.overlays.base
import
BaseOverlay
overlay
=
BaseOverlay
(
"
base.bit
"
)
```
Users can also use the absolute file path of the bitstream to instantiate the overlay.
In this notebook, we get the current bitstream loaded on PL, and try to download it multiple times.
%% Cell type:code id: tags:
```
python
import
os
,
warnings
from
pynq
import
PL
from
pynq
import
Overlay
ol
=
Overlay
(
"
/home/xilinx/pynq/overlays/soclabs/design_1.bit
"
)
if
not
os
.
path
.
exists
(
PL
.
bitfile_name
):
warnings
.
warn
(
'
There is no overlay loaded after boot.
'
,
UserWarning
)
```
%% Output
%% Cell type:markdown id: tags:
**Note**
: If you see a warning message in the above cell, it means that no overlay
has been loaded after boot, hence the PL server is not aware of the
current status of the PL. In that case you won't be able to run this notebook
until you manually load an overlay at least once using:
```
python
from
pynq
import
Overlay
ol
=
Overlay
(
'
your_overlay.bit
'
)
```
If you do not see any warning message, you can safely proceed.
%% Cell type:code id: tags:
```
python
ol
=
Overlay
(
PL
.
bitfile_name
)
```
%% Cell type:markdown id: tags:
Now we can check the download timestamp for this overlay.
%% Cell type:code id: tags:
```
python
ol
.
download
()
ol
.
timestamp
```
%% Output
'2023/2/20 17:44:40 +479858'
%% Cell type:markdown id: tags:
%% Cell type:code id: tags:
```
python
from
pynq
import
Overlay
from
pynq
import
MMIO
import
time
from
time
import
sleep
,
time
#ADP_address = 0x80020000 # nanosoc FT1248 com channel
#ADP_address = 0x80030000 # streamio TX/RX loopback (unbuffered)
#ADP_address = 0x80040000 # streamio TX/RX loopback (FIFO buffered)
ADP_address
=
0x80050000
# local test ADP controller COM channel
UART2_address
=
0x80060000
# nanosoc UART2 com serial (9600 baud?)
#ADP_address = 0x80070000 # uart TX/RX loopback
# HARDWARE CONSTANTS
RX_FIFO
=
0x00
TX_FIFO
=
0x04
# Status Reg
STAT_REG
=
0x08
RX_VALID
=
0
RX_FULL
=
1
TX_EMPTY
=
2
TX_FULL
=
3
IS_INTR
=
4
# Ctrl Reg
CTRL_REG
=
0x0C
RST_TX
=
0
RST_RX
=
1
INTR_EN
=
4
class
ADPIO
:
def
__init__
(
self
,
address
):
# Setup axi core
self
.
uart
=
MMIO
(
address
,
0x10000
,
debug
=
False
)
self
.
address
=
address
def
setupCtrlReg
(
self
):
# # Reset FIFOs, disable interrupts
# self.uart.write(CTRL_REG, 1 << RST_TX | 1 << RST_RX)
# sleep(1)
self
.
uart
.
write
(
CTRL_REG
,
0
)
sleep
(
1
)
self
.
uart
.
write
(
TX_FIFO
,
0x1b
)
sleep
(
1
)
def
read
(
self
,
count
,
timeout
=
1
):
# status = currentStatus(uart) bad idea
buf
=
""
stop_time
=
time
()
+
timeout
for
i
in
range
(
count
):
# Wait till RX fifo has valid data, stop waiting if timeoutpasses
while
(
not
(
self
.
uart
.
read
(
STAT_REG
)
&
1
<<
RX_VALID
))
and
(
time
()
<
stop_time
):
pass
if
time
()
>=
stop_time
:
break
buf
+=
chr
(
self
.
uart
.
read
(
RX_FIFO
))
return
buf
def
write
(
self
,
buf
,
timeout
=
1
):
# Write bytes via UART
stop_time
=
time
()
+
timeout
wr_count
=
0
for
i
in
buf
:
# Wait while TX FIFO is Full, stop waiting if timeout passes
while
(
self
.
uart
.
read
(
STAT_REG
)
&
1
<<
TX_FULL
)
and
(
time
()
<
stop_time
):
pass
# Check timeout
if
time
()
>
stop_time
:
wr_count
=
-
1
break
self
.
uart
.
write
(
TX_FIFO
,
ord
(
i
))
wr_count
+=
1
return
wr_count
```
%% Cell type:markdown id: tags:
Inspect the ADP banner after reset (0x50CLAB02 expected)
%% Cell type:code id: tags:
```
python
adp
=
ADPIO
(
ADP_address
)
# Setup AXI UART register
adp
.
setupCtrlReg
()
adp
.
read
(
20
)
```
%% Output
' 0x50c1ab02\n\r\n\r]'
%% Cell type:markdown id: tags:
Also check the UART2 RX channel for any boot message
%% Cell type:code id: tags:
```
python
uart
=
ADPIO
(
UART2_address
)
# Setup AXI UART register
uart
.
setupCtrlReg
()
uart
.
read
(
50
)
```
%% Output
''
%% Cell type:markdown id: tags:
Now check adp Address pointer reets to zero
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
A
\n
'
)
adp
.
read
(
20
)
```
%% Output
'A 0x00000000\n\r]'
%% Cell type:markdown id: tags:
And do a couple of 32-bit reads
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
R
\n
'
)
adp
.
read
(
15
)
```
%% Output
'R 0x00000000\n\r]'
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
R
\n
'
)
adp
.
read
(
15
)
```
%% Output
'R 0x00000000\n\r]'
%% Cell type:markdown id: tags:
Verify the address pointer has auto-incremented two words
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
A
\n
'
)
adp
.
read
(
15
)
```
%% Output
'A 0x00000008\n\r]'
%% Cell type:markdown id: tags:
Now set adp address to high memory and write a couple of patterns
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
A c0000000
\n
'
)
adp
.
read
(
20
)
```
%% Output
'A 0xc0000000\n\r]'
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
W 111111111
\n
'
)
adp
.
read
(
15
)
```
%% Output
'W 0x11111111\n\r]'
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
W 22222222
\n
'
)
adp
.
read
(
15
)
```
%% Output
'W 0x22222222\n\r]'
%% Cell type:markdown id: tags:
Reset the address pointer and verify same patterns read back
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
A c0000000
\n
'
)
adp
.
read
(
20
)
```
%% Output
'A 0xc0000000\n\r]'
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
R
\n
'
)
adp
.
read
(
15
)
```
%% Output
'R 0x11111111\n\r]'
%% Cell type:code id: tags:
```
python
adp
.
write
(
'
R
\n
'
)
adp
.
read
(
15
)
```
%% Output
'R 0x22222222\n\r]'
%% Cell type:markdown id: tags:
## ol.download()
ol.timestamp
ol.reset()
%% Cell type:code id: tags:
```
python
ip_info
=
{
'
trace_cntrl
'
:
"
ft1248tb_i/ila_0
"
}
class
pynq
.
logictools
.
trace_analyzer
.
TraceAnalyzer
(
ip_info
)
```
%% Cell type:code id: tags:
```
python
#PL.ip_dict
```
%% Cell type:code id: tags:
```
python
gpio_0
.
register_map
```
%% Cell type:markdown id: tags:
## 2. Examining the PL state
While there can be multiple overlay instances in Python, there is only one bitstream that is currently loaded onto the programmable logic (PL).
This bitstream state is held in the singleton class, PL, and is available for user queries.
%% Cell type:code id: tags:
```
python
PL
.
bitfile_name
```
%% Cell type:code id: tags:
```
python
PL
.
timestamp
PL
.
ip_dict
leds_address
=
PL
.
ip_dict
[
'
led_4bits
'
][
'
phys_addr
'
]
from
pynq
import
MMIO
mmio_buttons
=
MMIO
(
0xa0000000
,
16
)
help
(
mmio_buttons
)
#print(hex(mmio_buttons))
#print(hex(mmio_buttons.read(0)))
hex
(
pl
.
ip_dict
[
"
axi_gpio_1
"
][
"
phys_addr
"
])
#buttons_address = ssc_dpram.ip_dict['push_button_4bits']['phys_addr']
#switches_address = ssc_dpram.ip_dict['dip_switch_4bits']['phys_addr']
#leds_address = ssc_dpram.ip_dict['led_4bitss']['phys_addr']
```
%% Cell type:markdown id: tags:
Users can verify whether an overlay instance is currently loaded using the Overlay is_loaded() method
%% Cell type:code id: tags:
```
python
ol
.
is_loaded
()
```
%% Cell type:markdown id: tags:
## 3. Overlay downloading overhead
Finally, using Python, we can see the bitstream download time over 50 downloads.
%% Cell type:code id: tags:
```
python
import
time
import
matplotlib.pyplot
as
plt
length
=
50
time_log
=
[]
for
i
in
range
(
length
):
start
=
time
.
time
()
ol
.
download
()
end
=
time
.
time
()
time_log
.
append
((
end
-
start
)
*
1000
)
%
matplotlib
inline
plt
.
plot
(
range
(
length
),
time_log
,
'
ro
'
)
plt
.
title
(
'
Bitstream loading time (ms)
'
)
plt
.
axis
([
0
,
length
,
0
,
1000
])
plt
.
show
()
```
%% Cell type:code id: tags:
```
python
``
`
%%
Cell
type
:
code
id
:
tags
:
```
python
```
%% Cell type:code id: tags:
```
python
```
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment