diff --git a/corsair/bitfield.py b/corsair/bitfield.py deleted file mode 100755 index bc487e4..0000000 --- a/corsair/bitfield.py +++ /dev/null @@ -1,309 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Bit field inside register -""" - -from . import utils -from . import config - - -class BitField(): - """Bit field. - - :param name: Bit field name - :type name: str - :param description: Bit field description - :type description: str - :param reset: Bit field reset vaue - :type reset: int - :param width: Bit field width vaue - :type width: int - :param lsb: Bit field LSB vaue - :type lsb: int - :param access: Bit field access mode - :type access: str - :param hardware: Bit field hardware options - :type hardware: str - """ - - def __init__(self, name='val', description='Value of the register', reset=0, width=1, - lsb=0, access='rw', hardware='n', **args): - self._enums = [] - - self.name = name - self.description = description - self.reset = utils.str2int(reset) - self.width = utils.str2int(width) - self.lsb = utils.str2int(lsb) - self.access = access - self.hardware = hardware - self.etc = args - - def __eq__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % (repr(self), repr(other))) - else: - return self.as_dict() == other.as_dict() - - def __ne__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % (repr(self), repr(other))) - else: - return not self.__eq__(other) - - def __repr__(self): - return 'BitField(%s)' % repr(self.name) - - def __str__(self): - return self.as_str() - - def __len__(self): - """Calculate number of enums inside bitfield""" - return len(self._enums) - - def __iter__(self): - """Create iterator over enums""" - return iter(self._enums) - - def __getitem__(self, key): - """Get enum by name or index.""" - try: - if utils.is_str(key): - key = utils.force_name_case(key) - return next(enum for enum in self if enum.name == key) - else: - return self._enums[key] - except (StopIteration, TypeError, KeyError, IndexError): - raise KeyError("There is no enum with the name/index '%s' in the '%s' bitfield!" % (key, self.name)) - - def __setitem__(self, key, value): - """Set enum by key""" - raise KeyError("Not able to set '%s' enum directly in the '%s' bit field!" - " Try to use add_enums() method." % (key, self.name)) - - def as_str(self, indent=''): - """Create an indented string with the bit field information.""" - inner_indent = indent + ' ' - bf_str = indent + '%s: %s\n' % (self.name, self.description) - bf_str += inner_indent + 'reset = %s\n' % utils.int2str(self.reset) - bf_str += inner_indent + 'width = %s\n' % self.width - bf_str += inner_indent + 'lsb = %s\n' % self.lsb - bf_str += inner_indent + 'access = %s\n' % self.access - bf_str += inner_indent + 'hardware = %s\n' % self.hardware - bf_str += inner_indent + 'enums:\n' - enums = [enum.as_str(inner_indent + inner_indent) for enum in self.enums] - bf_str += '\n'.join(enums) if enums else inner_indent + 'empty' - return bf_str - - def as_dict(self): - """Create a dictionary with the key attributes of the bit field.""" - d = { - 'name': self.name, - 'description': self.description, - 'reset': self.reset, - 'width': self.width, - 'lsb': self.lsb, - 'access': self.access, - 'hardware': self.hardware, - 'enums': [enum.as_dict() for enum in self.enums] - } - d.update(self.etc) - return d - - @property - def name(self): - """Name of the bit field.""" - return utils.force_name_case(self._name) - - @name.setter - def name(self, value): - if not utils.is_str(value): - raise ValueError("'name' attribute has to be 'str', but '%s' provided for the bitfield!" % type(value)) - self._name = value - - @property - def description(self): - """Description of the bitfield.""" - return self._description - - @description.setter - def description(self, value): - if not utils.is_str(value): - raise ValueError("'description' attribute has to be 'str', but '%s' provided for '%s' bitfield!" % - (type(value), self.name)) - self._description = value - - @property - def reset(self): - """Inital value of the bitfield.""" - return self._reset - - @reset.setter - def reset(self, value): - self._reset = utils.str2int(value) - - @property - def lsb(self): - """LSB value of the bitfield.""" - return self._lsb - - @lsb.setter - def lsb(self, value): - self._lsb = utils.str2int(value) - - @property - def width(self): - """Width value of the bitfield.""" - return self._width - - @width.setter - def width(self, value): - self._width = utils.str2int(value) - - @property - def access(self): - """Access mode for the bitfield.""" - return self._access - - @access.setter - def access(self, value): - if not utils.is_str(value): - raise ValueError("'access' attribute has to be 'str', but '%s' provided for '%s' bitfield!" % - (type(value), self.name)) - self._access = value - - @property - def hardware(self): - """Hardware mode for the bitfield.""" - return self._hardware - - @hardware.setter - def hardware(self, value): - value = value.lower() - for ch in value: - if ch not in "iocselaqfn": - raise ValueError("Unknown attribute '%s' for 'hardware' property of the '%s' bitfield!" % - (ch, self.name)) - self._hardware = value - - @property - def msb(self): - """Position of most significant bit (MSB) of the field.""" - return self.lsb + self.width - 1 - - @property - def byte_strobes(self): - """Dictionary with LSB and MSB values for the every byte in the write data bus.""" - strb = {} - first = self.lsb // 8 - last = self.msb // 8 - for i in range(first, last + 1): - # per every byte strobe - wdata_lsb = self.lsb if i == first else i * 8 - wdata_msb = (i + 1) * 8 - 1 if ((i + 1) * 8 - 1 - self.msb) < 0 else self.msb - bf_lsb = wdata_lsb - self.lsb - bf_msb = wdata_msb - self.lsb - strb[i] = {'bf_lsb': bf_lsb, 'bf_msb': bf_msb, - 'wdata_lsb': wdata_lsb, 'wdata_msb': wdata_msb} - return strb - - @property - def enum_names(self): - """List with all enum names.""" - return [enum.name for enum in self] - - @property - def enums(self): - """List with enum objects.""" - return self._enums - - def add_enums(self, new_enums): - """Add enum or list of enums. - - Enums are automatically sorted and stored in the ascending order of value attributes. - """ - # hack to handle single elements - new_enums = utils.listify(new_enums) - - # add enums to list one by one - for enum in new_enums: - # check existance - assert enum.name not in self.enum_names, \ - "Enum with name '%s' is already present in '%s' bitfield!" % (enum.name, self.name) - # check enum value is unique - assert enum.value not in [enum.value for enum in self], \ - "Enum with value '%d' is already present in '%s' bitfield!" % (enum.value, self.name) - # check enum conflicts with bitfield width - assert enum.value.bit_length() <= self.width, \ - "Enum '%s' value %d exceeds bitfield width %d!" % (enum.name, enum.value, self.width) - # if we are here - all is ok and enum can be added - try: - # find position to insert enum and not to break ascending order of enum values - enum_idx = next(i for i, old_enum in enumerate(self._enums) if old_enum.value > enum.value) - self._enums.insert(enum_idx, enum) - except StopIteration: - # when enum list is empty or all enum values are less than the current one - self._enums.append(enum) - return self - - @property - def bits(self): - """Create list with all positions of the bits represented by the bit field.""" - return list(range(self.lsb, self.msb + 1)) - - @property - def mask(self): - """Bit mask for the field.""" - return ((2**(self.width) - 1) << self.lsb) - - def is_vector(self): - """Check if the width of the bit field > 1.""" - return True if self.width > 1 else False - - def validate(self): - """Validate parameters of the bit field.""" - # name - assert self.name, "Empty bitfield name is not allowed!" - assert utils.is_first_letter(self.name), \ - "Name value '%s' for is wrong! Must start from a letter." % (self.name) - - # reset - assert utils.is_non_neg_int(self.reset), \ - "Reset value '%s' for '%s' is wrong! Only non-negative integers are allowed." % (self.reset, self.name) - - # width - assert self.width, "Empty bitfield width is not allowed!" - assert utils.is_pos_int(self.width), \ - "Width value '%s' for '%s' is wrong! Only positive integers are allowed." % (self.width, self.name) - - # lsb - assert utils.is_non_neg_int(self.lsb), \ - "LSB value '%s' for '%s' is wrong! Only non-negative integers are allowed." % (self.lsb, self.name) - - # access - assert self.access in ['rw', 'rw1c', 'rw1s', 'rw1t', 'ro', 'roc', 'roll', 'rolh', 'wo', 'wosc'], \ - "Unknown access mode '%s' for '%s' field!" % (self.access, self.name) - - # hardware - if 'q' in self.hardware or 'n' in self.hardware or 'f' in self.hardware: - assert len(self.hardware) == 1, \ - "Wrong hardware mode '%s' for field '%s'!" % (self.hardware, self.name) - else: - wrong_hw = list(set(self.hardware) - (set(self.hardware) & set('ioecsla'))) - assert wrong_hw == [], \ - "Wrong hardware mode(s) '%s' in '%s' for the field '%s'!" % (wrong_hw, self.hardware, self.name) - if 'q' in self.hardware: - q_access_allowed = ['rw', 'ro', 'wo'] - assert self.access in q_access_allowed, \ - "Hardware mode 'q' is allowed to use only with '%s'!" % (q_access_allowed) - - # enums - for enum in self.enums: - assert enum.value.bit_length() <= self.width, \ - "Enum '%s' value %d exceeds bitfield width %d!" % (enum.name, enum.value, self.width) - assert self.enum_names.count(enum.name) == 1, \ - "Enum '%s' name is not unique!" % (enum.name) - assert [e.value for e in self].count(enum.value) == 1, \ - "Enum '%s' value is not unique!" % (enum.value) - enum.validate() diff --git a/corsair/config.py b/corsair/config.py deleted file mode 100755 index d98aec8..0000000 --- a/corsair/config.py +++ /dev/null @@ -1,121 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Module to operate with Corsair configuration files -""" - -from . import utils -import configparser - - -def default_globcfg(): - """Create a global configuration with parameters by default.""" - return { - "base_address": 0, - "data_width": 32, - "address_width": 16, - "register_reset": "sync_pos", - "address_increment": "none", - "address_alignment": "data_width", - "force_name_case": "none", - } - - -def read_csrconfig(cfgpath): - """Parse Corsair configuration file. Return two dictionaries: global configuration and targets.""" - # open config file - cfg = configparser.ConfigParser() - cfg.read_file(open(cfgpath, 'r')) - - # parse global config - globcfg = default_globcfg() - if 'globcfg' in cfg.sections(): - globcfg.update(dict(cfg['globcfg'])) - globcfg["base_address"] = utils.str2int(globcfg["base_address"]) - globcfg["data_width"] = utils.str2int(globcfg["data_width"]) - globcfg["address_width"] = utils.str2int(globcfg["address_width"]) - try: - globcfg["address_increment"] = utils.str2int(globcfg["address_increment"]) - except ValueError: - pass - try: - globcfg["address_alignment"] = utils.str2int(globcfg["address_alignment"]) - except ValueError: - pass - validate_globcfg(globcfg) - - # parse targets - targets = {} - for target_name in [name for name in cfg.sections() if name != 'globcfg']: - if 'generator' in dict(cfg[target_name]).keys(): - targets[target_name] = dict(cfg[target_name]) - - return globcfg, targets - - -def write_csrconfig(cfgpath, globcfg, targets): - """Save Corsair configuration file.""" - cfg = configparser.ConfigParser() - data = {'globcfg': globcfg} - data.update(targets) - cfg.read_dict(data) - cfg.write(open(cfgpath, 'w')) - - -def validate_globcfg(globcfg): - """Validate a dictionary with global configuration.""" - # base_address - assert utils.is_non_neg_int(globcfg["base_address"]), \ - "Wrong value for 'base_address'='%s'. Must be a non negative integer." % globcfg["base_address"] - - # data_width - assert utils.is_non_neg_int(globcfg["data_width"]), \ - "Wrong value for 'data_width'='%s'. Must be a non negative integer." % globcfg["data_width"] - - # address_width - assert utils.is_non_neg_int(globcfg["address_width"]), \ - "Wrong value for 'address_width'='%s'. Must be a non negative integer." % globcfg["address_width"] - - # register_reset - register_reset_allowed = ['sync_pos', 'sync_neg', 'async_pos', 'async_neg'] - assert globcfg["register_reset"] in register_reset_allowed, \ - "Wrong value for 'register_reset'='%s'. Must be one of this: %s." % (globcfg["address_width"], - register_reset_allowed) - - # address_increment - address_increment_alowed = ['none', 'data_width'] - try: - is_valid = (globcfg["address_increment"] in address_increment_alowed or - utils.is_non_neg_int(globcfg["address_increment"])) - except ValueError: - is_valid = False - assert is_valid, \ - "Wrong value for 'address_increment'='%s'. Must be one of this: %s or a non negative integer." % ( - globcfg["address_increment"], address_increment_alowed) - - # address_alignment - address_alignment_alowed = ['none', 'data_width'] - try: - is_valid = (globcfg["address_alignment"] in address_alignment_alowed or - utils.is_non_neg_int(globcfg["address_alignment"])) - except ValueError: - is_valid = False - assert is_valid, \ - "Wrong value for 'address_alignment'='%s'. Must be one of this: %s or a non negative integer." % ( - globcfg["address_alignment"], address_alignment_alowed) - - # force_name_case - force_name_case_allowed = ['lower', 'upper', 'none'] - assert globcfg["force_name_case"] in force_name_case_allowed, \ - "Wrong value for 'force_name_case'='%s'. Must be one of this: %s." % (globcfg["force_name_case"], - force_name_case_allowed) - - -globcfg = default_globcfg() - - -def set_globcfg(globcfg_): - """Use specified global configuration for all operations""" - global globcfg - validate_globcfg(globcfg_) - globcfg = globcfg_ diff --git a/corsair/enum.py b/corsair/enum.py deleted file mode 100755 index ac24622..0000000 --- a/corsair/enum.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Enumerated value for bit field -""" - -from . import utils -from . import config - - -class EnumValue(): - """Enumerated value. - - :param name: Enum name - :type name: str - :param value: Enum value - :type value: int - :param description: Enum description - :type description: str - """ - - def __init__(self, name='enum', value=0, description='Enumerated value', **args): - self.name = name - self.description = description - self.value = value - self.etc = args - - def __eq__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % - (repr(self), repr(other))) - else: - return self.as_dict() == other.as_dict() - - def __ne__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % - (repr(self), repr(other))) - else: - return not self.__eq__(other) - - def __repr__(self): - return 'EnumValue(%s)' % repr(self.name) - - def __str__(self): - return self.as_str() - - def as_str(self, indent=''): - """Create an indented string with the enum information.""" - enum_str = indent + \ - '%s: %d - %s' % (self.name, self.value, self.description) - return enum_str - - def as_dict(self): - """Create a dictionary with the key attributes of the bit field.""" - d = {'name': self.name, 'description': self.description, 'value': self.value} - d.update(self.etc) - return d - - @property - def name(self): - """Name of the enum.""" - return utils.force_name_case(self._name) - - @name.setter - def name(self, value): - if not utils.is_str(value): - raise ValueError( - "'name' attribute has to be 'str', but '%s' provided for the enum!" % type(value)) - self._name = value - - @property - def value(self): - """Value of the enum.""" - return self._value - - @value.setter - def value(self, value_): - self._value = utils.str2int(value_) - - @property - def description(self): - """Description of the enum.""" - return self._description - - @description.setter - def description(self, value): - if not utils.is_str(value): - raise ValueError("'description' attribute has to be 'str', but '%s' provided for the '%s' enum!" % - (type(value), self.name)) - self._description = value - - def validate(self): - """Validate parameters of the enum.""" - # value type - assert utils.is_non_neg_int(self.value), \ - "Enum value '%s' for '%s' enum is wrong! Only non-negative integers are allowed." % \ - (self.value, self.name) diff --git a/corsair/generators.py b/corsair/generators.py deleted file mode 100755 index 339b488..0000000 --- a/corsair/generators.py +++ /dev/null @@ -1,608 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Output file generators -""" - -import os -import json -import yaml -import jinja2 -from corsair import __version__ -from . import utils -from . import config -from .regmap import RegisterMap -from pathlib import Path -import wavedrom - - -class Generator(): - """Base generator class. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - """ - - def __init__(self, rmap, **args): - self.rmap = rmap - self.etc = args - - def _name(self): - return self.__class__.__name__ - - def generate(self): - """Do file generation.""" - pass - - def validate(self): - """Validate generator parameters.""" - # config - config.validate_globcfg(config.globcfg) - # rmap - assert isinstance(self.rmap, RegisterMap), \ - "Register map has to be '%s', but '%s' was provided for '%s' generator!" % ( - repr(RegisterMap()), repr(self.rmap), self._name()) - self.rmap.validate() - - def make_target(self, name): - """Dump class attributes to dictionary that can be used as target for `csrconfig` generation. - - :param name: Name of the target - :return: Target dictionary - """ - params = vars(self) - params.pop('etc') - params.pop('rmap') - params['generator'] = self._name() - return {name: params} - - -class Jinja2(): - """Basic class for rendering Jinja2 templates""" - - def render(self, template, vars, templates_path=None): - """Render text with Jinja2. - - :param template: Jinja2 template filename - :param vars: Dictionary with variables for Jinja2 rendering - :param templates_path: Path to search templates. If no path provided, then internal templates will be used - :return: String with rendered text - """ - # prepare template - if not templates_path: - templates_path = str(Path(__file__).parent / 'templates') - j2_env = jinja2.Environment(loader=jinja2.FileSystemLoader(searchpath=templates_path), - trim_blocks=True, lstrip_blocks=True) - j2_env.globals.update(zip=zip) - j2_template = j2_env.get_template(template) - # render - return j2_template.render(vars) - - def render_to_file(self, template, vars, path, templates_path=None): - """Render text with Jinja2 and save it to the file. - - :param template: Jinja2 template filename - :param vars: Dictionary with variables for Jinja2 rendering - :param path: Path to the output file - :param templates_path: Path to search templates. If no path provided, then internal templates will be used - """ - # render - rendered_text = self.render(template, vars, templates_path) - # save - utils.create_dirs(self.path) - with open(path, "w") as f: - f.write(rendered_text) - - -class Wavedrom(): - """Basic class for rendering register images with wavedrom""" - - def draw_regs(self, imgdir, rmap): - imgdir.mkdir(exist_ok=True) - - bits = config.globcfg['data_width'] - lanes = bits // 16 if bits > 16 else 1 - for reg in rmap: - reg_wd = {"reg": [], - "config": {"bits": bits, "lanes": lanes, "fontsize": 10}} - bit_pos = -1 - for bf in reg: - if bit_pos == -1 and bf.lsb > 0: - reg_wd["reg"].append({"bits": bf.lsb}) - elif bf.lsb - bit_pos > 1: - reg_wd["reg"].append({"bits": bf.lsb - bit_pos - 1}) - name = bf.name - name_max_len = 5 * bf.width - if len(bf.name) > name_max_len: # to prevent labels overlapping - name = bf.name[:name_max_len - 1] + '..' - reg_wd["reg"].append({"name": name, "attr": bf.access, "bits": bf.width}) - bit_pos = bf.msb - if (bits - 1) > bit_pos: - reg_wd["reg"].append({"bits": bits - bit_pos - 1}) - wavedrom.render(json.dumps(reg_wd)).saveas(str(imgdir / ("%s.svg" % reg.name.lower()))) - - -class Json(Generator): - """Dump register map to a JSON file. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - """ - - def __init__(self, rmap=None, path='regs.json', **args): - super().__init__(rmap, **args) - self.path = path - - def generate(self): - # validate register map - self.rmap.validate() - # prepare data - data = {'regmap': list(self.rmap.as_dict().values())} - # dump - utils.create_dirs(self.path) - with open(self.path, 'w') as f: - json.dump(data, f, indent=4) - - -class Yaml(Generator): - """Dump register map to a YAML file. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - """ - - def __init__(self, rmap=None, path='regs.yaml', **args): - super().__init__(rmap, **args) - self.path = path - - def generate(self): - # validate parameters - self.validate() - # prepare data - data = {'regmap': list(self.rmap.as_dict().values())} - # dump - utils.create_dirs(self.path) - with open(self.path, 'w') as f: - yaml.Dumper.ignore_aliases = lambda *args: True # hack to disable aliases - yaml.dump(data, f, indent=4, default_flow_style=False, sort_keys=False) - - -class Txt(Generator): - """Dump register map to a text table. - - Note: only registers with single bitfield are allowed. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - """ - - def __init__(self, rmap=None, path='regs.txt', **args): - super().__init__(rmap, **args) - self.path = path - - def generate(self): - # validate parameters - self.validate() - for reg in self.rmap: - if len(reg) > 1: - raise ValueError("Only registers with single bitfield are allowed for %s generator." % self._name()) - # prepare template strings - data_w = config.globcfg['data_width'] - address_w = config.globcfg['address_width'] - address_digits = address_w // 4 + (1 if address_w % 4 else 0) - address_str = "0x%0{0}x".format(address_digits) - reset_digits = data_w // 4 + (1 if data_w % 4 else 0) - reset_str = "0x%0{0}x".format(reset_digits) - row_template = "| %-{0}s | %-{1}s | %-{2}s | %-{3}s | %-{4}s | %-{5}s | %-{6}s |\n" - # prepare table data - row_top = ["Address", "Name", "Width", "Access", "Hardware", "Reset", "Description"] - col_address = [address_str % reg.address for reg in self.rmap] - col_names = self.rmap.reg_names - col_width = ["%d" % reg.bitfields[0].width for reg in self.rmap] - col_access = [reg.bitfields[0].access for reg in self.rmap] - col_hardware = [reg.bitfields[0].hardware for reg in self.rmap] - col_reset = [reset_str % reg.reset for reg in self.rmap] - col_description = [reg.description for reg in self.rmap] - # calculate width of the columns for pretty printing - cols_w = [max(address_digits + 2, len(row_top[0])), - max(max([len(s) for s in col_names]), len(row_top[1])), - max(max([len(s) for s in col_width]), len(row_top[2])), - max(max([len(s) for s in col_access]), len(row_top[3])), - max(max([len(s) for s in col_hardware]), len(row_top[4])), - max(reset_digits + 2, len(row_top[5])), - max(max([len(s) for s in col_description]), len(row_top[6]))] - row_template = row_template.format(*cols_w) - # render - out_lines = [row_template % tuple(row_top)] - out_lines.append(row_template % tuple(["-" * w for w in cols_w])) - for i in range(len(col_names)): - out_lines.append(row_template % (col_address[i], col_names[i], - col_width[i], col_access[i], col_hardware[i], col_reset[i], col_description[i])) - # save to file - utils.create_dirs(self.path) - with open(self.path, 'w') as f: - f.writelines(out_lines) - - -class Verilog(Generator, Jinja2): - """Create Verilog file with register map. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param read_filler: Numeric value to return if wrong address was read - :type read_filler: int - :param interface: Register map bus protocol. Use one of: `axil`, `apb`, `amm`, `lb` - :type interface: str - """ - - def __init__(self, rmap=None, path='regs.v', read_filler=0, interface='axil', **args): - super().__init__(rmap, **args) - self.path = path - self.read_filler = read_filler - self.interface = interface - - def validate(self): - super().validate() - assert self.interface in ['axil', 'apb', 'amm', 'lb'], \ - "Unknown '%s' interface!" % (self.interface) - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'regmap_verilog.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['module_name'] = utils.get_file_name(self.path) - j2_vars['read_filler'] = utils.str2int(self.read_filler) - j2_vars['interface'] = self.interface - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - - -class Vhdl(Generator, Jinja2): - """Create VHDL file with register map. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param read_filler: Numeric value to return if wrong address was read - :type read_filler: int - :param interface: Register map bus protocol. Use one of: `axil`, `apb`, `amm`, `lb` - :type interface: str - """ - - def __init__(self, rmap=None, path='regs.vhd', read_filler=0, interface='axil', **args): - super().__init__(rmap, **args) - self.path = path - self.read_filler = read_filler - self.interface = interface - - def validate(self): - super().validate() - assert self.interface in ['axil', 'apb', 'amm', 'lb'], \ - "Unknown '%s' interface!" % (self.interface) - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'regmap_vhdl.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['module_name'] = utils.get_file_name(self.path) - j2_vars['read_filler'] = utils.str2int(self.read_filler) - j2_vars['interface'] = self.interface - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - - -class VerilogHeader(Generator, Jinja2): - """Create Verilog header file with register map defines. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param prefix: Prefix for the all defines. If empty output file name will be used. - :type prefix: str - """ - - def __init__(self, rmap=None, path='regs.vh', prefix="CSR", **args): - super().__init__(rmap, **args) - self.path = path - self.prefix = prefix - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'verilog_header.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['prefix'] = self.prefix.upper() - j2_vars['file_name'] = utils.get_file_name(self.path) - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - - -class CHeader(Generator, Jinja2): - """Create C header file with register map defines. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param prefix: Prefix for the all defines and types. If empty output file name will be used. - :type prefix: str - """ - - def __init__(self, rmap=None, path='regs.h', prefix="CSR", **args): - super().__init__(rmap, **args) - self.path = path - self.prefix = prefix - - def validate(self): - super().validate() - data_width_allowed = [8, 16, 32, 64] - assert config.globcfg['data_width'] in [8, 16, 32, 64], \ - "For %s generator, global 'data_width' must be one of '%s', but current is %d" % \ - (self._name(), data_width_allowed, config.globcfg['data_width']) - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'c_header.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['prefix'] = self.prefix.upper() - j2_vars['file_name'] = utils.get_file_name(self.path) - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - - -class SystemVerilogPackage(Generator, Jinja2): - """Create SystemVerilog package with register map parameters. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param prefix: Prefix for the all parameters and types. If empty output file name will be used. - :type prefix: str - """ - - def __init__(self, rmap=None, path='regs_pkg.sv', prefix="CSR", **args): - super().__init__(rmap, **args) - self.path = path - self.prefix = prefix - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'sv_package.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['prefix'] = self.prefix.upper() - j2_vars['file_name'] = utils.get_file_name(self.path) - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - - -class LbBridgeVerilog(Generator, Jinja2): - """Create Verilog file with bridge to Local Bus. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param bridge_type: Bridge protocol. Use one of `axil`, `apb`, `amm`. - :type bridge_type: str - """ - - def __init__(self, rmap=None, path='axil2lb.v', bridge_type='axil', **args): - super().__init__(rmap, **args) - self.path = path - self.bridge_type = bridge_type - - def validate(self): - assert self.bridge_type in ['axil', 'apb', 'amm'], \ - "Unknown '%s' bridge type!" % (self.bridge_type) - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - if self.bridge_type == 'axil': - j2_template = 'axil2lb_verilog.j2' - elif self.bridge_type == 'apb': - j2_template = 'apb2lb_verilog.j2' - elif self.bridge_type == 'amm': - j2_template = 'amm2lb_verilog.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['module_name'] = utils.get_file_name(self.path) - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - - -class LbBridgeVhdl(Generator, Jinja2): - """Create VHDL file with bridge to Local Bus. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param bridge_type: Bridge protocol. Use one of `axil`, `apb`, `amm`. - :type bridge_type: str - """ - - def __init__(self, rmap=None, path='axil2lb.v', bridge_type='axil', **args): - super().__init__(rmap, **args) - self.path = path - self.bridge_type = bridge_type - - def validate(self): - assert self.bridge_type in ['axil', 'apb', 'amm'], \ - "Unknown '%s' bridge type!" % (self.bridge_type) - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - if self.bridge_type == 'axil': - j2_template = 'axil2lb_vhdl.j2' - elif self.bridge_type == 'apb': - j2_template = 'apb2lb_vhdl.j2' - elif self.bridge_type == 'amm': - j2_template = 'amm2lb_vhdl.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['module_name'] = utils.get_file_name(self.path) - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - - -class Markdown(Generator, Jinja2, Wavedrom): - """Create documentation for a register map in Markdown. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param title: Document title - :type title: str - :param print_images: Enable generating images for bit fields of a register - :type print_images: bool - :param image_dir: Path to directory where all images will be saved - :type image_dir: str - :param print_conventions: Enable generating table with register access modes explained - :type print_conventions: bool - """ - - def __init__(self, rmap=None, path='regs.md', title='Register map', - print_images=True, image_dir="regs_img", print_conventions=True, **args): - super().__init__(rmap, **args) - self.path = path - self.title = title - self.print_images = print_images - self.image_dir = image_dir - self.print_conventions = print_conventions - - def generate(self): - filename = utils.get_file_name(self.path) - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'regmap_md.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['print_images'] = utils.str2bool(self.print_images) - j2_vars['print_conventions'] = utils.str2bool(self.print_conventions) - j2_vars['image_dir'] = self.image_dir - j2_vars['filename'] = filename - j2_vars['title'] = self.title - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - # draw register images - if self.print_images: - self.draw_regs(Path(self.path).parent / self.image_dir, self.rmap) - - -class Asciidoc(Generator, Jinja2, Wavedrom): - """Create documentation for a register map in AsciiDoc. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - :param title: Document title - :type title: str - :param print_images: Enable generating images for bit fields of a register - :type print_images: bool - :param image_dir: Path to directory where all images will be saved - :type image_dir: str - :param print_conventions: Enable generating table with register access modes explained - :type print_conventions: bool - """ - - def __init__(self, rmap=None, path='regs.adoc', title='Register map', - print_images=True, image_dir="regs_img", print_conventions=True, **args): - super().__init__(rmap, **args) - self.path = path - self.title = title - self.print_images = print_images - self.image_dir = image_dir - self.print_conventions = print_conventions - - def generate(self): - filename = utils.get_file_name(self.path) - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'regmap_asciidoc.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['print_images'] = utils.str2bool(self.print_images) - j2_vars['print_conventions'] = utils.str2bool(self.print_conventions) - j2_vars['image_dir'] = self.image_dir - j2_vars['filename'] = filename - j2_vars['title'] = self.title - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) - # draw register images - if self.print_images: - self.draw_regs(Path(self.path).parent / self.image_dir, self.rmap) - - -class Python(Generator, Jinja2): - """Create Python file to access register map via some interface. - - :param rmap: Register map object - :type rmap: :class:`corsair.RegisterMap` - :param path: Path to the output file - :type path: str - """ - - def __init__(self, rmap=None, path='regs.py', **args): - super().__init__(rmap, **args) - self.path = path - - def generate(self): - # validate parameters - self.validate() - # prepare jinja2 - j2_template = 'regmap_py.j2' - j2_vars = {} - j2_vars['corsair_ver'] = __version__ - j2_vars['rmap'] = self.rmap - j2_vars['config'] = config.globcfg - # render - self.render_to_file(j2_template, j2_vars, self.path) diff --git a/corsair/reg.py b/corsair/reg.py deleted file mode 100755 index 6999ed7..0000000 --- a/corsair/reg.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Control and status register -""" - -from . import utils -from . import config - - -class Register(): - """Control and status register. - - :param name: Bit field name - :type name: str - :param description: Bit field description - :type description: str - :param address: Register address - :type address: int, None - """ - - def __init__(self, name='csr0', description='Control and status register 0', address=None, **args): - self._bitfields = [] - - self.name = name - self.description = description - self.address = address - self.etc = args - - def __eq__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % (repr(self), repr(other))) - else: - return self.as_dict() == other.as_dict() - - def __ne__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % (repr(self), repr(other))) - else: - return not self.__eq__(other) - - def __repr__(self): - return 'Register(%s, %s, %s)' % (repr(self.name), repr(self.description), repr(self.address)) - - def __str__(self): - return self.as_str() - - def as_str(self, indent=''): - """Create an indented string with the information about the register.""" - inner_indent = indent + ' ' - bitfields = [bf.as_str(inner_indent) for bf in self.bitfields] - bitfields_str = '\n'.join(bitfields) if bitfields else inner_indent + 'empty' - reg_str = indent + '(0x%x) %s: %s\n' % (self.address, self.name, self.description) - reg_str += bitfields_str - return reg_str - - def as_dict(self): - """Create a dictionary with the key attributes of the register.""" - d = { - 'name': self.name, - 'description': self.description, - 'address': self.address, - 'bitfields': [bf.as_dict() for bf in self.bitfields] - } - d.update(self.etc) - return d - - def __len__(self): - """Calculate number of bit fields inside register""" - return len(self._bitfields) - - def __iter__(self): - """Create iterator over bit fields """ - return iter(self._bitfields) - - def __getitem__(self, key): - """Get bit field by name or index""" - try: - if utils.is_str(key): - key = utils.force_name_case(key) - return next(bf for bf in self if bf.name == key) - else: - return self._bitfields[key] - except (StopIteration, TypeError, KeyError, IndexError): - raise KeyError("There is no bit field with the name/index '%s' in the '%s' register!" % (key, self.name)) - - def __setitem__(self, key, value): - """Set bit field by key""" - raise KeyError("Not able to set '%s' bit field directly in the '%s' register!" - " Try to use add_bitfields() method." % (key, self.name)) - - @property - def name(self): - """Name of the register.""" - return utils.force_name_case(self._name) - - @name.setter - def name(self, value): - if not utils.is_str(value): - raise ValueError("'name' attribute has to be 'str', but '%s' provided for the register!" % type(value)) - self._name = value - - @property - def address(self): - """Address of the register.""" - return self._address - - @address.setter - def address(self, value): - self._address = utils.str2int(value) - - @property - def description(self): - """Description of the register.""" - return self._description - - @description.setter - def description(self, value): - if not utils.is_str(value): - raise ValueError("'description' attribute has to be 'str', but '%s' provided for '%s' register!" % - (type(value), self.name)) - self._description = value - - @property - def bitfield_names(self): - """List with all bit field names.""" - return [bf.name for bf in self] - - @property - def bitfields(self): - """List with bit field objects.""" - return self._bitfields - - def add_bitfields(self, new_bitfields): - """Add bit field or list of bit feilds. - - Bit fields are automatically sorted and stored in the ascending order of msb attributes. - """ - # hack to handle single elements - new_bitfields = utils.listify(new_bitfields) - - # add bit fields to list one by one - for bf in new_bitfields: - # check existance - assert bf.name not in self.bitfield_names, \ - "Bit field with name '%s' is already present in '%s' register!" % (bf.name, self.name) - # check fields overlapping - overlaps = [set(bf.bits).intersection(set(old_bf.bits)) for old_bf in self._bitfields] - overlaps_names = [self.bitfield_names[i] for i, ovl in enumerate(overlaps) if ovl] - assert not (self.bitfields and overlaps_names), \ - "Position of a bit field '%s' conflicts with other bit field(s): %s!" % (bf.name, repr(overlaps_names)) - # check bit field conflicts with data width - data_width = config.globcfg['data_width'] - assert bf.msb < data_width, \ - "Field '%s' (msb=%d) exceeds interface data width %d!" % \ - (bf.name, bf.msb, data_width) - # if we are here - all is ok and bit field can be added - try: - # find position to insert bit field and not to break ascending order of bit field msb positions - bf_idx = next(i for i, old_bf in enumerate(self._bitfields) if old_bf.msb > bf.msb) - self._bitfields.insert(bf_idx, bf) - except StopIteration: - # when bit field list is empty or all bit field msb positions are less than the current one - self._bitfields.append(bf) - return self - - @property - def reset(self): - """Reset value of the refister after reset.""" - init = 0 - for bf in self: - init |= bf.reset << bf.lsb - return init - - @property - def access(self): - """Register access mode, based on bitfields.""" - accesses = list(set([bf.access for bf in self.bitfields])) - if len(accesses) == 1: - return accesses[0][:2] - else: - return 'rw' - - def validate(self): - """Validate parameters of the register.""" - # name - assert self.name, "Empty register name is not allowed!" - assert utils.is_first_letter(self.name), \ - "'name' value '%s' for the register is wrong! Must start from a letter." % (self.name) - - # address - assert utils.is_non_neg_int(self.address), \ - "Address value '%s' for '%s' is wrong! Only non-negative integers are allowed." % (self.address, self.name) - - # bit fields overlapping - for bf in self._bitfields: - overlaps = [set(bf.bits).intersection(set(bf_.bits)) for bf_ in self._bitfields] - overlaps_names = [self.bitfield_names[i] for i, ovl in enumerate(overlaps) if ovl] - overlaps_names.pop(overlaps_names.index(bf.name)) - assert not overlaps_names, \ - "Position and size of a bit field '%s' conflicts with other bit field(s): %s!" % \ - (bf.name, repr(overlaps_names)) - - # bit fields vs data_width - data_width = config.globcfg['data_width'] - for bf in self._bitfields: - assert bf.msb < data_width, \ - "Field '%s' (msb=%d) exceeds interface data width %d!" % \ - (bf.name, bf.msb, data_width) - - # bit fields - for bf in self.bitfields: - assert self.bitfield_names.count(bf.name) == 1, \ - "Bitfield '%s' name is not unique!" % (bf.name) - bf.validate() diff --git a/corsair/regmap.py b/corsair/regmap.py deleted file mode 100755 index a9d5da6..0000000 --- a/corsair/regmap.py +++ /dev/null @@ -1,227 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Register map -""" - -from . import utils -from . import config -from .reg import Register -from .bitfield import BitField -from .enum import EnumValue -import json -import yaml - - -class RegisterMap(): - """CSR map""" - - def __init__(self): - self._regs = [] - - def __eq__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % (repr(self), repr(other))) - else: - return self.as_dict() == other.as_dict() - - def __ne__(self, other): - if self.__class__ != other.__class__: - raise TypeError("Failed to compare '%s' with '%s'!" % (repr(self), repr(other))) - else: - return not self.__eq__(other) - - def __repr__(self): - return 'RegisterMap()' - - def __str__(self): - return self.as_str() - - def as_str(self, indent=''): - """Create indented string with the information about register map.""" - inner_indent = indent + ' ' - regs = [reg.as_str(inner_indent) for reg in self.regs] - regs_str = '\n'.join(regs) if regs else inner_indent + 'empty' - return indent + 'register map:\n' + regs_str - - def as_dict(self): - """Return register map as a dictionary.""" - return {reg.name: reg.as_dict() for reg in self.regs} - - def __len__(self): - """Calculate number of the registers""" - return len(self._regs) - - def __iter__(self): - """Create iterator over registers""" - return iter(self._regs) - - def __getitem__(self, key): - """Get register by name or index""" - try: - if isinstance(key, str): - return next(reg for reg in self if reg.name == key) - else: - return self._regs[key] - except (StopIteration, TypeError, KeyError, IndexError): - raise KeyError("There is no register with a name/index '%s'!" % (key)) - - def __setitem__(self, key, value): - """Set register by key""" - raise KeyError("Not able to set '%s' register directly!" - " Try use add_registers() method." % (key)) - - @property - def reg_names(self): - """List with all register names.""" - return [reg.name for reg in self] - - def _addr_resolve(self, reg): - """Resolve address for a register with no address.""" - # some error checks - assert len(self) != 0, \ - "Register '%s' with no address is not allowed to be the first register in a map!" % (reg.name) - assert config.globcfg['address_increment'] != 'none', \ - "Register '%s' with no address is not allowed when address auto increment is disabled!" % (reg.name) - - prev_addr = self.regs[-1].address - - if config.globcfg['address_increment'] == 'data_width': - addr_step = config.globcfg['data_width'] // 8 - else: - addr_step = config.globcfg['address_increment'] - - reg.address = prev_addr + addr_step - - def _addr_check_alignment(self, reg): - """Check address alignment.""" - if config.globcfg['address_alignment'] == 'none': - align_val = 1 - elif config.globcfg['address_alignment'] == 'data_width': - align_val = config.globcfg['data_width'] // 8 - else: - align_val = config.globcfg['address_alignment'] - - assert (reg.address % align_val) == 0, \ - "Register '%s' with address '%d' is not %d bytes alligned!" % (reg.name, reg.address, align_val) - - def _addr_check_conflicts(self, reg): - addresses = [reg.address for reg in self] - if reg.address in addresses: - conflict_reg = self[addresses.index(reg.address)] - assert False, "Register '%s' with address '%d' conflicts with register '%s' with the same address!" % \ - (reg.name, reg.address, conflict_reg.name) - - @property - def regs(self): - """List with register objects.""" - return self._regs - - def add_registers(self, new_regs): - """Add list of registers. - - Register are automatically sorted and stored in the ascending order of addresses. - """ - # hack to handle single elements - new_regs = utils.listify(new_regs) - - # add registers to the list one by one - for reg in new_regs: - # check existance - assert reg.name not in self.reg_names, \ - "Register with name '%s' is already present!" % (reg.name) - # aplly calculated address if register address is empty - if reg.address is None: - self._addr_resolve(reg) - # check address alignment - self._addr_check_alignment(reg) - # check address conflicts - self._addr_check_conflicts(reg) - # if we here - all is ok and register can be added - try: - # find position to insert register and not to break ascending order of addresses - reg_idx = next(i for i, r in enumerate(self._regs) if r.address > reg.address) - self._regs.insert(reg_idx, reg) - except StopIteration: - # when registers list is empty or all addresses are less than the current one - self._regs.append(reg) - return self - - def validate(self): - """Validate the register map.""" - for reg in self.regs: - assert self.reg_names.count(reg.name) == 1, \ - "Register '%s' name is not unique!" % (reg.name) - reg.validate() - - def read_file(self, path): - """Read register map from file (based on extension).""" - ext = utils.get_file_ext(path) - if ext in ['.yaml', '.yml']: - self.read_yaml(path) - elif ext == '.json': - self.read_json(path) - elif ext == '.txt': - self.read_txt(path) - else: - raise ValueError("Unknown extension '%s' of the file '%s'" % (ext, path)) - - def read_json(self, path): - """Read register map from JSON file.""" - with open(path, 'r') as f: - data = json.load(f) - self._fill_from_file_data(data['regmap']) - - def read_yaml(self, path): - """Read register map from YAML file.""" - with open(path, 'r') as f: - data = yaml.safe_load(f) - self._fill_from_file_data(data['regmap']) - - def read_txt(self, path): - """Read register map from text file.""" - with open(path, 'r') as f: - raw_lines = f.readlines() - data = [] - reg_start_idx = None - for i, line in enumerate(raw_lines): - if '-----' in line: - reg_start_idx = i + 1 - if reg_start_idx and i >= reg_start_idx: - # register with one bitfield template - reg = {"name": None, "description": None, - "bitfields": [{"width": None, "access": None, "hardware": None}]} - # prepare the line - line_data = [s.strip() for s in line.split("|")[1:-1]] - if len(line_data) != 7: - raise ValueError("Not enough / too much columns in line %d. Plese fix!" % (i + 1)) - # extract register properties - if line_data[0]: # address value can be ommited - reg["address"] = line_data[0] - reg["address"] = line_data[0] if line_data[0] else None - reg["name"] = line_data[1] - reg["bitfields"][0]["width"] = line_data[2] - reg["bitfields"][0]["access"] = line_data[3] - reg["bitfields"][0]["hardware"] = line_data[4] - if line_data[4]: # reset value can be ommited - reg["bitfields"][0]["reset"] = line_data[5] - reg["description"] = line_data[6] - data.append(reg) - if not reg_start_idx: - raise ValueError("Can't find table with registers!") - self._fill_from_file_data(data) - - def _fill_from_file_data(self, data): - """Fill register map with data from file.""" - self._regs = [] - for data_reg in data: - data_reg_filtered = {k: v for k, v in data_reg.items() if k != 'bitfields'} - reg = Register(**data_reg_filtered) - for data_bf in data_reg['bitfields']: - data_bf_filtered = {k: v for k, v in data_bf.items() if k != 'enums'} - bf = BitField(**data_bf_filtered) - if 'enums' in data_bf.keys(): - for data_enum in data_bf['enums']: - bf.add_enums(EnumValue(**data_enum)) - reg.add_bitfields(bf) - self.add_registers(reg) diff --git a/corsair/templates/amm2lb_verilog.j2 b/corsair/templates/amm2lb_verilog.j2 deleted file mode 100755 index e0dd6e1..0000000 --- a/corsair/templates/amm2lb_verilog.j2 +++ /dev/null @@ -1,84 +0,0 @@ -// Created with Corsair v{{ corsair_ver }} -// -// Avalon-MM to Local Bus bridge -// - -module {{ module_name }} #( - parameter ADDR_W = {{ config['address_width'] }}, - parameter DATA_W = {{ config['data_width'] }}, - parameter STRB_W = DATA_W / 8 -)( - input clk, - input rst, - // Local Bus - input wready, - output [ADDR_W-1:0] waddr, - output [DATA_W-1:0] wdata, - output wen, - output [STRB_W-1:0] wstrb, - input [DATA_W-1:0] rdata, - input rvalid, - output [ADDR_W-1:0] raddr, - output ren, -{% macro amm_core(regmap_embed=False) %} - // Avalon-MM - input [ADDR_W-1:0] address, - input read, - output [DATA_W-1:0] readdata, - output readdatavalid, - input [STRB_W-1:0] byteenable, - input write, - input [DATA_W-1:0] writedata, - output waitrequest -); -{% if regmap_embed %} -wire wready; -wire [ADDR_W-1:0] waddr; -wire [DATA_W-1:0] wdata; -wire wen; -wire [STRB_W-1:0] wstrb; -wire [DATA_W-1:0] rdata; -wire rvalid; -wire [ADDR_W-1:0] raddr; -wire ren; -{% endif %} - - assign waddr = address, - raddr = address; - - assign waitrequest = ~wready; - assign readdatavalid = rvalid; - - assign wdata = writedata, - readdata = rdata; - - assign wen = write; - - assign wstrb = byteenable; - reg ren_int; - {% set rst_type = config['register_reset']%} - {%- if rst_type == 'async_pos' or rst_type == 'sync_pos' %} - {% set rst_active = 1%} - {%- elif rst_type == 'async_neg' or rst_type == 'sync_neg' %} - {% set rst_active = 0%} - {%- endif %} - always @(posedge clk - {%- if rst_type == 'async_pos' %} or posedge rst) - {%- elif rst_type == 'async_neg' %} or negedge rst) - {%- else -%} ) {%- endif %} begin - if (rst == 1'b{{ rst_active }}) - ren_int <= 1'b0; - else - begin - if (read) - ren_int <= 1'b1; - else - if (rvalid) - ren_int <= 1'b0; - end - end - - assign ren = ren_int; -{% endmacro %} -{{ amm_core() }} -endmodule diff --git a/corsair/templates/amm2lb_vhdl.j2 b/corsair/templates/amm2lb_vhdl.j2 deleted file mode 100644 index 32fc58d..0000000 --- a/corsair/templates/amm2lb_vhdl.j2 +++ /dev/null @@ -1,127 +0,0 @@ -{#- Many thanks to github.com/smirnovich for providing the VHDL code for this template #} - -{#- 'process' header with reset logic #} -{% macro process_begin(sig='test', init="'0'") %} - {% set rst_type = config['register_reset']%} - {% if rst_type == 'sync_pos' %} -process (clk) begin -if rising_edge(clk) then -if (rst = '1') then - {{ sig }} <= {{ init }}; -else - {%- elif rst_type == 'sync_neg' %} -process (clk) begin -if rising_edge(clk) then -if (rst = '0') then - {{ sig }} <= {{ init }}; -else - {%- elif rst_type == 'async_pos' %} -process (clk, rst) begin -if (rst = '1') then - {{ sig }} <= {{ init }}; -elsif rising_edge(clk) then - {%- elif rst_type == 'async_neg' %} -process (clk, rst) begin -if (rst = '0') then - {{ sig }} <= {{ init }}; -elsif rising_edge(clk) then - {%- endif %} -{%- endmacro %} - -{#- 'process' footer #} -{% macro process_end() %} - {% if 'async' in config['register_reset'] %} -end if; -end process; - {% else %} -end if; -end if; -end process; - {% endif %} -{%- endmacro %} - --- Created with Corsair v{{ corsair_ver }} --- --- Avalon-MM to Local Bus bridge --- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity {{ module_name }} is -generic( - ADDR_W : integer := {{ config['address_width'] }}; - DATA_W : integer := {{ config['data_width'] }}; - STRB_W : integer := {{ config['data_width'] // 8 }} -); -port( - clk : in std_logic; - rst : in std_logic; - -- Local Bus - wready : in std_logic; - waddr : out std_logic_vector(ADDR_W-1 downto 0); - wdata : out std_logic_vector(DATA_W-1 downto 0); - wen : out std_logic; - wstrb : out std_logic_vector(STRB_W-1 downto 0); - rdata : in std_logic_vector(DATA_W-1 downto 0); - rvalid : in std_logic; - raddr : out std_logic_vector(ADDR_W-1 downto 0); - ren : out std_logic; - {% macro amm_ports() %} - -- Avalon-MM - address : in std_logic_vector(ADDR_W-1 downto 0); - read : in std_logic; - readdata : out std_logic_vector(DATA_W-1 downto 0); - readdatavalid : out std_logic; - byteenable : in std_logic_vector(STRB_W-1 downto 0); - write : in std_logic; - writedata : in std_logic_vector(DATA_W-1 downto 0); - waitrequest : out std_logic - {% endmacro %} - {{ amm_ports() }} -); -end {{ module_name }}; -architecture arch_imp of {{ module_name }} is -{% macro amm_signals(regmap_embed=False) %} - {% if regmap_embed %} -signal wready : std_logic; -signal waddr : std_logic_vector(ADDR_W-1 downto 0); -signal wdata : std_logic_vector(DATA_W-1 downto 0); -signal wen : std_logic; -signal wstrb : std_logic_vector(STRB_W-1 downto 0); -signal rdata : std_logic_vector(DATA_W-1 downto 0); -signal rvalid : std_logic; -signal raddr : std_logic_vector(ADDR_W-1 downto 0); -signal ren : std_logic; - {% endif %} -signal ren_int : std_logic; -{% endmacro %} -{{ amm_signals() }} -begin -{% macro amm_core() %} -waddr <= address; -raddr <= address; - -waitrequest <= not wready; -readdatavalid <= rvalid; - -wdata <= writedata; -readdata <= rdata; - -wen <= write; - -wstrb <= byteenable; - -{{ process_begin("ren_int", "'1'") }} - if (read = '1') then - ren_int <= '1'; - elsif (rvalid = '1') then - ren_int <= '0'; - end if; -{{ process_end() }} - -ren <= ren_int; - -{% endmacro %} -{{ amm_core() }} -end arch_imp; \ No newline at end of file diff --git a/corsair/templates/apb2lb_verilog.j2 b/corsair/templates/apb2lb_verilog.j2 deleted file mode 100755 index f47684d..0000000 --- a/corsair/templates/apb2lb_verilog.j2 +++ /dev/null @@ -1,60 +0,0 @@ -// Created with Corsair v{{ corsair_ver }} -// -// APB to Local Bus bridge -// - -module {{ module_name }} #( - parameter ADDR_W = {{ config['address_width'] }}, - parameter DATA_W = {{ config['data_width'] }}, - parameter STRB_W = DATA_W / 8 -)( - // Local Bus - input wready, - output [ADDR_W-1:0] waddr, - output [DATA_W-1:0] wdata, - output wen, - output [STRB_W-1:0] wstrb, - input [DATA_W-1:0] rdata, - input rvalid, - output [ADDR_W-1:0] raddr, - output ren, -{% macro apb_core(regmap_embed=False) %} - // APB - input psel, - input [ADDR_W-1:0] paddr, - input penable, - input pwrite, - input [DATA_W-1:0] pwdata, - input [STRB_W-1:0] pstrb, - output [DATA_W-1:0] prdata, - output pready, - output pslverr -); -{% if regmap_embed %} -wire wready; -wire [ADDR_W-1:0] waddr; -wire [DATA_W-1:0] wdata; -wire wen; -wire [STRB_W-1:0] wstrb; -wire [DATA_W-1:0] rdata; -wire rvalid; -wire [ADDR_W-1:0] raddr; -wire ren; -{% endif %} -// APB interface -assign prdata = rdata; -assign pslverr = 1'b0; // always OKAY -assign pready = wen ? wready : - (ren & penable) ? rvalid : 1'b1; - -// Local Bus interface -assign waddr = paddr; -assign wdata = pwdata; -assign wstrb = pstrb; -assign wen = psel & penable & pwrite; - -assign raddr = paddr; -assign ren = psel & penable & (~pwrite); -{% endmacro %} -{{ apb_core() }} -endmodule diff --git a/corsair/templates/apb2lb_vhdl.j2 b/corsair/templates/apb2lb_vhdl.j2 deleted file mode 100644 index d61d926..0000000 --- a/corsair/templates/apb2lb_vhdl.j2 +++ /dev/null @@ -1,77 +0,0 @@ -{#- Many thanks to github.com/smirnovich for providing the VHDL code for this template #} - --- Created with Corsair v{{ corsair_ver }} --- --- APB to Local Bus bridge --- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity {{ module_name }} is -generic( - ADDR_W : integer := {{ config['address_width'] }}; - DATA_W : integer := {{ config['data_width'] }}; - STRB_W : integer := {{ config['data_width'] // 8 }} -); -port( - -- Local Bus - wready : in std_logic; - waddr : out std_logic_vector(ADDR_W-1 downto 0); - wdata : out std_logic_vector(DATA_W-1 downto 0); - wen : out std_logic; - wstrb : out std_logic_vector(STRB_W-1 downto 0); - rdata : in std_logic_vector(DATA_W-1 downto 0); - rvalid : in std_logic; - raddr : out std_logic_vector(ADDR_W-1 downto 0); - ren : out std_logic; - {% macro apb_ports() %} - -- APB - psel : in std_logic; - paddr : in std_logic_vector(ADDR_W-1 downto 0); - penable : in std_logic; - pwrite : in std_logic; - pwdata : in std_logic_vector(DATA_W-1 downto 0); - pstrb : in std_logic_vector(STRB_W-1 downto 0); - prdata : out std_logic_vector(DATA_W-1 downto 0); - pready : out std_logic; - pslverr : out std_logic - {% endmacro %} - {{ apb_ports() }} -); -end {{ module_name }}; -architecture arch_imp of {{ module_name }} is -{% macro apb_signals(regmap_embed=False) %} - {% if regmap_embed %} -signal wready : std_logic; -signal waddr : std_logic_vector(ADDR_W-1 downto 0); -signal wdata : std_logic_vector(DATA_W-1 downto 0); -signal wen : std_logic; -signal wstrb : std_logic_vector(STRB_W-1 downto 0); -signal rdata : std_logic_vector(DATA_W-1 downto 0); -signal rvalid : std_logic; -signal raddr : std_logic_vector(ADDR_W-1 downto 0); -signal ren : std_logic; - {% endif %} -{% endmacro %} -{{ apb_signals() }} -begin -{% macro apb_core() %} --- APB interface -prdata <= rdata; -pslverr <= '0'; -- always OKAY -pready <= wready when (psel='1' and penable='1' and pwrite='1') else - rvalid when (psel='1' and pwrite='0' and penable='1') else - '1'; - --- Local Bus interface -waddr <= paddr; -wdata <= pwdata; -wstrb <= pstrb; -wen <= psel and penable and pwrite; - -raddr <= paddr; -ren <= psel and penable and (not pwrite); -{% endmacro %} -{{ apb_core() }} -end arch_imp; diff --git a/corsair/templates/axil2lb_verilog.j2 b/corsair/templates/axil2lb_verilog.j2 deleted file mode 100755 index 8f580f5..0000000 --- a/corsair/templates/axil2lb_verilog.j2 +++ /dev/null @@ -1,162 +0,0 @@ -// Created with Corsair v{{ corsair_ver }} -// -// AXI-Lite to Local Bus bridge -// - -module {{ module_name }} #( - parameter ADDR_W = {{ config['address_width'] }}, - parameter DATA_W = {{ config['data_width'] }}, - parameter STRB_W = DATA_W / 8 -)( - input clk, - input rst, - // Local Bus - input wready, - output [ADDR_W-1:0] waddr, - output [DATA_W-1:0] wdata, - output wen, - output [STRB_W-1:0] wstrb, - input [DATA_W-1:0] rdata, - input rvalid, - output [ADDR_W-1:0] raddr, - output ren, -{% macro axil_core(regmap_embed=False) %} - // AXI - input [ADDR_W-1:0] axil_awaddr, - input [2:0] axil_awprot, - input axil_awvalid, - output axil_awready, - input [DATA_W-1:0] axil_wdata, - input [STRB_W-1:0] axil_wstrb, - input axil_wvalid, - output axil_wready, - output [1:0] axil_bresp, - output axil_bvalid, - input axil_bready, - - input [ADDR_W-1:0] axil_araddr, - input [2:0] axil_arprot, - input axil_arvalid, - output axil_arready, - output [DATA_W-1:0] axil_rdata, - output [1:0] axil_rresp, - output axil_rvalid, - input axil_rready -); -{% if regmap_embed %} -wire wready; -wire [ADDR_W-1:0] waddr; -wire [DATA_W-1:0] wdata; -wire wen; -wire [STRB_W-1:0] wstrb; -wire [DATA_W-1:0] rdata; -wire rvalid; -wire [ADDR_W-1:0] raddr; -wire ren; -{% endif %} - reg [ADDR_W-1:0] waddr_int; - reg [ADDR_W-1:0] raddr_int; - reg [DATA_W-1:0] wdata_int; - reg [STRB_W-1:0] strb_int; - reg awflag; - reg wflag; - reg arflag; - reg rflag; - - reg axil_bvalid_int; - reg [DATA_W-1:0] axil_rdata_int; - reg axil_rvalid_int; - - assign axil_awready = ~awflag; - assign axil_wready = ~wflag; - assign axil_bvalid = axil_bvalid_int; - assign waddr = waddr_int; - assign wdata = wdata_int; - assign wstrb = strb_int; - assign wen = awflag && wflag; - assign axil_bresp = 'd0; // always okay - - {% set rst_type = config['register_reset'] %} - {%- if rst_type == 'async_pos' or rst_type == 'sync_pos' %} - {% set rst_active = 1%} - {%- elif rst_type == 'async_neg' or rst_type == 'sync_neg' %} - {% set rst_active = 0%} - {%- endif %} - always @(posedge clk - {%- if rst_type == 'async_pos' %} or posedge rst) - {%- elif rst_type == 'async_neg' %} or negedge rst) - {%- else -%} ) {%- endif %} begin - if (rst == 1'b{{ rst_active }}) begin - waddr_int <= 'd0; - wdata_int <= 'd0; - strb_int <= 'd0; - awflag <= 1'b0; - wflag <= 1'b0; - axil_bvalid_int <= 1'b0; - end else begin - if (axil_awvalid == 1'b1 && awflag == 1'b0) begin - awflag <= 1'b1; - waddr_int <= axil_awaddr; - end else if (wen == 1'b1 && wready == 1'b1) begin - awflag <= 1'b0; - end - - if (axil_wvalid == 1'b1 && wflag == 1'b0) begin - wflag <= 1'b1; - wdata_int <= axil_wdata; - strb_int <= axil_wstrb; - end else if (wen == 1'b1 && wready == 1'b1) begin - wflag <= 1'b0; - end - - if (axil_bvalid_int == 1'b1 && axil_bready == 1'b1) begin - axil_bvalid_int <= 1'b0; - end else if ((axil_wvalid == 1'b1 && awflag == 1'b1) || (axil_awvalid == 1'b1 && wflag == 1'b1) || (wflag == 1'b1 && awflag == 1'b1)) begin - axil_bvalid_int <= wready; - end - end - end - - assign axil_arready = ~arflag; - assign axil_rdata = axil_rdata_int; - assign axil_rvalid = axil_rvalid_int; - assign raddr = raddr_int; - assign ren = arflag && ~rflag; - assign axil_rresp = 'd0; // always okay - - {% set rst_type = config['register_reset'] %} - always @(posedge clk - {%- if rst_type == 'async_pos' %} or posedge rst) - {%- elif rst_type == 'async_neg' %} or negedge rst) - {%- else -%} ) {%- endif %} begin - if (rst == 1'b{{ rst_active }}) begin - raddr_int <= 'd0; - arflag <= 1'b0; - rflag <= 1'b0; - axil_rdata_int <= 'd0; - axil_rvalid_int <= 1'b0; - end else begin - if (axil_arvalid == 1'b1 && arflag == 1'b0) begin - arflag <= 1'b1; - raddr_int <= axil_araddr; - end else if (axil_rvalid_int == 1'b1 && axil_rready == 1'b1) begin - arflag <= 1'b0; - end - - if (rvalid == 1'b1 && ren == 1'b1 && rflag == 1'b0) begin - rflag <= 1'b1; - end else if (axil_rvalid_int == 1'b1 && axil_rready == 1'b1) begin - rflag <= 1'b0; - end - - if (rvalid == 1'b1 && axil_rvalid_int == 1'b0) begin - axil_rdata_int <= rdata; - axil_rvalid_int <= 1'b1; - end else if (axil_rvalid_int == 1'b1 && axil_rready == 1'b1) begin - axil_rvalid_int <= 1'b0; - end - end - end -{% endmacro %} -{{ axil_core() }} -endmodule diff --git a/corsair/templates/axil2lb_vhdl.j2 b/corsair/templates/axil2lb_vhdl.j2 deleted file mode 100644 index ee493f8..0000000 --- a/corsair/templates/axil2lb_vhdl.j2 +++ /dev/null @@ -1,195 +0,0 @@ -{#- Many thanks to github.com/smirnovich for providing the VHDL code for this template #} - -{#- 'process' header with reset logic #} -{% macro process_begin(sig=['test'], init=["'0'"]) %} - {% set rst_type = config['register_reset']%} - {% if rst_type == 'sync_pos' %} -process (clk) begin -if rising_edge(clk) then -if (rst = '1') then - {% for s, i in zip(sig, init) %} - {{s}} <= {{i}}; - {% endfor -%} -else - {%- elif rst_type == 'sync_neg' %} -process (clk) begin -if rising_edge(clk) then -if (rst = '0') then - {% for s, i in zip(sig, init) %} - {{s}} <= {{i}}; - {% endfor -%} -else - {%- elif rst_type == 'async_pos' %} -process (clk, rst) begin -if (rst = '1') then - {% for s, i in zip(sig, init) %} - {{s}} <= {{i}}; - {% endfor -%} -elsif rising_edge(clk) then - {%- elif rst_type == 'async_neg' %} -process (clk, rst) begin -if (rst = '0') then - {% for s, i in zip(sig, init) %} - {{s}} <= {{i}}; - {% endfor -%} -elsif rising_edge(clk) then - {%- endif %} -{%- endmacro %} - -{#- 'process' footer #} -{% macro process_end() %} - {% if 'async' in config['register_reset'] %} -end if; -end process; - {% else %} -end if; -end if; -end process; - {% endif %} -{%- endmacro %} - --- Created with Corsair v{{ corsair_ver }} --- --- AXI-Lite to Local Bus bridge --- -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity {{ module_name }} is -generic( - ADDR_W : integer := {{ config['address_width'] }}; - DATA_W : integer := {{ config['data_width'] }}; - STRB_W : integer := {{ config['data_width'] // 8 }} -); -port( - clk : in std_logic; - rst : in std_logic; - -- Local Bus - wready : in std_logic; - waddr : out std_logic_vector(ADDR_W-1 downto 0); - wdata : out std_logic_vector(DATA_W-1 downto 0); - wen : out std_logic; - wstrb : out std_logic_vector(STRB_W-1 downto 0); - rdata : in std_logic_vector(DATA_W-1 downto 0); - rvalid : in std_logic; - raddr : out std_logic_vector(ADDR_W-1 downto 0); - ren : out std_logic; - {% macro axil_ports() %} - -- AXI-Lite - axil_awaddr : in std_logic_vector(ADDR_W-1 downto 0); - axil_awprot : in std_logic_vector(2 downto 0); - axil_awvalid : in std_logic; - axil_awready : out std_logic; - axil_wdata : in std_logic_vector(DATA_W-1 downto 0); - axil_wstrb : in std_logic_vector(STRB_W-1 downto 0); - axil_wvalid : in std_logic; - axil_wready : out std_logic; - axil_bresp : out std_logic_vector(1 downto 0); - axil_bvalid : out std_logic; - axil_bready : in std_logic; - axil_araddr : in std_logic_vector(ADDR_W-1 downto 0); - axil_arprot : in std_logic_vector(2 downto 0); - axil_arvalid : in std_logic; - axil_arready : out std_logic; - axil_rdata : out std_logic_vector(DATA_W-1 downto 0); - axil_rresp : out std_logic_vector(1 downto 0); - axil_rvalid : out std_logic; - axil_rready : in std_logic - {% endmacro %} - {{ axil_ports() }} -); -end {{ module_name }}; -architecture arch_imp of {{ module_name }} is -{% macro axil_signals(regmap_embed=False) %} - {% if regmap_embed %} -signal wready : std_logic; -signal waddr : std_logic_vector(ADDR_W-1 downto 0); -signal wdata : std_logic_vector(DATA_W-1 downto 0); -signal wen : std_logic; -signal wstrb : std_logic_vector(STRB_W-1 downto 0); -signal rdata : std_logic_vector(DATA_W-1 downto 0); -signal rvalid : std_logic; -signal raddr : std_logic_vector(ADDR_W-1 downto 0); -signal ren : std_logic; - {% endif %} -signal waddr_int : std_logic_vector(ADDR_W-1 downto 0); -signal raddr_int : std_logic_vector(ADDR_W-1 downto 0); -signal wdata_int : std_logic_vector(DATA_W-1 downto 0); -signal strb_int : std_logic_vector(STRB_W-1 downto 0); -signal awflag : std_logic; -signal wflag : std_logic; -signal arflag : std_logic; -signal rflag : std_logic; -signal wen_int : std_logic; -signal ren_int : std_logic; -signal axil_bvalid_int : std_logic; -signal axil_rdata_int : std_logic_vector(DATA_W-1 downto 0); -signal axil_rvalid_int : std_logic; -{% endmacro %} -{{ axil_signals() }} -begin -{% macro axil_core() %} -axil_awready <= not awflag; -axil_wready <= not wflag; -axil_bvalid <= axil_bvalid_int; -waddr <= waddr_int; -wdata <= wdata_int; -wstrb <= strb_int; -wen_int <= awflag and wflag; -wen <= wen_int; -axil_bresp <= b"00"; - -{{ process_begin(["waddr_int", "wdata_int", "strb_int", "awflag", "wflag", "axil_bvalid_int"], - ["(others => '0')", "(others => '0')", "(others => '0')", "'0'", "'0'", "'0'"]) }} - if (axil_awvalid = '1' and awflag = '0') then - awflag <= '1'; - waddr_int <= axil_awaddr; - elsif (wen_int = '1' and wready = '1') then - awflag <= '0'; - end if; - if (axil_wvalid = '1' and wflag = '0') then - wflag <= '1'; - wdata_int <= axil_wdata; - strb_int <= axil_wstrb; - elsif (wen_int = '1' and wready = '1') then - wflag <= '0'; - end if; - if (axil_bvalid_int = '1' and axil_bready = '1') then - axil_bvalid_int <= '0'; - elsif ((axil_wvalid = '1' and awflag = '1') or (axil_awvalid = '1' and wflag = '1') or (wflag = '1' and awflag = '1')) then - axil_bvalid_int <= wready; - end if; -{{ process_end() }} - -axil_arready <= not arflag; -axil_rdata <= axil_rdata_int; -axil_rvalid <= axil_rvalid_int; -raddr <= raddr_int; -ren_int <= arflag and (not rflag); -ren <= ren_int; -axil_rresp <= b"00"; - -{{ process_begin(["raddr_int", "arflag", "rflag", "axil_rdata_int", "axil_rvalid_int"], - ["(others => '0')", "'0'", "'0'", "(others => '0')", "'0'"]) }} - if (axil_arvalid = '1' and arflag = '0') then - arflag <= '1'; - raddr_int <= axil_araddr; - elsif (axil_rvalid_int = '1' and axil_rready = '1') then - arflag <= '0'; - end if; - if (rvalid = '1' and ren_int = '1' and rflag = '0') then - rflag <= '1'; - elsif (axil_rvalid_int = '1' and axil_rready = '1') then - rflag <= '0'; - end if; - if (rvalid = '1' and axil_rvalid_int = '0') then - axil_rdata_int <= rdata; - axil_rvalid_int <= '1'; - elsif (axil_rvalid_int = '1' and axil_rready = '1') then - axil_rvalid_int <= '0'; - end if; -{{ process_end() }} -{% endmacro %} -{{ axil_core() }} -end arch_imp; \ No newline at end of file diff --git a/corsair/templates/c_header.j2 b/corsair/templates/c_header.j2 deleted file mode 100755 index 3f965d0..0000000 --- a/corsair/templates/c_header.j2 +++ /dev/null @@ -1,117 +0,0 @@ -{# MACRO #} -{% macro data_t() %} -uint{{ config['data_width'] }}_t -{%- endmacro %} - -{#- register access #} -{% macro reg_access(reg) %} - {% if 'ro' in reg.access %} -__I - {%- elif 'wo' in reg.access %} -__O - {%- else %} -__IO - {%- endif %} -{%- endmacro %} - -{#- module name #} -{% macro module_name() %} - {%- if prefix %} -{{ prefix }} - {%- else %} -{{ file_name }} - {%- endif %} -{%- endmacro %} - -{#- module prefix #} -{% macro module_prefix() %} -{{ module_name() }}_ -{%- endmacro %} - -{#- register data type #} -{% macro reg_type(reg) %} -{{ module_prefix()|lower }}{{ reg.name.lower() }}_t -{%- endmacro %} - -{#- TEMPLATE NAMESPACE #} -{% set tmp = namespace() %} - -{#- TEMPLATE #} -// Created with Corsair v{{ corsair_ver }} -#ifndef __{{ file_name.upper() }}_H -#define __{{ file_name.upper() }}_H - -#define __I volatile const // 'read only' permissions -#define __O volatile // 'write only' permissions -#define __IO volatile // 'read / write' permissions - - -#ifdef __cplusplus -#include -extern "C" { -#else -#include -#endif - -#define {{ module_prefix()|upper }}BASE_ADDR {{ "0x%x" % config['base_address'] }} - -{% for reg in rmap %} -// {{ reg.name }} - {{ reg.description }} -#define {{ module_prefix()|upper }}{{ reg.name.upper() }}_ADDR {{ "0x%x" % (reg.address) }} -#define {{ module_prefix()|upper }}{{ reg.name.upper() }}_RESET {{ "0x%x" % (reg.reset) }} -typedef struct { - {% set tmp.lsb = 0 %} - {% for bf in reg %} - {% if tmp.lsb != bf.lsb %} - {{ data_t() }} : {{ bf.lsb - tmp.lsb }}; // reserved - {% endif %} - {% set tmp.lsb = bf.lsb + bf.width %} - {{ data_t() }} {{ bf.name.upper() }} : {{ bf.width }}; // {{ bf.description }} - {% endfor %} - {%if tmp.lsb < config.data_width - 1%} - {{ data_t() }} : {{ config.data_width - tmp.lsb }}; // reserved - {% endif %} -} {{ module_prefix()|lower }}{{ reg.name.lower() }}_t; - - {% for bf in reg %} -// {{ reg.name }}.{{ bf.name }} - {{ bf.description }} -#define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_WIDTH {{ bf.width }} -#define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_LSB {{ bf.lsb }} -#define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_MASK {{ "0x%x" % (bf.mask) }} -#define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_RESET {{ "0x%x" % (bf.reset) }} - {% if bf.enums %} -typedef enum { - {% for enum in bf %} - {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_{{ enum.name.upper() }} = {{ "0x%x" % (enum.value) }}, //{{ enum.description }} - {% endfor %} -} {{ module_prefix()|lower }}{{ reg.name.lower() }}_{{ bf.name.lower() }}_t; - {% endif %} - - {% endfor %} -{% endfor %} - -// Register map structure -typedef struct { -{% set tmp.addr_next = 0 %} -{% set tmp.reserved_cnt = 0 %} -{% set tmp.bytes_in_word = config['data_width'] // 8 %} -{% for reg in rmap %} - {% if tmp.addr_next != reg.address %} - __IO {{ data_t() }} RESERVED{{ tmp.reserved_cnt }}[{{ (reg.address - tmp.addr_next) // tmp.bytes_in_word }}]; - {% set tmp.reserved_cnt = tmp.reserved_cnt + 1 %} - {% endif %} - {% set tmp.addr_next = reg.address + tmp.bytes_in_word %} - union { - {{ reg_access(reg) }} {{ data_t() }} {{ reg.name.upper() }}; // {{ reg.description }} - {{ reg_access(reg) }} {{ module_prefix()|lower }}{{ reg.name.lower() }}_t {{ reg.name.upper() }}_bf; // Bit access for {{ reg.name.upper() }} register - }; -{% endfor %} -} {{ module_prefix()|lower }}t; - -#define {{ module_name()|upper }} (({{ module_prefix()|lower }}t*)({{ module_prefix()|upper }}BASE_ADDR)) - -#ifdef __cplusplus -} -#endif - -#endif /* __{{ file_name.upper() }}_H */ diff --git a/corsair/templates/regmap_asciidoc.j2 b/corsair/templates/regmap_asciidoc.j2 deleted file mode 100644 index 3e24401..0000000 --- a/corsair/templates/regmap_asciidoc.j2 +++ /dev/null @@ -1,102 +0,0 @@ -{#- Many thanks to github.com/EgorVorontsov for providing base for this template #} - -{#- MACRO #} -{#- bit field range #} -{% macro range(bf) %} - {% if bf.width == 1 %} -{{ bf.msb }} - {%- else %} -{{ bf.msb }}:{{ bf.lsb }} - {%- endif %} -{%- endmacro %} - -{#- bit field mode #} -{% macro mode(bf) %} -{{ bf.access }} -{%- endmacro %} - -{#- value in hex format #} -{% macro literal(initial, width) %} -{{ "0x%0{w}x".format(w=width // 4) % initial }} -{%- endmacro %} - -{#- TEMPLATE NAMESPACE #} -{% set tmp = namespace() %} - -{#- TEMPLATE #} -== {{ title }} - -Created with https://github.com/esynr3z/corsair[Corsair] v{{ corsair_ver }}. - -{% if print_conventions %} -=== Conventions - -[#table-Register_access_modes,cols="1,1", options="header"] -|========================== -| Access mode | Description -| rw | Read and Write -| rw1c | Read and Write 1 to Clear -| rw1s | Read and Write 1 to Set -| ro | Read Only -| roc | Read Only to Clear -| roll | Read Only / Latch Low -| rolh | Read Only / Latch High -| wo | Write only -| wosc | Write Only / Self Clear -|========================== -{% endif %} - -[[register_map_summary]] -=== Register map summary - -Base address: {{ "0x%08x" % config['base_address'] }} - -[#table-Register_map,cols="1,1,1", options="header"] -|========================== -| Name | Address | Description -{% for reg in rmap %} -{{ "| %-24s | %-10s | %s" % ("<<%s>>" % (reg.name), literal(reg.address, config['address_width']), reg.description) }} -{% endfor %} -|========================== - - -{% for reg in rmap %} - -[[{{ reg.name }}]] -=== {{ reg.name }} - -{{ reg.description }} - -Address offset: {{ literal(reg.address, config['address_width']) }} - -Reset value: {{ literal(reg.reset, config['data_width']) }} - -{% if print_images %} -image::{{ image_dir }}/{{ reg.name.lower()}}.svg[{{ reg.name.lower()}}] -{% endif %} - -[#table-{{ reg.name }},cols="1,1,1,1,1", options="header"] -|========================== -| Name | Bits | Mode | Reset | Description -{% for bf in reg.bitfields[::-1] %} -{{ "| %-16s | %-6s | %-15s | %-10s | %s" % (bf.name, range(bf), mode(bf), literal(bf.reset, bf.width), bf.description) }} -{% endfor %} -|========================== - -{% for bf in reg %} - {% if bf.enums %} - -Enumerated values for {{ reg.name }}.{{ bf.name }}. - -[#table-{{ reg.name }}_{{ bf.name }}_enums,cols="1,1,1", options="header"] -|========================== -| Name | Bits | Description - {% for enum in bf %} -{{ "| %-16s | %-6s | %s" % (enum.name, literal(enum.value, bf.width), enum.description) }} - {% endfor %} -|========================== - {% endif %} -{% endfor %} - -Back to <> -{% endfor %} diff --git a/corsair/templates/regmap_md.j2 b/corsair/templates/regmap_md.j2 deleted file mode 100755 index 9bf0fb8..0000000 --- a/corsair/templates/regmap_md.j2 +++ /dev/null @@ -1,94 +0,0 @@ -{# MACRO #} -{#- generic range #} -{% macro range(msb, lsb) %} - {% if msb == lsb %} -{{ msb }} - {%- else %} -{{ msb }}:{{ lsb }} - {%- endif %} -{%- endmacro %} - -{#- bit field mode #} -{% macro mode(bf) %} -{{ bf.access }} -{%- endmacro %} - -{#- value in hex format #} -{% macro literal(reset, width) %} -{{ "0x%0{w}x".format(w=width // 4) % reset }} -{%- endmacro %} - -{#- TEMPLATE NAMESPACE #} -{% set tmp = namespace() %} - -{#- TEMPLATE #} -# {{ title }} - -Created with [Corsair](https://github.com/esynr3z/corsair) v{{ corsair_ver }}. - -{% if print_conventions %} -## Conventions - -| Access mode | Description | -| :---------- | :------------------------ | -| rw | Read and Write | -| rw1c | Read and Write 1 to Clear | -| rw1s | Read and Write 1 to Set | -| ro | Read Only | -| roc | Read Only to Clear | -| roll | Read Only / Latch Low | -| rolh | Read Only / Latch High | -| wo | Write only | -| wosc | Write Only / Self Clear | -{% endif %} - -## Register map summary - -Base address: {{ "0x%08x" % config['base_address'] }} - -| Name | Address | Description | -| :--- | :--- | :--- | -{% for reg in rmap %} -{{ "| %-24s | %-10s | %s" % ("[%s](#%s)" % (reg.name, reg.name.lower()), literal(reg.address, config['address_width']), reg.description) }} | -{% endfor %} -{% for reg in rmap %} - -## {{ reg.name }} - -{{ reg.description }} - -Address offset: {{ literal(reg.address, config['address_width']) }} - -Reset value: {{ literal(reg.reset, config['data_width']) }} - -{% if print_images %} -![{{ reg.name.lower()}}]({{ image_dir }}/{{ reg.name.lower()}}.svg) -{% endif %} - -| Name | Bits | Mode | Reset | Description | -| :--- | :--- | :--- | :--- | :--- | - {% set tmp.reserved_msb = config['data_width'] - 1 %} - {% for bf in reg.bitfields[::-1] %} - {% if tmp.reserved_msb > bf.msb %} - {% set tmp.reserved_lsb = bf.msb + 1 %} - {% set tmp.reserved_width = tmp.reserved_msb - tmp.reserved_lsb + 1 %} -{{ "| %-16s | %-6s | %-15s | %-10s | %s |" % ('-', range(tmp.reserved_msb, tmp.reserved_lsb), '-', literal(0, tmp.reserved_width), 'Reserved') }} - {% endif %} -{{ "| %-16s | %-6s | %-15s | %-10s | %s |" % (bf.name, range(bf.msb, bf.lsb), mode(bf), literal(bf.reset, bf.width), bf.description) }} - {% set tmp.reserved_msb = bf.lsb - 1 %} - {% endfor %} - {% for bf in reg %} - {% if bf.enums %} - -Enumerated values for {{ reg.name }}.{{ bf.name }}. - -| Name | Value | Description | -| :--- | :--- | :--- | - {% for enum in bf %} -{{ "| %-16s | %-6s | %s |" % (enum.name, literal(enum.value, bf.width), enum.description) }} - {% endfor %} - {% endif %} - {% endfor %} - -Back to [Register map](#register-map-summary). -{% endfor %} \ No newline at end of file diff --git a/corsair/templates/regmap_py.j2 b/corsair/templates/regmap_py.j2 deleted file mode 100755 index e72dfda..0000000 --- a/corsair/templates/regmap_py.j2 +++ /dev/null @@ -1,94 +0,0 @@ -{# MACRO #} -{#- value in hex format #} -{% macro literal(val, width) %} -{{ "0x%0{w}x".format(w=width // 4) % val }} -{%- endmacro %} - -{#- register address #} -{% macro reg_addr(reg) %} -{{ reg.name.upper() }}_ADDR -{%- endmacro %} - -{#- bitfield position #} -{% macro bf_pos(reg, bf) %} -{{ reg.name.upper() }}_{{ bf.name.upper() }}_POS -{%- endmacro %} - -{#- bitfield mask #} -{% macro bf_msk(reg, bf) %} -{{ reg.name.upper() }}_{{ bf.name.upper() }}_MSK -{%- endmacro %} - -{#- TEMPLATE #} -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -""" Created with Corsair v{{ corsair_ver }} - -Control/status register map. -""" - -{% for reg in rmap %} - -class _Reg{{ reg.name.capitalize() }}: - def __init__(self, rmap): - self._rmap = rmap - {% for bf in reg %} - - @property - def {{ bf.name.lower() }}(self): - """{{ bf.description }}""" - {% if 'r' not in bf.access %} - return 0 - {% else %} - rdata = self._rmap._if.read(self._rmap.{{ reg_addr(reg) }}) - return (rdata >> self._rmap.{{ bf_pos(reg, bf) }}) & self._rmap.{{ bf_msk(reg, bf) }} - {% endif %} - {% if 'w' in bf.access %} - - @{{ bf.name.lower() }}.setter - def {{ bf.name.lower() }}(self, val): - rdata = self._rmap._if.read(self._rmap.{{ reg_addr(reg) }}) - rdata = rdata & (~(self._rmap.{{ bf_msk(reg, bf) }} << self._rmap.{{ bf_pos(reg, bf) }})) - rdata = rdata | (val << self._rmap.{{ bf_pos(reg, bf) }}) - self._rmap._if.write(self._rmap.{{ reg_addr(reg) }}, rdata) - {% endif %} - {% endfor %} - -{% endfor %} - -class RegMap: - """Control/Status register map""" -{% for reg in rmap %} - - # {{ reg.name.upper() }} - {{ reg.description }} - {{ reg_addr(reg) }} = {{ literal(reg.address, config['address_width']) }} - {% for bf in reg %} - {{ bf_pos(reg, bf) }} = {{ bf.lsb }} - {{ bf_msk(reg, bf) }} = {{ literal(2 ** bf.width - 1, bf.width) }} - {% endfor %} -{% endfor %} - - def __init__(self, interface): - self._if = interface -{% for reg in rmap %} - - @property - def {{ reg.name.lower() }}(self): - """{{ reg.description }}""" - {% if 'r' not in reg.access %} - return 0 - {% else %} - return self._if.read(self.{{ reg_addr(reg) }}) - {% endif %} - {% if 'w' in reg.access %} - - @{{ reg.name.lower() }}.setter - def {{ reg.name.lower() }}(self, val): - self._if.write(self.{{ reg_addr(reg) }}, val) - {% endif %} - - @property - def {{ reg.name.lower() }}_bf(self): - return _Reg{{ reg.name.capitalize() }}(self) -{% endfor %} diff --git a/corsair/templates/regmap_verilog.j2 b/corsair/templates/regmap_verilog.j2 deleted file mode 100755 index 559754f..0000000 --- a/corsair/templates/regmap_verilog.j2 +++ /dev/null @@ -1,476 +0,0 @@ -{# MACRO #} -{#- vector range for select operations #} -{% macro range(msb, lsb, is_vector=true) %} - {% if is_vector %} - {% if msb == lsb %} -[{{ msb }}] - {%- else %} -[{{ msb }}:{{ lsb }}] - {%- endif %} - {%- endif %} -{%- endmacro %} - -{#- vector range for declarations #} -{% macro range_decl(msb, is_vector=true) %} - {% if is_vector %} -[{{ msb }}:0] - {%- endif %} -{%- endmacro %} - -{#- literal #} -{% macro literal(val, width=1) %} - {% if width == 1 %} -1'b{{ val }} - {%- else %} -{{ width}}'h{{ '%x' % val }} - {%- endif %} -{%- endmacro %} - -{#- special literal for all zeros #} -{% macro zeros(width=1) %} - {% if width == 1 %} -1'b0 - {%- else %} -{{ width }}'h0 - {%- endif %} -{%- endmacro %} - -{#- special literal for all ones #} -{% macro ones(width=1) %} - {% if width == 1 %} -1'b1 - {%- else %} -{{ "{%d{1'b1}}" % width }} - {%- endif %} -{%- endmacro %} - -{#- self clear logic #} -{% macro self_clear(sig, enable=False, width=1) %} - {% if enable %} - {{ sig }} <= {{ zeros(width) }}; - {%- endif %} -{%- endmacro %} - -{#- 'always' header with reset logic #} -{% macro always_begin(sig='', width=1, init=0) %} - {% set rst_type = config['register_reset']%} - {% if rst_type == 'sync_pos' %} -always @(posedge clk) begin - if (rst) begin - {% elif rst_type == 'sync_neg' %} -always @(posedge clk) begin - if (!rst) begin - {% elif rst_type == 'async_pos' %} -always @(posedge clk or posedge rst) begin - if (rst) begin - {% elif rst_type == 'async_neg' %} -always @(posedge clk or negedge rst) begin - if (!rst) begin - {% endif %} - {{ sig }} <= {{ literal(init, width) }}; - end else -{%- endmacro %} - -{#- signal: csr for rdata bus #} -{% macro sig_csr_rdata(reg) %} -csr_{{ reg.name.lower() }}_rdata -{%- endmacro %} - -{#- port: bitfield output #} -{% macro port_bf_out(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_out -{%- endmacro %} - -{#- port: bitfield input #} -{% macro port_bf_in(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_in -{%- endmacro %} - -{#- port: bitfield input enable #} -{% macro port_bf_en(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_en -{%- endmacro %} - -{#- port: bitfield clear enable #} -{% macro port_bf_clr(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_clr -{%- endmacro %} - -{#- port: bitfield set enable #} -{% macro port_bf_set(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_set -{%- endmacro %} - -{#- port: bitfield read enable #} -{% macro port_bf_ren(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_ren -{%- endmacro %} - -{#- port: bitfield read valid #} -{% macro port_bf_rvalid(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_rvalid -{%- endmacro %} - -{#- port: bitfield write enable #} -{% macro port_bf_wen(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_wen -{%- endmacro %} - -{#- port: bitfield write ready #} -{% macro port_bf_wready(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_wready -{%- endmacro %} - -{#- signal: bitfield registered read valid #} -{% macro sig_bf_rvalid_ff(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_rvalid_ff -{%- endmacro %} - -{#- signal: bitfield flip-flops #} -{% macro sig_bf_ff(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_ff -{%- endmacro %} - -{#- port: bitfield read access strobe #} -{% macro port_bf_raccess(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_raccess -{%- endmacro %} - -{#- port: bitfield write access strobe #} -{% macro port_bf_waccess(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_waccess -{%- endmacro %} - -{#- port: bitfield lock signal #} -{% macro port_bf_lock(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_lock -{%- endmacro %} - -{#- signal: register read enable #} -{% macro sig_csr_ren(reg) %} -csr_{{ reg.name.lower() }}_ren -{%- endmacro %} - -{#- signal: register read enable registered #} -{% macro sig_csr_ren_ff(reg) %} -csr_{{ reg.name.lower() }}_ren_ff -{%- endmacro %} - -{#- signal: register write enable #} -{% macro sig_csr_wen(reg) %} -csr_{{ reg.name.lower() }}_wen -{%- endmacro %} - -{#- TEMPLATE NAMESPACE #} -{% set tmp = namespace() %} -{% from "amm2lb_verilog.j2" import amm_core with context %} -{% from "axil2lb_verilog.j2" import axil_core with context %} -{% from "apb2lb_verilog.j2" import apb_core with context %} - -{#- TEMPLATE #} -// Created with Corsair v{{ corsair_ver }} - -module {{ module_name }} #( - parameter ADDR_W = {{ config['address_width'] }}, - parameter DATA_W = {{ config['data_width'] }}, - parameter STRB_W = DATA_W / 8 -)( - // System - input clk, - input rst, -{% for reg in rmap %} - {% for bf in reg %} - // {{ reg.name }}.{{ bf.name }} - {% if 'a' in bf.hardware %} - {% if 'i' in bf.hardware %} - output {{ port_bf_raccess(reg, bf) }}, - {% endif %} - {% if 'o' in bf.hardware %} - output {{ port_bf_waccess(reg, bf) }}, - {% endif %} - {% endif %} - {% if 'l' in bf.hardware %} - input {{ port_bf_lock(reg, bf) }}, - {% endif %} - {% if 'e' in bf.hardware %} - input {{ port_bf_en(reg, bf) }}, - {% endif %} - {% if 'c' in bf.hardware %} - input {{ port_bf_clr(reg, bf) }}, - {% endif %} - {% if 's' in bf.hardware %} - input {{ port_bf_set(reg, bf) }}, - {% endif %} - {% if 'q' in bf.hardware and 'r' in bf.access %} - input {{ port_bf_rvalid(reg, bf) }}, - output {{ port_bf_ren(reg, bf) }}, - input {{ range_decl(bf.width - 1, bf.is_vector()) }} {{ port_bf_in(reg, bf) }}, - {% endif %} - {% if 'i' in bf.hardware %} - input {{ range_decl(bf.width - 1, bf.is_vector()) }} {{ port_bf_in(reg, bf) }}, - {% endif %} - {% if 'o' in bf.hardware %} - output {{ range_decl(bf.width - 1, bf.is_vector()) }} {{ port_bf_out(reg, bf) }}, - {% endif %} - {% if 'q' in bf.hardware and 'w' in bf.access %} - output {{ range_decl(bf.width - 1, bf.is_vector()) }} {{ port_bf_out(reg, bf) }}, - input {{ port_bf_wready(reg, bf) }}, - output {{ port_bf_wen(reg, bf) }}, - {% endif %} - {% endfor %} - -{% endfor %} -{% if interface == 'apb' %} -{{ apb_core(regmap_embed=True) }} -{% elif interface == 'axil' %} -{{ axil_core(regmap_embed=True) }} -{% elif interface == 'amm' %} -{{ amm_core(regmap_embed=True) }} -{% else %} - // Local Bus - input [ADDR_W-1:0] waddr, - input [DATA_W-1:0] wdata, - input wen, - input [STRB_W-1:0] wstrb, - output wready, - input [ADDR_W-1:0] raddr, - input ren, - output [DATA_W-1:0] rdata, - output rvalid -); -{% endif %} -{% for reg in rmap %} -//------------------------------------------------------------------------------ -// CSR: -// [{{ '0x%x' % reg.address }}] - {{ reg.name }} - {{ reg.description }} -//------------------------------------------------------------------------------ -wire {{ range_decl(config['data_width'] - 1) }} {{ sig_csr_rdata(reg) }}; -{# fill unused bits with zeros #} - {% set tmp.last_bit = 0 %} - {% for bf in reg %} - {% if bf.lsb > tmp.last_bit %} -assign {{ sig_csr_rdata(reg) }}{{ range(bf.lsb - 1, tmp.last_bit) }} = {{ zeros(bf.lsb - tmp.last_bit) }}; - {% endif %} - {% set tmp.last_bit = bf.msb + 1 %} - {% endfor %} - {% if config['data_width'] > tmp.last_bit %} -assign {{ sig_csr_rdata(reg) }}{{ range(config['data_width'] - 1, tmp.last_bit) }} = {{ zeros(config['data_width'] - tmp.last_bit) }}; - {% endif %} - - {% if 'w' in reg.access %} -wire {{ sig_csr_wen(reg) }}; -assign {{ sig_csr_wen(reg) }} = wen && (waddr == {{ literal(reg.address, config['address_width']) }}); - {% endif %} - - {% if 'r' in reg.access %} -wire {{ sig_csr_ren(reg) }}; -assign {{ sig_csr_ren(reg) }} = ren && (raddr == {{ literal(reg.address, config['address_width']) }}); -reg {{ sig_csr_ren_ff(reg) }}; -{{ always_begin(sig=sig_csr_ren_ff(reg) -)}} begin - {{ sig_csr_ren_ff(reg) }} <= {{ sig_csr_ren(reg) }}; - end -end - {% endif %} - {% for bf in reg %} -//--------------------- -// Bit field: -// {{ reg.name }}{{ range(bf.msb, bf.lsb) }} - {{ bf.name }} - {{ bf.description }} -// access: {{ bf.access }}, hardware: {{ bf.hardware }} -//--------------------- - {% if 'a' in bf.hardware %} - {% if 'o' in bf.hardware %} -assign {{ port_bf_waccess(reg, bf) }} = wready && {{ sig_csr_wen(reg) }}; - {% endif %} - {% if 'i' in bf.hardware %} -assign {{ port_bf_raccess(reg, bf) }} = rvalid && {{ sig_csr_ren(reg) }}; - {% endif %} - {% endif %} -reg {{ range_decl(bf.width - 1, bf.is_vector()) }} {{ sig_bf_ff(reg, bf) }}; - - {% if 'wo' in bf.access %} -assign {{ sig_csr_rdata(reg) }}{{ range(bf.msb, bf.lsb) }} = {{ zeros(bf.width) }}; - {% elif 'r' in bf.access and 'q' in bf.hardware %} -assign {{ sig_csr_rdata(reg) }}{{ range(bf.msb, bf.lsb) }} = {{ port_bf_in(reg, bf) }}; - {% else %} -assign {{ sig_csr_rdata(reg) }}{{ range(bf.msb, bf.lsb) }} = {{ sig_bf_ff(reg, bf) }}; - {% endif %} - - {% if 'w' in bf.access and 'q' in bf.hardware %} -assign {{ port_bf_out(reg, bf) }} = wdata{{ range(bf.msb, bf.lsb) }}; - {% elif 'o' in bf.hardware %} -assign {{ port_bf_out(reg, bf) }} = {{ sig_bf_ff(reg, bf) }}; - {% endif %} - {% if 'r' in bf.access and 'q' in bf.hardware %} -assign {{ port_bf_ren(reg, bf) }} = {{ sig_csr_ren(reg) }} & (~{{ sig_csr_ren_ff(reg) }}); - {% endif %} - {% if 'w' in bf.access and 'q' in bf.hardware %} -assign {{ port_bf_wen(reg, bf) }} = {{ sig_csr_wen(reg) }}; - {% endif %} - -{{ always_begin(sig=sig_bf_ff(reg, bf), width=bf.width, init=bf.reset) -}} {% if 'l' in bf.hardware %}if (!{{ port_bf_lock(reg, bf) }}){% endif %} begin - {% if 's' in bf.hardware %} - if ({{ port_bf_set(reg, bf) }}) begin - {{ sig_bf_ff(reg, bf) }} <= {{ ones(bf.width) }}; - end else - {%- endif %} {% if 'c' in bf.hardware -%} - if ({{ port_bf_clr(reg, bf) }}) begin - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - end else - {%- endif %} {% if bf.access == 'roc' %} - if ({{ sig_csr_ren(reg) }} && !{{ sig_csr_ren_ff(reg) }}) begin - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - end else - {%- endif %} {% if bf.access == 'rolh' %} - if ({{ sig_csr_ren(reg) }} && !{{ sig_csr_ren_ff(reg) }} && ({{ sig_bf_ff(reg, bf) }} != {{ zeros(bf.width) }})) begin - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - end else - {%- endif %} {% if bf.access == 'roll' -%} - if ({{ sig_csr_ren(reg) }} && !{{ sig_csr_ren_ff(reg) }} && ({{ sig_bf_ff(reg, bf) }} != {{ ones(bf.width) }})) begin - {{ sig_bf_ff(reg, bf) }} <= {{ ones(bf.width) }}; - end else - {%- endif %} {% if 'w' in bf.access -%} - if ({{ sig_csr_wen(reg) }}) begin - {% for num, val in bf.byte_strobes.items() %} - {% if 'w1c' in bf.access %} - if (wstrb[{{ num }}] && wdata{{ range(val['wdata_msb'], val['wdata_lsb']) }}) begin - {{ sig_bf_ff(reg, bf) }}{{ range(val['bf_msb'], val['bf_lsb'], bf.is_vector()) }} <= {{ zeros(val['bf_msb'] - val['bf_lsb'] + 1) }}; - {% elif 'w1s' in bf.access %} - if (wstrb[{{ num }}] && wdata{{ range(val['wdata_msb'], val['wdata_lsb']) }}) begin - {{ sig_bf_ff(reg, bf) }}{{ range(val['bf_msb'], val['bf_lsb'], bf.is_vector()) }} <= {{ ones(val['bf_msb'] - val['bf_lsb'] + 1) }}; - {% else %} - if (wstrb[{{ num }}]) begin - {{ sig_bf_ff(reg, bf) }}{{ range(val['bf_msb'], val['bf_lsb'], bf.is_vector()) }} <= wdata{{ range(val['wdata_msb'], val['wdata_lsb']) }}; - {% endif %} - end - {% endfor %} - end else - {%- endif %} {% if 'i' in bf.hardware -%} {%- if 'e' in bf.hardware and 'll' in bf.access -%} - if ({{ port_bf_en(reg, bf) }} && ({{ port_bf_in(reg, bf) }} == {{ zeros(bf.width) }})) begin - {% elif 'e' in bf.hardware and 'lh' in bf.access -%} - if ({{ port_bf_en(reg, bf) }} && ({{ port_bf_in(reg, bf)}} == {{ ones(bf.width) }})) begin - {% elif bf.access == 'roll' -%} - if ({{ port_bf_in(reg, bf) }} == {{ zeros(bf.width) }}) begin - {% elif bf.access == 'rolh' -%} - if ({{ port_bf_in(reg, bf) }} == {{ ones(bf.width) }}) begin - {% elif 'e' in bf.hardware -%} - if ({{ port_bf_en(reg, bf) }}) begin - {% else -%} {# no condition #} - begin - {%- endif %} - {{ sig_bf_ff(reg, bf) }} <= {{ port_bf_in(reg, bf) }}; - {% elif 'i' in bf.hardware -%} - begin - {{ sig_bf_ff(reg, bf) }} <= {{ port_bf_in(reg, bf) }}; - {% elif 'sc' in bf.access -%} - begin - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - {% else -%} - begin - {{ sig_bf_ff(reg, bf) }} <= {{ sig_bf_ff(reg, bf) }}; - {% endif %} - end - end -end - - {% if 'r' in bf.access and 'q' in bf.hardware %} -reg {{ sig_bf_rvalid_ff(reg, bf) }}; -{{ always_begin(sig=sig_bf_rvalid_ff(reg, bf) -)}} begin - {{ sig_bf_rvalid_ff(reg, bf) }} <= {{ port_bf_rvalid(reg, bf) }}; - end -end - {%endif%} - - {% endfor %} -{% endfor %} -//------------------------------------------------------------------------------ -// Write ready -//------------------------------------------------------------------------------ -{% set tmp.fifo_cnt = 0 %} -{% for reg in rmap %} - {% for bf in reg %} - {% if 'q' in bf.hardware and 'w' in bf.access %} - {% if tmp.fifo_cnt == 0 %} -reg wready_drv; - -always @(*) begin - if ({{ sig_csr_wen(reg) }}) - wready_drv = {{ port_bf_wready(reg, bf) }}; - {% else %} - else if ({{ sig_csr_wen(reg) }}) - wready_drv = {{ port_bf_wready(reg, bf) }}; - {% endif %} - {% set tmp.fifo_cnt = tmp.fifo_cnt + 1 %} - {% endif %} - {% endfor %} -{% endfor %} -{% if tmp.fifo_cnt %} - else - wready_drv = 1'b1; -end - -assign wready = wready_drv; -{% else %} -assign wready = 1'b1; -{% endif %} - -//------------------------------------------------------------------------------ -// Read address decoder -//------------------------------------------------------------------------------ -reg {{ range_decl(config['data_width'] - 1) }} rdata_ff; -{{ always_begin(sig='rdata_ff', width=config['data_width'], init=read_filler -)}} if (ren) begin - case (raddr) -{% for reg in rmap %} - {{ literal(reg.address, config['address_width']) }}: rdata_ff <= {{ sig_csr_rdata(reg) }}; -{% endfor %} - default: rdata_ff <= {{ literal(read_filler, config['data_width']) }}; - endcase - end else begin - rdata_ff <= {{ literal(read_filler, config['data_width']) }}; - end -end -assign rdata = rdata_ff; - -//------------------------------------------------------------------------------ -// Read data valid -//------------------------------------------------------------------------------ -reg rvalid_ff; -{{ always_begin(sig='rvalid_ff' -)}} if (ren && rvalid) begin - rvalid_ff <= 1'b0; - end else if (ren) begin - rvalid_ff <= 1'b1; - end -end - -{% set tmp.fifo_cnt = 0 %} -{% for reg in rmap %} - {% for bf in reg %} - {% if 'q' in bf.hardware and 'r' in bf.access %} - {% if tmp.fifo_cnt == 0 %} -reg rvalid_drv; -always @(*) begin - if ({{ sig_csr_ren_ff(reg) }}) - rvalid_drv = {{ sig_bf_rvalid_ff(reg, bf) }}; - {% else %} - else if ({{ sig_csr_ren_ff(reg) }}) - rvalid_drv = {{ sig_bf_rvalid_ff(reg, bf) }}; - {% endif %} - {% set tmp.fifo_cnt = tmp.fifo_cnt + 1 %} - {% endif %} - {% endfor %} -{% endfor %} -{% if tmp.fifo_cnt %} - else - rvalid_drv = rvalid_ff; -end - -assign rvalid = rvalid_drv; -{% else %} -assign rvalid = rvalid_ff; -{% endif %} - -endmodule diff --git a/corsair/templates/regmap_vhdl.j2 b/corsair/templates/regmap_vhdl.j2 deleted file mode 100644 index 642c4dd..0000000 --- a/corsair/templates/regmap_vhdl.j2 +++ /dev/null @@ -1,583 +0,0 @@ -{#- Many thanks to github.com/smirnovich for providing the VHDL code for this template #} - -{# MACRO #} -{#- vector range for select operations #} -{% macro range(msb, lsb, is_vector=true) %} - {% if is_vector %} - {% if msb == lsb %} -({{ msb }}) - {%- else %} -({{ msb }} downto {{ lsb }}) - {%- endif %} - {%- endif %} -{%- endmacro %} - -{#- vector range for declarations #} -{% macro range_decl(msb, is_vector=true) %} - {% if is_vector %} -std_logic_vector({{ msb }} downto 0) - {%- else %} -std_logic - {%- endif %} -{%- endmacro %} - -{#- literal #} -{% macro literal(val, width=1, width_is_param=0) %} - {% if width == 1 %} -'{{ val }}' - {%- elif width_is_param == 1 %} -std_logic_vector(to_unsigned({{ val }}, {{ width }})) - {%- else %} -"{{ ('{:0%db}' % width).format(val) }}" - {%- endif %} -{%- endmacro %} - -{% macro hex_literal(val, width) %} -x"{{ ('{:0%dx}' % (width//4)).format(val) }}" -{%- endmacro %} - -{#- comment with literal in hex #} -{% macro literal_comment(val) %} --- {{ "0x%x" % val }} -{%- endmacro %} - -{#- special literal for all zeros #} -{% macro zeros(width=1) %} - {% if width == 1 %} -'0' - {%- else %} -(others => '0') - {%- endif %} -{%- endmacro %} - -{#- special literal for all ones #} -{% macro ones(width=1) %} - {% if width == 1 %} -'1' - {%- else %} -(others => '1') - {%- endif %} -{%- endmacro %} - -{% macro always_begin(sig='test', width=1, init=0) %} -{%- endmacro %} - -{#- 'process' header with reset logic #} -{% macro process_begin(sig='test', width=1, init=0, width_is_param=0) %} - {% set rst_type = config['register_reset']%} - {% if rst_type == 'sync_pos' %} -process (clk) begin -if rising_edge(clk) then -if (rst = '1') then - {{ sig }} <= {{ literal(init, width, width_is_param) }}; {{ literal_comment(init) }} -else - {%- elif rst_type == 'sync_neg' %} -process (clk) begin -if rising_edge(clk) then -if (rst = '0') then - {{ sig }} <= {{ literal(init, width, width_is_param) }}; {{ literal_comment(init) }} -else - {%- elif rst_type == 'async_pos' %} -process (clk, rst) begin -if (rst = '1') then - {{ sig }} <= {{ literal(init, width, width_is_param) }}; {{ literal_comment(init) }} -elsif rising_edge(clk) then - {%- elif rst_type == 'async_neg' %} -process (clk, rst) begin -if (rst = '0') then - {{ sig }} <= {{ literal(init, width, width_is_param) }}; {{ literal_comment(init) }} -elsif rising_edge(clk) then - {%- endif %} -{%- endmacro %} - -{#- 'process' footer #} -{% macro process_end() %} - {% if 'async' in config['register_reset'] %} -end if; -end process; - {% else %} -end if; -end if; -end process; - {% endif %} -{%- endmacro %} - -{#- signal: csr for rdata bus #} -{% macro sig_csr_rdata(reg) %} -csr_{{ reg.name.lower() }}_rdata -{%- endmacro %} - -{#- port: bitfield output #} -{% macro port_bf_out(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_out -{%- endmacro %} - -{#- port: bitfield input #} -{% macro port_bf_in(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_in -{%- endmacro %} - -{#- port: bitfield input enable #} -{% macro port_bf_en(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_en -{%- endmacro %} - -{#- port: bitfield clear enable #} -{% macro port_bf_clr(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_clr -{%- endmacro %} - -{#- port: bitfield set enable #} -{% macro port_bf_set(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_set -{%- endmacro %} - -{#- port: bitfield read enable #} -{% macro port_bf_ren(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_ren -{%- endmacro %} - -{#- port: bitfield read valid #} -{% macro port_bf_rvalid(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_rvalid -{%- endmacro %} - -{#- port: bitfield write enable #} -{% macro port_bf_wen(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_wen -{%- endmacro %} - -{#- port: bitfield write ready #} -{% macro port_bf_wready(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_wready -{%- endmacro %} - -{#- signal: bitfield registered read valid #} -{% macro sig_bf_rvalid_ff(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_rvalid_ff -{%- endmacro %} - -{#- signal: bitfield flip-flops #} -{% macro sig_bf_ff(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_ff -{%- endmacro %} - -{#- port: bitfield read access strobe #} -{% macro port_bf_raccess(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_raccess -{%- endmacro %} - -{#- port: bitfield write access strobe #} -{% macro port_bf_waccess(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_waccess -{%- endmacro %} - -{#- port: bitfield lock signal #} -{% macro port_bf_lock(reg, bf) %} -csr_{{ reg.name.lower() }}_{{ bf.name.lower() }}_lock -{%- endmacro %} - -{#- signal: register read enable #} -{% macro sig_csr_ren(reg) %} -csr_{{ reg.name.lower() }}_ren -{%- endmacro %} - -{#- signal: register read enable registered #} -{% macro sig_csr_ren_ff(reg) %} -csr_{{ reg.name.lower() }}_ren_ff -{%- endmacro %} - -{#- signal: register write enable #} -{% macro sig_csr_wen(reg) %} -csr_{{ reg.name.lower() }}_wen -{%- endmacro %} - -{#- conditional #} -{% macro cond(val, branch_n, last=False) %} - {% if branch_n == 0 and not last %} -if ({{ val }}) then - {%- elif branch_n and not last %} -elsif ({{ val }}) then - {%- elif branch_n == 0 and last %} - {%- else %} -else - {%- endif %} -{%- endmacro %} - -{#- TEMPLATE NAMESPACE #} -{% set tmp = namespace() %} -{% from "amm2lb_vhdl.j2" import amm_core with context %} -{% from "amm2lb_vhdl.j2" import amm_ports with context %} -{% from "amm2lb_vhdl.j2" import amm_signals with context %} -{% from "apb2lb_vhdl.j2" import apb_core with context %} -{% from "apb2lb_vhdl.j2" import apb_ports with context %} -{% from "apb2lb_vhdl.j2" import apb_signals with context %} -{% from "axil2lb_vhdl.j2" import axil_core with context %} -{% from "axil2lb_vhdl.j2" import axil_ports with context %} -{% from "axil2lb_vhdl.j2" import axil_signals with context %} - -{#- TEMPLATE #} --- Created with Corsair v{{ corsair_ver }} -library ieee; -use ieee.std_logic_1164.all; -use ieee.numeric_std.all; - -entity {{ module_name }} is -generic( - ADDR_W : integer := {{ config['address_width'] }}; - DATA_W : integer := {{ config['data_width'] }}; - STRB_W : integer := {{ config['data_width'] // 8 }} -); -port( - clk : in std_logic; - rst : in std_logic; -{% for reg in rmap %} - {% for bf in reg %} - -- {{ reg.name }}.{{ bf.name }} - {% if 'a' in bf.hardware %} - {% if 'i' in bf.hardware %} - {{ port_bf_raccess(reg, bf) }} : out {{range_decl(0, False)}}; - {% endif %} - {% if 'o' in bf.hardware %} - {{ port_bf_waccess(reg, bf) }} : out {{range_decl(0, False)}}; - {% endif %} - {% endif %} - {% if 'l' in bf.hardware %} - {{ port_bf_lock(reg, bf) }} : in {{range_decl(0, False)}}; - {% endif %} - {% if 'e' in bf.hardware %} - {{ port_bf_en(reg, bf) }} : in {{range_decl(0, False)}}; - {% endif %} - {% if 'c' in bf.hardware %} - {{ port_bf_clr(reg, bf) }} : in {{range_decl(0, False)}}; - {% endif %} - {% if 's' in bf.hardware %} - {{ port_bf_set(reg, bf) }} : in {{range_decl(0, False)}}; - {% endif %} - {% if 'q' in bf.hardware and 'r' in bf.access %} - {{ port_bf_rvalid(reg, bf) }} : in {{range_decl(0, False)}}; - {{ port_bf_ren(reg, bf) }} : out {{range_decl(0, False)}}; - {{ port_bf_in(reg, bf) }} : in {{ range_decl(bf.width - 1, bf.is_vector()) }}; - {% endif %} - {% if 'i' in bf.hardware %} - {{ port_bf_in(reg, bf) }} : in {{ range_decl(bf.width - 1, bf.is_vector()) }}; - {% endif %} - {% if 'o' in bf.hardware %} - {{ port_bf_out(reg, bf) }} : out {{ range_decl(bf.width - 1, bf.is_vector()) }}; - {% endif %} - {% if 'q' in bf.hardware and 'w' in bf.access %} - {{ port_bf_out(reg, bf) }} : out {{ range_decl(bf.width - 1, bf.is_vector()) }}; - {{ port_bf_wready(reg, bf) }} : in {{range_decl(0, False)}}; - {{ port_bf_wen(reg, bf) }} : out {{range_decl(0, False)}}; - {% endif %} - {% endfor %} - -{% endfor %} -{% if interface == 'apb' %} -{{ apb_ports() }} -{% elif interface == 'axil' %} -{{ axil_ports() }} -{% elif interface == 'amm' %} -{{ amm_ports() }} -{% else %} - -- Local Bus - waddr : in std_logic_vector(ADDR_W-1 downto 0); - wdata : in std_logic_vector(DATA_W-1 downto 0); - wen : in std_logic; - wstrb : in std_logic_vector(STRB_W-1 downto 0); - wready : out std_logic; - raddr : in std_logic_vector(ADDR_W-1 downto 0); - ren : in std_logic; - rdata : out std_logic_vector(DATA_W-1 downto 0); - rvalid : out std_logic -{% endif %} -); -end entity; - -architecture rtl of {{ module_name }} is - -{% if interface == 'apb' %} -{{ apb_signals(regmap_embed=True) }} -{% elif interface == 'axil' %} -{{ axil_signals(regmap_embed=True) }} -{% elif interface == 'amm' %} -{{ amm_signals(regmap_embed=True) }} -{% endif %} -{% for reg in rmap %} -signal {{ sig_csr_rdata(reg) }} : {{ range_decl(config['data_width'] - 1) }}; - {% if 'w' in reg.access %} -signal {{ sig_csr_wen(reg) }} : {{ range_decl(0, False) }}; - {% endif %} - {% if 'r' in reg.access %} -signal {{ sig_csr_ren(reg) }} : {{ range_decl(0, False) }}; -signal {{ sig_csr_ren_ff(reg) }} : {{ range_decl(0, False) }}; - {% endif %} - {% for bf in reg %} -signal {{ sig_bf_ff(reg, bf) }} : {{ range_decl(bf.width - 1, bf.is_vector()) }}; - {% if 'r' in bf.access and 'q' in bf.hardware %} -signal {{ sig_bf_rvalid_ff(reg, bf) }} : {{ range_decl(0, False) }}; - {% endif %} - {% endfor %} - -{% endfor %} -{% set tmp.rd_fifo_cnt = 0 %} -{% set tmp.wr_fifo_cnt = 0 %} -{% for reg in rmap %} - {% for bf in reg %} - {% if 'q' in bf.hardware and 'w' in bf.access %} - {% if tmp.wr_fifo_cnt == 0 %} -signal wready_drv : {{ range_decl(0, False) }}; - {% endif %} - {% set tmp.wr_fifo_cnt = tmp.wr_fifo_cnt + 1 %} - {% endif %} - {% if 'q' in bf.hardware and 'r' in bf.access %} - {% if tmp.rd_fifo_cnt == 0 %} -signal rvalid_drv : {{ range_decl(0, False) }}; - {% endif %} - {% set tmp.rd_fifo_cnt = tmp.rd_fifo_cnt + 1 %} - {% endif %} - {% endfor %} -{% endfor %} -signal rdata_ff : {{ range_decl(config['data_width'] - 1) }}; -signal rvalid_ff : {{ range_decl(0, False) }}; -begin - -{% if interface == 'apb' %} -{{ apb_core() }} -{% elif interface == 'axil' %} -{{ axil_core() }} -{% elif interface == 'amm' %} -{{ amm_core() }} -{% endif %} -{% for reg in rmap %} --------------------------------------------------------------------------------- --- CSR: --- [{{ '0x%x' % reg.address }}] - {{ reg.name }} - {{ reg.description }} --------------------------------------------------------------------------------- -{# fill unused bits with zeros #} - {% set tmp.last_bit = 0 %} - {% for bf in reg %} - {% if bf.lsb > tmp.last_bit %} -{{ sig_csr_rdata(reg) }}{{ range(bf.lsb - 1, tmp.last_bit) }} <= {{ zeros(bf.lsb - tmp.last_bit) }}; - {% endif %} - {% set tmp.last_bit = bf.msb + 1 %} - {% endfor %} - {% if config['data_width'] > tmp.last_bit %} -{{ sig_csr_rdata(reg) }}{{ range(config['data_width'] - 1, tmp.last_bit) }} <= {{ zeros(config['data_width'] - tmp.last_bit) }}; - {% endif %} - - {% if 'w' in reg.access %} -{{ sig_csr_wen(reg) }} <= wen when (waddr = {{ literal(reg.address, "ADDR_W", width_is_param=1) }}) else '0'; {{ literal_comment(reg.address) }} - {% endif %} - - {% if 'r' in reg.access %} -{{ sig_csr_ren(reg) }} <= ren when (raddr = {{ literal(reg.address, "ADDR_W", width_is_param=1) }}) else '0'; {{ literal_comment(reg.address) }} -{{ process_begin(sig=sig_csr_ren_ff(reg))}} - {{ sig_csr_ren_ff(reg) }} <= {{ sig_csr_ren(reg) }}; -{{ process_end() }} - {% endif %} - {% for bf in reg %} ------------------------ --- Bit field: --- {{ reg.name }}{{ range(bf.msb, bf.lsb) }} - {{ bf.name }} - {{ bf.description }} --- access: {{ bf.access }}, hardware: {{ bf.hardware }} ------------------------ - {% if 'a' in bf.hardware %} - {% if 'o' in bf.hardware %} -{{ port_bf_waccess(reg, bf) }} <= wready and {{ sig_csr_wen(reg) }}; - {% endif %} - {% if 'i' in bf.hardware %} -{{ port_bf_raccess(reg, bf) }} <= rvalid and {{ sig_csr_ren(reg) }}; - {% endif %} - {% endif %} - - {% if 'wo' in bf.access %} -{{ sig_csr_rdata(reg) }}{{ range(bf.msb, bf.lsb) }} <= {{ zeros(bf.width) }}; - {% elif 'r' in bf.access and 'q' in bf.hardware %} -{{ sig_csr_rdata(reg) }}{{ range(bf.msb, bf.lsb) }} <= {{ port_bf_in(reg, bf) }}; - {% else %} -{{ sig_csr_rdata(reg) }}{{ range(bf.msb, bf.lsb) }} <= {{ sig_bf_ff(reg, bf) }}; - {% endif %} - - {% if 'w' in bf.access and 'q' in bf.hardware %} -{{ port_bf_out(reg, bf) }} <= wdata{{ range(bf.msb, bf.lsb) }}; - {% elif 'o' in bf.hardware %} -{{ port_bf_out(reg, bf) }} <= {{ sig_bf_ff(reg, bf) }}; - {% endif %} - {% if 'r' in bf.access and 'q' in bf.hardware %} -{{ port_bf_ren(reg, bf) }} <= {{ sig_csr_ren(reg) }} and (not {{ sig_csr_ren_ff(reg) }}); - {% endif %} - {% if 'w' in bf.access and 'q' in bf.hardware %} -{{ port_bf_wen(reg, bf) }} <= {{ sig_csr_wen(reg) }}; - {% endif %} - -{{ process_begin(sig=sig_bf_ff(reg, bf), width=bf.width, init=bf.reset)}} - {% if 'l' in bf.hardware %} - if ({{ "%s = '0'" % port_bf_lock(reg, bf) }}) then - {% endif %} - {% set tmp.cond_cnt = 0 %} - {% if 's' in bf.hardware %} - if ({{ "%s = '1'" % port_bf_set(reg, bf) }}) then - {{ sig_bf_ff(reg, bf) }} <= {{ ones(bf.width) }}; - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {%- endif %} - {% if 'c' in bf.hardware %} - {{ cond("%s = '1'" % port_bf_clr(reg, bf), tmp.cond_cnt) }} - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {%- endif %} - {% if bf.access == 'roc' %} - {{ cond("{} = '1' and {} = '0'".format(sig_csr_ren(reg), sig_csr_ren_ff(reg)), tmp.cond_cnt) }} - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {%- endif %} - {% if bf.access == 'rolh' %} - {{ cond("{} = '1' and {} = '0' and {} = {}".format(sig_csr_ren(reg), sig_csr_ren_ff(reg), sig_bf_ff(reg, bf), ones(bf.width)), tmp.cond_cnt) }} - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {%- endif %} - {% if bf.access == 'roll' %} - {{ cond("{} = '1' and {} = '0' and {} = {}".format(sig_csr_ren(reg), sig_csr_ren_ff(reg), sig_bf_ff(reg, bf), zeros(bf.width)), tmp.cond_cnt) }} - {{ sig_bf_ff(reg, bf) }} <= {{ ones(bf.width) }}; - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {%- endif %} - {% if 'w' in bf.access %} - {{ cond("%s = '1'" % sig_csr_wen(reg), tmp.cond_cnt) }} - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {% for num, val in bf.byte_strobes.items() %} - {% if 'w1c' in bf.access %} - if ((wstrb({{ num }}) = '1') and (wdata({{ val['wdata_lsb'] }}) = '1')) then - {{ sig_bf_ff(reg, bf) }}{{ range(val['bf_msb'], val['bf_lsb'], bf.is_vector()) }} <= {{ zeros(val['bf_msb'] - val['bf_lsb'] + 1) }}; - {% elif 'w1s' in bf.access %} - if ((wstrb({{ num }}) = '1') and (wdata({{ val['wdata_lsb'] }}) = '1')) then - {{ sig_bf_ff(reg, bf) }}{{ range(val['bf_msb'], val['bf_lsb'], bf.is_vector()) }} <= {{ ones(val['bf_msb'] - val['bf_lsb'] + 1) }}; - {% else %} - if (wstrb({{ num }}) = '1') then - {{ sig_bf_ff(reg, bf) }}{{ range(val['bf_msb'], val['bf_lsb'], bf.is_vector()) }} <= wdata{{ range(val['wdata_msb'], val['wdata_lsb']) }}; - {% endif %} - end if; - {% endfor %} - {%- endif %} - {% if 'i' in bf.hardware %} {%- if 'e' in bf.hardware and 'll' in bf.access %} - {{ cond("(%s = '1') and (%s = %s)" % (port_bf_en(reg, bf), port_bf_in(reg, bf), zeros(bf.width)), tmp.cond_cnt)}} - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {% elif 'e' in bf.hardware and 'lh' in bf.access %} - {{ cond("(%s = '1') and (%s = %s)" % (port_bf_en(reg, bf), port_bf_in(reg, bf), ones(bf.width)), tmp.cond_cnt)}} - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {% elif 'll' in bf.access %} - {{ cond("%s = %s" % (port_bf_in(reg, bf), zeros(bf.width)), tmp.cond_cnt)}} - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {% elif 'lh' in bf.access %} - {{ cond("%s = %s" % (port_bf_in(reg, bf), ones(bf.width)), tmp.cond_cnt)}} - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {% elif 'e' in bf.hardware %} - {{ cond("%s = '1'" % port_bf_en(reg, bf), tmp.cond_cnt)}} - {% set tmp.cond_cnt = tmp.cond_cnt + 1 %} - {% endif %} - {{ sig_bf_ff(reg, bf) }} <= {{ port_bf_in(reg, bf) }}; - {% elif 'i' in bf.hardware %} - {{ cond("", tmp.cond_cnt, last=True) }} - {{ sig_bf_ff(reg, bf) }} <= {{ port_bf_in(reg, bf) }}; - {% elif 'sc' in bf.access %} - {{ cond("", tmp.cond_cnt, last=True) }} - {{ sig_bf_ff(reg, bf) }} <= {{ zeros(bf.width) }}; - {% else %} - {{ cond("", tmp.cond_cnt, last=True) }} - {{ sig_bf_ff(reg, bf) }} <= {{ sig_bf_ff(reg, bf) }}; - {% endif %} - {% if tmp.cond_cnt != 0 %} - end if; - {% endif %} - {% if 'l' in bf.hardware %} - end if; - {% endif %} -{{ process_end() }} - - {% if 'r' in bf.access and 'q' in bf.hardware %} -{{ process_begin(sig=sig_bf_rvalid_ff(reg, bf)) }} - {{ sig_bf_rvalid_ff(reg, bf) }} <= {{ port_bf_rvalid(reg, bf) }}; -{{ process_end() }} - {%endif%} - - {% endfor %} -{% endfor %} --------------------------------------------------------------------------------- --- Write ready --------------------------------------------------------------------------------- -{% set tmp.fifo_cnt = 0 %} -{% for reg in rmap %} - {% for bf in reg %} - {% if 'q' in bf.hardware and 'w' in bf.access %} - {% if tmp.fifo_cnt == 0 %} -wready_drv <= - {% set tmp.fifo_cnt = tmp.fifo_cnt + 1 %} - {% endif %} - {{ port_bf_wready(reg, bf) }} when ({{ sig_csr_wen(reg) }} = '1') else - {% endif %} - {% endfor %} -{% endfor %} -{% if tmp.fifo_cnt %} - '1'; - -wready <= wready_drv; -{% else %} -wready <= '1'; -{% endif %} - --------------------------------------------------------------------------------- --- Read address decoder --------------------------------------------------------------------------------- -{{ process_begin(sig='rdata_ff', width=config['data_width'], init=read_filler)}} - if (ren = '1') then -{% set loop_ns = namespace(first_reg = True) %} -{% for reg in rmap %} - {% if loop_ns.first_reg %} - if raddr = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} - rdata_ff <= {{ sig_csr_rdata(reg) }}; - {% else %} - elsif raddr = {{ literal(reg.address, "ADDR_W", width_is_param=1)}} then {{ literal_comment(reg.address) }} - rdata_ff <= {{ sig_csr_rdata(reg) }}; - {% endif %} - {% set loop_ns.first_reg = False %} -{% endfor %} - else - rdata_ff <= {{ literal(read_filler, config['data_width']) }}; {{ literal_comment(read_filler) }} - end if; - else - rdata_ff <= {{ literal(read_filler, config['data_width']) }}; {{ literal_comment(read_filler) }} - end if; -{{ process_end() }} -rdata <= rdata_ff; - --------------------------------------------------------------------------------- --- Read data valid --------------------------------------------------------------------------------- -{{ process_begin(sig='rvalid_ff')}} - if ((ren = '1') and (rvalid = '1')) then - rvalid_ff <= '0'; - elsif (ren = '1') then - rvalid_ff <= '1'; - end if; -{{ process_end() }} - -{% set tmp.fifo_cnt = 0 %} -{% for reg in rmap %} - {% for bf in reg %} - {% if 'q' in bf.hardware and 'r' in bf.access %} - {% if tmp.fifo_cnt == 0 %} -rvalid_drv <= - {% set tmp.fifo_cnt = tmp.fifo_cnt + 1 %} - {% endif %} - {{ sig_bf_rvalid_ff(reg, bf) }} when ({{ sig_csr_ren_ff(reg) }} = '1') else - {% endif %} - {% endfor %} -{% endfor %} -{% if tmp.fifo_cnt %} - rvalid_ff; - -rvalid <= rvalid_drv; -{% else %} -rvalid <= rvalid_ff; -{% endif %} - -end architecture; diff --git a/corsair/templates/sv_package.j2 b/corsair/templates/sv_package.j2 deleted file mode 100755 index d584e40..0000000 --- a/corsair/templates/sv_package.j2 +++ /dev/null @@ -1,44 +0,0 @@ -{# MACRO #} -{% macro module_prefix() %} - {%- if prefix %} -{{ prefix }}_ - {%- else %} -{{ file_name }}_ - {%- endif %} -{%- endmacro %} - -{#- TEMPLATE NAMESPACE #} -{% set tmp = namespace() %} - -{#- TEMPLATE #} -// Created with Corsair v{{ corsair_ver }} -package {{ file_name }}; - -parameter {{ module_prefix()|upper }}BASE_ADDR = {{ config['base_address'] }}; -parameter {{ module_prefix()|upper }}DATA_WIDTH = {{ config['data_width'] }}; -parameter {{ module_prefix()|upper }}ADDR_WIDTH = {{ config['address_width'] }}; - -{% for reg in rmap %} -// {{ reg.name }} -parameter {{ module_prefix()|upper }}{{ reg.name.upper() }}_ADDR = {{ "%d'h%x" % (config['address_width'], reg.address) }}; -parameter {{ module_prefix()|upper }}{{ reg.name.upper() }}_RESET = {{ "%d'h%x" % (config['data_width'], reg.reset) }}; - - {% for bf in reg %} -// {{ reg.name }}.{{ bf.name }} -parameter {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_WIDTH = {{ bf.width }}; -parameter {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_LSB = {{ bf.lsb }}; -parameter {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_MASK = {{ "%d'h%x" % (config['data_width'], bf.mask) }}; -parameter {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_RESET = {{ "%d'h%x" % (bf.width, bf.reset) }}; - {% if bf.enums %} -typedef enum { - {% for i in range(bf|length - 1) %} - {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_{{ bf[i].name.upper() }} = {{ "%d'h%x" % (bf.width, bf[i].value) }}, //{{ bf[i].description }} - {% endfor %} - {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_{{ bf[-1].name.upper() }} = {{ "%d'h%x" % (bf.width, bf[-1].value) }} //{{ bf[-1].description }} -} {{ prefix.lower() }}{{ reg.name.lower() }}_{{ bf.name.lower() }}_t; - {% endif %} - - {% endfor %} - -{% endfor %} -endpackage \ No newline at end of file diff --git a/corsair/templates/verilog_header.j2 b/corsair/templates/verilog_header.j2 deleted file mode 100755 index b27f40f..0000000 --- a/corsair/templates/verilog_header.j2 +++ /dev/null @@ -1,41 +0,0 @@ -{# MACRO #} -{% macro module_prefix() %} - {%- if prefix %} -{{ prefix }}_ - {%- else %} -{{ file_name }}_ - {%- endif %} -{%- endmacro %} - -{#- TEMPLATE NAMESPACE #} -{% set tmp = namespace() %} - -{#- TEMPLATE #} -// Created with Corsair v{{ corsair_ver }} - -`ifndef __{{ file_name.upper() }}_VH -`define __{{ file_name.upper() }}_VH - -`define {{ module_prefix()|upper }}BASE_ADDR {{ config['base_address'] }} -`define {{ module_prefix()|upper }}DATA_WIDTH {{ config['data_width'] }} -`define {{ module_prefix()|upper }}ADDR_WIDTH {{ config['address_width'] }} - -{% for reg in rmap %} -// {{ reg.name }} - {{ reg.description }} -`define {{ module_prefix()|upper }}{{ reg.name.upper() }}_ADDR {{ "%d'h%x" % (config['address_width'], reg.address) }} -`define {{ module_prefix()|upper }}{{ reg.name.upper() }}_RESET {{ "%d'h%x" % (config['data_width'], reg.reset) }} - - {% for bf in reg %} -// {{ reg.name }}.{{ bf.name }} - {{ bf.description }} -`define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_WIDTH {{ bf.width }} -`define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_LSB {{ bf.lsb }} -`define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_MASK {{ "%d'h%x" % (config['data_width'], reg.address) }} -`define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_RESET {{ "%d'h%x" % (bf.width, bf.reset) }} - {% for enum in bf %} -`define {{ module_prefix()|upper }}{{ reg.name.upper() }}_{{ bf.name.upper() }}_{{ enum.name.upper() }} {{ "%d'h%x" % (bf.width, enum.value) }} //{{ enum.description }} - {% endfor %} - - {% endfor %} - -{% endfor %} -`endif // __{{ file_name.upper() }}_VH \ No newline at end of file diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..fef32a8 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +"""Tests for Corsair.""" diff --git a/tests/hdl/.gitignore b/tests/hdl/.gitignore deleted file mode 100755 index b8f99f5..0000000 --- a/tests/hdl/.gitignore +++ /dev/null @@ -1 +0,0 @@ -work diff --git a/tests/hdl/beh/amm.sv b/tests/hdl/beh/amm.sv deleted file mode 100755 index c76230a..0000000 --- a/tests/hdl/beh/amm.sv +++ /dev/null @@ -1,55 +0,0 @@ -interface amm #( - parameter ADDR_W = 16, - parameter DATA_W = 32, - parameter STRB_W = DATA_W/8 -) ( - // synthesis translate_off - input clk, - input reset - // synthesis translate_on -); - - logic [ADDR_W-1:0] address ; - logic read_s = 0 ; - logic [DATA_W-1:0] readdata ; - logic readdatavalid; - logic [STRB_W-1:0] byteenable ; - logic write_s ; - logic [DATA_W-1:0] writedata ; - logic waitrequest ; - - task write( - input logic [ADDR_W-1:0] addr, - input logic [DATA_W-1:0] data, - input logic [STRB_W-1:0] strb = {STRB_W{1'b1}} - ); - @(posedge clk); - address = addr; - writedata = data; - byteenable = strb; - write_s = 1; - wait(~waitrequest); - @(posedge clk); - write_s = 0; - address = 0; - writedata = 0; - byteenable = 0; - endtask : write - - - task read( - input logic [ADDR_W-1:0] addr, - output logic [DATA_W-1:0] data - ); - @(posedge clk); - address = addr; - read_s = 1; - wait(~waitrequest); - @(posedge clk); - read_s = 0; - wait(readdatavalid); - @(posedge clk); - data = readdata; - endtask : read - -endinterface \ No newline at end of file diff --git a/tests/hdl/beh/apb.sv b/tests/hdl/beh/apb.sv deleted file mode 100755 index f419da0..0000000 --- a/tests/hdl/beh/apb.sv +++ /dev/null @@ -1,65 +0,0 @@ -interface apb #( - parameter ADDR_W = 12, - parameter DATA_W = 32, - parameter STRB_W = DATA_W/8 -)( - input logic pclk, - input logic presetn -); - -logic psel = 1'b0; -logic [ADDR_W-1:0] paddr = '0; -logic penable = 1'b0; -logic pwrite = 1'b0; -logic [DATA_W-1:0] pwdata = '0; -logic [STRB_W-1:0] pstrb = '0; - -logic [DATA_W-1:0] prdata; -logic pready; -logic pslverr; - -task read ( - input logic [ADDR_W-1:0] addr, - output logic [DATA_W-1:0] data -); - @(posedge pclk); - paddr <= addr; - pwrite <= 1'b0; - psel <= 1'b1; - - @(posedge pclk); - penable <= 1'b1; - - do @(posedge pclk); - while (!pready); - penable <= 1'b0; - psel <= 1'b0; - - data = prdata; -endtask - -task write ( - input logic [ADDR_W-1:0] addr, - input logic [DATA_W-1:0] data, - input logic [STRB_W-1:0] strb = {STRB_W{1'b1}} -); - @(posedge pclk); - paddr <= addr; - pwdata <= data; - pwrite <= 1'b1; - pstrb <= strb; - psel <= 1'b1; - - @(posedge pclk); - penable <= 1'b1; - - do @(posedge pclk); - while (!pready); - pwdata <= '0; - penable <= 1'b0; - pwrite <= 1'b0; - pstrb <= '0; - psel <= 1'b0; -endtask - -endinterface \ No newline at end of file diff --git a/tests/hdl/beh/axilite.sv b/tests/hdl/beh/axilite.sv deleted file mode 100755 index b45e3bc..0000000 --- a/tests/hdl/beh/axilite.sv +++ /dev/null @@ -1,107 +0,0 @@ -interface axilite #( - parameter ADDR_W = 16, - parameter DATA_W = 32, - parameter STRB_W = DATA_W/8 -) ( - // synthesis translate_off - input logic clk - // synthesis translate_on -); - - logic [ADDR_W-1:0] awaddr; - logic [2:0] awprot; - logic awvalid; - logic awready; - - logic [DATA_W-1:0] wdata; - logic [STRB_W-1:0] wstrb; - logic wvalid; - logic wready; - - logic [1:0] bresp; - logic bvalid; - logic bready; - - logic [ADDR_W-1:0] araddr; - logic [2:0] arprot; - logic arvalid; - logic arready; - - logic [DATA_W-1:0] rdata; - logic [1:0] rresp; - logic rvalid; - logic rready; - - - modport out ( - input awready, wready, bresp, bvalid, arready, rdata, rresp, rvalid, - output awaddr, awprot, awvalid, wdata, wstrb, wvalid, bready, araddr, arprot, arvalid, rready - ); - - modport in ( - input awaddr, awprot, awvalid, wdata, wstrb, wvalid, bready, araddr, arprot, arvalid, rready, - output awready, wready, bresp, bvalid, arready, rdata, rresp, rvalid - ); - - - // synthesis translate_off - - task master_init; - awaddr <= 'b0; - awprot <= 'b0; - awvalid <= 'b0; - wdata <= 'b0; - wstrb <= 'b0; - wvalid <= 'b0; - bready <= 'b0; - araddr <= 'b0; - arprot <= 'b0; - arvalid <= 'b0; - rready <= 'b0; - endtask - - task write( - logic [ADDR_W-1:0] addr, - logic [DATA_W-1:0] data, - logic [STRB_W-1:0] strb = {STRB_W{1'b1}} - ); - @(posedge clk); - awvalid <= 1'b1; - awaddr <= addr; - wait(awready == 1'b1); - @(posedge clk); - awvalid <= 1'b0; - - wvalid <= 1'b1; - wdata <= data; - wstrb <= strb; - wait(wready == 1'b1); - @(posedge clk); - wvalid <= 1'b0; - - wait(bvalid == 1'b1); - @(posedge clk); - bready <= 1'b1; - @(posedge clk); - bready <= 1'b0; - endtask - - task read(logic [ADDR_W-1:0] addr, output logic [DATA_W-1:0] data); - - arvalid <= 1'b1; - araddr <= addr; - wait(arready == 1'b1); - @(posedge clk); - arvalid <= 1'b0; - - wait(rvalid == 1'b1); - @(posedge clk); - rready <= 1'b1; - data <= rdata; - @(posedge clk); - rready <= 1'b0; - endtask - - // synthesis translate_on - -endinterface //axilite \ No newline at end of file diff --git a/tests/hdl/sim.py b/tests/hdl/sim.py deleted file mode 100755 index c78cd0a..0000000 --- a/tests/hdl/sim.py +++ /dev/null @@ -1,262 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""HDL simulation utilities. - -All simulator executables must be visible in PATH. -""" - -import subprocess -import argparse -from pathlib import Path - - -def file_ext(filepath): - """Get file extension from filepath""" - return Path(filepath).suffix - - -def parent_dir(filepath): - """Get parent directory path from filepath""" - return Path(filepath).resolve().parent - - -def make_dir(name): - """Make directory with specified name""" - return Path(name).mkdir() - - -def path_join(*other): - """Add each of other argumetns to path in turn""" - return Path().joinpath(*other) - - -def remove_tree(dirpath): - """Remove an entire directory tree if it exists""" - p = Path(dirpath) - if p.exists() and p.is_dir(): - for child in p.glob('*'): - if child.is_file(): - child.unlink() - else: - remove_tree(child) - p.rmdir() - - -def get_define(name, defines): - """Return define value from defines list""" - try: - return next(d for d in defines if name in d).split('=')[-1] - except StopIteration: - return None - - -def write_memfile(path, data): - """Write data to memory file (can be loaded with $readmemh)""" - with Path(path).open(mode='w', encoding="utf-8") as memfile: - memfile.writelines(['%x\n' % d for d in data]) - - -class Simulator: - """Simulator wrapper""" - - def __init__(self, name='modelsim', gui=True, cwd='work', passed_marker='!@# TEST PASSED #@!'): - self.gui = gui - self.passed_marker = passed_marker - - self.cwd = Path(cwd).resolve() - if parent_dir(__file__) == self.cwd: - raise ValueError("Wrong working directory '%s'" % self.cwd) - - self.name = name - self._runners = {'modelsim': self._run_modelsim, - 'vivado': self._run_vivado} - if self.name not in self._runners.keys(): - raise ValueError("Unknown simulator tool '%s'" % self.name) - - self.worklib = 'worklib' - self.top = 'top' - self.sources = [] - self.defines = [] - self.incdirs = [] - - self.stdout = '' - self.retcode = 0 - - def setup(self): - """Prepare working directory""" - remove_tree(self.cwd) - make_dir(self.cwd) - - def run(self): - """Run selected simulator""" - # some preprocessing - self.sources = [str(Path(filepath).resolve()) for filepath in self.sources] - self.incdirs = [str(Path(dirpath).resolve()) for dirpath in self.incdirs] - self.defines += ['TOP_NAME=%s' % self.top, 'SIM'] - # run simulation - self._runners[self.name]() - - def get_define(self, name): - """Return define value from defines list""" - return get_define(name, self.defines) - - @property - def is_passed(self): - return self.passed_marker in self.stdout - - def _exec(self, prog, args): - """Execute external program. - - Args: - prog : string with program name - args : string with program arguments - """ - exec_str = prog + " " + args - print(exec_str) - child = subprocess.Popen(exec_str.split(), cwd=self.cwd, stdout=subprocess.PIPE) - self.stdout = child.communicate()[0].decode("utf-8") - print(self.stdout) - self.retcode = child.returncode - if self.retcode: - raise RuntimeError("Execution failed at '%s' with return code %d!" % (exec_str, self.retcode)) - - def _run_modelsim(self): - """Run Modelsim""" - print('Run Modelsim (cwd=%s)' % self.cwd) - print(' '.join([d for d in self.defines])) - # compile sources - defines = ' '.join(['+define+' + define for define in self.defines]) - incdirs = ' '.join(['+incdir+' + incdir for incdir in self.incdirs]) - scr_compile = [] - for src in self.sources: - ext = file_ext(src) - if ext in ['.v', '.sv']: - scr_compile += [{ - 'tool': 'vlog', - 'args': '-suppress 2902 %s %s -sv -timescale 1ns/1ps %s' % (defines, incdirs, src) - }] - elif ext in ['.vhd', '.vhdl']: - scr_compile += [{ - 'tool': 'vcom', - 'args': '-93 %s\n' % src - }] - self._exec('vlib', self.worklib) - self._exec('vmap', 'work %s' % self.worklib) - for src in scr_compile: - self._exec(src['tool'], src['args']) - # prepare simulation - if not self.gui: - run = 'run -all' - else: - run = '' - sumulate_tcl = """ -proc rr {{}} {{ - write format wave -window .main_pane.wave.interior.cs.body.pw.wf wave.do -{sources} - uplevel #0 source simulate.tcl -}} -proc q {{}} {{quit -force}} -eval vsim {worklib}.{top} -if [file exist wave.do] {{ - source wave.do -}} -{run} -""" - sources = '' - for src in scr_compile: - ''.join([" %s %s\n" % (src['tool'], src['args']) for src in scr_compile]) - with path_join(self.cwd, 'simulate.tcl').open(mode='w', encoding="utf-8") as f: - f.write(sumulate_tcl.format( - worklib=self.worklib, - top=self.top, - incdirs=incdirs, - sources=''.join([" %s %s\n" % (src['tool'], src['args']) for src in scr_compile]), - defines=defines, - run=run - )) - vsim_args = '-do simulate.tcl' - if not self.gui: - vsim_args += ' -c' - vsim_args += ' -onfinish exit' - else: - vsim_args += ' -onfinish stop' - self._exec('vsim', vsim_args) - - def _run_vivado(self): - """Run Vivado simulator""" - print('Run Vivado (cwd=%s)' % self.cwd) - print(' '.join([d for d in self.defines])) - # prepare and run elaboration - elab_args = "--debug all --incr --prj files.prj %s.%s " % (self.worklib, self.top) - elab_args += " --override_timeunit --override_timeprecision --timescale 1ns/1ps " - elab_args += ' '.join(['-d ' + define for define in self.defines]) + ' ' - elab_args += ' '.join(['-i ' + incdir for incdir in self.incdirs]) - sources = '' - for src in self.sources: - ext = file_ext(src) - if ext == '.sv': - sources += 'sv %s %s\n' % (self.worklib, src) - elif ext == '.v': - sources += 'verilog %s %s\n' % (self.worklib, src) - elif ext == '.vhd': - sources += 'vhdl %s %s\n' % (self.worklib, src) - with path_join(self.cwd, 'files.prj').open(mode='w', encoding="utf-8") as f: - f.write(sources) - self._exec('xelab', elab_args) - # prepare and run simulation - reinvoke_tcl = """ -proc rr {{}} {{ - exec xelab {elab_args} - save_wave_config work - close_sim - source xsim.dir/{worklib}.{top}/xsim_script.tcl -}} -""" - with path_join(self.cwd, 'reinvoke.tcl').open(mode='w', encoding="utf-8") as f: - f.write(reinvoke_tcl.format(elab_args=elab_args, worklib=self.worklib, top=self.top)) - work_wcfg = """ - - - - -""" - with path_join(self.cwd, 'work.wcfg').open(mode='w', encoding="utf-8") as f: - f.write(work_wcfg) - sim_args = "%s.%s" % (self.worklib, self.top) - if not self.gui: - sim_args += ' --R' - else: - sim_args += ' --gui --t reinvoke.tcl --view work.wcfg' - self._exec('xsim', sim_args) - - -class CliArgs: - """Parse command line parameters for simulation""" - - def __init__(self, default_test='test', default_simtool='modelsim', default_gui=True, default_defines=[]): - self.args_parser = argparse.ArgumentParser() - self.args_parser.add_argument('-t', - default=default_test, - metavar='', - dest='test', - help="test ; default is '%s'" % default_test) - self.args_parser.add_argument('-s', - default=default_simtool, - metavar='', - dest='simtool', - help="simulation tool ; default is '%s'" % default_simtool) - self.args_parser.add_argument('-b', - default=default_gui, - dest='gui', - action='store_false', - help='enable batch mode (no GUI)') - self.args_parser.add_argument('-d', - default=default_defines, - metavar='', - dest='defines', - nargs='+', - help="define ; option can be used multiple times") - - def parse(self): - return self.args_parser.parse_args() diff --git a/tests/hdl/test_lb_bridge.py b/tests/hdl/test_lb_bridge.py deleted file mode 100755 index 7e83af5..0000000 --- a/tests/hdl/test_lb_bridge.py +++ /dev/null @@ -1,95 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Tests for generated bridges -""" - -import sys -from attr.setters import convert -sys.path.insert(0, '../..') -import pytest -from sim import Simulator, CliArgs, path_join, parent_dir -import corsair - - -TEST_DIR = parent_dir(__file__) - - -def gen_bridge(tmpdir, bridge, reset, hdl): - corsair.config.globcfg['register_reset'] = reset - if hdl == 'vhdl': - bridge_path = path_join(tmpdir, '%s2lb.vhd' % bridge) - corsair.generators.LbBridgeVhdl(path=bridge_path, bridge_type=bridge).generate() - else: - bridge_path = path_join(tmpdir, '%s2lb.v' % bridge) - corsair.generators.LbBridgeVerilog(path=bridge_path, bridge_type=bridge).generate() - return bridge_path - - -@pytest.fixture() -def simtool(): - return 'modelsim' - - -@pytest.fixture(params=['apb', 'axil', 'amm']) -def bridge(request): - return request.param - - -@pytest.fixture(params=['verilog', 'vhdl']) -def hdl(request): - return request.param - - -@pytest.fixture(params=['sync_pos', 'sync_neg', 'async_pos', 'async_neg']) -def reset(request): - return request.param - - -def test(tmpdir, bridge, reset, hdl, simtool, defines=[], gui=False, pytest_run=True): - # create sim - tb_dir = path_join(TEST_DIR, 'test_lb_bridge') - beh_dir = path_join(TEST_DIR, 'beh') - sim = Simulator(name=simtool, gui=gui, cwd=tmpdir) - sim.incdirs += [tmpdir, tb_dir, beh_dir] - sim.sources += [path_join(tb_dir, 'tb.sv')] - sim.sources += beh_dir.glob('*.sv') - sim.defines += defines - sim.top = 'tb' - sim.setup() - # prepare test - dut_src = gen_bridge(tmpdir, bridge, reset, hdl) - sim.sources += [dut_src] - sim.defines += [ - 'DUT_DATA_W=%s' % corsair.config.globcfg['data_width'], - 'DUT_ADDR_W=%s' % corsair.config.globcfg['address_width'], - 'DUT_%s' % bridge.upper(), - 'RESET_ACTIVE=%d' % ('pos' in reset), - ] - # run sim - sim.run() - if pytest_run: - assert sim.is_passed - - -if __name__ == '__main__': - # run script with key -h to see help - cli = CliArgs(default_test='test') - cli.args_parser.add_argument('--bridge', default='apb', metavar='', dest='bridge', - help="bridge to LocalBus; default is 'apb'") - cli.args_parser.add_argument('--hdl', default='verilog', metavar='', dest='hdl', - help="choosen HDL; default is 'verilog'") - cli.args_parser.add_argument('--reset', default='sync_pos', metavar='', dest='reset', - help="reset for bridge registers; default is 'sync_pos'") - args = cli.parse() - try: - globals()[args.test](tmpdir='work', - bridge=args.bridge, - reset=args.reset, - hdl=args.hdl, - simtool=args.simtool, - gui=args.gui, - defines=args.defines, - pytest_run=False) - except KeyError: - print("There is no test with name '%s'!" % args.test) diff --git a/tests/hdl/test_lb_bridge/dut_amm2lb.svh b/tests/hdl/test_lb_bridge/dut_amm2lb.svh deleted file mode 100755 index 89eed2b..0000000 --- a/tests/hdl/test_lb_bridge/dut_amm2lb.svh +++ /dev/null @@ -1,33 +0,0 @@ -amm2lb dut ( - .clk (clk ), - .rst (reset ), - // Avalon-MM - .address (mst.address ), - .read (mst.read_s ), - .readdata (mst.readdata ), - .readdatavalid(mst.readdatavalid), - .byteenable (mst.byteenable ), - .write (mst.write_s ), - .writedata (mst.writedata ), - .waitrequest (mst.waitrequest ), - // Local Bus - .wready (wready ), - .waddr (waddr ), - .wdata (wdata ), - .wen (wen ), - .wstrb (wstrb ), - .rdata (rdata ), - .rvalid (rvalid ), - .raddr (raddr ), - .ren (ren ) -); - -// Avalon-MM master -amm #( - .ADDR_W(ADDR_W), - .DATA_W(DATA_W), - .STRB_W(STRB_W) -) mst ( - .clk(clk), - .reset(reset) -); diff --git a/tests/hdl/test_lb_bridge/dut_apb2lb.svh b/tests/hdl/test_lb_bridge/dut_apb2lb.svh deleted file mode 100755 index 9531cdd..0000000 --- a/tests/hdl/test_lb_bridge/dut_apb2lb.svh +++ /dev/null @@ -1,32 +0,0 @@ -apb2lb dut ( - // APB - .psel (mst.psel), - .paddr (mst.paddr), - .penable (mst.penable), - .pwrite (mst.pwrite), - .pwdata (mst.pwdata), - .pstrb (mst.pstrb), - .prdata (mst.prdata), - .pready (mst.pready), - .pslverr (mst.pslverr), - // Local Bus - .wready (wready), - .waddr (waddr), - .wdata (wdata), - .wen (wen), - .wstrb (wstrb), - .rdata (rdata), - .rvalid (rvalid), - .raddr (raddr), - .ren (ren) -); - -// APB master -apb #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .STRB_W (STRB_W) -) mst ( - .pclk (clk), - .presetn (~rst) -); diff --git a/tests/hdl/test_lb_bridge/dut_axil2lb.svh b/tests/hdl/test_lb_bridge/dut_axil2lb.svh deleted file mode 100755 index 1efd860..0000000 --- a/tests/hdl/test_lb_bridge/dut_axil2lb.svh +++ /dev/null @@ -1,45 +0,0 @@ -axil2lb dut ( - // CLK - .clk (clk), - // Reset - .rst (rst), - // APB - .axil_awaddr (mst.awaddr), - .axil_awprot (mst.awprot), - .axil_awvalid (mst.awvalid), - .axil_awready (mst.awready), - .axil_wdata (mst.wdata), - .axil_wstrb (mst.wstrb), - .axil_wvalid (mst.wvalid), - .axil_wready (mst.wready), - .axil_bresp (mst.bresp), - .axil_bvalid (mst.bvalid), - .axil_bready (mst.bready), - .axil_araddr (mst.araddr), - .axil_arprot (mst.arprot), - .axil_arvalid (mst.arvalid), - .axil_arready (mst.arready), - .axil_rdata (mst.rdata), - .axil_rresp (mst.rresp), - .axil_rvalid (mst.rvalid), - .axil_rready (mst.rready), - // Local Bus - .wready (wready), - .waddr (waddr), - .wdata (wdata), - .wen (wen), - .wstrb (wstrb), - .rdata (rdata), - .rvalid (rvalid), - .raddr (raddr), - .ren (ren) -); - -// AXI-Lite master -axilite #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .STRB_W (STRB_W) -) mst ( - .clk (clk) -); diff --git a/tests/hdl/test_lb_bridge/tb.sv b/tests/hdl/test_lb_bridge/tb.sv deleted file mode 100755 index f3783f4..0000000 --- a/tests/hdl/test_lb_bridge/tb.sv +++ /dev/null @@ -1,158 +0,0 @@ -`timescale 1ns/1ps - -module tb; - -// Clock and reset -logic clk = 1'b0; -always #5 clk <= ~clk; - -logic rst = `RESET_ACTIVE; -initial begin - repeat (5) @(negedge clk); - rst <= !`RESET_ACTIVE; -end - -// DUT -localparam ADDR_W = `DUT_ADDR_W; -localparam DATA_W = `DUT_DATA_W; -localparam STRB_W = DATA_W / 8; - -logic wready = 1'b1; -logic [ADDR_W-1:0] waddr; -logic [DATA_W-1:0] wdata; -logic wen; -logic [STRB_W-1:0] wstrb; -logic [DATA_W-1:0] rdata = '0; -logic rvalid = 1'b0; -logic [ADDR_W-1:0] raddr; -logic ren; - -`ifdef DUT_APB - `include "dut_apb2lb.svh" -`elsif DUT_AXIL - `include "dut_axil2lb.svh" -`elsif DUT_AMM - `include "dut_amm2lb.svh" -`elsif DUT_SPI - `include "dut_spi2lb.svh" -`else - $error("Unknown bridge!"); -`endif - -// Test body -int errors = 0; - -task validate_write( - input logic [ADDR_W-1:0] addr, - input logic [DATA_W-1:0] data, - input logic [STRB_W-1:0] strb -); - @(posedge clk); - wait(wen && wready); - @(posedge clk); - if (waddr != addr) - errors++; - if (wdata != data) - errors++; - if (wstrb != strb) - errors++; -endtask - -task handle_read( - input logic [ADDR_W-1:0] addr, - input int waitstates = 1 -); - @(posedge clk); - wait(ren); - repeat (waitstates) @(posedge clk); - rvalid <= 1'b1; - case (addr) - 'h008: rdata <= 'hdeadbeef; - 'h014: rdata <= 'hc0debabe; - endcase - @(posedge clk); - rdata <= 0; - rvalid <= 1'b0; - @(posedge clk); - if (ren != 0) - errors++; -endtask - -initial begin : main - logic [ADDR_W-1:0] addr; - logic [DATA_W-1:0] data; - logic [STRB_W-1:0] strb; - - wait(rst == !`RESET_ACTIVE); - - // test simple write - addr = 'h80000004; - data = 'hdeadbeef; - fork - mst.write(addr, data); - validate_write(addr, data, {STRB_W{1'b1}}); - join - - // test write with byte strobes - addr = 'h00c; - data = 'hcafebabe; - strb = 'b0110; - fork - mst.write(addr, data, strb); - validate_write(addr, data, strb); - join - - // test write with wait states - addr = 'h010; - data = 'h0acce55; - fork - mst.write(addr, data); - validate_write(addr, data, {STRB_W{1'b1}}); - begin - wready <= 1'b0; - repeat (800) @(posedge clk); - wready <= 1'b1; - end - join - - // test read - addr = 'h014; - fork - mst.read(addr, data); - handle_read(addr); - join - if (data != 'hc0debabe) - errors++; - - // test read with 0 latency - addr = 'h014; - fork - mst.read(addr, data); - handle_read(addr, 0); - join - if (data != 'hc0debabe) - errors++; - - // test read with wait states - addr = 'h008; - fork - mst.read(addr, data); - handle_read(addr, 5); - join - if (data != 'hdeadbeef) - errors++; - - if (errors) - $display("!@# TEST FAILED - %d ERRORS #@!", errors); - else - $display("!@# TEST PASSED #@!"); - $finish; -end - -initial begin : timeout - #50us; - $display("!@# TEST FAILED - TIMEOUT #@!"); - $finish; -end - -endmodule diff --git a/tests/hdl/test_rmap.py b/tests/hdl/test_rmap.py deleted file mode 100755 index 90e184e..0000000 --- a/tests/hdl/test_rmap.py +++ /dev/null @@ -1,156 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Tests for regmap module -""" - -import sys -sys.path.insert(0, '../..') -import pytest -from sim import Simulator, CliArgs, path_join, parent_dir -from corsair import config, generators, RegisterMap, Register, BitField - - -TEST_DIR = parent_dir(__file__) - - -def gen_rtl(tmpdir, interface, reset, hdl): - # global configuration - globcfg = config.default_globcfg() - globcfg['data_width'] = 32 - globcfg['address_width'] = 12 - globcfg['register_reset'] = reset - config.set_globcfg(globcfg) - - # register map - rmap = RegisterMap() - rmap.add_registers(Register('REGRW', 'register rw', 0x0).add_bitfields([ - BitField("BFO", "bitfield o", width=3, lsb=1, access='rw', reset=5, hardware='o'), - BitField("BFIOE", "bitfield ioe", width=4, lsb=4, access='rw', hardware='ioe'), - BitField("BFIOEA", "bitfield ioa", width=2, lsb=8, access='rw', hardware='ioea'), - BitField("BFOL", "bitfield ol", width=8, lsb=10, access='rw', hardware='ol'), - BitField("BFOS", "bitfield os", width=1, lsb=18, access='rw', hardware='os'), - BitField("BFOC", "bitfield oc", width=1, lsb=23, access='rw', hardware='oc'), - BitField("BFN", "bitfield n", width=8, lsb=24, access='rw', hardware='n'), - ])) - rmap.add_registers(Register('REGRWQ', 'register rw queue', 0x4).add_bitfields([ - BitField("BFIOQ", "bitfield ioq", width=12, lsb=0, access='rw', hardware='q'), - ])) - rmap.add_registers(Register('REGRW1X', 'register rw1x', 0x8).add_bitfields([ - BitField("BFC", "bitfield rw1c s", width=1, lsb=1, access='rw1c', hardware='s'), - BitField("BFS", "bitfield rw1s c", width=1, lsb=4, access='rw1s', reset=1, hardware='c'), - ])) - rmap.add_registers(Register('REGRO', 'register ro', 0x10).add_bitfields([ - BitField("BFI", "bitfield ro i", width=8, lsb=0, access='ro', hardware='i'), - BitField("BFF", "bitfield ro f", width=4, lsb=8, access='ro', hardware='f', reset=13), - BitField("BFIE", "bitfield ro ie", width=4, lsb=12, access='ro', hardware='ie'), - ])) - rmap.add_registers(Register('REGROC', 'register ro', 0x14).add_bitfields([ - BitField("BFIE", "bitfield roc ie", width=16, lsb=0, access='roc', hardware='ie'), - ])) - rmap.add_registers(Register('REGROQ', 'register ro queue', 0x20).add_bitfields([ - BitField("BFIQ", "bitfield ro iq", width=24, lsb=0, access='ro', hardware='q'), - ])) - rmap.add_registers(Register('REGROLX', 'register roll / rolh', 0x24).add_bitfields([ - BitField("BFLL", "bitfield roll i", width=1, lsb=0, access='roll', reset=1, hardware='i'), - BitField("BFLH", "bitfield rolh i", width=1, lsb=16, access='rolh', hardware='i'), - BitField("BFLLE", "bitfield roll ie", width=1, lsb=23, access='roll', reset=1, hardware='ie'), - BitField("BFLHE", "bitfield rolh ie", width=1, lsb=28, access='rolh', hardware='ie'), - ])) - rmap.add_registers(Register('REGWO', 'register wo / wosc', 0x28).add_bitfields([ - BitField("BFWO", "bitfield wo o", width=4, lsb=8, access='wo', hardware='o'), - BitField("BFSC", "bitfield wosc o", width=1, lsb=16, access='wosc', hardware='o'), - ])) - rmap.add_registers(Register('REGWOQ', 'register wo queue', 0x30).add_bitfields([ - BitField("BFOQ", "bitfield wo oq", width=24, lsb=0, access='wo', hardware='q'), - ])) - - if hdl == 'vhdl': - regmap_path = path_join(tmpdir, 'regs.vhd') - generators.Vhdl(rmap, regmap_path, read_filler=0xdeadc0de, interface=interface).generate() - else: - regmap_path = path_join(tmpdir, 'regs.v') - generators.Verilog(rmap, regmap_path, read_filler=0xdeadc0de, interface=interface).generate() - - header_path = path_join(tmpdir, 'regs.vh') - generators.VerilogHeader(rmap, header_path).generate() - - package_path = path_join(tmpdir, 'regs_pkg.sv') - generators.SystemVerilogPackage(rmap, package_path).generate() - - return (package_path, regmap_path) - - -@pytest.fixture() -def simtool(): - return 'modelsim' - - -@pytest.fixture(params=['apb', 'axil', 'amm']) -def interface(request): - return request.param - - -@pytest.fixture(params=['verilog', 'vhdl']) -def hdl(request): - return request.param - - -@pytest.fixture(params=['sync_pos', 'sync_neg', 'async_pos', 'async_neg']) -def reset(request): - return request.param - - -@pytest.fixture(params=['tb_rw', 'tb_wo', 'tb_ro']) -def tb(request): - return request.param - - -def test(tmpdir, tb, interface, reset, hdl, simtool, defines=[], gui=False, pytest_run=True): - # create sim - tb_dir = path_join(TEST_DIR, 'test_rmap') - beh_dir = path_join(TEST_DIR, 'beh') - sim = Simulator(name=simtool, gui=gui, cwd=tmpdir) - sim.incdirs += [tmpdir, tb_dir, beh_dir] - sim.sources += [path_join(tb_dir, '%s.sv' % tb)] - sim.sources += beh_dir.glob('*.sv') - sim.defines += defines - sim.top = tb - sim.setup() - # prepare test - src = gen_rtl(tmpdir, interface, reset, hdl) - sim.sources = list(src) + sim.sources - sim.defines += [ - 'INTERFACE_%s' % interface.upper(), - 'RESET_ACTIVE=%d' % ('pos' in reset), - ] - # run sim - sim.run() - if pytest_run: - assert sim.is_passed - - -if __name__ == '__main__': - # run script with key -h to see help - cli = CliArgs(default_test='test') - cli.args_parser.add_argument('--tb', default='tb_rw', metavar='', dest='tb', - help="run testbench named ; default is 'tb_rw'") - cli.args_parser.add_argument('--interface', default='apb', metavar='', dest='interface', - help="interface to register map; default is 'apb'") - cli.args_parser.add_argument('--reset', default='sync_pos', metavar='', dest='reset', - help="reset for interface registers; default is 'sync_pos'") - cli.args_parser.add_argument('--hdl', default='verilog', metavar='', dest='hdl', - help="choosen HDL; default is 'verilog'") - args = cli.parse() - try: - globals()[args.test](tmpdir='work', - tb=args.tb, - interface=args.interface, - reset=args.reset, - hdl=args.hdl, - simtool=args.simtool, - gui=args.gui, - defines=args.defines, - pytest_run=False) - except KeyError: - print("There is no test with name '%s'!" % args.test) diff --git a/tests/hdl/test_rmap/dut.svh b/tests/hdl/test_rmap/dut.svh deleted file mode 100755 index 596bbe2..0000000 --- a/tests/hdl/test_rmap/dut.svh +++ /dev/null @@ -1,224 +0,0 @@ -// REGRW.BFO -logic [2:0] csr_regrw_bfo_out; -// REGRW.BFIOE -logic csr_regrw_bfioe_en = 0; -logic [3:0] csr_regrw_bfioe_in = 0; -logic [3:0] csr_regrw_bfioe_out; -// REGRW.BFIOEA -logic csr_regrw_bfioea_raccess; -logic csr_regrw_bfioea_waccess; -logic csr_regrw_bfioea_en = 0; -logic [1:0] csr_regrw_bfioea_in = 0; -logic [1:0] csr_regrw_bfioea_out; -// REGRW.BFOL -logic csr_regrw_bfol_lock = 0; -logic [7:0] csr_regrw_bfol_out; -// REGRW.BFOS -logic csr_regrw_bfos_set = 0; -logic csr_regrw_bfos_out; -// REGRW.BFOC -logic csr_regrw_bfoc_clr = 0; -logic csr_regrw_bfoc_out; -// REGRW.BFN - -// REGRWQ.BFIOQ -logic csr_regrwq_bfioq_rvalid = 0; -logic csr_regrwq_bfioq_ren; -logic [11:0] csr_regrwq_bfioq_in = 0; -logic [11:0] csr_regrwq_bfioq_out; -logic csr_regrwq_bfioq_wready = 0; -logic csr_regrwq_bfioq_wen; - -// REGRW1X.BFC -logic csr_regrw1x_bfc_set = 0; -// REGRW1X.BFS -logic csr_regrw1x_bfs_clr = 0; - -// REGRO.BFI -logic [7:0] csr_regro_bfi_in = 0; -// REGRO.BFF -// REGRO.BFIE -logic csr_regro_bfie_en = 0; -logic [3:0] csr_regro_bfie_in = 0; - -// REGROC.BFI -logic csr_regroc_bfie_en = 0; -logic [15:0] csr_regroc_bfie_in = 0; - -// REGROQ.BFIQ -logic csr_regroq_bfiq_rvalid = 0; -logic csr_regroq_bfiq_ren; -logic [23:0] csr_regroq_bfiq_in = 0; - -// REGROLX.BFLL -logic csr_regrolx_bfll_in = 1; -// REGROLX.BFLH -logic csr_regrolx_bflh_in = 0; -// REGROLX.BFLLE -logic csr_regrolx_bflle_en = 0; -logic csr_regrolx_bflle_in = 1; - // REGROLX.BFLHE -logic csr_regrolx_bflhe_en = 0; -logic csr_regrolx_bflhe_in = 0; - -// REGWO.BFWO -logic [3:0] csr_regwo_bfwo_out; -// REGWO.BFSC -logic csr_regwo_bfsc_out; - -// REGWOQ.BFOQ -logic [23:0] csr_regwoq_bfoq_out; -logic csr_regwoq_bfoq_wready = 0; -logic csr_regwoq_bfoq_wen; - - -regs dut ( - // System - .clk (clk), - .rst (rst), - // REGRW.BFIO - .csr_regrw_bfo_out (csr_regrw_bfo_out), - // REGRW.BFIOE - .csr_regrw_bfioe_en (csr_regrw_bfioe_en), - .csr_regrw_bfioe_in (csr_regrw_bfioe_in), - .csr_regrw_bfioe_out (csr_regrw_bfioe_out), - // REGRW.BFIOEA - .csr_regrw_bfioea_raccess (csr_regrw_bfioea_raccess), - .csr_regrw_bfioea_waccess (csr_regrw_bfioea_waccess), - .csr_regrw_bfioea_en (csr_regrw_bfioea_en), - .csr_regrw_bfioea_in (csr_regrw_bfioea_in), - .csr_regrw_bfioea_out (csr_regrw_bfioea_out), - // REGRW.BFIOL - .csr_regrw_bfol_lock (csr_regrw_bfol_lock), - .csr_regrw_bfol_out (csr_regrw_bfol_out), - // REGRW.BFOS - .csr_regrw_bfos_set (csr_regrw_bfos_set), - .csr_regrw_bfos_out (csr_regrw_bfos_out), - // REGRW.BFOC - .csr_regrw_bfoc_clr (csr_regrw_bfoc_clr), - .csr_regrw_bfoc_out (csr_regrw_bfoc_out), - // REGRW.BFN - - // REGRWQ.BFIOQ - .csr_regrwq_bfioq_rvalid (csr_regrwq_bfioq_rvalid), - .csr_regrwq_bfioq_ren (csr_regrwq_bfioq_ren), - .csr_regrwq_bfioq_in (csr_regrwq_bfioq_in), - .csr_regrwq_bfioq_out (csr_regrwq_bfioq_out), - .csr_regrwq_bfioq_wready (csr_regrwq_bfioq_wready), - .csr_regrwq_bfioq_wen (csr_regrwq_bfioq_wen), - - // REGRW1X.BFC - .csr_regrw1x_bfc_set (csr_regrw1x_bfc_set), - // REGRW1X.BFS - .csr_regrw1x_bfs_clr (csr_regrw1x_bfs_clr), - - // REGRO.BFI - .csr_regro_bfi_in (csr_regro_bfi_in), - // REGRO.BFF - // REGRO.BFIE - .csr_regro_bfie_en (csr_regro_bfie_en), - .csr_regro_bfie_in (csr_regro_bfie_in), - - // REGROC.BFI - .csr_regroc_bfie_en (csr_regroc_bfie_en), - .csr_regroc_bfie_in (csr_regroc_bfie_in), - - // REGROQ.BFIQ - .csr_regroq_bfiq_rvalid (csr_regroq_bfiq_rvalid), - .csr_regroq_bfiq_ren (csr_regroq_bfiq_ren), - .csr_regroq_bfiq_in (csr_regroq_bfiq_in), - - // REGROLX.BFLL - .csr_regrolx_bfll_in (csr_regrolx_bfll_in), - // REGROLX.BFLH - .csr_regrolx_bflh_in (csr_regrolx_bflh_in), - // REGROLX.BFLLE - .csr_regrolx_bflle_en (csr_regrolx_bflle_en), - .csr_regrolx_bflle_in (csr_regrolx_bflle_in), - // REGROLX.BFLHE - .csr_regrolx_bflhe_en (csr_regrolx_bflhe_en), - .csr_regrolx_bflhe_in (csr_regrolx_bflhe_in), - - // REGWO.BFWO - .csr_regwo_bfwo_out (csr_regwo_bfwo_out), - // REGWO.BFSC - .csr_regwo_bfsc_out (csr_regwo_bfsc_out), - - // REGWOQ.BFOQ - .csr_regwoq_bfoq_out (csr_regwoq_bfoq_out), - .csr_regwoq_bfoq_wready (csr_regwoq_bfoq_wready), - .csr_regwoq_bfoq_wen (csr_regwoq_bfoq_wen), - -`ifdef INTERFACE_AXIL - .axil_awaddr (mst.awaddr), - .axil_awprot (mst.awprot), - .axil_awvalid (mst.awvalid), - .axil_awready (mst.awready), - .axil_wdata (mst.wdata), - .axil_wstrb (mst.wstrb), - .axil_wvalid (mst.wvalid), - .axil_wready (mst.wready), - .axil_bresp (mst.bresp), - .axil_bvalid (mst.bvalid), - .axil_bready (mst.bready), - .axil_araddr (mst.araddr), - .axil_arprot (mst.arprot), - .axil_arvalid (mst.arvalid), - .axil_arready (mst.arready), - .axil_rdata (mst.rdata), - .axil_rresp (mst.rresp), - .axil_rvalid (mst.rvalid), - .axil_rready (mst.rready) -); -// AXI-Lite master -axilite #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .STRB_W (STRB_W) -) mst ( - .clk (clk) -); -`elsif INTERFACE_APB - // APB - .psel (mst.psel), - .paddr (mst.paddr), - .penable (mst.penable), - .pwrite (mst.pwrite), - .pwdata (mst.pwdata), - .pstrb (mst.pstrb), - .prdata (mst.prdata), - .pready (mst.pready), - .pslverr (mst.pslverr) -); -// APB master -apb #( - .ADDR_W (ADDR_W), - .DATA_W (DATA_W), - .STRB_W (STRB_W) -) mst ( - .pclk (clk), - .presetn (~rst) -); -`elsif INTERFACE_AMM - // Avalon-MM - .address (mst.address), - .read (mst.read_s), - .readdata (mst.readdata), - .readdatavalid(mst.readdatavalid), - .byteenable (mst.byteenable), - .write (mst.write_s), - .writedata (mst.writedata), - .waitrequest (mst.waitrequest) -); -// Avalon-MM master -amm #( - .ADDR_W(ADDR_W), - .DATA_W(DATA_W), - .STRB_W(STRB_W) -) mst ( - .clk(clk), - .reset(reset) -); -`else - $error("Unknown interface to register map!"); -`endif diff --git a/tests/hdl/test_rmap/env.svh b/tests/hdl/test_rmap/env.svh deleted file mode 100755 index fc85440..0000000 --- a/tests/hdl/test_rmap/env.svh +++ /dev/null @@ -1,30 +0,0 @@ -`include "regs.vh" -import regs_pkg::*; - -// Clock and reset -logic clk = 1'b0; -always #5 clk <= ~clk; - -logic rst = `RESET_ACTIVE; -initial begin - repeat (5) @(negedge clk); - rst <= !`RESET_ACTIVE; -end - -// DUT -localparam ADDR_W = CSR_ADDR_WIDTH; -localparam DATA_W = CSR_DATA_WIDTH; -localparam STRB_W = DATA_W / 8; - -logic wready; -logic [ADDR_W-1:0] waddr; -logic [DATA_W-1:0] wdata; -logic wen; -logic [STRB_W-1:0] wstrb; -logic [DATA_W-1:0] rdata; -logic rvalid; -logic [ADDR_W-1:0] raddr; -logic ren; - -// DUT -`include "dut.svh" diff --git a/tests/hdl/test_rmap/tb_ro.sv b/tests/hdl/test_rmap/tb_ro.sv deleted file mode 100755 index 6a82c09..0000000 --- a/tests/hdl/test_rmap/tb_ro.sv +++ /dev/null @@ -1,438 +0,0 @@ -`timescale 1ns/1ps - -module tb_ro; - -// Test environment with DUT and bridge to LocalBus -`include "env.svh" - -// Test body -int errors = 0; -logic [ADDR_W-1:0] addr; -logic [DATA_W-1:0] data; -logic [STRB_W-1:0] strb; - -task test_ro_i; - $display("%0t, Start RO+I tests!", $time); - addr = CSR_REGRO_ADDR; - // read - mst.read(addr, data); - if (data[CSR_REGRO_BFI_LSB+:CSR_REGRO_BFI_WIDTH] != 0) - errors++; - // update hardware value - @(posedge clk); - csr_regro_bfi_in = 100; - // read again - mst.read(addr, data); - if (data[CSR_REGRO_BFI_LSB+:CSR_REGRO_BFI_WIDTH] != 100) - errors++; - // write has no effect - data = 200 << CSR_REGRO_BFI_LSB; - mst.write(addr, data); - mst.read(addr, data); - if (data[CSR_REGRO_BFI_LSB+:CSR_REGRO_BFI_WIDTH] != 100) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_ro_ie; - $display("%0t, Start RO+IE tests!", $time); - addr = CSR_REGRO_ADDR; - // read - mst.read(addr, data); - if (data[CSR_REGRO_BFIE_LSB+:CSR_REGRO_BFIE_WIDTH] != 0) - errors++; - // update hardware value without enable - @(posedge clk); - csr_regro_bfie_in = 10; - // read again - mst.read(addr, data); - if (data[CSR_REGRO_BFIE_LSB+:CSR_REGRO_BFIE_WIDTH] == 10) - errors++; - // update hardware value with enable - @(posedge clk); - csr_regro_bfie_en = 1; - csr_regro_bfie_in = 13; - @(posedge clk); - csr_regro_bfie_en = 0; - // read again - mst.read(addr, data); - if (data[CSR_REGRO_BFIE_LSB+:CSR_REGRO_BFIE_WIDTH] != 13) - errors++; - // write has no effect - data = 9 << CSR_REGRO_BFIE_LSB; - mst.write(addr, data); - mst.read(addr, data); - if (data[CSR_REGRO_BFIE_LSB+:CSR_REGRO_BFIE_WIDTH] != 13) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_ro_f; - $display("%0t, Start RO+F tests!", $time); - addr = CSR_REGRO_ADDR; - // read - mst.read(addr, data); - if (data[CSR_REGRO_BFF_LSB+:CSR_REGRO_BFF_WIDTH] != CSR_REGRO_BFF_RESET) - errors++; - // write has no effect - data = 9 << CSR_REGRO_BFF_LSB; - mst.write(addr, data); - mst.read(addr, data); - if (data[CSR_REGRO_BFF_LSB+:CSR_REGRO_BFF_WIDTH] != CSR_REGRO_BFF_RESET) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_roc_ie; - $display("%0t, Start ROC+IE tests!", $time); - addr = CSR_REGROC_ADDR; - // update hardware value - @(posedge clk); - csr_regroc_bfie_en = 1; - csr_regroc_bfie_in = 13; - @(posedge clk); - csr_regroc_bfie_en = 0; - // read - mst.read(addr, data); - if (data[CSR_REGROC_BFIE_LSB+:CSR_REGROC_BFIE_WIDTH] != 13) - errors++; - // read again - mst.read(addr, data); - if (data[CSR_REGROC_BFIE_LSB+:CSR_REGROC_BFIE_WIDTH] != 0) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -logic [CSR_REGROQ_BFIQ_WIDTH-1:0] fifo [$]; -task test_ro_iq; - $display("%0t, Start RO+IQ tests!", $time); - // push 5 elements to the fifo - fifo.delete(); - for (int i=1; i<6; i++) begin - fifo.push_front((i + 4096) * i); - end - addr = CSR_REGROQ_ADDR; - // read 5 elements from the fifo with data values control - fork - for (int i=1; i<6; i++) begin - mst.read(addr, data); - if (data !== ((i + 4096) * i)) - errors++; - end - csr_regroq_bfiq_rvalid <= 1'b1; - csr_regroq_bfiq_in <= fifo.pop_back(); - for (int i=0; i<5; i++) begin - wait (csr_regroq_bfiq_ren); - repeat (i+1) @(posedge clk); - if (i != 0) begin - csr_regroq_bfiq_in <= fifo.pop_back(); - csr_regroq_bfiq_rvalid <= 1'b1; - end - @(posedge clk); - csr_regroq_bfiq_rvalid <= 1'b0; - @(posedge clk); - @(posedge clk); - end - join - $display("%0t, %0d errors", $time, errors); -endtask - -task test_roll_i; - $display("%0t, Start ROLL+I tests!", $time); - addr = CSR_REGROLX_ADDR; - // check latched value - @(posedge clk); - if (csr_regrolx_bfll_in != 1) - errors++; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 1) - errors++; - // latch value - @(posedge clk); - csr_regrolx_bfll_in <= 1'b0; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 0) - errors++; - // check that is stucked at 0 - @(posedge clk); - csr_regrolx_bfll_in <= 1'b1; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 0) - errors++; - // read again - mst.read(addr, data); - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 1) - errors++; - - // check simultanious reading & latching -- latched value should not be reset - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - csr_regrolx_bfll_in <= 1'b0; - @(posedge clk); - csr_regrolx_bfll_in <= 1'b1; - end - join - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 1) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 0) errors++; - - // check latching just after read operation - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - @(posedge clk); - csr_regrolx_bfll_in <= 1'b0; - @(posedge clk); - csr_regrolx_bfll_in <= 1'b1; - end - join - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 1) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLL_LSB+:CSR_REGROLX_BFLL_WIDTH] != 0) errors++; - - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rolh_i; - $display("%0t, Start ROLH+I tests!", $time); - addr = CSR_REGROLX_ADDR; - // check latched value - @(posedge clk); - if (csr_regrolx_bflh_in != 0) - errors++; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 0) - errors++; - // latch value - @(posedge clk); - csr_regrolx_bflh_in <= 1'b1; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 1) - errors++; - // check that is stucked at 1 - @(posedge clk); - csr_regrolx_bflh_in <= 1'b0; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 1) - errors++; - // read again - mst.read(addr, data); - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 0) - errors++; - - // check simultanious reading & latching -- latched value should not be reset - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - csr_regrolx_bflh_in <= 1'b1; - @(posedge clk); - csr_regrolx_bflh_in <= 1'b0; - end - join - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 0) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 1) errors++; - - // check latching just after read operation - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - @(posedge clk); - csr_regrolx_bflh_in <= 1'b1; - @(posedge clk); - csr_regrolx_bflh_in <= 1'b0; - end - join - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 0) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLH_LSB+:CSR_REGROLX_BFLH_WIDTH] != 1) errors++; - - $display("%0t, %0d errors", $time, errors); -endtask - -task test_roll_ie; - $display("%0t, Start ROLL+IE tests!", $time); - addr = CSR_REGROLX_ADDR; - // check original value - mst.read(addr, data); - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 1) - errors++; - // latch value without enable - @(posedge clk); - csr_regrolx_bflle_in <= 1'b0; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 1) - errors++; - // latch value with enable - @(posedge clk); - csr_regrolx_bflle_en <= 1'b1; - csr_regrolx_bflle_in <= 1'b0; - @(posedge clk); - csr_regrolx_bflle_en <= 1'b0; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 0) - errors++; - // check that is stucked at 0 - @(posedge clk); - csr_regrolx_bflle_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflle_en <= 1'b0; - @(posedge clk); - csr_regrolx_bflle_in <= 1'b1; - csr_regrolx_bflle_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflle_en <= 1'b0; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 0) - errors++; - // read again - mst.read(addr, data); - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 1) - errors++; - - // check simultanious reading & latching -- latched value should not be reset - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - csr_regrolx_bflle_in <= 1'b0; - csr_regrolx_bflle_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflle_in <= 1'b1; - csr_regrolx_bflle_en <= 1'b0; - end - join - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 1) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 0) errors++; - - // check latching just after read operation - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - @(posedge clk); - csr_regrolx_bflle_in <= 1'b0; - csr_regrolx_bflle_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflle_in <= 1'b1; - csr_regrolx_bflle_en <= 1'b0; - end - join - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 1) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLLE_LSB+:CSR_REGROLX_BFLLE_WIDTH] != 0) errors++; - - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rolh_ie; - $display("%0t, Start ROLH+IE tests!", $time); - addr = CSR_REGROLX_ADDR; - // check original value - mst.read(addr, data); - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 0) - errors++; - // latch value without enable - @(posedge clk); - csr_regrolx_bflhe_in <= 1'b1; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 0) - errors++; - // latch value with enable - @(posedge clk); - csr_regrolx_bflhe_en <= 1'b1; - csr_regrolx_bflhe_in <= 1'b1; - @(posedge clk); - csr_regrolx_bflhe_en <= 1'b0; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 1) - errors++; - // check that is stucked at 1 - @(posedge clk); - csr_regrolx_bflhe_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflhe_en <= 1'b0; - @(posedge clk); - csr_regrolx_bflhe_in <= 1'b0; - csr_regrolx_bflhe_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflhe_en <= 1'b0; - mst.read(addr, data); - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 1) - errors++; - // read again - mst.read(addr, data); - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 0) - errors++; - - // check simultanious reading & latching -- latched value should not be reset - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - csr_regrolx_bflhe_in <= 1'b1; - csr_regrolx_bflhe_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflhe_in <= 1'b0; - csr_regrolx_bflhe_en <= 1'b0; - end - join - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 0) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 1) errors++; - - // check latching just after read operation - fork - mst.read(addr, data); - begin // simultanious read with latching new tick - @(posedge tb_ro.dut.csr_regrolx_ren); - @(posedge clk); - csr_regrolx_bflhe_in <= 1'b1; - csr_regrolx_bflhe_en <= 1'b1; - @(posedge clk); - csr_regrolx_bflhe_in <= 1'b0; - csr_regrolx_bflhe_en <= 1'b0; - end - join - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 0) errors++; - mst.read(addr, data); // reading once more time to check that latch was not reset - if (data[CSR_REGROLX_BFLHE_LSB+:CSR_REGROLX_BFLHE_WIDTH] != 1) errors++; - - $display("%0t, %0d errors", $time, errors); -endtask - -initial begin : main - wait(!rst); - repeat(5) @(posedge clk); - - test_ro_i(); - test_ro_ie(); - test_ro_f(); - test_roc_ie(); - test_ro_iq(); - test_roll_i(); - test_rolh_i(); - test_roll_ie(); - test_rolh_ie(); - - repeat(5) @(posedge clk); - if (errors) - $display("!@# TEST FAILED - %d ERRORS #@!", errors); - else - $display("!@# TEST PASSED #@!"); - $finish; -end - -initial begin : timeout - #500us; - $display("!@# TEST FAILED - TIMEOUT #@!"); - $finish; -end - -endmodule diff --git a/tests/hdl/test_rmap/tb_rw.sv b/tests/hdl/test_rmap/tb_rw.sv deleted file mode 100755 index 1b3ce00..0000000 --- a/tests/hdl/test_rmap/tb_rw.sv +++ /dev/null @@ -1,315 +0,0 @@ -`timescale 1ns/1ps - -module tb_rw; - -// Test environment with DUT and bridge to LocalBus -`include "env.svh" - -// Test body -int errors = 0; -logic [ADDR_W-1:0] addr; -logic [DATA_W-1:0] data; -logic [STRB_W-1:0] strb; - -task test_rw_o; - $display("%0t, Start RW+O tests!", $time); - // read after reset - addr = CSR_REGRW_ADDR; - mst.read(addr, data); - if (data != CSR_REGRW_RESET) - errors++; - if (data[CSR_REGRW_BFO_LSB+:CSR_REGRW_BFO_WIDTH] != CSR_REGRW_BFO_RESET) - errors++; - // write with read back - data = 3 << CSR_REGRW_BFO_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regrw_bfo_out != 3) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFO_LSB+:CSR_REGRW_BFO_WIDTH] != 3) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw_ioe; - $display("%0t, Start RW+IOE tests!", $time); - addr = CSR_REGRW_ADDR; - // write with read back - data = 10 << CSR_REGRW_BFIOE_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regrw_bfioe_out != 10) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFIOE_LSB+:CSR_REGRW_BFIOE_WIDTH] != 10) - errors++; - // update bitfield from hardware - @(posedge clk); - csr_regrw_bfioe_en = 1; - csr_regrw_bfioe_in = 12; - @(posedge clk); - csr_regrw_bfioe_en = 0; - @(posedge clk); - if (csr_regrw_bfioe_out != 12) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFIOE_LSB+:CSR_REGRW_BFIOE_WIDTH] != 12) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw_ioea; - $display("%0t, Start RW+IOEA tests!", $time); - addr = CSR_REGRW_ADDR; - // write with read back - data = 2 << CSR_REGRW_BFIOEA_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regrw_bfioea_out != 2) - errors++; - fork - mst.read(addr, data); - begin - wait(csr_regrw_bfioea_raccess); - @(posedge clk); - if (csr_regrw_bfioea_raccess != 1) - errors++; - @(posedge clk); - if (csr_regrw_bfioea_raccess != 0) - errors++; - end - join - if (data[CSR_REGRW_BFIOEA_LSB+:CSR_REGRW_BFIOEA_WIDTH] != 2) - errors++; - // update bitfield from hardware - @(posedge clk); - csr_regrw_bfioea_en = 1; - csr_regrw_bfioea_in = 1; - @(posedge clk); - csr_regrw_bfioea_en = 0; - @(posedge clk); - if (csr_regrw_bfioea_out != 1) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFIOEA_LSB+:CSR_REGRW_BFIOEA_WIDTH] != 1) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw_ol; - $display("%0t, Start RW+OL tests!", $time); - addr = CSR_REGRW_ADDR; - // write when locked - csr_regrw_bfol_lock = 1; - data = 128 << CSR_REGRW_BFOL_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regrw_bfol_out == 128) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFOL_LSB+:CSR_REGRW_BFOL_WIDTH] == 128) - errors++; - // write when unlocked - csr_regrw_bfol_lock = 0; - data = 200 << CSR_REGRW_BFOL_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regrw_bfol_out != 200) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFOL_LSB+:CSR_REGRW_BFOL_WIDTH] != 200) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw_os; - $display("%0t, Start RW+OS tests!", $time); - addr = CSR_REGRW_ADDR; - // read - mst.read(addr, data); - if (data[CSR_REGRW_BFOS_LSB+:CSR_REGRW_BFOS_WIDTH] != 0) - errors++; - // update by hardware - @(posedge clk); - csr_regrw_bfos_set = 1; - @(posedge clk); - csr_regrw_bfos_set = 0; - @(posedge clk); - if (csr_regrw_bfos_out != 1) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFOS_LSB+:CSR_REGRW_BFOS_WIDTH] != 1) - errors++; - // write - data = 0 << CSR_REGRW_BFOS_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regrw_bfos_out != 0) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFOS_LSB+:CSR_REGRW_BFOS_WIDTH] != 0) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw_oc; - $display("%0t, Start RW+OC tests!", $time); - addr = CSR_REGRW_ADDR; - // write - data = 1 << CSR_REGRW_BFOC_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regrw_bfoc_out != 1) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFOC_LSB+:CSR_REGRW_BFOC_WIDTH] != 1) - errors++; - // update by hardware - @(posedge clk); - csr_regrw_bfoc_clr = 1; - @(posedge clk); - csr_regrw_bfoc_clr = 0; - @(posedge clk); - if (csr_regrw_bfoc_out != 0) - errors++; - mst.read(addr, data); - if (data[CSR_REGRW_BFOC_LSB+:CSR_REGRW_BFOC_WIDTH] != 0) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw_n; - - $display("%0t, Start RW+N tests!", $time); - addr = CSR_REGRW_ADDR; - // write - data = 200 << CSR_REGRW_BFN_LSB; - mst.write(addr, data); - @(posedge clk); - mst.read(addr, data); - if (data[CSR_REGRW_BFN_LSB+:CSR_REGRW_BFN_WIDTH] != 200) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -logic [CSR_REGRWQ_BFIOQ_WIDTH-1:0] fifo [$]; -task test_rw_q; - $display("%0t, Start RW+Q tests!", $time); - // push 5 elements to the fifo - fifo.delete(); - addr = CSR_REGRWQ_ADDR; - csr_regrwq_bfioq_wready = 1; - fork - for (int i=0; i<5; i++) begin - mst.write(addr, (i + 200) * i); - end - repeat (5) begin - wait(csr_regrwq_bfioq_wen); - @(posedge clk); - fifo.push_front(csr_regrwq_bfioq_out); - @(posedge clk); - end - join - @(posedge clk); - // read 5 elements from the fifo with data values control - fork - for (int i=0; i<5; i++) begin - mst.read(addr, data); - if (data !== ((i + 200) * i)) - errors++; - end - for (int i=0; i<5; i++) begin - wait (csr_regrwq_bfioq_ren); - repeat (i+1) @(posedge clk); - csr_regrwq_bfioq_in <= fifo.pop_back(); - csr_regrwq_bfioq_rvalid <= 1'b1; - @(posedge clk); - csr_regrwq_bfioq_rvalid <= 1'b0; - @(posedge clk); - @(posedge clk); - end - join - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw1c_s; - $display("%0t, Start RW1C+S tests!", $time); - addr = CSR_REGRW1X_ADDR; - // read - mst.read(addr, data); - if (data[CSR_REGRW1X_BFC_LSB+:CSR_REGRW1X_BFC_WIDTH] != 0) - errors++; - // update by hardware - @(posedge clk); - csr_regrw1x_bfc_set = 1; - @(posedge clk); - csr_regrw1x_bfc_set = 0; - @(posedge clk); - mst.read(addr, data); - if (data[CSR_REGRW1X_BFC_LSB+:CSR_REGRW1X_BFC_WIDTH] != 1) - errors++; - // write to clear - data = 1 << CSR_REGRW1X_BFC_LSB; - mst.write(addr, data); - mst.read(addr, data); - if (data[CSR_REGRW1X_BFC_LSB+:CSR_REGRW1X_BFC_WIDTH] != 0) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_rw1s_c; - $display("%0t, Start RW1S+C tests!", $time); - addr = CSR_REGRW1X_ADDR; - // read - mst.read(addr, data); - if (data[CSR_REGRW1X_BFS_LSB+:CSR_REGRW1X_BFS_WIDTH] != 1) - errors++; - // update by hardware - @(posedge clk); - csr_regrw1x_bfs_clr = 1; - @(posedge clk); - csr_regrw1x_bfs_clr = 0; - @(posedge clk); - mst.read(addr, data); - if (data[CSR_REGRW1X_BFS_LSB+:CSR_REGRW1X_BFS_WIDTH] != 0) - errors++; - // write to set - data = 1 << CSR_REGRW1X_BFS_LSB; - mst.write(addr, data); - mst.read(addr, data); - if (data[CSR_REGRW1X_BFS_LSB+:CSR_REGRW1X_BFS_WIDTH] != 1) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -initial begin : main - wait(!rst); - repeat(5) @(posedge clk); - - test_rw_o(); - test_rw_ioe(); - test_rw_ioea(); - test_rw_ol(); - test_rw_os(); - test_rw_oc(); - test_rw_n(); - test_rw_q(); - test_rw1c_s(); - test_rw1s_c(); - - repeat(5) @(posedge clk); - if (errors) - $display("!@# TEST FAILED - %0d ERRORS #@!", errors); - else - $display("!@# TEST PASSED #@!"); - $finish; -end - -initial begin : timeout - #500us; - $display("!@# TEST FAILED - TIMEOUT #@!"); - $finish; -end - -endmodule diff --git a/tests/hdl/test_rmap/tb_wo.sv b/tests/hdl/test_rmap/tb_wo.sv deleted file mode 100755 index 567d6ab..0000000 --- a/tests/hdl/test_rmap/tb_wo.sv +++ /dev/null @@ -1,121 +0,0 @@ -`timescale 1ns/1ps - -module tb_wo; - -// Test environment with DUT and bridge to LocalBus -`include "env.svh" - -// Test body -int errors = 0; -logic [ADDR_W-1:0] addr; -logic [DATA_W-1:0] data; -logic [STRB_W-1:0] strb; - -task test_wo_o; - $display("%0t, Start WO+O tests!", $time); - addr = CSR_REGWO_ADDR; - // write - data = 10 << CSR_REGWO_BFWO_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regwo_bfwo_out != 10) - errors++; - // read - mst.read(addr, data); - if (data != 0) - errors++; - // write again - data = 3 << CSR_REGWO_BFWO_LSB; - mst.write(addr, data); - @(posedge clk); - if (csr_regwo_bfwo_out != 3) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -task test_wosc_o; - $display("%0t, Start WOSC+O tests!", $time); - addr = CSR_REGWO_ADDR; - // write - data = 1 << CSR_REGWO_BFSC_LSB; - fork - mst.write(addr, data); - begin : check - wait(csr_regwo_bfsc_out); - repeat(2) @(posedge clk); - if (csr_regwo_bfsc_out != 0) - errors++; - end - join - // read - mst.read(addr, data); - if (data != 0) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -logic [CSR_REGWOQ_BFOQ_WIDTH-1:0] fifo [$]; - -task test_wo_oq; - $display("%0t, Start WO+OQ tests!", $time); - addr = CSR_REGWOQ_ADDR; - // push 5 elements to the fifo - fifo.delete(); - csr_regwoq_bfoq_wready = 1; - fork - for (int i=0; i<5; i++) begin - mst.write(addr, (i + 4096) * i); - end - repeat (5) begin - wait(csr_regwoq_bfoq_wen); - @(posedge clk); - fifo.push_front(csr_regwoq_bfoq_out); - @(posedge clk); - end - join - // push 1 more element after wait - @(posedge clk); - csr_regwoq_bfoq_wready = 0; - fork - mst.write(addr, 24'hAABBCC); - begin - repeat (4) @(posedge clk); - csr_regwoq_bfoq_wready = 1; - @(posedge clk); - if (csr_regwoq_bfoq_wen) - fifo.push_front(csr_regwoq_bfoq_out); - end - join - // pop data and check - for (int i=0; i<5; i++) begin - if (fifo.pop_back() !== ((i + 4096) * i)) - errors++; - end - if (fifo.pop_front() != 24'hAABBCC) - errors++; - $display("%0t, %0d errors", $time, errors); -endtask - -initial begin : main - wait(!rst); - repeat(5) @(posedge clk); - - test_wo_o(); - test_wosc_o(); - test_wo_oq(); - - repeat(5) @(posedge clk); - if (errors) - $display("!@# TEST FAILED - %d ERRORS #@!", errors); - else - $display("!@# TEST PASSED #@!"); - $finish; -end - -initial begin : timeout - #500us; - $display("!@# TEST FAILED - TIMEOUT #@!"); - $finish; -end - -endmodule diff --git a/tests/test_bitfield.py b/tests/test_bitfield.py deleted file mode 100755 index 343a7f0..0000000 --- a/tests/test_bitfield.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Bit field module tests -""" - -from corsair.enum import EnumValue -import pytest -from corsair import BitField -import copy - - -def test_create(): - """Test of a bit field creation.""" - # create with defaults - bf = BitField() - bf.validate() - - # create with non-default values - name = 'ABC' - description = 'abc' - reset = 1 - width = 6 - lsb = 0 - access = 'ro' - hardware = 'i' - bf = BitField(name=name, description=description, reset=reset, width=width, - lsb=lsb, access=access, hardware=hardware) - print(repr(bf)) - print(bf) - assert ((name, description, reset, width, lsb, access, hardware) == - (bf.name, bf.description, bf.reset, bf.width, bf.lsb, bf.access, bf.hardware)) - - -def test_eq(): - """Test of (non)equality comparision of bit fields.""" - bf1 = BitField('bf_a', reset=2) - bf2 = copy.deepcopy(bf1) - assert bf1 == bf2 - bf2.reset = 3 - assert bf1 != bf2 - - -def test_name(): - """Name property""" - # init - bf = BitField(name='abc') - assert bf.name == 'abc' - # set - bf.name = 'cde' - assert bf.name == 'cde' - # set wrong - with pytest.raises(ValueError): - bf.name = 5 - bf.name = '5cde' - with pytest.raises(AssertionError): - bf.validate() - - -def test_description(): - """Description property""" - # init - bf = BitField(description='abc') - assert bf.description == 'abc' - # set - bf.description = 'cde' - assert bf.description == 'cde' - # set wrong - with pytest.raises(ValueError): - bf.description = 5 - - -def test_reset(): - """Reset property""" - # init - bf = BitField(reset=0x5) - assert bf.reset == 0x5 - bf = BitField(reset='0x5') - assert bf.reset == 0x5 - # set - bf.reset = 0x3 - assert bf.reset == 0x3 - bf.reset = '0x6' - assert bf.reset == 0x6 - # set wrong - with pytest.raises(ValueError): - bf.reset = 'zz' - - -def test_lsb(): - """LCB property""" - # init - bf = BitField(lsb=0x5) - assert bf.lsb == 0x5 - bf = BitField(lsb='0x5') - assert bf.lsb == 0x5 - # set - bf.lsb = 0x3 - assert bf.lsb == 0x3 - bf.lsb = '0x6' - assert bf.lsb == 0x6 - # set wrong - with pytest.raises(ValueError): - bf.lsb = 'zz' - - -def test_width(): - """Width property""" - # init - bf = BitField(width=0x5) - assert bf.width == 0x5 - bf = BitField(width='0x5') - assert bf.width == 0x5 - # set - bf.width = 0x3 - assert bf.width == 0x3 - bf.width = '0x6' - assert bf.width == 0x6 - # set wrong - with pytest.raises(ValueError): - bf.width = 'zz' - - -def test_msb(): - """MSB property""" - bf = BitField('bf_a', lsb=2, width=4) - assert bf.msb == 5 - - -def test_access(): - """Access property""" - # init - bf = BitField(access='ro') - assert bf.access == 'ro' - # set - bf.access = 'rw' - assert bf.access == 'rw' - # set wrong - with pytest.raises(ValueError): - bf.access = 5 - bf.access = 'w0' - with pytest.raises(AssertionError): - bf.validate() - - -def test_hardware(): - """Hardware property""" - # init - bf = BitField(hardware='ioq') - assert bf.hardware == 'ioq' - # set - bf.hardware = 'iol' - assert bf.hardware == 'iol' - # set wrong - with pytest.raises(ValueError): - bf.hardware = 'rw' - bf.access = 'rw' - bf.hardware = 'iq' - with pytest.raises(AssertionError): - bf.validate() - - -def test_bits(): - """Test of adding a field with position that overlaps with other field in a register.""" - bf = BitField('bf_a', lsb=5, width=4) - assert bf.bits == [5, 6, 7, 8] - - -def test_byte_strobes(): - """Test byte strobes info of the bit field.""" - bf_a = BitField('bf_a', lsb=0, width=16) - bf_b = BitField('bf_b', lsb=0, width=13) - bf_c = BitField('bf_c', lsb=8, width=16) - bf_d = BitField('bf_d', lsb=14, width=14) - assert bf_a.byte_strobes == {0: {'bf_lsb': 0, 'bf_msb': 7, - 'wdata_lsb': 0, 'wdata_msb': 7}, - 1: {'bf_lsb': 8, 'bf_msb': 15, - 'wdata_lsb': 8, 'wdata_msb': 15}} - assert bf_b.byte_strobes == {0: {'bf_lsb': 0, 'bf_msb': 7, - 'wdata_lsb': 0, 'wdata_msb': 7}, - 1: {'bf_lsb': 8, 'bf_msb': 12, - 'wdata_lsb': 8, 'wdata_msb': 12}} - assert bf_c.byte_strobes == {1: {'bf_lsb': 0, 'bf_msb': 7, - 'wdata_lsb': 8, 'wdata_msb': 15}, - 2: {'bf_lsb': 8, 'bf_msb': 15, - 'wdata_lsb': 16, 'wdata_msb': 23}} - assert bf_d.byte_strobes == {1: {'bf_lsb': 0, 'bf_msb': 1, - 'wdata_lsb': 14, 'wdata_msb': 15}, - 2: {'bf_lsb': 2, 'bf_msb': 9, - 'wdata_lsb': 16, 'wdata_msb': 23}, - 3: {'bf_lsb': 10, 'bf_msb': 13, - 'wdata_lsb': 24, 'wdata_msb': 27}} - - -def test_add_enum(): - """Test of adding enum to a bitfield""" - # single - bf = BitField('bf_a', 'Bit field A') - enum = EnumValue("enum_a", 1, "descr") - bf.add_enums(enum) - assert enum == bf['enum_a'] - assert enum == bf[0] - # multiple - bf = BitField('bf_a', 'Bit field A') - enums = [ - EnumValue('enum_a', 0, 'Enum A'), - EnumValue('enum_b', 1, 'Enum B') - ] - bf.add_enums(enums) - assert enums[0] == bf['enum_a'] - assert enums[0] == bf[0] - assert enums[1] == bf['enum_b'] - assert enums[1] == bf[1] - # wrong access - with pytest.raises(KeyError): - bf['enum_c'] - with pytest.raises(KeyError): - bf[2] - - -def test_enum_name_conflict(): - """Test of adding an enum with a name that already present in a bitfield""" - bf = BitField('bf_a', 'Bit field A') - bf.add_enums(EnumValue('enum_a', 0, 'Enum A')) - with pytest.raises(AssertionError): - bf.add_enums(EnumValue('enum_a', 1, 'Enum B',)) - - -def test_enum_value_conflict(): - """Test of adding an enum with a value that already present in a bitfield""" - bf = BitField('bf_a', 'Bit field A') - bf.add_enums(EnumValue('enum_a', 0, 'Enum A')) - with pytest.raises(AssertionError): - bf.add_enums(EnumValue('enum_b', 0, 'Enum B')) - - -def test_enum_order(): - """Test of adding enums and check that they are presented in ascending order in a bitfield.""" - bf = BitField('bf_a', 'Bit field A', width=8) - bf.add_enums(EnumValue('enum_a', 3, 'Enum A')) - bf.add_enums(EnumValue('enum_b', 0, 'Enum B')) - bf.add_enums(EnumValue('enum_c', 5, 'Enum C')) - bf.add_enums(EnumValue('enum_d', 1, 'Enum D')) - assert bf.enum_names == ['enum_b', 'enum_d', 'enum_a', 'enum_c'] - - -def test_enum_width_conflict(): - """Wait exception when enum value bit length exce exceeds bitfield width.""" - bf = BitField('bf_a', 'Bit field A', width=2) - with pytest.raises(AssertionError): - bf.add_enums(EnumValue('enum_a', 8, 'Enum A')) - - -def test_enum_unique(): - """All enums must be unique""" - # name - bf = BitField('bf_a', 'Bit field A', width=8) - bf.add_enums(EnumValue('enum_a', 3, 'Enum A')) - bf.add_enums(EnumValue('enum_b', 0, 'Enum B')) - bf[1].name = 'enum_b' - with pytest.raises(AssertionError): - bf.validate() - # value - bf = BitField('bf_a', 'Bit field A', width=8) - bf.add_enums(EnumValue('enum_a', 3, 'Enum A',)) - bf.add_enums(EnumValue('enum_b', 0, 'Enum B',)) - bf['enum_b'].value = 3 - with pytest.raises(AssertionError): - bf.validate() - - -def test_custom_props(): - """Add custom properties on creation""" - # init - bf = BitField() - assert bf.etc == {} - bf = BitField(the_answer=42) - assert bf.etc['the_answer'] == 42 - assert bf.as_dict()['the_answer'] == 42 diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100755 index c155007..0000000 --- a/tests/test_config.py +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Configuration module tests. -""" - -import pytest -from corsair import config - - -def test_csrconfig(tmpdir): - cfg_path = str(tmpdir.join('csrconfig')) - globcfg = { - "base_address": 0, - "regmap_path": 'regs.json', - "data_width": 32, - "address_width": 12, - "register_reset": "sync_pos", - "address_increment": "none", - "address_alignment": "data_width", - "force_name_case": "none", - } - targets = { - "target.a": { - "generator": "a", - "param_b": "b", - }, - "target.b": { - "generator": "a", - }, - } - config.write_csrconfig(cfg_path, globcfg, targets) - test_globcfg, test_targets = config.read_csrconfig(cfg_path) - assert test_targets == targets - assert test_globcfg == globcfg diff --git a/tests/test_enum.py b/tests/test_enum.py deleted file mode 100755 index a4aa899..0000000 --- a/tests/test_enum.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Bit field module tests -""" - -import pytest -from corsair import EnumValue -import copy - - -def test_create(): - """Test of a enum creation.""" - # create with defaults - enum = EnumValue() - enum.validate() - - # create with non-default values - name = 'OK' - description = 'Ok' - value = 1 - enum = EnumValue(name=name, description=description, value=value) - print(repr(enum)) - print(enum) - assert ((name, description, value) == (enum.name, enum.description, enum.value)) - - -def test_eq(): - """Test of (non)equality comparision of enums.""" - e1 = EnumValue('AA', value=2) - e2 = copy.deepcopy(e1) - assert e1 == e2 - e2.value = 3 - assert e1 != e2 - - -def test_name(): - """Name property""" - # init - enum = EnumValue(name='abc') - assert enum.name == 'abc' - # set - enum.name = 'cde' - assert enum.name == 'cde' - # set wrong - with pytest.raises(ValueError): - enum.name = 5 - - -def test_description(): - """Description property""" - # init - enum = EnumValue(description='abc') - assert enum.description == 'abc' - # set - enum.description = 'cde' - assert enum.description == 'cde' - # set wrong - with pytest.raises(ValueError): - enum.description = 5 - - -def test_value(): - """Value property""" - # init - enum = EnumValue(value=0x5) - assert enum.value == 0x5 - enum = EnumValue(value='0x5') - assert enum.value == 0x5 - # set - enum.value = 0x3 - assert enum.value == 0x3 - enum.value = '0x6' - assert enum.value == 0x6 - # set wrong - with pytest.raises(ValueError): - enum.value = 'zz' - enum.value = -5 - with pytest.raises(AssertionError): - enum.validate() - - -def test_custom_props(): - """Add custom properties on creation""" - # init - enum = EnumValue() - assert enum.etc == {} - enum = EnumValue(the_answer=42) - assert enum.etc['the_answer'] == 42 - assert enum.as_dict()['the_answer'] == 42 diff --git a/tests/test_examples.py b/tests/test_examples.py deleted file mode 100755 index 05f306b..0000000 --- a/tests/test_examples.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Test of examples. -""" - -import os -import subprocess -import pytest -from pathlib import Path - - -def test_examples(tmpdir): - # prepare examples - res = subprocess.run(["cp", "-R", "examples", str(tmpdir)]) - assert res.returncode == 0 - - # prepare environment - to make sure Makefile will find corsair repo - my_env = os.environ.copy() - if 'PYTHONPATH' not in my_env.keys(): - my_env['PYTHONPATH'] = "" - my_env['PYTHONPATH'] = "%s:%s" % (str(Path(os.getcwd()).absolute()), my_env['PYTHONPATH']) - examples_path = str(tmpdir.join('examples')) - - # clean examples - res = subprocess.run(["make", "-C", examples_path, "clean"], env=my_env) - assert res.returncode == 0 - - # build examples - res = subprocess.run(["make", "-C", examples_path], env=my_env) - assert res.returncode == 0 diff --git a/tests/test_generators.py b/tests/test_generators.py deleted file mode 100755 index 00c07df..0000000 --- a/tests/test_generators.py +++ /dev/null @@ -1,222 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Generators module tests -""" - -import pytest -from corsair import RegisterMap, generators, config, utils - - -class TestJson: - """Class 'generators.Json' testing.""" - - def test_dump(self, tmpdir): - """Test of writing register map to a JSON file""" - output_file = str(tmpdir.join('map_out.json')) - print('output_file:', output_file) - # create regmap - rmap = utils.create_template() - rmap[0].etc['the_answer'] = 42 - # write to file - generators.Json(rmap, output_file).generate() - # read back - rmap_test = RegisterMap() - rmap_test.read_file(output_file) - assert rmap_test == rmap - assert rmap[0].etc['the_answer'] == rmap_test[0].etc['the_answer'] == 42 - - -class TestYaml: - """Class 'generators.Yaml' testing.""" - - def test_dump(self, tmpdir): - """Test of writing register map to a YAML file""" - output_file = str(tmpdir.join('map_out.yaml')) - print('output_file:', output_file) - # create regmap - rmap = utils.create_template() - rmap[0].etc['the_answer'] = 42 - # write to file - generators.Yaml(rmap, output_file).generate() - # read back - rmap_test = RegisterMap() - rmap_test.read_file(output_file) - assert rmap_test == rmap - assert rmap[0].etc['the_answer'] == rmap_test[0].etc['the_answer'] == 42 - - -class TestTxt: - """Class 'generators.Txt' testing.""" - - def test_txt(self, tmpdir): - """Test of writing register map to a txt file""" - # prepare output file - output_file = str(tmpdir.join('map_out.txt')) - print('output_file:', output_file) - # create regmap - rmap = utils.create_template_simple() - # write to file - generators.Txt(rmap, output_file).generate() - # read back - rmap_test = RegisterMap() - rmap_test.read_file(output_file) - assert rmap_test == rmap - - -class TestVerilog: - """Class 'generators.Verilog' testing.""" - - def test_verilog_write(self, tmpdir): - """Test of creating regmap module in Verilog.""" - output_file = str(tmpdir.join('regs.v')) - print('output_file:', output_file) - # create regmap - rmap = utils.create_template() - # write output file - generators.Verilog(rmap, output_file).generate() - # read file and verify - with open(output_file, 'r') as f: - raw_str = ''.join(f.readlines()) - assert 'module regs' in raw_str - assert 'endmodule' in raw_str - - -class TestVhdl: - """Class 'generators.Vhdl' testing.""" - - def test_vhdl_write(self, tmpdir): - """Test of creating regmap module in VHDL.""" - output_file = str(tmpdir.join('regs.vhd')) - print('output_file:', output_file) - # create regmap - rmap = utils.create_template() - # write output file - generators.Vhdl(rmap, output_file).generate() - # read file and verify - with open(output_file, 'r') as f: - raw_str = ''.join(f.readlines()) - assert "if raddr =" in raw_str - assert 'end architecture;' in raw_str - - -class TestVerilogHeader: - """Class 'generators.VerilogHeader' testing.""" - - def test_vheader_write(self, tmpdir): - """Test of creating Verilog header.""" - output_file = str(tmpdir.join('regs.vh')) - print('output_file:', output_file) - # create regmap - rmap = utils.create_template() - # write output file - generators.VerilogHeader(rmap, output_file).generate() - # read file and verify - with open(output_file, 'r') as f: - raw_str = ''.join(f.readlines()) - assert '`define CSR_' in raw_str - - -class TestLbBridgeVerilog: - """Class 'generators.LbBridgeVerilog' testing.""" - - def _test(self, tmpdir, filename, bridge_type, assert_str): - output_file = str(tmpdir.join(filename)) - print('output_file:', output_file) - # write output file - generators.LbBridgeVerilog(path=output_file, bridge_type=bridge_type).generate() - # read file and verify - with open(output_file, 'r') as f: - raw_str = ''.join(f.readlines()) - assert assert_str in raw_str - - def test_apb(self, tmpdir): - """Test of creating APB to LocalBus module in Verilog""" - self._test(tmpdir, 'apb2lb.v', 'apb', 'APB to Local Bus bridge') - - def test_amm(self, tmpdir): - """Test of creating Avalon-MM to LocalBus module in Verilog""" - self._test(tmpdir, 'amm2lb.v', 'amm', 'Avalon-MM to Local Bus bridge') - - def test_axil(self, tmpdir): - """Test of creating AXI-Lite to LocalBus module in Verilog""" - self._test(tmpdir, 'axil2lb.v', 'axil', 'AXI-Lite to Local Bus bridge') - - -class TestLbBridgeVhdl: - """Class 'generators.LbBridgeVhdl' testing.""" - - def _test(self, tmpdir, filename, bridge_type, assert_str): - output_file = str(tmpdir.join(filename)) - print('output_file:', output_file) - # write output file - generators.LbBridgeVhdl(path=output_file, bridge_type=bridge_type).generate() - # read file and verify - with open(output_file, 'r') as f: - raw_str = ''.join(f.readlines()) - assert assert_str in raw_str - - def test_apb(self, tmpdir): - """Test of creating APB to LocalBus module in VHDL""" - self._test(tmpdir, 'apb2lb.vhd', 'apb', 'APB to Local Bus bridge') - - def test_amm(self, tmpdir): - """Test of creating Avalon-MM to LocalBus module in VHDL""" - self._test(tmpdir, 'amm2lb.vhd', 'amm', 'Avalon-MM to Local Bus bridge') - - def test_axil(self, tmpdir): - """Test of creating AXI-Lite to LocalBus module in VHDL""" - self._test(tmpdir, 'axil2lb.vhd', 'axil', 'AXI-Lite to Local Bus bridge') - - -class TestMarkdown: - """Class 'generators.Markdown' testing.""" - - def test_md(self, tmpdir): - """Test of creating markdown regmap file.""" - md_path = str(tmpdir.join('regs.md')) - print('md_path:', md_path) - # create regmap - rmap = utils.create_template() - # write output file - generators.Markdown(rmap, md_path).generate() - # read file and verify - with open(md_path, 'r') as f: - raw_str = ''.join(f.readlines()) - assert '## Register map' in raw_str - assert 'Back to [Register map](#register-map-summary).' in raw_str - - -class TestAsciidoc: - """Class 'generators.Asciidoc' testing.""" - - def test_adoc(self, tmpdir): - """Test of creating asciidoc regmap file.""" - adoc_path = str(tmpdir.join('regs.adoc')) - print('adoc_path:', adoc_path) - # create regmap - rmap = utils.create_template() - # write output file - generators.Asciidoc(rmap, adoc_path).generate() - # read file and verify - with open(adoc_path, 'r') as f: - raw_str = ''.join(f.readlines()) - assert '=== Register map summary' in raw_str - assert 'Back to <>' in raw_str - - -class TestPython: - """Class 'generators.Python' testing.""" - - def test_py(self, tmpdir): - """Test of creating python regmap file.""" - py_path = str(tmpdir.join('regs.py')) - print('py_path:', py_path) - # create regmap - rmap = utils.create_template() - # write output file - generators.Python(rmap, py_path).generate() - # read file and verify - with open(py_path, 'r') as f: - raw_str = ''.join(f.readlines()) - assert 'class RegMap:' in raw_str diff --git a/tests/test_reg.py b/tests/test_reg.py deleted file mode 100755 index 8b246f1..0000000 --- a/tests/test_reg.py +++ /dev/null @@ -1,188 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Register module tests -""" - -import pytest -from corsair import Register, BitField -import copy - - -def test_create(): - """Test of a register creation.""" - # create with defaults - reg = Register() - with pytest.raises(AssertionError): - # address is None by default - reg.validate() - - # create with non-default values - name = 'REGA' - description = 'Register A' - address = 0x4 - bitfields = [ - BitField('BFA', 'Bit field A', lsb=0), - BitField('BFB', 'Bit field B', lsb=1), - BitField('BFC', 'Bit field C', lsb=2) - ] - reg = Register(name, description, address) - reg.add_bitfields(bitfields) - print(repr(reg)) - print(reg) - assert ((name, description, address, bitfields) == - (reg.name, reg.description, reg.address, reg.bitfields)) - - -def test_eq(): - """Test of (non)equality comparision of registes.""" - reg1 = Register('reg_a') - reg1.add_bitfields([ - BitField('bf_a', 'Bit field A', lsb=0), - BitField('bf_b', 'Bit field B', lsb=1) - ]) - reg2 = copy.deepcopy(reg1) - assert reg1 == reg2 - reg2['bf_a'].access = 'wo' - assert reg1 != reg2 - - -def test_name(): - """Name property""" - # init - reg = Register(name='abc', address=0) - assert reg.name == 'abc' - # set - reg.name = 'cde' - assert reg.name == 'cde' - # set wrong - with pytest.raises(ValueError): - reg.name = 5 - reg.name = '5cde' - with pytest.raises(AssertionError): - reg.validate() - - -def test_description(): - """Description property""" - # init - reg = Register(description='abc', address=0) - assert reg.description == 'abc' - # set - reg.description = 'cde' - assert reg.description == 'cde' - # set wrong - with pytest.raises(ValueError): - reg.description = 5 - - -def test_address(): - """Address property""" - # init - reg = Register(address=0x5) - assert reg.address == 0x5 - reg = Register(address='0x5') - assert reg.address == 0x5 - # set - reg.address = 0x3 - assert reg.address == 0x3 - reg.address = '0x6' - assert reg.address == 0x6 - # set wrong - with pytest.raises(ValueError): - reg.address = 'zz' - reg.address = None - with pytest.raises(AssertionError): - reg.validate() - - -def test_add_bitfields(): - """Test of adding field to a register.""" - # single - reg = Register('REGA', 'Register A') - bf = BitField('bf_a', 'Bit field A') - reg.add_bitfields(bf) - assert bf == reg['bf_a'] - assert bf == reg[0] - # multiple - reg = Register('REGA', 'Register A') - bf = [ - BitField('bf_a', 'Bit field A', lsb=0), - BitField('bf_b', 'Bit field B', lsb=1) - ] - reg.add_bitfields(bf) - assert bf[0] == reg['bf_a'] - assert bf[0] == reg[0] - assert bf[1] == reg['bf_b'] - assert bf[1] == reg[1] - - -def test_access_bitfields(): - """Test of trying to get bit field with wrong name/index.""" - reg = Register('REGA', 'Register A') - bf = [ - BitField('bf_a', 'Bit field A', lsb=0), - BitField('bf_b', 'Bit field B', lsb=1) - ] - reg.add_bitfields(bf) - with pytest.raises(KeyError): - reg['bf_c'] - with pytest.raises(KeyError): - reg[3] - - -def test_field_name_conflict(): - """Test of adding a field with a name that already present in a register.""" - reg = Register('REGA', 'Register A') - reg.add_bitfields(BitField('bf_a', 'Bit field A', lsb=0)) - with pytest.raises(AssertionError): - reg.add_bitfields(BitField('bf_a', 'Bit field A', lsb=0)) - - -def test_field_position_conflict(): - """Test of adding a field with position that overlaps with other field in a register.""" - reg = Register('REGA', 'Register A') - reg.add_bitfields(BitField('bf_a', 'Bit field A', lsb=0, width=8)) - reg.add_bitfields(BitField('bf_b', 'Bit field B', lsb=8, width=8)) - with pytest.raises(AssertionError): - reg.add_bitfields(BitField('bf_c', 'Bit field C', lsb=4, width=10)) - - -def test_field_order(): - """Test of adding fields and check that they are presented in ascending order in a register.""" - reg = Register('REGA', 'Register A') - reg.add_bitfields(BitField('bf_a', 'Bit field A', lsb=0, width=3)) - reg.add_bitfields(BitField('bf_b', 'Bit field B', lsb=16, width=1)) - reg.add_bitfields(BitField('bf_c', 'Bit field C', lsb=5, width=6)) - reg.add_bitfields(BitField('bf_d', 'Bit field D', lsb=18, width=12)) - assert reg.bitfield_names == ['bf_a', 'bf_c', 'bf_b', 'bf_d'] - - -def test_field_datawidth_conflict(): - """Wait exception when bf.msb value exceeds data width.""" - reg = Register('reg_a', 'Register A', 0x4) - with pytest.raises(AssertionError): - reg.add_bitfields([ - BitField('bf_a', 'Bit field A', lsb=0, width=35), - ]) - - -def test_bitfields_unique(): - """All bitfields must have unique names""" - # name - reg = Register('reg_a', 'Register A') - reg.add_bitfields(BitField('bf_a', 'Bit field A', lsb=0, width=3)) - reg.add_bitfields(BitField('bf_b', 'Bit field B', lsb=16, width=1)) - reg[1].name = 'bf_a' - with pytest.raises(AssertionError): - reg.validate() - - -def test_custom_props(): - """Add custom properties on creation""" - # init - reg = Register() - assert reg.etc == {} - reg = Register(the_answer=42) - assert reg.etc['the_answer'] == 42 - assert reg.as_dict()['the_answer'] == 42 diff --git a/tests/test_regmap.py b/tests/test_regmap.py deleted file mode 100755 index 9f8fd50..0000000 --- a/tests/test_regmap.py +++ /dev/null @@ -1,192 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- - -"""Register map module tests -""" - -import pytest -from corsair import config, Register, BitField, RegisterMap -import copy - - -def test_create(): - """Test of a register map creation.""" - name = 'reg_a' - description = 'Register A' - address = 0x4 - reg = Register(name, description, address) - reg.add_bitfields([ - BitField('bf_a', 'Bit field A', lsb=0), - BitField('bf_b', 'Bit field B', lsb=1) - ]) - rmap = RegisterMap() - rmap.add_registers(reg) - print(repr(rmap)) - print(rmap) - assert rmap['reg_a'] == reg - - -def test_eq(): - """Test of equality comparision of register maps.""" - reg = Register('reg_a', 'Register A', 0x4) - reg.add_bitfields([ - BitField('bf_a', 'Bit field A', lsb=0), - BitField('bf_b', 'Bit field B', lsb=1) - ]) - rmap1 = RegisterMap() - rmap1.add_registers(reg) - rmap2 = copy.deepcopy(rmap1) - assert rmap1 == rmap2 - - -def test_ne(): - """Test of non equality comparision of register maps.""" - reg = Register('reg_a', 'Register A', 0x4) - reg.add_bitfields([ - BitField('bf_a', 'Bit field A', lsb=0), - BitField('bf_b', 'Bit field B', lsb=1) - ]) - rmap1 = RegisterMap() - rmap1.add_registers(reg) - rmap2 = copy.deepcopy(rmap1) - rmap2['reg_a']['bf_b'].reset = 1 - assert rmap1 != rmap2 - - -def test_add_registers(): - """Test of adding several registers to a map""" - reg_a = Register('reg_a', 'Register A', 0x8) - reg_b = Register('reg_b', 'Register B', 0xC) - rmap = RegisterMap() - rmap.add_registers([reg_a, reg_b]) - assert rmap[0] == reg_a - assert rmap['reg_a'] == reg_a - assert rmap[1] == reg_b - assert rmap['reg_b'] == reg_b - - -def test_reg_name_conflict(): - """Test of adding register with a name that already present in a map.""" - rmap = RegisterMap() - rmap.add_registers(Register('reg_a', 'Register A', 0x8)) - with pytest.raises(AssertionError): - rmap.add_registers(Register('reg_a', 'Register A copypaste', 0x8)) - - -def test_reg_no_addr_first(): - """Test of adding first register with no address to a map""" - rmap = RegisterMap() - with pytest.raises(AssertionError): - rmap.add_registers(Register('reg_a', 'Register A')) - - -def test_reg_no_addr_no_incr(): - """Test of adding register with no address to a map when address auto increment is deisabled.""" - rmap = RegisterMap() - rmap.add_registers(Register('reg_a', 'Register A', 0x0)) - with pytest.raises(AssertionError): - rmap.add_registers(Register('reg_b', 'Register B')) - - -def test_reg_addr_align_data_width(): - """Test of adding register with address not aligned to a proper value (based on a data width).""" - globcfg = config.default_globcfg() - globcfg['address_alignment'] = 'data_width' - globcfg['data_width'] = 32 - config.set_globcfg(globcfg) - rmap = RegisterMap() - with pytest.raises(AssertionError): - rmap.add_registers(Register('reg_a', 'Register A', 0x2)) - config.set_globcfg(config.default_globcfg()) - - -def test_reg_addr_align_custom(): - """Test of adding register with address not aligned to a proper value (based on a custom value).""" - globcfg = config.default_globcfg() - globcfg['address_alignment'] = 128 - config.set_globcfg(globcfg) - rmap = RegisterMap() - with pytest.raises(AssertionError): - rmap.add_registers(Register('reg_a', 'Register A', 0x4)) - config.set_globcfg(config.default_globcfg()) - - -def test_reg_addr_align_none(): - """Test of adding register with address not aligned to a proper value (based on a custom value).""" - globcfg = config.default_globcfg() - globcfg['address_alignment'] = 'none' - globcfg['data_width'] = 32 - config.set_globcfg(globcfg) - rmap = RegisterMap() - # no exception - rmap.add_registers(Register('reg_a', 'Register A', 0x2)) - config.set_globcfg(config.default_globcfg()) - - -def test_reg_addr_conflict(): - """Test of adding register with an address that already present in a map.""" - rmap = RegisterMap() - rmap.add_registers(Register('reg_a', 'Register A', 0x0)) - with pytest.raises(AssertionError): - rmap.add_registers(Register('reg_b', 'Register B', 0x0)) - - -def test_reg_addr_order(): - """Test of adding registers and check that they are presented in ascending order in a map.""" - rmap = RegisterMap() - rmap.add_registers(Register('reg_a', 'Register A', 0x0)) - rmap.add_registers(Register('reg_b', 'Register B', 0x10)) - rmap.add_registers(Register('reg_c', 'Register C', 0x4)) - rmap.add_registers(Register('reg_d', 'Register D', 0x14)) - assert rmap.reg_names == ['reg_a', 'reg_c', 'reg_b', 'reg_d'] - - -def test_reg_addr_auto_incr_data_width(): - """Test of auto increment of a register's address based on interface data width.""" - globcfg = config.default_globcfg() - globcfg['address_increment'] = 'data_width' - globcfg['data_width'] = 64 - config.set_globcfg(globcfg) - rmap = RegisterMap() - rmap.add_registers(Register('reg_a', 'Register A', 0x0)) - rmap.add_registers(Register('reg_b', 'Register B')) - assert rmap['reg_b'].address == 0x8 - config.set_globcfg(config.default_globcfg()) - - -def test_reg_addr_auto_incr_custom(): - """Test of auto increment of a register's address.""" - globcfg = config.default_globcfg() - globcfg['address_alignment'] = 'none' - globcfg['address_increment'] = 0x2 - config.set_globcfg(globcfg) - rmap = RegisterMap() - rmap.add_registers(Register('reg_a', 'Register A', 0x0)) - rmap.add_registers(Register('reg_b', 'Register B')) - assert rmap['reg_b'].address == 0x2 - config.set_globcfg(config.default_globcfg()) - - -def test_reg_addr_auto_incr_align(): - """Test of alignment check of an auto incremented register's address.""" - globcfg = config.default_globcfg() - globcfg['address_alignment'] = 0x4 - globcfg['address_increment'] = 0x2 - config.set_globcfg(globcfg) - rmap = RegisterMap() - rmap.add_registers(Register('reg_a', 'Register A', 0x0)) - with pytest.raises(AssertionError): - rmap.add_registers(Register('reg_b', 'Register B')) - config.set_globcfg(config.default_globcfg()) - - -def test_reg_unique(): - """All registers must have unique names""" - rmap = RegisterMap() - rmap.add_registers([ - Register('rega', 'Register A', 0x0), - Register('regb', 'Register B', 0x4), - ]) - rmap[1].name = 'rega' - with pytest.raises(AssertionError): - rmap.validate()