[CSR] adding virtual csr registers
This commit is contained in:
parent
6653ef7e7c
commit
7239212729
@ -41,6 +41,11 @@ class CSR:
|
||||
All Control and Status Registers are stored here
|
||||
"""
|
||||
|
||||
virtual_regs: Dict[int, Callable[[], int]]
|
||||
"""
|
||||
list of virtual CSR registers, with values computed on read
|
||||
"""
|
||||
|
||||
name_to_addr: Dict[str, int] = {
|
||||
'mstatus': 0x300,
|
||||
'misa': 0x301,
|
||||
@ -56,7 +61,9 @@ class CSR:
|
||||
'mhartid': 0xF14,
|
||||
'time': 0xc01,
|
||||
'timeh': 0xc81,
|
||||
'halt': 0x789
|
||||
'halt': 0x789,
|
||||
'mtimecmp': 0x780,
|
||||
'mtimecmph': 0x781,
|
||||
}
|
||||
"""
|
||||
Translation for named registers
|
||||
@ -67,6 +74,7 @@ class CSR:
|
||||
def __init__(self):
|
||||
self.regs = defaultdict(lambda: 0)
|
||||
self.listeners = defaultdict(lambda: (lambda x, y: None))
|
||||
#TODO: implement write masks (bitmasks which control writeable bits in registers
|
||||
|
||||
def set(self, addr: Union[str, int], val: int):
|
||||
addr = self._addr_to_name(addr)
|
||||
@ -75,15 +83,18 @@ class CSR:
|
||||
self.listeners[addr](self.regs[addr], val)
|
||||
self.regs[addr] = val
|
||||
|
||||
def get(self, addr: Union[str, int]):
|
||||
def get(self, addr: Union[str, int]) -> int:
|
||||
addr = self._addr_to_name(addr)
|
||||
if addr is None:
|
||||
return
|
||||
if addr in self.virtual_regs:
|
||||
return self.virtual_regs[addr]()
|
||||
return self.regs[addr]
|
||||
|
||||
def set_listener(self, addr: Union[str, int], listener: Callable[[int, int], None]):
|
||||
addr = self._addr_to_name(addr)
|
||||
if addr is None:
|
||||
print("unknown csr address name: {}".format(addr))
|
||||
return
|
||||
self.listeners[addr] = listener
|
||||
|
||||
@ -107,7 +118,7 @@ class CSR:
|
||||
new_val = erased | (val << off)
|
||||
self.set('mstatus', new_val)
|
||||
|
||||
def get_mstatus(self, name):
|
||||
def get_mstatus(self, name) -> int:
|
||||
size = 2 if name in MSTATUS_LEN_2 else 1
|
||||
off = MSTATUS_OFFSETS[name]
|
||||
mask = (2**size - 1) << off
|
||||
@ -134,3 +145,14 @@ class CSR:
|
||||
return None
|
||||
return self.name_to_addr[addr]
|
||||
return addr
|
||||
|
||||
def virtual_register(self, addr: Union[str, int]):
|
||||
addr = self._addr_to_name(addr)
|
||||
if addr is None:
|
||||
print("unknown csr address name: {}".format(addr))
|
||||
|
||||
def inner(func: Callable[[], int]):
|
||||
self.virtual_regs[addr] = func
|
||||
return func
|
||||
|
||||
return inner
|
||||
|
Loading…
Reference in New Issue
Block a user