Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implements options #54

Draft
wants to merge 3 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pyfpga/ise.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def _make_custom(self):
self.data['speed'] = info['speed']
self.data['package'] = info['package']

def add_slog(self, pathname):
def add_slog(self, pathname, options=None):
"""Add System Verilog file/s."""
raise NotImplementedError('ISE does not support SystemVerilog')

Expand Down
82 changes: 65 additions & 17 deletions pyfpga/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ def add_include(self, path):
raise NotADirectoryError(path)
self.data.setdefault('includes', []).append(path.as_posix())

def _add_file(self, pathname, hdl=None, lib=None):
def _add_file(self, pathname, hdl=None, lib=None, options=None):
files = glob.glob(pathname, recursive=True)
if len(files) == 0:
raise FileNotFoundError(pathname)
Expand All @@ -89,55 +89,74 @@ def _add_file(self, pathname, hdl=None, lib=None):
attr['hdl'] = hdl
if lib:
attr['lib'] = lib
if options:
attr['opt'] = options
if path in self.data.get('files', {}):
del self.data['files'][path]
self.data.setdefault('files', {})[path] = attr

def add_slog(self, pathname):
def add_slog(self, pathname, options=None):
"""Add System Verilog file/s.

:param pathname: path to a SV file (glob compliant)
:type pathname: str
:param options: extra options for the underlying command
:type options: str, optional
:raises FileNotFoundError: when pathname is not found
"""
self.logger.debug('Executing add_slog: %s', pathname)
self._add_file(pathname, 'slog')
self.logger.debug('Executing add_slog:')
self.logger.debug('* pathname = %s', pathname)
self.logger.debug('* options = %s', options)
self._add_file(pathname, 'slog', options)

def add_vhdl(self, pathname, lib=None):
def add_vhdl(self, pathname, lib=None, options=None):
"""Add VHDL file/s.

:param pathname: path to a SV file (glob compliant)
:type pathname: str
:param lib: VHDL library name
:type lib: str, optional
:param options: extra options for the underlying command
:type options: str, optional
:raises FileNotFoundError: when pathname is not found
"""
self.logger.debug('Executing add_vhdl:')
self.logger.debug('* pathname = %s', pathname)
lib_str = 'default library' if lib is None else lib
self.logger.debug('Executing add_vhdl: %s : %s', lib_str, pathname)
self._add_file(pathname, 'vhdl', lib)
self.logger.debug('* lib = %s', lib_str)
self.logger.debug('* options = %s', options)
self._add_file(pathname, 'vhdl', lib, options)

def add_vlog(self, pathname):
def add_vlog(self, pathname, options=None):
"""Add Verilog file/s.

:param pathname: path to a SV file (glob compliant)
:type pathname: str
:param options: extra options for the underlying command
:type options: str, optional
:raises FileNotFoundError: when pathname is not found
"""
self.logger.debug('Executing add_vlog: %s', pathname)
self._add_file(pathname, 'vlog')
self.logger.debug('Executing add_vlog:')
self.logger.debug('* pathname = %s', pathname)
self.logger.debug('* options = %s', options)
self._add_file(pathname, 'vlog', options)

def add_cons(self, path):
def add_cons(self, path, options=None):
"""Add a constraint file.

:param pathname: path of a file
:param pathname: path to a constraint file
:type pathname: str
:param options: extra options for the underlying command
:type options: str, optional
:raises FileNotFoundError: if path is not found
"""
self.logger.debug('Executing add_cons: %s', path)
path = Path(path).resolve()
if not path.is_file():
raise FileNotFoundError(path)
attr = {}
if options:
attr['opt'] = options
self.data.setdefault('constraints', {})[path.as_posix()] = attr

def add_param(self, name, value):
Expand All @@ -148,7 +167,9 @@ def add_param(self, name, value):
:param value: parameter/generic value
:type name: str
"""
self.logger.debug('Executing add_param: %s : %s', name, value)
self.logger.debug('Executing add_param:')
self.logger.debug('* name = %s', name)
self.logger.debug('* value = %s', value)
self.data.setdefault('params', {})[name] = value

def add_define(self, name, value):
Expand All @@ -159,7 +180,9 @@ def add_define(self, name, value):
:param value: define value
:type name: str
"""
self.logger.debug('Executing add_define: %s : %s', name, value)
self.logger.debug('Executing add_define:')
self.logger.debug('* name = %s', name)
self.logger.debug('* value = %s', value)
self.data.setdefault('defines', {})[name] = value

def add_fileset(self, pathname):
Expand Down Expand Up @@ -194,7 +217,9 @@ def add_hook(self, stage, hook):
:type hook: str
:raises ValueError: when stage is invalid
"""
self.logger.debug('Executing add_hook: %s : %s', stage, hook)
self.logger.debug('Executing add_hook:')
self.logger.debug('* stage = %s', stage)
self.logger.debug('* hook = %s', hook)
stages = [
'precfg', 'postcfg', 'presyn', 'postsyn',
'prepar', 'postpar', 'prebit', 'postbit'
Expand All @@ -203,6 +228,25 @@ def add_hook(self, stage, hook):
raise ValueError('Invalid stage.')
self.data.setdefault('hooks', {}).setdefault(stage, []).append(hook)

def set_options(self, command, options):
"""Set extra options for the specified underlying command.

:param command: command where to apply the options
:type command: str
:param options: extra options for the underlying command
:type options: str
:raises ValueError: when command is invalid
"""
self.logger.debug('Executing set_options:')
self.logger.debug('* command = %s', command)
self.logger.debug('* options = %s', options)
commands = ['prj', 'syn', 'par', 'bit']
if command not in commands:
raise ValueError('Invalid command.')
self.data.setdefault('options', {}).setdefault(command, []).append(
options
)

def set_debug(self):
"""Enables debug messages."""
self.logger.setLevel(logging.DEBUG)
Expand All @@ -219,7 +263,9 @@ def make(self, first='cfg', last='bit'):

.. note:: valid steps are ``cfg``, ``syn``, ``par`` and ``bit``.
"""
self.logger.debug('Executing make')
self.logger.debug('Executing make:')
self.logger.debug('* first = %s', first)
self.logger.debug('* last = %s', last)
if last not in STEPS:
raise ValueError('Invalid last step.')
if first not in STEPS:
Expand Down Expand Up @@ -247,7 +293,9 @@ def prog(self, bitstream=None, position=1):
:raises ValueError: for missing or wrong values
:raises RuntimeError: error running the needed underlying tool
"""
self.logger.debug('Executing prog')
self.logger.debug('Executing prog:')
self.logger.debug('* bitstream = %s', bitstream)
self.logger.debug('* position = %s', position)
if position not in range(1, 9):
raise ValueError('Invalid position.')
self.logger.info('Programming')
Expand Down