Skip to content

Commit

Permalink
ENH: Simplified FW build procedure
Browse files Browse the repository at this point in the history
  • Loading branch information
Marco Vogt committed Nov 8, 2024
1 parent 2d39da0 commit f71aeac
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 12 deletions.
60 changes: 58 additions & 2 deletions basil/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
# ------------------------------------------------------------
#


from array import array

import numpy as np
from bitarray import bitarray
import os.path
import git
import fileinput


def logging(fn):
Expand Down Expand Up @@ -45,6 +46,61 @@ def bitarray_to_byte_array(bitarr):
return array('B', bs.astype(np.uint8))


def get_si_tcp(rel_path=''):
''' Download SiTCP/SiTCP10G sources from the official github repo and apply patches
'''

sitcp_repo = r'https://github.com/BeeBeansTechnologies/SiTCP_Netlist_for_Kintex7'
sitcp_10G_repo = r'https://github.com/BeeBeansTechnologies/SiTCPXG_Netlist_for_Kintex7'

def line_prepender(filename, line):
with open(filename, 'rb+') as f:
content = f.read()
f.seek(0, 0)
add = bytearray()
add.extend(map(ord, line))
add.extend(map(ord, '\n'))
f.write(add + content)

sitcp_folder = os.path.join(os.path.os.getcwd(), rel_path, 'SiTCP/')

# Only download if the SiTCP git repository is not present
if not os.path.isdir(os.path.join(sitcp_folder, '.git')):
print('Downloading SiTCP')

# Has to be moved to be allowed to use existing folder for git checkout
git.Repo.clone_from(url=sitcp_repo,
to_path=sitcp_folder, branch='master')
# Patch sources, see README of bdaq53
line_prepender(filename=sitcp_folder + 'TIMER.v', line=r'`default_nettype wire')
line_prepender(filename=sitcp_folder + 'WRAP_SiTCP_GMII_XC7K_32K.V', line=r'`default_nettype wire')
for line in fileinput.input([sitcp_folder + 'WRAP_SiTCP_GMII_XC7K_32K.V'], inplace=True):
print(line.replace("assign\tMY_IP_ADDR[31:0]\t= (~FORCE_DEFAULTn | (EXT_IP_ADDR[31:0]==32'd0) \t? DEFAULT_IP_ADDR[31:0]\t\t: EXT_IP_ADDR[31:0]\t\t);",
'assign\tMY_IP_ADDR[31:0]\t= EXT_IP_ADDR[31:0];'), end='')
else: # update if existing
print('SiTCP already present. Checking for updates')
g = git.cmd.Git(sitcp_folder)
g.pull()

sitcp_10G_folder = os.path.join(os.path.os.getcwd(), rel_path, 'SiTCP10G/')
# Only download if the SiTCP10G git repository is not present
if not os.path.isdir(os.path.join(sitcp_10G_folder, '.git')):
print('Downloading SiTCP10G')

# Has to be moved to be allowed to use existing folder for git checkout
git.Repo.clone_from(url=sitcp_10G_repo,
to_path=sitcp_10G_folder, branch='master')
# Patch sources, see README of bdaq53
for line in fileinput.input([sitcp_10G_folder + 'WRAP_SiTCPXG_XC7K_128K.v'], inplace=True):
print(line.replace("\t\t.MY_IP_ADDR \t\t\t\t\t(MY_IP_ADDR[31:0] \t\t\t),\t// in\t: My IP address[31:0]",
"\t\t.MY_IP_ADDR \t\t\t\t\t({8'd192, 8'd168, 8'd100, 8'd12}),\t// in\t: My IP address[31:0]"), end='')

else: # update if existing
print('SiTCP10G already present. Checking for updates')
g = git.cmd.Git(sitcp_10G_folder)
g.pull()


# Python 2/3 compatibility function for array.tobytes function


Expand Down
27 changes: 17 additions & 10 deletions examples/bdaq/Readme.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,23 @@
### Ethernet example for the BDAQ53 hardware

# Ethernet example for the BDAQ53 hardware
This example shows how to control a GPIO module and how to receive data via the Ethernet interface.
1. Data transfer is started by setting a bit [0] in the GPIO.
2. FPGA starts to send data from a 32 bit counter through a BRAM FIFO.
3. The Python script checks the received data and counts the transferred bytes during a given time period.
4. At the end, the average data rate is printed and the FPGA data source is stopped by clearing bit [0].

## Build script
To build this example firmware, navigate to `firmware/vivado` and start the process using the Makefile
```terminal
cd firmware/vivado
make
```
`make download`, `make synthesize` and `make clean` can be used to call the sub-tasks individually.

The firmware makes use of the free SiTcp Ethernet module ([GitHub][url1]). Put the extracted files in */firmware/src/SiTCP*.
You can find build instructions in the *Firmware section* of the ([bdaq53 readme][url2]).
The firmware makes use of the free SiTcp Ethernet module ([GitHub][url1]).
You can find further build instructions in the *Firmware section* of the ([bdaq53 readme][url2]).

[url1]: https://github.com/BeeBeansTechnologies/SiTCP_Netlist_for_Kintex7
[url2]: https://gitlab.cern.ch/silab/bdaq53#firmware

1. Data transfer is started by setting a bit [0] in the GPIO.
2. FPGA starts to send data from a 32 bit counter, as fast as possible through a FIFO.
3. Python receives the data and counts bytes during a given time period.
4. At the end, the average data rate is printed and the FPGA data source is stopped by clearing bit [0].

Test for CocoTB available in */test*
## Test
A test for CocoTB is available under `test`
21 changes: 21 additions & 0 deletions examples/bdaq/firmware/vivado/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Targets
.PHONY: all clean

# Run the main process
all: download synthesize

# Download SiTCP to the base directory
download:
@echo "Downloading SiTCP"
@python -c "from basil.utils import utils; utils.get_si_tcp('..')"

# Start synthesis
synthesize:
@echo "Starrting firmware synthesis"
vivado -mode batch -source run.tcl -notrace

# Clean generated files
clean:
@echo "Removing generated Vivado files"
rm -f *.log *.jou *.str
rm -rf designs reports output .Xil .ngc2edfcache ipcore.*
10 changes: 10 additions & 0 deletions examples/bdaq/firmware/vivado/run.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,17 @@
# vivado -mode tcl -source run.tcl
#

# Use current environment python instead of vivado included python
if {[info exists ::env(PYTHONPATH)]} {
unset ::env(PYTHONPATH)
}
if {[info exists ::env(PYTHONHOME)]} {
unset ::env(PYTHONHOME)
}
# Get rid of Vivado python (since Vivado 2021) in PATH and use python from calling shell
set env(PATH) [join [lsearch -inline -all -not -regexp [split $::env(PATH) ":"] (.*)lnx64\/python(.*)] ":"]

set firmware_dir [exec python -c "import os; print(os.path.dirname(os.getcwd()))"]
set basil_dir [exec python -c "import basil, os; print(str(os.path.dirname(basil.__file__)))"]
set include_dirs [list $basil_dir/firmware/modules $basil_dir/firmware/modules/utils]

Expand Down

0 comments on commit f71aeac

Please sign in to comment.