Skip to content

Commit f40994a

Browse files
committed
Export more useful data
1 parent 658589d commit f40994a

File tree

6 files changed

+95
-40
lines changed

6 files changed

+95
-40
lines changed

chipflow_digital_ip/base/_platform_timer.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,30 +7,39 @@
77

88
__all__ = ["PlatformTimer"]
99

10+
# Some deep weirness going on, putting docstrings in the normal location
11+
# doesn't work with subclasses of csr.Register. I have no idea why!!!
12+
#
13+
class CNT(csr.Register, access="r"):
14+
"""
15+
Cycle counter (read-only).
16+
"""
17+
def __init__(self, width):
18+
super().__init__({"val": csr.Field(csr.action.R, unsigned(width))})
1019

11-
class PlatformTimer(wiring.Component):
12-
class CNT(csr.Register, access="r"):
13-
"""Cycle counter (read-only)."""
14-
def __init__(self, width):
15-
super().__init__({"val": csr.Field(csr.action.R, unsigned(width))})
1620

17-
class CMP(csr.Register, access="rw"):
18-
"""Comparator (read/write).
21+
class CMP(csr.Register, access="rw"):
22+
"""
23+
Comparator (read/write).
24+
25+
If set to a non-zero value, an interrupt is triggered when CNT is greater than or equal
26+
to CMP.
27+
"""
28+
def __init__(self, width):
29+
super().__init__({"val": csr.Field(csr.action.RW, unsigned(width))})
1930

20-
If set to a non-zero value, an interrupt is triggered when CNT is greater than or equal
21-
to CMP.
22-
"""
23-
def __init__(self, width):
24-
super().__init__({"val": csr.Field(csr.action.RW, unsigned(width))})
2531

26-
"""Platform timer peripheral."""
32+
class PlatformTimer(wiring.Component):
33+
"""
34+
Simple timer that counts clock cycles and raises an interrupt when the count hits a configured threshold
35+
"""
2736
def __init__(self):
2837
self.width = 48
2938

3039
regs = csr.Builder(addr_width=4, data_width=8)
3140

32-
self._cnt = regs.add("cnt", self.CNT(self.width), offset=0x0)
33-
self._cmp = regs.add("cmp", self.CMP(self.width), offset=0x8)
41+
self._cnt = regs.add("cnt", CNT(self.width), offset=0x0)
42+
self._cmp = regs.add("cmp", CMP(self.width), offset=0x8)
3443

3544
self._bridge = csr.Bridge(regs.as_memory_map())
3645

chipflow_digital_ip/io/_gpio.py

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,6 @@
1010

1111

1212
class GPIOPeripheral(wiring.Component):
13-
14-
class Signature(wiring.Signature):
15-
def __init__(self, pin_count=1):
16-
if pin_count > 32:
17-
raise ValueError(f"Pin pin_count must be lesser than or equal to 32, not {pin_count}")
18-
self._pin_count = pin_count
19-
super().__init__({
20-
"gpio": Out(BidirIOSignature(pin_count, all_have_oe=True))
21-
})
22-
23-
@property
24-
def pin_count(self):
25-
return self._pin_count
26-
2713
"""Wrapper for amaranth_soc gpio with chipflow_lib.IOSignature support
2814
2915
Parameters
@@ -55,7 +41,23 @@ def pin_count(self):
5541
If ``input_stages`` is not a non-negative integer.
5642
"""
5743

58-
def __init__(self, *, pin_count, addr_width=4, data_width=8, input_stages=2):
44+
class Signature(wiring.Signature):
45+
"""
46+
Signature of the gpio port wiring
47+
"""
48+
def __init__(self, pin_count=1):
49+
if pin_count > 32:
50+
raise ValueError(f"Pin pin_count must be lesser than or equal to 32, not {pin_count}")
51+
self._pin_count = pin_count
52+
super().__init__({
53+
"gpio": Out(BidirIOSignature(pin_count, all_have_oe=True))
54+
})
55+
56+
@property
57+
def pin_count(self):
58+
return self._pin_count
59+
60+
def __init__(self, *, pin_count=8, addr_width=4, data_width=8, input_stages=2):
5961
self._gpio = gpio.Peripheral(pin_count=pin_count,
6062
addr_width=addr_width,
6163
data_width=data_width,

chipflow_digital_ip/memory/_qspi_flash.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -256,7 +256,7 @@ def __init__(self):
256256
"d": Out(BidirIOSignature(4, all_have_oe=True)),
257257
})
258258

259-
def __init__(self, *, addr_width, data_width):
259+
def __init__(self, *, addr_width=24, data_width=32):
260260
super().__init__({
261261
"pins": Out(self.Signature()),
262262
"csr_bus": In(csr.Signature(addr_width=4, data_width=8)),

chipflow_digital_ip/memory/_sram.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ class SRAMPeripheral(wiring.Component):
5353
Wishbone bus interface.
5454
"""
5555
# TODO raise bus.err if read-only and a bus write is attempted.
56-
def __init__(self, *, size, data_width=32, granularity=8, writable=True):
56+
def __init__(self, *, size=1024, data_width=32, granularity=8, writable=True):
5757
if not isinstance(size, int) or size <= 0 or size & size-1:
5858
raise ValueError("Size must be an integer power of two, not {!r}"
5959
.format(size))

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ requires-python = ">=3.11"
1717
dependencies = [
1818
"amaranth>=0.5,<0.6",
1919
"chipflow-lib @ git+https://github.com/ChipFlow/chipflow-lib.git",
20-
"amaranth-soc @ git+https://github.com/amaranth-lang/amaranth-soc",
20+
"amaranth-soc @ git+https://github.com/ChipFlow/amaranth-soc.git",
2121
"amaranth-stdio @ git+https://github.com/amaranth-lang/amaranth-stdio",
2222
]
2323

tools/export_ips.py

Lines changed: 51 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,10 @@
44
import sys
55

66
from amaranth.lib import wiring
7+
from amaranth_soc.memory import MemoryMap
78
from docstring_parser import parse_from_object
89

10+
911
import chipflow_digital_ip
1012

1113
def children(mod):
@@ -23,16 +25,58 @@ def children(mod):
2325
done.append(e)
2426
stack.extend([(f"{e}.{attr}", getattr(o, attr)) for attr in dir(o) if not attr.startswith("_")])
2527

28+
def name_to_str(n: MemoryMap.Name) -> str:
29+
return ".".join(f"{part}" for part in n)
30+
31+
def docs_for_obj(obj) -> dict:
32+
docstring = parse_from_object(obj)
33+
#init_signature = inspect.signature(cls.__init__)
34+
#print(f"{name} Signature:i {init_signature}")
35+
d = {}
36+
if docstring.short_description:
37+
d['short_description'] = docstring.short_description
38+
if docstring.long_description:
39+
d['long_description'] = docstring.long_description
40+
if docstring.params:
41+
d['params'] = [p.__dict__ for p in docstring.params if p.args[0]=="param"]
42+
d['attributes'] = [p.__dict__ for p in docstring.params if p.args[0]=="attribute"]
43+
if docstring.raises:
44+
d['raises'] = [p.__dict__ for p in docstring.raises]
45+
if docstring.examples:
46+
d['examples'] = [ e.__dict__ for e in docstring.examples]
47+
return d
48+
49+
50+
def list_resources(mm: MemoryMap) -> dict:
51+
d = {}
52+
for resource, rname, _ in mm.resources():
53+
cls = resource.__class__
54+
print(f"adding resource {resource}. {type(resource)} {cls.__name__}, {cls.__qualname__}, {cls.__doc__}")
55+
ri = mm.find_resource(resource)
56+
d[name_to_str(rname)] = {
57+
'resource': docs_for_obj(resource),
58+
'start': f"{ri.start:#x}",
59+
'end': f"{ri.end:#x}",
60+
'width': ri.width,
61+
}
62+
for window, wname, (start, end, ratio) in mm.windows():
63+
d[name_to_str(wname)] = {
64+
'window': docs_for_obj(window),
65+
'start': f"{start:#x}",
66+
'end': f"{end:#x}",
67+
'ratio': ratio,
68+
'children': list_resources(window)
69+
}
70+
return d
71+
2672
gen = children(chipflow_digital_ip)
2773
output={}
2874
for name, cls in gen:
29-
docstring = parse_from_object(cls)
30-
d = {
31-
'short_description': docstring.short_description,
32-
'long_description': docstring.long_description,
33-
'params': [p.__dict__ for p in docstring.params],
34-
'examples': [ e.__dict__ for e in docstring.examples],
35-
}
75+
# instantiate and get registers
76+
obj = cls()
77+
d = docs_for_obj(obj)
78+
if hasattr(obj, 'bus') and hasattr(obj.bus, 'memory_map') and isinstance(obj.bus.memory_map, MemoryMap):
79+
d['memory_map'] = list_resources(obj.bus.memory_map)
3680
output[name] = d
3781

3882
json.dump(output, sys.stdout, indent=2)

0 commit comments

Comments
 (0)