Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
  • 5 commits
  • 6 files changed
  • 0 comments
  • 2 contributors
16  examples/basic/reslice.py
... ...
@@ -0,0 +1,16 @@
  1
+from migen.fhdl.std import *
  2
+from migen.fhdl import verilog
  3
+
  4
+class Example(Module):
  5
+	def __init__(self):
  6
+		a = Signal(3)
  7
+		b = Signal(4)
  8
+		c = Signal(5)
  9
+		d = Signal(7)
  10
+		s1 = c[:3][:2]
  11
+		s2 = Cat(a, b)[:6]
  12
+		s3 = Cat(s1, s2)[-5:]
  13
+		self.comb += s3.eq(0)
  14
+		self.comb += d.eq(Cat(d[::-1], Cat(s1[:1], s3[-4:])[:3]))
  15
+
  16
+print(verilog.convert(Example()))
13  migen/fhdl/structure.py
@@ -75,16 +75,9 @@ def __getitem__(self, key):
75 75
 				key += flen(self)
76 76
 			return _Slice(self, key, key+1)
77 77
 		elif isinstance(key, slice):
78  
-			start = key.start or 0
79  
-			stop = key.stop or flen(self)
80  
-			if start < 0:
81  
-				start += flen(self)
82  
-			if stop < 0:
83  
-				stop += flen(self)
84  
-			if stop > flen(self):
85  
-				stop = flen(self)
86  
-			if key.step != None:
87  
-				raise KeyError
  78
+			start, stop, step = key.indices(flen(self))
  79
+			if step != 1:
  80
+				return Cat(*(self[i] for i in range(start, stop, step)))
88 81
 			return _Slice(self, start, stop)
89 82
 		else:
90 83
 			raise KeyError
53  migen/fhdl/tools.py
@@ -119,14 +119,11 @@ def generate_reset(rst, sl):
119 119
 def insert_reset(rst, sl):
120 120
 	return [If(rst, *generate_reset(rst, sl)).Else(*sl)]
121 121
 
122  
-# Basics are FHDL structure elements that back-ends are not required to support
123  
-# but can be expressed in terms of other elements (lowered) before conversion.
124  
-class _BasicLowerer(NodeTransformer):
125  
-	def __init__(self, clock_domains):
126  
-		self.comb = []
  122
+class _Lowerer(NodeTransformer):
  123
+	def __init__(self):
127 124
 		self.target_context = False
128 125
 		self.extra_stmts = []
129  
-		self.clock_domains = clock_domains
  126
+		self.comb = []
130 127
 
131 128
 	def visit_Assign(self, node):
132 129
 		old_target_context, old_extra_stmts = self.target_context, self.extra_stmts
@@ -142,7 +139,14 @@ def visit_Assign(self, node):
142 139
 		
143 140
 		self.target_context, self.extra_stmts = old_target_context, old_extra_stmts
144 141
 		return r
145  
-	
  142
+
  143
+# Basics are FHDL structure elements that back-ends are not required to support
  144
+# but can be expressed in terms of other elements (lowered) before conversion.
  145
+class _BasicLowerer(_Lowerer):
  146
+	def __init__(self, clock_domains):
  147
+		self.clock_domains = clock_domains
  148
+		_Lowerer.__init__(self)
  149
+
146 150
 	def visit_ArrayProxy(self, node):
147 151
 		array_muxed = Signal(value_bits_sign(node), variable=True)
148 152
 		if self.target_context:
@@ -163,26 +167,43 @@ def visit_ClockSignal(self, node):
163 167
 	def visit_ResetSignal(self, node):
164 168
 		return self.clock_domains[node.cd].rst
165 169
 
166  
-def lower_basics(f):
167  
-	bl = _BasicLowerer(f.clock_domains)
168  
-	f = bl.visit(f)
169  
-	f.comb += bl.comb
  170
+class _ComplexSliceLowerer(_Lowerer):
  171
+	def visit_Slice(self, node):
  172
+		if not isinstance(node.value, Signal):
  173
+			slice_proxy = Signal(value_bits_sign(node.value))
  174
+			if self.target_context:
  175
+				a = _Assign(node.value, slice_proxy)
  176
+			else:
  177
+				a = _Assign(slice_proxy, node.value)
  178
+			self.comb.append(self.visit_Assign(a))
  179
+			node = _Slice(slice_proxy, node.start, node.stop)
  180
+		return NodeTransformer.visit_Slice(self, node)
  181
+
  182
+def _apply_lowerer(l, f):
  183
+	f = l.visit(f)
  184
+	f.comb += l.comb
170 185
 
171 186
 	for special in f.specials:
172 187
 		for obj, attr, direction in special.iter_expressions():
173 188
 			if direction != SPECIAL_INOUT:
174 189
 				# inouts are only supported by Migen when connected directly to top-level
175 190
 				# in this case, they are Signal and never need lowering
176  
-				bl.comb = []
177  
-				bl.target_context = direction != SPECIAL_INPUT
178  
-				bl.extra_stmts = []
  191
+				l.comb = []
  192
+				l.target_context = direction != SPECIAL_INPUT
  193
+				l.extra_stmts = []
179 194
 				expr = getattr(obj, attr)
180  
-				expr = bl.visit(expr)
  195
+				expr = l.visit(expr)
181 196
 				setattr(obj, attr, expr)
182  
-				f.comb += bl.comb + bl.extra_stmts
  197
+				f.comb += l.comb + l.extra_stmts
183 198
 
184 199
 	return f
185 200
 
  201
+def lower_basics(f):
  202
+	return _apply_lowerer(_BasicLowerer(f.clock_domains), f)
  203
+
  204
+def lower_complex_slices(f):
  205
+	return _apply_lowerer(_ComplexSliceLowerer(), f)
  206
+
186 207
 class _ClockDomainRenamer(NodeVisitor):
187 208
 	def __init__(self, old, new):
188 209
 		self.old = old
1  migen/fhdl/verilog.py
@@ -302,6 +302,7 @@ def convert(f, ios=None, name="top",
302 302
 			else:
303 303
 				raise KeyError("Unresolved clock domain: '"+cd_name+"'")
304 304
 	
  305
+	f = lower_complex_slices(f)
305 306
 	_insert_resets(f)
306 307
 	f = lower_basics(f)
307 308
 	fs, lowered_specials = _lower_specials(special_overrides, f.specials)
8  migen/genlib/coding.py
@@ -22,10 +22,8 @@ def __init__(self, width):
22 22
 		self.i = Signal(width) # one-hot, lsb has priority
23 23
 		self.o = Signal(max=width) # binary
24 24
 		self.n = Signal() # none
25  
-		act = If(0)
26  
-		for j in range(width):
27  
-			act = act.Elif(self.i[j], self.o.eq(j))
28  
-		self.comb += act
  25
+		for j in range(width)[::-1]: # last has priority
  26
+			self.comb += If(self.i[j], self.o.eq(j))
29 27
 		self.comb += self.n.eq(self.i == 0)
30 28
 
31 29
 class Decoder(Module):
@@ -41,9 +39,7 @@ class PriorityDecoder(Decoder):
41 39
 	pass # same
42 40
 
43 41
 def _main():
44  
-	from migen.sim.generic import Simulator, TopLevel
45 42
 	from migen.fhdl import verilog
46  
-
47 43
 	e = Encoder(8)
48 44
 	print(verilog.convert(e, ios={e.i, e.o, e.n}))
49 45
 	pe = PriorityEncoder(8)
6  migen/genlib/misc.py
... ...
@@ -1,12 +1,6 @@
1 1
 from migen.fhdl.std import *
2  
-from migen.fhdl.tools import value_bits_sign
3 2
 from migen.fhdl.structure import _Operator
4 3
 
5  
-def bitreverse(s):
6  
-	length, signed = value_bits_sign(s)
7  
-	l = [s[i] for i in reversed(range(length))]
8  
-	return Cat(*l)
9  
-
10 4
 def optree(op, operands, lb=None, ub=None, default=None):
11 5
 	if lb is None:
12 6
 		lb = 0

No commit comments for this range

Something went wrong with that request. Please try again.