decoder compiles
This commit is contained in:
@@ -1,17 +1,16 @@
|
||||
import re
|
||||
from re import Match
|
||||
from typing import overload
|
||||
|
||||
from systemrdl.node import AddrmapNode, Node
|
||||
from systemrdl.rdltypes.references import PropertyReference
|
||||
|
||||
from .identifier_filter import kw_filter as kwf
|
||||
from .sv_int import SVInt
|
||||
|
||||
|
||||
def get_indexed_path(top_node: Node, target_node: Node) -> str:
|
||||
def get_indexed_path(top_node: Node, target_node: Node, indexer: str = "i") -> str:
|
||||
"""
|
||||
TODO: Add words about indexing and why i'm doing this. Copy from logbook
|
||||
Get the relative path from top_node to target_node, replacing any unknown
|
||||
array indexes with incrementing iterators (i0, i1, ...).
|
||||
"""
|
||||
path = target_node.get_rel_path(top_node, empty_array_suffix="[!]")
|
||||
|
||||
@@ -21,7 +20,7 @@ def get_indexed_path(top_node: Node, target_node: Node) -> str:
|
||||
self.i = 0
|
||||
|
||||
def __call__(self, match: Match[str]) -> str:
|
||||
s = f"i{self.i}"
|
||||
s = f"{indexer}{self.i}"
|
||||
self.i += 1
|
||||
return s
|
||||
|
||||
@@ -54,13 +53,10 @@ def ref_is_internal(top_node: AddrmapNode, ref: Node | PropertyReference) -> boo
|
||||
|
||||
For the sake of this exporter, root signals are treated as internal.
|
||||
"""
|
||||
# current_node: Optional[Node]
|
||||
if isinstance(ref, Node):
|
||||
current_node = ref
|
||||
elif isinstance(ref, PropertyReference):
|
||||
if isinstance(ref, PropertyReference):
|
||||
current_node = ref.node
|
||||
else:
|
||||
raise RuntimeError
|
||||
current_node = ref
|
||||
|
||||
while current_node is not None:
|
||||
if current_node == top_node:
|
||||
@@ -77,46 +73,3 @@ def ref_is_internal(top_node: AddrmapNode, ref: Node | PropertyReference) -> boo
|
||||
# A root signal was referenced, which dodged the top addrmap
|
||||
# This is considered internal for this exporter
|
||||
return True
|
||||
|
||||
|
||||
@overload
|
||||
def do_slice(value: SVInt, high: int, low: int) -> SVInt: ...
|
||||
@overload
|
||||
def do_slice(value: str, high: int, low: int) -> str: ...
|
||||
def do_slice(value: SVInt | str, high: int, low: int) -> SVInt | str:
|
||||
if isinstance(value, str):
|
||||
# If string, assume this is an identifier. Append bit-slice
|
||||
if high == low:
|
||||
return f"{value}[{low}]"
|
||||
else:
|
||||
return f"{value}[{high}:{low}]"
|
||||
else:
|
||||
# it is an SVInt literal. Slice it down
|
||||
mask = (1 << (high + 1)) - 1
|
||||
v = (value.value & mask) >> low
|
||||
|
||||
if value.width is not None:
|
||||
w = high - low + 1
|
||||
else:
|
||||
w = None
|
||||
|
||||
return SVInt(v, w)
|
||||
|
||||
|
||||
@overload
|
||||
def do_bitswap(value: SVInt) -> SVInt: ...
|
||||
@overload
|
||||
def do_bitswap(value: str) -> str: ...
|
||||
def do_bitswap(value: SVInt | str) -> SVInt | str:
|
||||
if isinstance(value, str):
|
||||
# If string, assume this is an identifier. Wrap in a streaming operator
|
||||
return "{<<{" + value + "}}"
|
||||
else:
|
||||
# it is an SVInt literal. bitswap it
|
||||
assert value.width is not None # width must be known!
|
||||
v = value.value
|
||||
vswap = 0
|
||||
for _ in range(value.width):
|
||||
vswap = (vswap << 1) + (v & 1)
|
||||
v >>= 1
|
||||
return SVInt(vswap, value.width)
|
||||
|
||||
Reference in New Issue
Block a user