Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
dnorthcote committed Jan 24, 2023
0 parents commit 751ac85
Showing 147 changed files with 53,919 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
22 changes: 22 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Ignore Logs
*.log

# Ignore Simulink Files
*.autosave
*.slxc
*\.hbs
*\.Xil
*\hdl_prj
*\slprj
*\wavedata

# Ignore Vivado Files
*.jou
*vivado.txt

# Ignore Jupyter
*.ipynb_checkpoints
**/__pycache__

# Ignore ./rfstrath/rfstrath/
**/rfstrath/rfstrath
28 changes: 28 additions & 0 deletions LICENCE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
BSD 3-Clause License

Copyright (c) 2023, Strathclyde Academic Media

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
72 changes: 72 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<img src="./rfsoc_book/notebooks/common/rfsoc_book_banner.jpg" width="100%">

# Software Defined Radio with Zynq® UltraScale+ RFSoC
This repository contains the companion Jupyter Notebooks for the Software Defined Radio with Zynq® UltraScale+ RFSoC book.

To begin installing the Jupyter Notebooks on your system, click-on one of the options below.
* [RFSoC Setup](#rfsoc-setup)
* [Notebook Installation](#notebook-installation)

## RFSoC Setup
This repository is currently only compatible with [RFSoC-PYNQ v2.7](https://github.com/Xilinx/PYNQ/releases). Follow the steps below to setup the RFSoC platform for installing the companion Jupyter Notebooks.

1. Currently, there are only 3 compatible RFSoC platforms. These are the [RFSoC4x2](http://rfsoc-pynq.io/), [ZCU111](https://www.xilinx.com/products/boards-and-kits/zcu111.html), and [RFSoC2x2](http://rfsoc-pynq.io/).

2. Install PYNQ v2.7 onto an SD card and plug it in to your RFSoC platform.

3. Your RFSoC platform requires internet access to install the companion Jupyter Notebooks. Follow the instructions [here](https://pynq.readthedocs.io/en/v3.0.0/getting_started/network_connection.html?highlight=internet) that assist with internet access.

4. Navigate to JupyterLab by opening a browser (preferably Chrome) and connecting to `http://<board_ip_address>:9090/lab`.

## Notebook Installation
The companion Jupyter Notebooks can be installed on a computer or RFSoC platform. Follow the instructions below to install the notebooks through JupyterLab. If you haven't already, launch JupyterLab on your computer or RFSoC platform.

1. We need to open a terminal in JupyterLab. Firstly, open a launcher window as given in the following figure.

<p align="center">
<img src="../main/open_jupyter_launcher.jpg" width="35%" />
<p/>

2. Now open a terminal in Jupyter as shown below:

<p align="center">
<img src="../main/open_terminal_window.jpg" width="35%" />
<p/>

3. Install the RFSoC Book notebooks through PIP by executing the following command in the terminal.

```sh
pip install https://github.com/strath-sdr/RFSoC-Book/archive/v1.0.0.tar.gz
```

4. Run the following command in the Jupyter terminal window to install the notebooks and dependencies.

```sh
python -m rfsoc_book install
```

5. The RFSoC-Book notebooks are installed. Navigate to the JupyterLab workspace and you will find the notebooks in a folder named `rfsoc_book`.

## Additional Commands
The RFSoC Book module provides additional commands for those that would like to clean notebooks after use, or uninstall notebooks from their system.

Notebooks can be reset by running the following command in the Jupyter terminal.

```sh
python -m rfsoc_book clean
```

To uninstall all notebooks and dependencies, run the command below in the Jupyter terminal.

```sh
python -m rfsoc_book uninstall
```

## Warning and Disclaimer
The best efforts of the authors have been used to ensure that accurate and current information is presented in this repository. This includes researching the topics covered and developing examples. The material included is provided on an "as-is" basis in the best of faith, and the authors do not make any warranty of any kind, expressed, or implied, with regard to the documentation contained in this repository. The authors shall not be held liable for any loss or damage resulting directly or indirectly from any information or examples contained herein.

---
Copyright © 2023 Strathclyde Academic Media

---
---
Binary file added open_jupyter_launcher.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added open_terminal_window.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added rfsoc_book/__init__.py
Empty file.
165 changes: 165 additions & 0 deletions rfsoc_book/__main__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# library
import sys
import os
import subprocess
import shutil
from distutils.dir_util import copy_tree

# variables
package_name = 'rfsoc_book'
board_list = ['ZCU111', 'RFSoC2x2', 'RFSoC4x2']

# dialogue
help_dialogue = ''.join(['\r\nThe rfsoc_book module accepts one of the following arguments:', '\r\n',
'* install : Installs the notebooks and packages to the Jupyter directory', '\r\n',
'* uninstall : Uninstalls the notebooks and packages from the Jupyter directory', '\r\n',
'* clean : Returns the notebooks to their original states', '\r\n',
'* help : Displays this dialogue', '\r\n'])

error_dialogue = '\r\nUnknown error occurred.\r\n'

# check arguments
args = sys.argv
if len(args) > 2:
raise RuntimeError(help_dialogue)

arg = args[1]
if arg not in ['install', 'uninstall', 'clean', 'help', 'unpackage']:
raise ValueError(help_dialogue)

# define functions
def install_notebooks():
print('\r\n***** Installing Notebooks *****\r\n')
dst = get_notebook_dst()
src = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', 'notebooks'))
if os.path.exists(dst):
raise RuntimeError(''.join(['Notebooks already installed. ',
'Please uninstall notebooks before reinstalling.\r\n']))
if not os.path.exists(src):
raise RuntimeError(''.join(['Path does not exist: ', src, '\r\n']))
copy_tree(src, dst)
logfile = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', 'install.txt'))
with open(logfile, 'w') as f:
f.write(dst)

def install_packages():
dst = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', 'package_list.txt'))
if not os.path.exists(dst):
raise RuntimeError(error_dialogue)
with open(dst, 'r') as f:
package_list = f.readlines()
for package in package_list:
package_name, package_src = package.split(' ')
print(''.join(['***** Installing ', package_name, ' *****\r\n']))
status = subprocess.check_call(["pip3", "install", package_src])
print('\r\n') # Pip is not playing nice
if status != 0:
raise RuntimeError(''.join(['Package ', package_src, ' failed to install.\r\n']))

def uninstall_notebooks():
print('\r\n***** Uninstalling Notebooks *****\r\n')
logfile = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', 'install.txt'))
if not os.path.exists(logfile):
raise RuntimeError('Notebooks do not have an install location. Nothing has been removed.\r\n')
with open(logfile, 'r') as f:
dst = f.readline()
if not os.path.exists(dst):
raise RuntimeError('Notebooks are not installed. Nothing has been removed.\r\n')
shutil.rmtree(dst)
os.remove(logfile)
print('Notebooks uninstalled successfully.\r\n')

def uninstall_packages():
dst = os.path.abspath(os.path.join(os.path.realpath(__file__), '..', 'package_list.txt'))
if not os.path.exists(dst):
raise RuntimeError(error_dialogue)
with open(dst, 'r') as f:
package_list = f.readlines()
for package in package_list:
package_name, _ = package.split(' ')
print(''.join(['***** Uninstalling ', package_name, ' *****\r\n']))
status = subprocess.check_call(["pip3", "uninstall", "-y", package_name])
print('\r\n') # Pip is not playing nice
if status != 0:
raise RuntimeError(''.join(['Package ', package_name, ' failed to uninstall.\r\n']))

def unpackage_notebooks():
print('\r\n***** Unpackaging Notebooks *****\r\n')
if 'BOARD' not in os.environ:
board = 'RFSoC4x2'
else:
board = os.environ['BOARD']
if board not in board_list:
board = 'RFSoC4x2'
currentdir = get_notebook_dst()
for folder in os.listdir(currentdir):
notebookdir = os.path.join(currentdir, folder, 'boards')
if os.path.exists(notebookdir):
for file in os.listdir(notebookdir):
file_split = file.split('_')
if board in file_split:
file_split.remove(board)
file_name = '_'.join(file_split)
src = os.path.join(notebookdir, file)
dst = os.path.join(notebookdir, '..', file_name)
shutil.copy(src, dst)

def clean_notebooks():
print('\r\n***** Cleaning Notebooks *****\r\n')
uninstall_notebooks()
install_notebooks()
unpackage_notebooks()
print('Notebooks cleaned successfully\r\n')

def get_notebook_dst():
if 'PYNQ_JUPYTER_NOTEBOOKS' not in os.environ:
# Install to current working directory if not on PYNQ
dst = os.path.join(os.getcwd(), package_name)
dialogue = ''.join(['Not using a PYNQ board. ',
'Use `export PYNQ_JUPYTER_NOTEBOOKS=<desired-notebook-path>` ',
'to set the notebooks directory.\r\n',
'Installing notebooks to the current working directory: ',
dst, '\r\n'])
else:
dst = os.path.join(os.environ['PYNQ_JUPYTER_NOTEBOOKS'], package_name)
dialogue = ''.join(['Using a PYNQ board. ',
'Installing notebooks to the PYNQ Jupyter directory: ',
dst, '\r\n'])
print(dialogue)
return dst

# run script
if arg == 'install':
install_notebooks()
unpackage_notebooks()
if 'BOARD' not in os.environ:
print('Not installing RFSoC packages.\r\n')
else:
board = os.environ['BOARD']
if board in board_list:
print('Installing RFSoC packages...\r\n')
install_packages()
else:
print('Not installing RFSoC packages as not an RFSoC platform.\r\n')
print('rfsoc_book installed successfully\r\n')
elif arg == 'uninstall':
uninstall_notebooks()
#if 'BOARD' not in os.environ:
# print('Not uninstalling RFSoC packages.\r\n')
#else:
# board = os.environ['BOARD']
# if board in board_list:
# print('Uninstalling RFSoC packages...\r\n')
# uninstall_packages()
# else:
# print('Not uninstalling RFSoC packages as not an RFSoC platform.\r\n')
print('rfsoc_book uninstalled successfully\r\n')
elif arg == 'clean':
clean_notebooks()
elif arg == 'help':
print(help_dialogue)
elif arg == 'unpackage':
unpackage_notebooks()
else:
raise RuntimeError(error_dialogue)

Loading

0 comments on commit 751ac85

Please sign in to comment.