Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 12 commits
  • 8 files changed
  • 0 comments
  • 1 contributor
44  migen/bank/csrgen.py
@@ -84,3 +84,47 @@ def get_fragment(self):
84 84
 							sync.append(If(field.we, field.storage.eq(field.w)))
85 85
 		
86 86
 		return Fragment(comb, sync)
  87
+
  88
+# address_map(name, memory) returns the CSR offset at which to map
  89
+# the CSR object (register bank or memory).
  90
+# If memory=None, the object is the register bank of object source.name.
  91
+# Otherwise, it is a memory object belonging to source.name.
  92
+# address_map is called exactly once for each object at each call to
  93
+# scan(), so it can have side effects.
  94
+class BankArray:
  95
+	def __init__(self, source, address_map):
  96
+		self.source = source
  97
+		self.address_map = address_map
  98
+		self.scan()
  99
+
  100
+	def scan(self):
  101
+		self.banks = []
  102
+		self.srams = []
  103
+		for name, obj in self.source.__dict__.items():
  104
+			if hasattr(obj, "get_registers"):
  105
+				registers = obj.get_registers()
  106
+			else:
  107
+				registers = []
  108
+			if hasattr(obj, "get_memories"):
  109
+				memories = obj.get_memories()
  110
+				for memory in memories:
  111
+					mapaddr = self.address_map(name, memory)
  112
+					mmap = csr.SRAM(memory, mapaddr)
  113
+					registers += mmap.get_registers()
  114
+					self.srams.append(mmap)
  115
+			if registers:
  116
+				mapaddr = self.address_map(name, None)
  117
+				rmap = Bank(registers, mapaddr)
  118
+				self.banks.append(rmap)
  119
+
  120
+	def get_banks(self):
  121
+		return self.banks
  122
+
  123
+	def get_srams(self):
  124
+		return self.srams
  125
+
  126
+	def get_buses(self):
  127
+		return [i.bus for i in self.banks + self.srams]
  128
+
  129
+	def get_fragment(self):
  130
+		return sum([i.get_fragment() for i in self.banks + self.srams], Fragment())
55  migen/bank/description.py
... ...
@@ -1,17 +1,14 @@
1  
-from migen.fhdl.structure import *
  1
+from copy import copy
2 2
 
3  
-def regprefix(prefix, registers):
4  
-	for register in registers:
5  
-		register.name = prefix + register.name
6  
-	return registers
  3
+from migen.fhdl.structure import *
  4
+from migen.fhdl.specials import Memory
7 5
 
8  
-def memprefix(prefix, memories):
9  
-	for memory in memories:
10  
-		memory.name_override = prefix + memory.name_override
11  
-	return memories
  6
+class Register(HUID):
  7
+	pass
12 8
 
13  
-class RegisterRaw:
  9
+class RegisterRaw(Register):
14 10
 	def __init__(self, name, size=1):
  11
+		Register.__init__(self)
15 12
 		self.name = name
16 13
 		self.size = size
17 14
 		self.re = Signal()
@@ -37,8 +34,9 @@ def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, re
37 34
 				self.w = Signal(self.size)
38 35
 				self.we = Signal()
39 36
 
40  
-class RegisterFields:
  37
+class RegisterFields(Register):
41 38
 	def __init__(self, name, fields):
  39
+		Register.__init__(self)
42 40
 		self.name = name
43 41
 		self.fields = fields
44 42
 
@@ -47,6 +45,41 @@ def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, re
47 45
 		self.field = Field(name, size, access_bus, access_dev, reset, atomic_write)
48 46
 		RegisterFields.__init__(self, name, [self.field])
49 47
 
  48
+def regprefix(prefix, registers):
  49
+	r = []
  50
+	for register in registers:
  51
+		c = copy(register)
  52
+		c.name = prefix + c.name
  53
+		r.append(c)
  54
+	return r
  55
+
  56
+def memprefix(prefix, memories):
  57
+	r = []
  58
+	for memory in memories:
  59
+		c = copy(memory)
  60
+		c.name_override = prefix + c.name_override
  61
+		r.append(c)
  62
+	return memories
  63
+
  64
+class AutoReg:
  65
+	def get_memories(self):
  66
+		r = []
  67
+		for k, v in self.__dict__.items():
  68
+			if isinstance(v, Memory):
  69
+				r.append(v)
  70
+			elif hasattr(v, "get_memories") and callable(v.get_memories):
  71
+				r += memprefix(k + "_", v.get_memories())
  72
+		return sorted(r, key=lambda x: x.huid)
  73
+
  74
+	def get_registers(self):
  75
+		r = []
  76
+		for k, v in self.__dict__.items():
  77
+			if isinstance(v, Register):
  78
+				r.append(v)
  79
+			elif hasattr(v, "get_registers") and callable(v.get_registers):
  80
+				r += regprefix(k + "_", v.get_registers())
  81
+		return sorted(r, key=lambda x: x.huid)
  82
+
50 83
 (ALIAS_NON_ATOMIC, ALIAS_ATOMIC_HOLD, ALIAS_ATOMIC_COMMIT) = range(3)
51 84
 
52 85
 class FieldAlias:
49  migen/bank/eventmanager.py
... ...
@@ -1,9 +1,11 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.module import Module
2 3
 from migen.bank.description import *
3 4
 from migen.genlib.misc import optree
4 5
 
5  
-class EventSource:
  6
+class EventSource(HUID):
6 7
 	def __init__(self):
  8
+		HUID.__init__(self)
7 9
 		self.trigger = Signal()
8 10
 		self.pending = Signal()
9 11
 
@@ -13,52 +15,51 @@ class EventSourcePulse(EventSource):
13 15
 class EventSourceLevel(EventSource):
14 16
 	pass
15 17
 
16  
-class EventManager:
17  
-	def __init__(self, *sources):
18  
-		self.sources = sources
  18
+class EventManager(Module, AutoReg):
  19
+	def __init__(self):
19 20
 		self.irq = Signal()
20  
-		n = len(self.sources)
  21
+	
  22
+	def do_finalize(self):
  23
+		sources_u = [v for v in self.__dict__.values() if isinstance(v, EventSource)]
  24
+		sources = sorted(sources_u, key=lambda x: x.huid)
  25
+		n = len(sources)
21 26
 		self.status = RegisterRaw("status", n)
22 27
 		self.pending = RegisterRaw("pending", n)
23 28
 		self.enable = RegisterFields("enable",
24 29
 		  [Field("s" + str(i), access_bus=READ_WRITE, access_dev=READ_ONLY) for i in range(n)])
25  
-	
26  
-	def get_registers(self):
27  
-		return [self.status, self.pending, self.enable]
28  
-	
29  
-	def get_fragment(self):
30  
-		comb = []
31  
-		sync = []
32  
-		
  30
+
33 31
 		# status
34  
-		for i, source in enumerate(self.sources):
  32
+		for i, source in enumerate(sources):
35 33
 			if isinstance(source, EventSourcePulse):
36  
-				comb.append(self.status.w[i].eq(0))
  34
+				self.comb += self.status.w[i].eq(0)
37 35
 			elif isinstance(source, EventSourceLevel):
38  
-				comb.append(self.status.w[i].eq(source.trigger))
  36
+				self.comb += self.status.w[i].eq(source.trigger)
39 37
 			else:
40 38
 				raise TypeError
41 39
 		
42 40
 		# pending
43  
-		for i, source in enumerate(self.sources):
  41
+		for i, source in enumerate(sources):
44 42
 			# W1C
45  
-			sync.append(If(self.pending.re & self.pending.r[i], source.pending.eq(0)))
  43
+			self.sync += If(self.pending.re & self.pending.r[i], source.pending.eq(0))
46 44
 			if isinstance(source, EventSourcePulse):
47 45
 				# set on a positive trigger pulse
48  
-				sync.append(If(source.trigger, source.pending.eq(1)))
  46
+				self.sync += If(source.trigger, source.pending.eq(1))
49 47
 			elif isinstance(source, EventSourceLevel):
50 48
 				# set on the falling edge of the trigger
51 49
 				old_trigger = Signal()
52  
-				sync += [
  50
+				self.sync += [
53 51
 					old_trigger.eq(source.trigger),
54 52
 					If(~source.trigger & old_trigger, source.pending.eq(1))
55 53
 				]
56 54
 			else:
57 55
 				raise TypeError
58  
-			comb.append(self.pending.w[i].eq(source.pending))
  56
+			self.comb += self.pending.w[i].eq(source.pending)
59 57
 		
60 58
 		# IRQ
61 59
 		irqs = [self.pending.w[i] & field.r for i, field in enumerate(self.enable.fields)]
62  
-		comb.append(self.irq.eq(optree("|", irqs)))
63  
-		
64  
-		return Fragment(comb, sync)
  60
+		self.comb += self.irq.eq(optree("|", irqs))
  61
+
  62
+	def __setattr__(self, name, value):
  63
+		if isinstance(value, EventSource) and self.finalized:
  64
+			raise FinalizeError
  65
+		object.__setattr__(self, name, value)
123  migen/bus/asmibus.py
... ...
@@ -1,21 +1,17 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.module import Module, FinalizeError
2 3
 from migen.genlib.misc import optree
3 4
 from migen.bus.transactions import *
4  
-from migen.sim.generic import Proxy, PureSimulable
5  
-
6  
-class FinalizeError(Exception):
7  
-	pass
  5
+from migen.sim.generic import Proxy
8 6
 
9 7
 (SLOT_EMPTY, SLOT_PENDING, SLOT_PROCESSING) = range(3)
10 8
 
11  
-class Slot:
  9
+class Slot(Module):
12 10
 	def __init__(self, aw, time):
13 11
 		self.state = Signal(2)
14 12
 		self.we = Signal()
15 13
 		self.adr = Signal(aw)
16  
-		self.time = time
17  
-		if self.time:
18  
-			self._counter = Signal(max=time+1)
  14
+		if time:
19 15
 			self.mature = Signal()
20 16
 		
21 17
 		self.allocate = Signal()
@@ -24,9 +20,9 @@ def __init__(self, aw, time):
24 20
 		self.process = Signal()
25 21
 		self.call = Signal()
26 22
 	
27  
-	def get_fragment(self):
28  
-		comb = []
29  
-		sync = [
  23
+		###
  24
+
  25
+		self.sync += [
30 26
 			If(self.allocate,
31 27
 				self.state.eq(SLOT_PENDING),
32 28
 				self.we.eq(self.allocate_we),
@@ -35,24 +31,21 @@ def get_fragment(self):
35 31
 			If(self.process, self.state.eq(SLOT_PROCESSING)),
36 32
 			If(self.call, self.state.eq(SLOT_EMPTY))
37 33
 		]
38  
-		if self.time:
39  
-			comb += [
40  
-				self.mature.eq(self._counter == 0)
41  
-			]
42  
-			sync += [
  34
+		if time:
  35
+			_counter = Signal(max=time+1)
  36
+			self.comb += self.mature.eq(self._counter == 0)
  37
+			self.sync += [
43 38
 				If(self.allocate,
44 39
 					self._counter.eq(self.time)
45 40
 				).Elif(self._counter != 0,
46 41
 					self._counter.eq(self._counter - 1)
47 42
 				)
48 43
 			]
49  
-		return Fragment(comb, sync)
50 44
 
51  
-class Port:
  45
+class Port(Module):
52 46
 	def __init__(self, hub, nslots):
53 47
 		self.hub = hub
54  
-		self.slots = [Slot(self.hub.aw, self.hub.time) for i in range(nslots)]
55  
-		self.finalized = False
  48
+		self.submodules.slots = [Slot(self.hub.aw, self.hub.time) for i in range(nslots)]
56 49
 		
57 50
 		# request issuance
58 51
 		self.adr = Signal(self.hub.aw)
@@ -67,36 +60,20 @@ def __init__(self, hub, nslots):
67 60
 		self.dat_r = Signal(self.hub.dw)
68 61
 		self.dat_w = Signal(self.hub.dw)
69 62
 		self.dat_wm = Signal(self.hub.dw//8)
70  
-	
71  
-	def finalize(self, tagbits, base):
72  
-		if self.finalized:
73  
-			raise FinalizeError
74  
-		self.finalized = True
  63
+
  64
+	def set_position(self, tagbits, base):
75 65
 		self.tagbits = tagbits
76 66
 		self.base = base
  67
+
  68
+	def do_finalize(self):
77 69
 		nslots = len(self.slots)
78 70
 		if nslots > 1:
79 71
 			self.tag_issue = Signal(max=nslots)
80  
-		self.tag_call = Signal(tagbits)
81  
-	
82  
-	def get_call_expression(self, slotn=0):
83  
-		if not self.finalized:
84  
-			raise FinalizeError
85  
-		return self.call \
86  
-			& (self.tag_call == (self.base + slotn))
87  
-		
88  
-	def get_fragment(self):
89  
-		if not self.finalized:
90  
-			raise FinalizeError
91  
-		
92  
-		slots_fragment = sum([s.get_fragment() for s in self.slots], Fragment())
93  
-		
94  
-		comb = []
95  
-		sync = []
96  
-		
  72
+		self.tag_call = Signal(self.tagbits)
  73
+
97 74
 		# allocate
98 75
 		for s in self.slots:
99  
-			comb += [
  76
+			self.comb += [
100 77
 				s.allocate_we.eq(self.we),
101 78
 				s.allocate_adr.eq(self.adr)
102 79
 			]
@@ -107,26 +84,29 @@ def get_fragment(self):
107 84
 				s.allocate.eq(self.stb),
108 85
 				self.tag_issue.eq(n) if needs_tags else None
109 86
 			).Else(choose_slot)
110  
-		comb.append(choose_slot)
111  
-		comb.append(self.ack.eq(optree("|", 
112  
-			[s.state == SLOT_EMPTY for s in self.slots])))
113  
-		
  87
+		self.comb += choose_slot
  88
+		self.comb += self.ack.eq(optree("|", 
  89
+			[s.state == SLOT_EMPTY for s in self.slots]))
  90
+
114 91
 		# call
115  
-		comb += [s.call.eq(self.get_call_expression(n))
  92
+		self.comb += [s.call.eq(self.get_call_expression(n))
116 93
 			for n, s in enumerate(self.slots)]
117  
-		
118  
-		return slots_fragment + Fragment(comb, sync)
  94
+	
  95
+	def get_call_expression(self, slotn=0):
  96
+		if not self.finalized:
  97
+			raise FinalizeError
  98
+		return self.call \
  99
+			& (self.tag_call == (self.base + slotn))
119 100
 
120  
-class Hub:
  101
+class Hub(Module):
121 102
 	def __init__(self, aw, dw, time=0):
122 103
 		self.aw = aw
123 104
 		self.dw = dw
124 105
 		self.time = time
125 106
 		self.ports = []
126  
-		self.finalized = False
127 107
 		
128 108
 		self.call = Signal()
129  
-		# tag_call is created by finalize()
  109
+		# tag_call is created by do_finalize()
130 110
 		self.dat_r = Signal(self.dw)
131 111
 		self.dat_w = Signal(self.dw)
132 112
 		self.dat_wm = Signal(self.dw//8)
@@ -138,41 +118,34 @@ def get_port(self, nslots=1):
138 118
 		self.ports.append(new_port)
139 119
 		return new_port
140 120
 	
141  
-	def finalize(self):
142  
-		if self.finalized:
143  
-			raise FinalizeError
144  
-		self.finalized = True
  121
+	def do_finalize(self):
145 122
 		nslots = sum([len(port.slots) for port in self.ports])
146 123
 		tagbits = bits_for(nslots-1)
147 124
 		base = 0
148 125
 		for port in self.ports:
149  
-			port.finalize(tagbits, base)
  126
+			port.set_position(tagbits, base)
  127
+			port.finalize()
150 128
 			base += len(port.slots)
  129
+		self.submodules += self.ports
151 130
 		self.tag_call = Signal(tagbits)
152  
-	
153  
-	def get_slots(self):
154  
-		if not self.finalized:
155  
-			raise FinalizeError
156  
-		return sum([port.slots for port in self.ports], [])
157  
-	
158  
-	def get_fragment(self):
159  
-		if not self.finalized:
160  
-			raise FinalizeError
161  
-		ports = sum([port.get_fragment() for port in self.ports], Fragment())
162  
-		comb = []
  131
+		
163 132
 		for port in self.ports:
164  
-			comb += [
  133
+			self.comb += [
165 134
 				port.call.eq(self.call),
166 135
 				port.tag_call.eq(self.tag_call),
167 136
 				port.dat_r.eq(self.dat_r)
168 137
 			]
169  
-		comb += [
  138
+		self.comb += [
170 139
 			self.dat_w.eq(optree("|", [port.dat_w for port in self.ports])),
171 140
 			self.dat_wm.eq(optree("|", [port.dat_wm for port in self.ports]))
172 141
 		]
173  
-		return ports + Fragment(comb)
  142
+	
  143
+	def get_slots(self):
  144
+		if not self.finalized:
  145
+			raise FinalizeError
  146
+		return sum([port.slots for port in self.ports], [])
174 147
 
175  
-class Tap(PureSimulable):
  148
+class Tap(Module):
176 149
 	def __init__(self, hub, handler=print):
177 150
 		self.hub = hub
178 151
 		self.handler = handler
@@ -212,7 +185,7 @@ def do_simulation(self, s):
212 185
 			transaction.latency = s.cycle_counter - transaction.latency + 1
213 186
 			self.transaction = transaction
214 187
 
215  
-class Initiator(PureSimulable):
  188
+class Initiator(Module):
216 189
 	def __init__(self, generator, port):
217 190
 		self.generator = generator
218 191
 		self.port = port
@@ -287,7 +260,7 @@ def select_slot(self, pending_slots):
287 260
 			self.last_slot += 1
288 261
 		return self.last_slot
289 262
 
290  
-class Target(PureSimulable):
  263
+class Target(Module):
291 264
 	def __init__(self, model, hub):
292 265
 		self.model = model
293 266
 		self.hub = hub
123  migen/fhdl/autofragment.py
... ...
@@ -1,123 +0,0 @@
1  
-import inspect
2  
-
3  
-from migen.fhdl.structure import *
4  
-from migen.fhdl.specials import Special
5  
-
6  
-def from_local():
7  
-	f = Fragment()
8  
-	frame = inspect.currentframe().f_back
9  
-	ns = frame.f_locals
10  
-	for x in ns:
11  
-		obj = ns[x]
12  
-		if hasattr(obj, "get_fragment"):
13  
-			f += obj.get_fragment()
14  
-	return f
15  
-
16  
-def from_attributes(obj):
17  
-	f = Fragment()
18  
-	for x in obj.__dict__.values():
19  
-		if hasattr(x, "get_fragment"):
20  
-			f += x.get_fragment()
21  
-	return f
22  
-
23  
-class _FModuleProxy:
24  
-	def __init__(self, fm):
25  
-		object.__setattr__(self, "_fm", fm)
26  
-
27  
-class _FModuleComb(_FModuleProxy):
28  
-	def __iadd__(self, other):
29  
-		if isinstance(other, (list, tuple)):
30  
-			self._fm._fragment.comb += other
31  
-		else:
32  
-			self._fm._fragment.comb.append(other)
33  
-		return self
34  
-
35  
-def _cd_append(d, key, statements):
36  
-	try:
37  
-		l = d[key]
38  
-	except KeyError:
39  
-		l = []
40  
-		d[key] = l
41  
-	if isinstance(statements, (list, tuple)):
42  
-		l += statements
43  
-	else:
44  
-		l.append(statements)
45  
-
46  
-class _FModuleSyncCD:
47  
-	def __init__(self, fm, cd):
48  
-		self._fm = fm
49  
-		self._cd = cd
50  
-
51  
-	def __iadd__(self, other):
52  
-		_cd_append(self._fm._fragment.sync, self._cd, other)
53  
-		return self
54  
-
55  
-class _FModuleSync(_FModuleProxy):
56  
-	def __iadd__(self, other):
57  
-		_cd_append(self._fm._fragment.sync, "sys", other)
58  
-		return self
59  
-
60  
-	def __getattr__(self, name):
61  
-		return _FModuleSyncCD(self._fm, name)
62  
-
63  
-	def __setattr__(self, name, value):
64  
-		if not isinstance(value, _FModuleSyncCD):
65  
-			raise AttributeError("Attempted to assign sync property - use += instead")
66  
-
67  
-class _FModuleSpecials(_FModuleProxy):
68  
-	def __iadd__(self, other):
69  
-		if isinstance(other, (set, list, tuple)):
70  
-			self._fm._fragment.specials |= set(other)
71  
-		else:
72  
-			self._fm._fragment.specials.add(other)
73  
-		return self
74  
-
75  
-class _FModuleSubmodules(_FModuleProxy):
76  
-	def __iadd__(self, other):
77  
-		if isinstance(other, (list, tuple)):
78  
-			self._fm._submodules += other
79  
-		else:
80  
-			self._fm._submodules.append(other)
81  
-		return self
82  
-
83  
-class FModule:
84  
-	auto_attr = True
85  
-
86  
-	def get_fragment(self):
87  
-		assert(not hasattr(self, "_fragment"))
88  
-		self._fragment = Fragment()
89  
-		self._submodules = []
90  
-		self.build_fragment()
91  
-		if hasattr(self, "do_simulation"):
92  
-			self._fragment.sim.append(self.do_simulation)
93  
-		for submodule in self._submodules:
94  
-			f += submodule.get_fragment()
95  
-		if self.auto_attr:
96  
-			for x in self.__dict__.values():
97  
-				if isinstance(x, Special):
98  
-					self._fragment.specials.add(x)
99  
-				elif hasattr(x, "get_fragment"):
100  
-					self._fragment += x.get_fragment()
101  
-		return self._fragment
102  
-
103  
-	def __getattr__(self, name):
104  
-		if name == "comb":
105  
-			return _FModuleComb(self)
106  
-		elif name == "sync":
107  
-			return _FModuleSync(self)
108  
-		elif name == "specials":
109  
-			return _FModuleSpecials(self)
110  
-		elif name == "submodules":
111  
-			return _FModuleSubmodules(self)
112  
-		else:
113  
-			raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'")
114  
-
115  
-	def __setattr__(self, name, value):
116  
-		if name in ["comb", "sync", "specials", "submodules"]:
117  
-			if not isinstance(value, _FModuleProxy):
118  
-				raise AttributeError("Attempted to assign special FModule property - use += instead")
119  
-		else:
120  
-			object.__setattr__(self, name, value)
121  
-
122  
-	def build_fragment(self):
123  
-		raise NotImplementedError("FModule.build_fragment needs to be overloaded")
129  migen/fhdl/module.py
... ...
@@ -0,0 +1,129 @@
  1
+import collections
  2
+
  3
+from migen.fhdl.structure import *
  4
+from migen.fhdl.specials import Special
  5
+from migen.fhdl.tools import flat_iteration
  6
+
  7
+class FinalizeError(Exception):
  8
+	pass
  9
+
  10
+def _flat_list(e):
  11
+	if isinstance(e, collections.Iterable):
  12
+		return flat_iteration(e)
  13
+	else:
  14
+		return [e]
  15
+
  16
+class _ModuleProxy:
  17
+	def __init__(self, fm):
  18
+		object.__setattr__(self, "_fm", fm)
  19
+
  20
+class _ModuleComb(_ModuleProxy):
  21
+	def __iadd__(self, other):
  22
+		self._fm._fragment.comb += _flat_list(other)
  23
+		return self
  24
+
  25
+def _cd_append(d, key, statements):
  26
+	try:
  27
+		l = d[key]
  28
+	except KeyError:
  29
+		l = []
  30
+		d[key] = l
  31
+	l += _flat_list(statements)
  32
+
  33
+class _ModuleSyncCD:
  34
+	def __init__(self, fm, cd):
  35
+		self._fm = fm
  36
+		self._cd = cd
  37
+
  38
+	def __iadd__(self, other):
  39
+		_cd_append(self._fm._fragment.sync, self._cd, other)
  40
+		return self
  41
+
  42
+class _ModuleSync(_ModuleProxy):
  43
+	def __iadd__(self, other):
  44
+		_cd_append(self._fm._fragment.sync, "sys", other)
  45
+		return self
  46
+
  47
+	def __getattr__(self, name):
  48
+		return _ModuleSyncCD(self._fm, name)
  49
+
  50
+	def __setattr__(self, name, value):
  51
+		if not isinstance(value, _ModuleSyncCD):
  52
+			raise AttributeError("Attempted to assign sync property - use += instead")
  53
+
  54
+# _ModuleForwardAttr enables user classes to do e.g.:
  55
+# self.subm.foobar = SomeModule()
  56
+# and then access the submodule with self.foobar.
  57
+class _ModuleForwardAttr:
  58
+	def __setattr__(self, name, value):
  59
+		self.__iadd__(value)
  60
+		setattr(self._fm, name, value)
  61
+
  62
+class _ModuleSpecials(_ModuleProxy, _ModuleForwardAttr):
  63
+	def __iadd__(self, other):
  64
+		self._fm._fragment.specials |= set(_flat_list(other))
  65
+		return self
  66
+
  67
+class _ModuleSubmodules(_ModuleProxy, _ModuleForwardAttr):
  68
+	def __iadd__(self, other):
  69
+		self._fm._submodules += _flat_list(other)
  70
+		return self
  71
+
  72
+class Module:
  73
+	def get_fragment(self):
  74
+		assert(not self._get_fragment_called)
  75
+		self._get_fragment_called = True
  76
+		self.finalize()
  77
+		return self._fragment
  78
+
  79
+	def __getattr__(self, name):
  80
+		if name == "comb":
  81
+			return _ModuleComb(self)
  82
+		elif name == "sync":
  83
+			return _ModuleSync(self)
  84
+		elif name == "specials":
  85
+			return _ModuleSpecials(self)
  86
+		elif name == "submodules":
  87
+			return _ModuleSubmodules(self)
  88
+
  89
+		# hack to have initialized regular attributes without using __init__
  90
+		# (which would require derived classes to call it)
  91
+		elif name == "finalized":
  92
+			self.finalized = False
  93
+			return self.finalized
  94
+		elif name == "_fragment":
  95
+			try:
  96
+				sim = [self.do_simulation]
  97
+			except AttributeError:
  98
+				sim = []
  99
+			self._fragment = Fragment(sim=sim)
  100
+			return self._fragment
  101
+		elif name == "_submodules":
  102
+			self._submodules = []
  103
+			return self._submodules
  104
+		elif name == "_get_fragment_called":
  105
+			self._get_fragment_called = False
  106
+			return self._get_fragment_called
  107
+
  108
+		else:
  109
+			raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'")
  110
+
  111
+	def __setattr__(self, name, value):
  112
+		if name in ["comb", "sync", "specials", "submodules"]:
  113
+			if not isinstance(value, _ModuleProxy):
  114
+				raise AttributeError("Attempted to assign special Module property - use += instead")
  115
+		else:
  116
+			object.__setattr__(self, name, value)
  117
+
  118
+	def finalize(self):
  119
+		if not self.finalized:
  120
+			self.finalized = True
  121
+			for submodule in self._submodules:
  122
+				self._fragment += submodule.get_fragment()
  123
+			self._submodules = []
  124
+			self.do_finalize()
  125
+			for submodule in self._submodules:
  126
+				self._fragment += submodule.get_fragment()
  127
+
  128
+	def do_finalize(self):
  129
+		pass
4  migen/fhdl/tools.py
... ...
@@ -1,10 +1,12 @@
  1
+import collections
  2
+
1 3
 from migen.fhdl.structure import *
2 4
 from migen.fhdl.structure import _Operator, _Slice, _Assign, _ArrayProxy
3 5
 from migen.fhdl.visit import NodeVisitor, NodeTransformer
4 6
 
5 7
 def flat_iteration(l):
6 8
 	for element in l:
7  
-		if isinstance(element, (list, tuple)):
  9
+		if isinstance(element, collections.Iterable):
8 10
 			for element2 in flat_iteration(element):
9 11
 				yield element2
10 12
 		else:
3  migen/pytholite/reg.py
@@ -3,9 +3,6 @@
3 3
 from migen.fhdl.structure import *
4 4
 from migen.fhdl import visit as fhdl
5 5
 
6  
-class FinalizeError(Exception):
7  
-	pass
8  
-
9 6
 class AbstractLoad:
10 7
 	def __init__(self, target, source):
11 8
 		self.target = target

No commit comments for this range

Something went wrong with that request. Please try again.