Skip to content

Commit

Permalink
Merge pull request #94 from antmicro/add-nextpnr-fpga-interchange
Browse files Browse the repository at this point in the history
edalize: add fpga_interchange variant to nextpnr flow
  • Loading branch information
acomodi committed Apr 20, 2021
2 parents 4a6899c + d24d830 commit d9d753c
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 10 deletions.
30 changes: 28 additions & 2 deletions edalize/nextpnr.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
class Nextpnr(Edatool):

argtypes = []
archs = ['xilinx', 'fpga_interchange']
families = ['xc7']

@classmethod
def get_doc(cls, api_ver):
Expand Down Expand Up @@ -95,37 +97,61 @@ def configure_main(self):
file_table = []

output_format = self.tool_options.get('output_format', 'fasm')
arch = self.tool_options.get('arch', 'xilinx')
arch = self.tool_options.get('arch')

assert arch in getattr(self, 'archs'), 'Missing or invalid "arch" parameter in "tool_options"'

synth_design = None
chipdb = None
device = None
xdc = None

for f in src_files:
if f.file_type in ['synthJson']:
synth_design = f.name
elif f.file_type in ['bba']:
chipdb = f.name
elif f.file_type in ['device']:
device = f.name
elif f.file_type in ['xdc']:
xdc = f.name
else:
continue

assert chipdb and xdc, "Missing required files."
assert device is not None or arch is not 'fpga_interchange', 'Missing required ".device" file for "fpga_interchange" arch'

additional_options = self.tool_options.get('nextpnr_impl_options', '')
package = self.tool_options.get('package', None)

assert package is not None or arch is not 'fpga_interchange', 'Missing required "package" parameter for "fpga_interchange" arch'

package = package.split('-')[0] if arch == "fpga_interchange" else None

family = self.tool_options.get('family', None)

assert family is not None or arch is not 'fpga_interchange', 'Missing required "family" parameter for "fpga_interchange" arch'
assert family in getattr(self, 'families') or arch is not 'fpga_interchange', 'Unsupported family: {}'.format(family)

schema_dir = self.tool_options.get('schema_dir', None)
assert schema_dir is not None or arch is not 'fpga_interchange', 'Missing required "schema_dir" parameter for "fpga_interchange" arch'

template_vars = {
'toplevel' : self.toplevel,
'arch' : arch,
'chipdb' : chipdb,
'device' : device,
'constr' : xdc,
'default_target' : output_format,
'name' : self.name,
'package' : package,
'family' : family,
'schema_dir' : schema_dir,
'additional_options': additional_options,
}

makefile_name = self.name + '-nextpnr.mk' if part_of_toolchain else 'Makefile'
self.render_template('nextpnr-makefile.j2',
self.render_template('nextpnr-{}-makefile.j2'.format(arch),
makefile_name,
template_vars)

37 changes: 29 additions & 8 deletions edalize/symbiflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
class Symbiflow(Edatool):

argtypes = ['vlogdefine', 'vlogparam', 'generic']
archs = ['xilinx', 'fpga_interchange']
families = ['xc7']

@classmethod
def get_doc(cls, api_ver):
Expand Down Expand Up @@ -78,16 +80,41 @@ def configure_nextpnr(self):
yosys_synth_options = self.tool_options.get('yosys_synth_options', '')
yosys_additional_commands = self.tool_options.get('yosys_additional_commands', '')
nextpnr_impl_options = self.tool_options.get('options', '')
arch = self.tool_options.get('arch')

assert arch in getattr(self, 'archs'), 'Missing or invalid "arch" parameter: {} in "tool_options"'.format(arch)

package = self.tool_options.get('package', None)
assert package is not None, 'Missing required "package" parameter'

schema_dir = self.tool_options.get('schema_dir', None)
assert schema_dir is not None or arch is not 'fpga_interchange', 'Missing required "schema_dir" parameter for "fpga_interchange" arch'

part = self.tool_options.get('part', None)

assert part is not None, 'Missing required "part" parameter'

target_family = None
for family in getattr(self, 'families'):
if family in part:
target_family = family
break

assert target_family is not None or arch is not "fpga_interchange", "Couldn't find family for part: {}. Available families: {}".format(part, ", ".join(getattr(self, 'families')))

nextpnr_edam = {
'files' : self.files,
'name' : self.name,
'toplevel' : self.toplevel,
'tool_options' : {'nextpnr' : {
'arch' : 'xilinx',
'arch' : arch,
'yosys_synth_options' : yosys_synth_options,
'yosys_additional_commands' : yosys_additional_commands,
'nextpnr_impl_options' : nextpnr_impl_options,
'nextpnr_as_subtool' : True,
'package' : package,
'family' : target_family,
'schema_dir' : schema_dir,
}

}
Expand All @@ -98,12 +125,6 @@ def configure_nextpnr(self):

builddir = self.tool_options.get('builddir', 'build')

part = self.tool_options.get('part', None)
package = self.tool_options.get('package', None)

assert part is not None, 'Missing required "part" parameter'
assert package is not None, 'Missing required "package" parameter'

partname = part + package

if 'xc7a' in part:
Expand Down Expand Up @@ -174,7 +195,7 @@ def configure_nextpnr(self):
'environment_script': environment_script,
}

self.render_template('symbiflow-nextpnr-makefile.j2',
self.render_template('symbiflow-nextpnr-{}-makefile.j2'.format(arch),
'Makefile',
makefile_params)

Expand Down
21 changes: 21 additions & 0 deletions edalize/templates/nextpnr/nextpnr-fpga_interchange-makefile.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#Auto generated by Edalize

TARGET := {{ name }}

all: $(TARGET).{{ default_target }}

{{ name }}.json: {{ name }}.mk
$(MAKE) -f $<

{{ name }}.netlist: {{ name }}.json
python -m fpga_interchange.yosys_json --schema_dir {{ schema_dir }} --device {{ device }} --top {{ toplevel }} {{ name }}.json {{ name }}.netlist

{{ name }}.phys: {{ name }}.netlist
nextpnr-{{ arch }} --chipdb {{ chipdb }} --package {{ package }} --xdc {{ constr }} --netlist {{ name }}.netlist --write {{ name }}.routed.json --phys {{ name }}.phys {{ additional_options }}

{{ name }}.fasm: {{ name }}.phys
python -m fpga_interchange.fasm_generator --schema_dir {{ schema_dir }} --family {{ family }} {{ device }} {{ name }}.netlist {{ name }}.phys {{ name }}.fasm


clean:
rm -f $(TARGET).json $(TARGET).routed.json $(TARGET).netlist $(TARGET).phys $(TARGET).fasm
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#Auto generated by Edalize
SHELL = bash

NAME := {{ top }}
PARTNAME:= {{ partname }}
BITSTREAM_DEVICE := {{ bitstream_device }}
BUILDDIR:= {{ builddir }}

all: ${NAME}.bit

{% if environment_script -%}
SOURCE_OPTS = source {{ environment_script }} &&
{%- endif %}

${BUILDDIR}:
mkdir ${BUILDDIR}

${NAME}.fasm: ${NAME}-nextpnr.mk | ${BUILDDIR}
${SOURCE_OPTS} $(MAKE) -f ${NAME}-nextpnr.mk

${NAME}.bit: ${NAME}.fasm
${SOURCE_OPTS} cd ${BUILDDIR} && symbiflow_write_bitstream -d ${BITSTREAM_DEVICE} -f ${NAME}.fasm -p ${PARTNAME} -b ${NAME}.bit

clean:
rm -rf ${BUILDDIR}

0 comments on commit d9d753c

Please sign in to comment.