blob: dbcb297e2679e0c074ad6e2cc72e284e8618e4eb [file] [log] [blame]
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
from typing import Sequence
from reggen.access import JsonEnum
from reggen.bits import Bits
from reggen.lib import check_keys, check_name, check_str, check_int, check_bool, check_list
from reggen.signal import Signal
class IntrType(JsonEnum):
Event = 1
Status = 2
_intr_type_map = {'event': IntrType.Event, 'status': IntrType.Status}
class Interrupt(Signal):
def __init__(self, name: str, desc: str, bits: Bits, auto_split: bool, intr_type: IntrType):
super().__init__(name, desc, bits)
self.intr_type = intr_type
self.auto_split = auto_split
@staticmethod
def from_raw(what: str, lsb: int, raw: object) -> 'Interrupt':
rd = check_keys(raw, what, ['name', 'desc'], ['width', 'type', 'auto_split'])
name = check_name(rd['name'], 'name field of ' + what)
desc = check_str(rd['desc'], 'desc field of ' + what)
width = check_int(rd.get('width', 1), 'width field of ' + what)
if width <= 0:
raise ValueError('The width field of signal {} ({}) '
'has value {}, but should be positive.'.format(
name, what, width))
bits = Bits(lsb + width - 1, lsb)
intr_type_str = check_str(rd.get('type', 'event'),
'intr_type field of ' + what)
auto_split = check_bool(rd.get('auto_split', False), 'auto_split of ' + what)
try:
intr_type = _intr_type_map[intr_type_str.lower()]
except KeyError:
raise ValueError(
'The intr_type field of signal {} ({}) '
'has value {}, but should be either event or status.'.format(
name, what, intr_type_str))
return Interrupt(name, desc, bits, auto_split, intr_type,)
@staticmethod
def from_raw_list(what: str, raw: object) -> Sequence['Interrupt']:
lsb = 0
ret = []
for idx, entry in enumerate(check_list(raw, what)):
entry_what = 'entry {} of {}'.format(idx, what)
interrupt = Interrupt.from_raw(entry_what, lsb, entry)
ret.append(interrupt)
lsb += interrupt.bits.width()
return ret