Skip to content

Commit

Permalink
[xilinx] Logic for parsing AXI memory ports from kernel (#958)
Browse files Browse the repository at this point in the history
* [xilinx] Logic for parsing AXI memory ports from kernel

* Actually use extracted port names

Starting with Alex's XML parsing stuff, we now actually pass this stuff
to our `gen_xo.tcl` script. This also uses the `mode` attribute on the
`port` XML elements to distinguish which ports are relevant.

* Use pathlib, not os.path

* [xilinx] Pair data with tests

* [xilinx] Add dot-product test

It's a test with 3 external memories, so it tests our new ability to
support more than 1 such interface.

* [xilinx] Add expect files for dot-product tests

* [xilinx] Add missing data file for old test

Co-authored-by: YoungSeok Na <yn224@havarti.cs.cornell.edu>
Co-authored-by: Adrian Sampson <adrian@radbox.org>
Co-authored-by: Rachit Nigam <rachit.nigam12@gmail.com>
  • Loading branch information
4 people authored Apr 12, 2022
1 parent 7a81d9a commit f706af7
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 3 deletions.
28 changes: 26 additions & 2 deletions fud/fud/stages/xilinx/xclbin.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import logging as log
import xml.etree.ElementTree as ET
from pathlib import Path

from fud.stages import Source, SourceType, Stage
Expand All @@ -7,6 +8,22 @@
from fud.utils import shell


def get_ports(kernel_xml):
"""Parse an XML file to get the names of AXI ports in a design.
The argument is the filename for a `kernel.xml` file that is also an
input to the Xilinx `.xo` packaging step (which describes the
physical ports in the design and how the logical arguments are
mapped onto these ports). We extract the names of all AXI master
ports.
"""
tree = ET.parse(kernel_xml)
root = tree.getroot()
for port in root.iter('port'):
if port.attrib['mode'] == 'master':
yield port.attrib['name']


class XilinxStage(Stage):
name = "xclbin"

Expand Down Expand Up @@ -58,12 +75,19 @@ def _define_steps(self, input_data, builder, config):
"/scratch/opt/Xilinx/Vivado/2020.2/bin/vivado "
"-mode batch "
"-source gen_xo.tcl "
"-tclargs xclbin/kernel.xo m0_axi"
"-tclargs xclbin/kernel.xo {port_names}"
)

@builder.step(package_cmd)
def package_xo(client: SourceType.UnTyped, tmpdir: SourceType.String):
self._shell(client, package_cmd.format(tmpdir=tmpdir), remote_exec)
# Get the AXI port names.
port_names = list(get_ports(Path(tmpdir) / 'kernel.xml'))

# Run the .xo packager Vivado script.
self._shell(client, package_cmd.format(
tmpdir=tmpdir,
port_names=' '.join(port_names),
), remote_exec)

xclbin_cmd = (
"cd {tmpdir} && "
Expand Down
Empty file.
1 change: 1 addition & 0 deletions tests/xilinx/dot-product.futil
1 change: 1 addition & 0 deletions tests/xilinx/dot-product.futil.data
28 changes: 28 additions & 0 deletions tests/xilinx/emulate/dot-product.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

{
"memories": {
"A0": [
27,
48,
88,
69,
9,
44,
3,
73
],
"B0": [
95,
68,
79,
39,
33,
88,
51,
99
],
"v0": [
0
]
}
}
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/xilinx/runt.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ source /opt/xilinx/xrt/setup.sh > /dev/null ; \
EMCONFIG_PATH=`pwd` \
XCL_EMULATION_MODE=hw_emu \
fud exec -q -s futil.exec ../../target/debug/futil \
{} --to fpga -s fpga.data data.json | \
{} --to fpga -s fpga.data {}.data | \
grep -Ev "^INFO|^Data|RD ="'
"""

0 comments on commit f706af7

Please sign in to comment.