Skip to content
Snippets Groups Projects
Commit 4a987fa1 authored by Pieter Donker's avatar Pieter Donker
Browse files

Task #893: split up long code files in smaller ones

parent 1d4fb7f1
Branches
No related tags found
No related merge requests found
......@@ -18,3 +18,4 @@ from peripheral import PeripheralLibrary, Peripheral
from system import System
from documentation import Documentation
from rom_system import RomSystem
from peripheral_lib import *
......@@ -32,360 +32,13 @@ from copy import deepcopy
from math import ceil
import logging
import yaml
from constants import *
#from constants import *
from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2
from peripheral_lib import *
logger = logging.getLogger('main.peripheral')
class BaseObject(object):
def __init__(self):
self.success = True
self._name = ""
self._prefix = ""
self._args = {}
def update_args(self, args):
""" update self._args with all kv pairs in args """
self._args.update(args)
def _as_str(self, key, default=None):
""" look in settings for key, if available return value as string,
if key not available retur default """
try:
val = str(self._args[key])
return val
except KeyError:
return default
def _as_int(self, key, default=None):
""" look in settings for key, if available return value as int if possible
otherwise return string, if key not available retur default """
try:
val = int(self._args[key])
return val
except ValueError:
return self._args[key]
except KeyError:
return default
def set_kv(self, key, val):
""" set_kv()
if key in valid keys, update key with given value, if key not excists add it.
"""
if val is not None:
self._args[key] = val
return True
return False
def get_kv(self, key, dtype=None):
""" get_kv()
return value for given key, if key in valid keys, else return None
"""
if key not in self._args:
logger.error("key not in arguments %s", key)
return None
if dtype == 'int':
return self._as_int(key)
if dtype == 'string':
return self._as_str(key)
return self._args[key]
def name(self, val=None):
""" set/get name """
if val is not None:
self._name = val
return
return self._name
def prefix(self, val=None):
""" set/get prefix """
if val is not None:
self._prefix = val
return
return self._prefix
class Field(BaseObject):
""" A field defines data at certain address or an array of addresses
"""
def __init__(self, name, settings=None):
super().__init__()
self.name(name)
self._valid_keys = ['number_of_fields', 'width', 'bit_offset', 'access_mode', 'side_effect', 'address_offset',
'address_length', 'reset_value', 'software_value', 'radix', 'field_description']
self._args.update({'number_of_fields' : DEFAULT_NUMBER_OF_FIELDS,
'width' : DEFAULT_WIDTH,
'bit_offset' : DEFAULT_BIT_OFFSET,
'access_mode' : DEFAULT_ACCESS_MODE,
'side_effect' : DEFAULT_SIDE_EFFECT,
'address_offset' : DEFAULT_ADDRESS_OFFSET,
'address_length' : DEFAULT_ADDRESS_LENGTH,
'reset_value' : RESET_VALUE,
'software_value' : DEFAULT_SOFTWARE_VALUE,
'radix' : DEFAULT_RADIX,
'field_description': DEFAULT_DESCRIPTION})
if settings is not None:
for key, val in settings.items():
if key in self._valid_keys:
if key == 'access_mode' and val.upper() not in VALID_ACCESS_MODES:
logger.error("Field.__init__(), Not a valid acces_mode '%s'", val)
self.success = False
elif key == 'side_effect' and val.upper() not in VALID_SIDE_EFFECTS:
logger.error("Field.__init__(), Not a valid side_effect '%s'", val)
self.success = False
else:
self.set_kv(key, val)
else:
logger.error("Field.__init__(), Not a valid key '%s'", key)
self.success = False
def number_of_fields(self, val=None):
""" set/get number of fields """
if val is not None:
self.set_kv('number_of_fields', val)
return
return self._as_int('number_of_fields')
def width(self, val=None):
""" set/get width of field
val: if not None set width of field
return: actual width of field """
if val is not None:
return self.set_kv('width', val)
return self._as_int('width')
def bit_offset(self, val=None):
""" set/get bit_offset of field
val: if not None set bit_offset of field
return: actual bit_offset of field """
if val is not None:
return self.set_kv('bit_offset', val)
return self._as_int('bit_offset')
def access_mode(self, val=None):
""" set/get access_mode of field
val: if not None and a valid mode set access_mode of field
return: actual access_mode of field """
if val is not None:
if val.upper() in VALID_ACCESS_MODES:
return self.set_kv('access_mode', val.upper())
else:
logger.error("unknown access_mode '%s'", val)
self.success = False
return False
return self._as_str('access_mode').upper()
def side_effect(self, val=None):
""" set/get side_effect of field
val: if not None and a valid side_effect set side_effect of field
return: actual side_effect of field """
if val is not None:
if val.upper() in VALID_SIDE_EFFECTS:
return self.set_kv('side_effect', val.upper())
else:
logger.error("unknown side_effect '%s'", val)
self.success = False
return False
return self._as_str('side_effect').upper()
def address_offset(self, val=None):
""" set/get address offset of field
val: if not None set address offset of field
return: actual address offset of field """
if val is not None:
return self.set_kv('address_offset', val)
return self._as_int('address_offset')
def address_length(self, val=None):
""" set/get address length of field
val: if not None set address length of field
return: active address_length of field """
if val is not None:
return self.set_kv('address_length', val)
return self._as_int('address_length')
def reset_value(self, val=None):
""" set/get default hardware reset value of field
val: if not None set default value of field
return: active hardware reset value of field """
if val is not None:
return self.set_kv('reset_value', val)
return self._as_int('reset_value')
def software_value(self, val=None):
""" set/get software reset value of field
val: if not None set default value of field
return: active software reset value of field """
if val is not None:
return self.set_kv('software_value', val)
return self._as_int('software_value')
def radix(self, val=None):
""" set/get radix value of field
val: if not None set default value of field
return: active radix value of field """
if val is not None:
if val.upper() in VALID_RADIXS:
return self.set_kv('radix', val.upper())
else:
logger.error("unknown radix '%s'", val)
self.success = False
return False
return self._as_int('radix')
def field_description(self, val=None):
""" set/get description of field
val: if not None set description of field
return: description of field """
if val is not None:
return self.set_kv('field_description', val)
return self._as_str('field_discription')
class Register(BaseObject):
""" A register consists of Fields
"""
def __init__(self, name, fields=None, settings=None):
super().__init__()
self.name(name)
self.fields = {} if fields is None else fields
self._valid_keys = ['number_of_slaves', 'address_length', 'slave_discription']
self._args.update({'number_of_slaves' : DEFAULT_NUMBER_OF_SLAVES,
'address_length' : DEFAULT_ADDRESS_LENGTH,
'slave_discription': DEFAULT_DESCRIPTION})
self.update_address_length()
def number_of_slaves(self, val=None):
""" set/get number of slaves """
if val is not None:
self.set_kv('number_of_slaves', val)
return
return self._as_int('number_of_slaves')
def add_field(self, name, settings):
""" add new Field to Register with given settings
"""
field = Field(name, settings)
if field.success:
self.fields[name] = field
self.update_address_length()
return True
return False
def update_address_length(self):
""" update total address_length of Register
"""
if len(self.fields) == 0:
return
n_words = 0
for field in self.fields.values():
n_words += int(ceil(float(field.width()) / c_word_w))
self.set_kv('address_length', n_words) # ceil_pow2(n_words))
def address_length(self, val=None):
""" set/get address_length of register
val: if not None set address_length of register
return: address_length of register """
if val is not None:
return self.set_kv('address_length', val)
return self._as_int('address_length', default=1)
class RAM(BaseObject):
""" A RAM is a Field that is repeated address_length times
"""
def __init__(self, name, fields=None, settings=None):
super().__init__()
self.name(name)
self.fields = {} if fields is None else fields
self._valid_keys = ['number_of_slaves']
self._args.update({'number_of_slaves' : DEFAULT_NUMBER_OF_SLAVES})
def number_of_slaves(self, val=None):
""" set/get number of slaves """
if val is not None:
self.set_kv('number_of_slaves', val)
return
return self._as_int('number_of_slaves')
def add_field(self, name, settings):
""" add new Field to Register with given settings
"""
field = Field(name, settings)
if field.success:
self.fields[name] = Field(name, settings)
self.update_address_length()
return True
return False
def update_address_length(self):
""" update total address_length of Register
"""
if len(self.fields) == 0:
return
n_words = 0
for field in self.fields.values():
n_words += int(ceil(float(field.width()) / c_word_w))
self.set_kv('address_length', n_words) # ceil_pow2(n_words))
# TODO: use BaseObject
class FIFO(object):
""" A FIFO is a specific set of Fields
"""
def __init__(self, name, settings):
self.number_offifos = 1
fifo_fields = {}
fifo_fields["fifo_status"] = Field(name="fifo_status",
settings={
'width': 4,
'mode': "RO",
'offset': 0x0,
'default': 0,
'descr': "fifo status register. Bit 0: Fifo Full Bit 1: Fifo Empty"
})
fifo_fields["fifo_used_w"] = Field(name="fifo_used_w",
settings={
'width': 32,
'mode': "RO",
'offset': 0x4,
'default': 0,
'descr': "fifo used words register."
})
fifo_fields["fifo_read_reg"] = Field(name="fifo_read_reg",
settings={
'width': settings['width'],
'mode': "RO",
'offset': 0x8,
'default': 0,
'descr': "fifo read register."
})
fifo_fields["fifo_write_reg"] = Field(name="fifo_write_reg",
settings={
'width': settings['width'],
'mode': "WO",
'offset': 0xC,
'default': 0,
'descr': "fifo write register."
})
self.register = Register("FIFO Register", fifo_fields)
self.address_length = settings['address_length']
class Peripheral(BaseObject):
""" A Peripheral consists of 1 or more MM slaves. The slave can be a
Register, RAM or FIFO.
......
import os
import sys
cwd = __file__[:__file__.rfind('/')]
print(cwd)
sys.path.append(cwd)
from constants import *
from base_object import BaseObject
from field import Field
from register import Register
from ram import RAM
from fifo import FIFO
###############################################################################
#
# Copyright (C) 2016
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author Date
# HJ jan 2017 Original
# EK feb 2017
# PD feb 2017
#
###############################################################################
import logging
logger = logging.getLogger('main.peripheral')
class BaseObject(object):
def __init__(self):
self.success = True
self._name = ""
self._prefix = ""
self._args = {}
def update_args(self, args):
""" update self._args with all kv pairs in args """
self._args.update(args)
def _as_str(self, key, default=None):
""" look in settings for key, if available return value as string,
if key not available retur default """
try:
val = str(self._args[key])
return val
except KeyError:
return default
def _as_int(self, key, default=None):
""" look in settings for key, if available return value as int if possible
otherwise return string, if key not available retur default """
try:
val = int(self._args[key])
return val
except ValueError:
return self._args[key]
except KeyError:
return default
def set_kv(self, key, val):
""" set_kv()
if key in valid keys, update key with given value, if key not excists add it.
"""
if val is not None:
self._args[key] = val
return True
return False
def get_kv(self, key, dtype=None):
""" get_kv()
return value for given key, if key in valid keys, else return None
"""
if key not in self._args:
logger.error("key not in arguments %s", key)
return None
if dtype == 'int':
return self._as_int(key)
if dtype == 'string':
return self._as_str(key)
return self._args[key]
def name(self, val=None):
""" set/get name """
if val is not None:
self._name = val
return
return self._name
def prefix(self, val=None):
""" set/get prefix """
if val is not None:
self._prefix = val
return
return self._prefix
###############################################################################
#
# Copyright (C) 2016
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author Date
# HJ jan 2017 Original
# EK feb 2017
# PD feb 2017
#
###############################################################################
import logging
from constants import *
from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2
from base_object import BaseObject
logger = logging.getLogger('main.perip.field')
class Field(BaseObject):
""" A field defines data at certain address or an array of addresses
"""
def __init__(self, name, settings=None):
super().__init__()
self.name(name)
self._valid_keys = ['number_of_fields', 'width', 'bit_offset', 'access_mode', 'side_effect', 'address_offset',
'address_length', 'reset_value', 'software_value', 'radix', 'field_description']
self._args.update({'number_of_fields' : DEFAULT_NUMBER_OF_FIELDS,
'width' : DEFAULT_WIDTH,
'bit_offset' : DEFAULT_BIT_OFFSET,
'access_mode' : DEFAULT_ACCESS_MODE,
'side_effect' : DEFAULT_SIDE_EFFECT,
'address_offset' : DEFAULT_ADDRESS_OFFSET,
'address_length' : DEFAULT_ADDRESS_LENGTH,
'reset_value' : RESET_VALUE,
'software_value' : DEFAULT_SOFTWARE_VALUE,
'radix' : DEFAULT_RADIX,
'field_description': DEFAULT_DESCRIPTION})
if settings is not None:
for key, val in settings.items():
if key in self._valid_keys:
if key == 'access_mode' and val.upper() not in VALID_ACCESS_MODES:
logger.error("Field.__init__(), Not a valid acces_mode '%s'", val)
self.success = False
elif key == 'side_effect' and val.upper() not in VALID_SIDE_EFFECTS:
logger.error("Field.__init__(), Not a valid side_effect '%s'", val)
self.success = False
else:
self.set_kv(key, val)
else:
logger.error("Field.__init__(), Not a valid key '%s'", key)
self.success = False
def number_of_fields(self, val=None):
""" set/get number of fields """
if val is not None:
self.set_kv('number_of_fields', val)
return
return self._as_int('number_of_fields')
def width(self, val=None):
""" set/get width of field
val: if not None set width of field
return: actual width of field """
if val is not None:
return self.set_kv('width', val)
return self._as_int('width')
def bit_offset(self, val=None):
""" set/get bit_offset of field
val: if not None set bit_offset of field
return: actual bit_offset of field """
if val is not None:
return self.set_kv('bit_offset', val)
return self._as_int('bit_offset')
def access_mode(self, val=None):
""" set/get access_mode of field
val: if not None and a valid mode set access_mode of field
return: actual access_mode of field """
if val is not None:
if val.upper() in VALID_ACCESS_MODES:
return self.set_kv('access_mode', val.upper())
else:
logger.error("unknown access_mode '%s'", val)
self.success = False
return False
return self._as_str('access_mode').upper()
def side_effect(self, val=None):
""" set/get side_effect of field
val: if not None and a valid side_effect set side_effect of field
return: actual side_effect of field """
if val is not None:
if val.upper() in VALID_SIDE_EFFECTS:
return self.set_kv('side_effect', val.upper())
else:
logger.error("unknown side_effect '%s'", val)
self.success = False
return False
return self._as_str('side_effect').upper()
def address_offset(self, val=None):
""" set/get address offset of field
val: if not None set address offset of field
return: actual address offset of field """
if val is not None:
return self.set_kv('address_offset', val)
return self._as_int('address_offset')
def address_length(self, val=None):
""" set/get address length of field
val: if not None set address length of field
return: active address_length of field """
if val is not None:
return self.set_kv('address_length', val)
return self._as_int('address_length')
def reset_value(self, val=None):
""" set/get default hardware reset value of field
val: if not None set default value of field
return: active hardware reset value of field """
if val is not None:
return self.set_kv('reset_value', val)
return self._as_int('reset_value')
def software_value(self, val=None):
""" set/get software reset value of field
val: if not None set default value of field
return: active software reset value of field """
if val is not None:
return self.set_kv('software_value', val)
return self._as_int('software_value')
def radix(self, val=None):
""" set/get radix value of field
val: if not None set default value of field
return: active radix value of field """
if val is not None:
if val.upper() in VALID_RADIXS:
return self.set_kv('radix', val.upper())
else:
logger.error("unknown radix '%s'", val)
self.success = False
return False
return self._as_int('radix')
def field_description(self, val=None):
""" set/get description of field
val: if not None set description of field
return: description of field """
if val is not None:
return self.set_kv('field_description', val)
return self._as_str('field_discription')
\ No newline at end of file
###############################################################################
#
# Copyright (C) 2016
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author Date
# HJ jan 2017 Original
# EK feb 2017
# PD feb 2017
#
###############################################################################
from math import ceil
import logging
from constants import *
from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2
from base_object import BaseObject
from field import Field
from register import Register
logger = logging.getLogger('main.perip.fifo')
# TODO: use BaseObject
class FIFO(object):
""" A FIFO is a specific set of Fields
"""
def __init__(self, name, settings):
self.number_offifos = 1
fifo_fields = {}
fifo_fields["fifo_status"] = Field(name="fifo_status",
settings={
'width': 4,
'mode': "RO",
'offset': 0x0,
'default': 0,
'descr': "fifo status register. Bit 0: Fifo Full Bit 1: Fifo Empty"
})
fifo_fields["fifo_used_w"] = Field(name="fifo_used_w",
settings={
'width': 32,
'mode': "RO",
'offset': 0x4,
'default': 0,
'descr': "fifo used words register."
})
fifo_fields["fifo_read_reg"] = Field(name="fifo_read_reg",
settings={
'width': settings['width'],
'mode': "RO",
'offset': 0x8,
'default': 0,
'descr': "fifo read register."
})
fifo_fields["fifo_write_reg"] = Field(name="fifo_write_reg",
settings={
'width': settings['width'],
'mode': "WO",
'offset': 0xC,
'default': 0,
'descr': "fifo write register."
})
self.register = Register("FIFO Register", fifo_fields)
self.address_length = settings['address_length']
###############################################################################
#
# Copyright (C) 2016
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author Date
# HJ jan 2017 Original
# EK feb 2017
# PD feb 2017
#
###############################################################################
from math import ceil
import logging
from constants import *
from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2
from base_object import BaseObject
from field import Field
logger = logging.getLogger('main.perip.ram')
class RAM(BaseObject):
""" A RAM is a Field that is repeated address_length times
"""
def __init__(self, name, fields=None, settings=None):
super().__init__()
self.name(name)
self.fields = {} if fields is None else fields
self._valid_keys = ['number_of_slaves']
self._args.update({'number_of_slaves' : DEFAULT_NUMBER_OF_SLAVES})
def number_of_slaves(self, val=None):
""" set/get number of slaves """
if val is not None:
self.set_kv('number_of_slaves', val)
return
return self._as_int('number_of_slaves')
def add_field(self, name, settings):
""" add new Field to Register with given settings
"""
field = Field(name, settings)
if field.success:
self.fields[name] = Field(name, settings)
self.update_address_length()
return True
return False
def update_address_length(self):
""" update total address_length of Register
"""
if len(self.fields) == 0:
return
n_words = 0
for field in self.fields.values():
n_words += int(ceil(float(field.width()) / c_word_w))
self.set_kv('address_length', n_words)
###############################################################################
#
# Copyright (C) 2016
# ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
# P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Author Date
# HJ jan 2017 Original
# EK feb 2017
# PD feb 2017
#
###############################################################################
from math import ceil
import logging
from constants import *
from common import c_word_w, c_nof_complex, ceil_pow2, ceil_log2
from base_object import BaseObject
from field import Field
logger = logging.getLogger('main.perip.register')
class Register(BaseObject):
""" A register consists of Fields
"""
def __init__(self, name, fields=None, settings=None):
super().__init__()
self.name(name)
self.fields = {} if fields is None else fields
self._valid_keys = ['number_of_slaves', 'address_length', 'slave_discription']
self._args.update({'number_of_slaves' : DEFAULT_NUMBER_OF_SLAVES,
'address_length' : DEFAULT_ADDRESS_LENGTH,
'slave_discription': DEFAULT_DESCRIPTION})
self.update_address_length()
def number_of_slaves(self, val=None):
""" set/get number of slaves """
if val is not None:
self.set_kv('number_of_slaves', val)
return
return self._as_int('number_of_slaves')
def add_field(self, name, settings):
""" add new Field to Register with given settings
"""
field = Field(name, settings)
if field.success:
self.fields[name] = field
self.update_address_length()
return True
return False
def update_address_length(self):
""" update total address_length of Register
"""
if len(self.fields) == 0:
return
n_words = 0
for field in self.fields.values():
n_words += int(ceil(float(field.width()) / c_word_w))
self.set_kv('address_length', n_words) # ceil_pow2(n_words))
def address_length(self, val=None):
""" set/get address_length of register
val: if not None set address_length of register
return: address_length of register """
if val is not None:
return self.set_kv('address_length', val)
return self._as_int('address_length', default=1)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment