/
bus.py
107 lines (88 loc) · 3.28 KB
/
bus.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
"""
CSR bus to attach things to stuff.
"""
from nmigen import *
from nmigen_soc.csr import Decoder
from nmigen_soc.csr.bus import Multiplexer, Element, Decoder
from .base import Peripheral, PeripheralBridge
from ...logger import logger
log = logger(__name__)
class RegMap:
"""mapping of the registers"""
# TODO export in various formats
def __init__(self):
log.debug("Create Register Map")
self._children = {}
def _add_sub(self, name_list, value):
front = name_list.pop(0)
log.debug("%s %d", name_list, value)
if len(name_list) == 0:
setattr(self, front, value)
self._children[front] = value
else:
if front not in self._children:
sub_reg = RegMap()
self._children[front] = sub_reg
setattr(self, front, sub_reg)
sub_reg._add_sub(name_list, value)
else:
sub_reg = self._children[front]
sub_reg._add_sub(name_list, value)
def show(self, leader=[]):
for i in self._children:
leader.append(i)
lower = self._children[i]
if isinstance(lower, RegMap):
lower.show(leader)
elif isinstance(lower, int):
print(".".join(leader), lower)
leader.pop()
class PeripheralCollection(Elaboratable):
"""Collection of peripherals to attach to a BonelessCPU"""
def __init__(self, addr_width=16, data_width=16):
log.debug("Create Peripheral Collection")
self._decoder = Decoder(addr_width=addr_width, data_width=data_width)
self.data_width = data_width
self.mem = self._decoder.bus.memory_map
self.devices = []
self.map = RegMap()
self.bus = self._decoder
self._built = False
def add(self, item):
self.devices.append(item)
def build(self):
if not self._built:
log.debug("Building Peripheral Collection")
# bind and add the bus if the device does not have one
# TODO this makes a double decoder
# rip it out for a single bridge
for i in self.devices:
try:
self._decoder.add(i.bus)
except NotImplementedError as e:
i._bridge = i.bridge(data_width=self.data_width)
i.bus = i._bridge.bus
self._decoder.add(i.bus)
# map all the CSR devices
for i, (start, end, width) in self.mem.all_resources():
length = end - start
if length > 1:
for j in range(length):
split_name = i.name.split("_")
last = split_name.pop()
last += "_" + str(j)
split_name.append(last)
self.map._add_sub(split_name, start + j)
else:
self.map._add_sub(i.name.split("_"), start)
self._built = True
def show(self):
self.build()
return self.map
def elaborate(self, platform):
self.build()
m = Module()
m.submodules.bus = self._decoder
for i in self.devices:
m.submodules[i.name] = i
return m