Skip to content
Snippets Groups Projects
Commit a076f472 authored by dwf1m12's avatar dwf1m12
Browse files

add baseline nanosoc test jupyter notebook example

parent 9386e4a4
No related branches found
No related tags found
No related merge requests found
%% 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
```
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment