Skip to content

Commit

Permalink
Add Surelog support as yosys frontend
Browse files Browse the repository at this point in the history
Signed-off-by: Maciej Dudek <[email protected]>
  • Loading branch information
mtdudek committed Aug 11, 2021
1 parent f4b3cc5 commit c63d188
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 21 deletions.
2 changes: 2 additions & 0 deletions edalize/icestorm.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@ def configure_main(self):
{'yosys' : {
'arch' : 'ice40',
'yosys_synth_options' : yosys_synth_options,
'yosys_read_options' : self.tool_options.get('yosys_read_options', []),
'yosys_as_subtool' : True,
'yosys_template' : self.tool_options.get('yosys_template'),
'frontend_options' : self.tool_options.get('frontedn_options',[])
},
'nextpnr' : {
'nextpnr_options' : self.tool_options.get('nextpnr_options', [])
Expand Down
59 changes: 59 additions & 0 deletions edalize/surelog.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

import logging
import os.path

from edalize.edatool import Edatool
import shutil

logger = logging.getLogger(__name__)

class Surelog(Edatool):

argtypes = ['vlogdefine', 'vlogparam']

@classmethod
def get_doc(cls, api_ver):
if api_ver == 0:
return {'description' : "Surelog",
'members' : [
{'name' : 'arch',
'type' : 'String',
'desc' : 'Target architecture. Legal values are *xilinx*, *ice40* and *ecp5*'}
],
'lists' : [
{'name' : 'surelog_options',
'type' : 'String',
'desc' : 'List of the Surelog parameters'},
]}

def configure_main(self):
(src_files, incdirs) = self._get_fileset_files()
verilog_file_list = []
systemverilog_file_list = []
for f in src_files:
if f.file_type.startswith('verilogSource'):
verilog_file_list.append(f.name)
if f.file_type.startswith('systemVerilogSource'):
systemverilog_file_list.append("-sv " + f.name)

surelog_options = self.tool_options.get('surelog_options', [])
arch = self.tool_options.get('arch', None)

pattern = len(self.vlogparam.keys()) * " -P%s=%%s"
verilog_params_command = pattern % tuple(self.vlogparam.keys()) % tuple(self.vlogparam.values())

verilog_defines_command = "+define" if self.vlogdefine.items() else ""
pattern = len(self.vlogdefine.keys()) * "+%s=%%s"
verilog_defines_command += pattern % tuple(self.vlogdefine.keys()) % tuple(self.vlogdefine.values())

pattern = len(incdirs) * " -I%s"
include_files_command = pattern % tuple(incdirs)

commands = self.EdaCommands()
share_path = os.path.join(os.path.dirname(shutil.which("uhdm-yosys")), "../share/uhdm-yosys")
commands.add(["surelog", f"{' '.join(surelog_options)}", "-parse", f"{verilog_defines_command}",
f"{verilog_params_command}", f"-top {self.toplevel}", f"{include_files_command}",
f"{' '.join(verilog_file_list)}", f"{' '.join(systemverilog_file_list)}"],
["slpp_all/surelog.uhdm"], [])
commands.add([f"cp slpp_all/surelog.uhdm {self.toplevel}.uhdm"] ,[self.toplevel + '.uhdm'], ["slpp_all/surelog.uhdm"])
self.commands = commands.commands
4 changes: 4 additions & 0 deletions edalize/symbiflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from edalize.edatool import Edatool
from edalize.yosys import Yosys
from edalize.surelog import Surelog
from importlib import import_module

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -100,8 +101,11 @@ def configure_nextpnr(self):
"yosys" : {
"arch" : vendor,
"yosys_synth_options" : yosys_synth_options,
"yosys_additional_commands" : yosys_additional_commands,
'yosys_read_options' : self.tool_options.get('yosys_read_options', []),
"yosys_template" : yosys_template,
"yosys_as_subtool" : True,
'frontend_options' : self.tool_options.get('frontend_options', []),
}
}
}
Expand Down
2 changes: 2 additions & 0 deletions edalize/trellis.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,10 @@ def configure_main(self):
{'yosys' : {
'arch' : 'ecp5',
'yosys_synth_options' : self.tool_options.get('yosys_synth_options', []),
'yosys_read_options' : self.tool_options.get('yosys_read_options'),
'yosys_as_subtool' : True,
'yosys_template' : self.tool_options.get('yosys_template'),
'frontend_options' : self.tool_options.get('frontend_options'),
},
'nextpnr' : {
'nextpnr_options' : self.tool_options.get('nextpnr_options', [])
Expand Down
13 changes: 13 additions & 0 deletions edalize/vivado.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,17 @@ def get_doc(cls, api_ver):
{'name' : 'hw_target',
'type' : 'Description',
'desc' : 'A pattern matching a board identifier. Refer to the Vivado documentation for ``get_hw_targets`` for details. Example: ``*/xilinx_tcf/Digilent/123456789123A``'},
],
'lists' : [
{'name' : 'yosys_synth_options',
'type' : 'String',
'desc' :'Additional options for synth command'},
{'name' : 'yosys_read_options',
'type' : 'String',
'desc' : 'Additional options for Yosys\' read command'},
{'name' : 'frontend_options',
'type' : 'String',
'desc' : 'Additional options for the Yosys frontend'},
]}

""" Get tool version
Expand Down Expand Up @@ -91,7 +102,9 @@ def configure_main(self):
'arch' : 'xilinx',
'output_format' : 'edif',
'yosys_synth_options' : self.tool_options.get('yosys_synth_options', []),
'yosys_read_options' : self.tool_options.get('yosys_read_options', []),
'yosys_as_subtool' : True,
'frontend_options' : self.tool_options.get('frontend_options', [])
}

yosys = Yosys(self.edam, self.work_root)
Expand Down
86 changes: 65 additions & 21 deletions edalize/yosys.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import os.path

from edalize.edatool import Edatool
from edalize.surelog import Surelog

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -38,6 +39,15 @@ def get_doc(cls, api_ver):
{'name' : 'yosys_synth_options',
'type' : 'String',
'desc' : 'Additional options for the synth command'},
{'name' : 'yosys_read_options',
'type' : 'String',
'desc' : 'Addtional options for the read_* command (e.g. read_verlog or read_uhdm)'},
{'name' : 'yosys_additional_commands',
'type' : 'String',
'desc' : 'Additional commands for the yosys script after synth'},
{'name' : 'frontend_options',
'type' : 'String',
'desc' : 'Additional options for the Yosys frontend'},
]}

def configure_main(self):
Expand All @@ -49,20 +59,51 @@ def configure_main(self):
file_table = []
unused_files = []

for f in self.files:
cmd = ""
if f['file_type'].startswith('verilogSource'):
cmd = 'read_verilog'
elif f['file_type'].startswith('systemVerilogSource'):
cmd = 'read_verilog -sv'
elif f['file_type'] == 'tclSource':
cmd = 'source'

if cmd:
if not self._add_include_dir(f, incdirs):
file_table.append(cmd + ' {' + f['name'] + '}')
else:
unused_files.append(f)
yosys_read_options = " ".join(self.tool_options.get('yosys_read_options', []))
yosys_synth_options = self.tool_options.get('yosys_synth_options', [])

arch = self.tool_options.get('arch', None)
if not arch:
logger.error("ERROR: arch is not defined.")

use_surelog = False
if "frontend=surelog" in yosys_synth_options:
use_surelog = True
yosys_synth_options.remove("frontend=surelog")

if use_surelog:
self.edam['tool_options']['surelog'] = {
'surelog_options' : self.tool_options.get('frontend_options', []),
'arch' : arch,
}
surelog = Surelog(self.edam, self.work_root)
surelog.configure()
self.vlogparam.clear()
self.vlogdefine.clear()
uhdm_file = os.path.abspath(self.work_root + '/' + self.toplevel + '.uhdm')
file_table.append('read_uhdm' + yosys_read_options + ' {' + uhdm_file + '}')
for f in self.files:
if f['file_type'].startswith('verilogSource') or\
f['file_type'].startswith('systemVerilogSource') or\
f['file_type'] == 'tclSource':
continue
else:
unused_files.append(f)
else:
for f in self.files:
cmd = ""
if f['file_type'].startswith('verilogSource'):
cmd = 'read_verilog'
elif f['file_type'].startswith('systemVerilogSource'):
cmd = 'read_verilog -sv'
elif f['file_type'] == 'tclSource':
cmd = 'source'

if cmd:
if not self._add_include_dir(f, incdirs):
file_table.append(cmd + ' {' + f['name'] + '}')
else:
unused_files.append(f)

self.edam['files'] = unused_files
of = [
Expand All @@ -86,10 +127,6 @@ def configure_main(self):
self.toplevel))

output_format = self.tool_options.get('output_format', 'blif')
arch = self.tool_options.get('arch', None)

if not arch:
logger.error("ERROR: arch is not defined.")

template = yosys_template or 'edalize_yosys_template.tcl'
template_vars = {
Expand All @@ -99,7 +136,8 @@ def configure_main(self):
'incdirs' : ' '.join(['-I'+d for d in incdirs]),
'top' : self.toplevel,
'synth_command' : "synth_" + arch,
'synth_options' : " ".join(self.tool_options.get('yosys_synth_options', '')),
'synth_options' : " ".join(yosys_synth_options),
'additional_commands' : self.tool_options.get('yosys_additional_commands', []),
'write_command' : "write_" + output_format,
'default_target' : output_format,
'edif_opts' : '-pvector bra' if arch=='xilinx' else '',
Expand All @@ -117,9 +155,15 @@ def configure_main(self):
template_vars)

commands = self.EdaCommands()
commands.add(['yosys', '-l', 'yosys.log', '-p', f'"tcl {template}"'],
dep = []
yosys = 'yosys'
if use_surelog:
commands.commands += surelog.commands
dep = [self.toplevel + ".uhdm"]
yosys = 'uhdm-' + yosys
commands.add([yosys, '-l', 'yosys.log', '-p', f'"tcl {template}"'],
[f'{self.name}.{output}' for output in ['blif', 'json','edif']],
[template])
[template]+dep)
if self.tool_options.get('yosys_as_subtool'):
self.commands = commands.commands
else:
Expand Down

0 comments on commit c63d188

Please sign in to comment.