Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

fhdl: tristate support

  • Loading branch information...
commit dc93a231c65dc644d5a360ae4f4a4f52965f33b0 1 parent 63d399b
Sébastien Bourdeauducq authored February 15, 2013
11  examples/basic/tristate.py
... ...
@@ -0,0 +1,11 @@
  1
+from migen.fhdl.structure import *
  2
+from migen.fhdl import verilog
  3
+
  4
+n = 6
  5
+pad = Signal(n)
  6
+o = Signal(n)
  7
+oe = Signal()
  8
+i = Signal(n)
  9
+
  10
+f = Fragment(tristates={Tristate(pad, o, oe, i)})
  11
+print(verilog.convert(f, ios={pad, o, oe, i}))
13  migen/fhdl/structure.py
@@ -229,6 +229,13 @@ def __getitem__(self, key):
229 229
 		else:
230 230
 			return list.__getitem__(self, key)
231 231
 
  232
+class Tristate:
  233
+	def __init__(self, target, o, oe, i=None):
  234
+		self.target = target
  235
+		self.o = o
  236
+		self.oe = oe
  237
+		self.i = i
  238
+
232 239
 # extras
233 240
 
234 241
 class Instance(HUID):
@@ -327,10 +334,11 @@ def get_port(self, write_capable=False, async_read=False,
327 334
 #
328 335
 
329 336
 class Fragment:
330  
-	def __init__(self, comb=None, sync=None, instances=None, memories=None, sim=None):
  337
+	def __init__(self, comb=None, sync=None, instances=None, tristates=None, memories=None, sim=None):
331 338
 		if comb is None: comb = []
332 339
 		if sync is None: sync = dict()
333 340
 		if instances is None: instances = set()
  341
+		if tristates is None: tristates = set()
334 342
 		if memories is None: memories = set()
335 343
 		if sim is None: sim = []
336 344
 		
@@ -340,9 +348,9 @@ def __init__(self, comb=None, sync=None, instances=None, memories=None, sim=None
340 348
 		self.comb = comb
341 349
 		self.sync = sync
342 350
 		self.instances = set(instances)
  351
+		self.tristates = set(tristates)
343 352
 		self.memories = set(memories)
344 353
 		self.sim = sim
345  
-		
346 354
 	
347 355
 	def __add__(self, other):
348 356
 		newsync = defaultdict(list)
@@ -352,6 +360,7 @@ def __add__(self, other):
352 360
 			newsync[k].extend(v)
353 361
 		return Fragment(self.comb + other.comb, newsync,
354 362
 			self.instances | other.instances,
  363
+			self.tristates | other.tristates,
355 364
 			self.memories | other.memories,
356 365
 			self.sim + other.sim)
357 366
 	
29  migen/fhdl/tools.py
@@ -64,7 +64,7 @@ def list_inst_ios(i, ins, outs, inouts):
64 64
 			return set.union(*(list_inst_ios(e, ins, outs, inouts) for e in i))
65 65
 		else:
66 66
 			return set()
67  
-	else:
  67
+	elif isinstance(i, Instance):
68 68
 		subsets = [list_signals(item.expr) for item in filter(lambda x:
69 69
 			(ins and isinstance(x, Instance.Input))
70 70
 			or (outs and isinstance(x, Instance.Output))
@@ -74,6 +74,33 @@ def list_inst_ios(i, ins, outs, inouts):
74 74
 			return set.union(*subsets)
75 75
 		else:
76 76
 			return set()
  77
+	else:
  78
+		return set()
  79
+
  80
+def list_tristate_ios(i, ins, outs, inouts):
  81
+	if isinstance(i, Fragment):
  82
+		return list_tristate_ios(i.tristates, ins, outs, inouts)
  83
+	elif isinstance(i, set):
  84
+		if i:
  85
+			return set.union(*(list_tristate_ios(e, ins, outs, inouts) for e in i))
  86
+		else:
  87
+			return set()
  88
+	elif isinstance(i, Tristate):
  89
+		r = set()
  90
+		if inouts:
  91
+			r.update(list_signals(i.target))
  92
+		if ins:
  93
+			r.update(list_signals(i.o))
  94
+			r.update(list_signals(i.oe))
  95
+		if outs:
  96
+			r.update(list_signals(i.i))
  97
+		return r
  98
+	else:
  99
+		return set()
  100
+
  101
+def list_it_ios(i, ins, outs, inouts):
  102
+	return list_inst_ios(i, ins, outs, inouts) \
  103
+		| list_tristate_ios(i, ins, outs, inouts)
77 104
 
78 105
 def list_mem_ios(m, ins, outs):
79 106
 	if isinstance(m, Fragment):
26  migen/fhdl/verilog.py
@@ -5,7 +5,7 @@
5 5
 from migen.fhdl.structure import _Operator, _Slice, _Assign
6 6
 from migen.fhdl.tools import *
7 7
 from migen.fhdl.namer import Namespace, build_namespace
8  
-from migen.fhdl import verilog_mem_behavioral
  8
+from migen.fhdl import verilog_behavioral as behavioral
9 9
 
10 10
 def _printsig(ns, s):
11 11
 	if s.signed:
@@ -135,11 +135,11 @@ def _list_comb_wires(f):
135 135
 	return r
136 136
 
137 137
 def _printheader(f, ios, name, ns):
138  
-	sigs = list_signals(f) | list_inst_ios(f, True, True, True) | list_mem_ios(f, True, True)
139  
-	inst_mem_outs = list_inst_ios(f, False, True, False) | list_mem_ios(f, False, True)
140  
-	inouts = list_inst_ios(f, False, False, True)
141  
-	targets = list_targets(f) | inst_mem_outs
142  
-	wires = _list_comb_wires(f) | inst_mem_outs
  138
+	sigs = list_signals(f) | list_it_ios(f, True, True, True) | list_mem_ios(f, True, True)
  139
+	it_mem_outs = list_it_ios(f, False, True, False) | list_mem_ios(f, False, True)
  140
+	inouts = list_it_ios(f, False, False, True)
  141
+	targets = list_targets(f) | it_mem_outs
  142
+	wires = _list_comb_wires(f) | it_mem_outs
143 143
 	r = "module " + name + "(\n"
144 144
 	firstp = True
145 145
 	for sig in sorted(ios, key=lambda x: x.huid):
@@ -259,6 +259,12 @@ def _printinstances(f, ns, clock_domains):
259 259
 		r += ");\n\n"
260 260
 	return r
261 261
 
  262
+def _printtristates(f, ns, handler):
  263
+	r = ""
  264
+	for tristate in f.tristates:
  265
+		r += handler(tristate, ns)
  266
+	return r
  267
+
262 268
 def _printmemories(f, ns, handler, clock_domains):
263 269
 	r = ""
264 270
 	for memory in f.memories:
@@ -270,7 +276,7 @@ def _printinit(f, ios, ns):
270 276
 	signals = list_signals(f) \
271 277
 		- ios \
272 278
 		- list_targets(f) \
273  
-		- list_inst_ios(f, False, True, False) \
  279
+		- list_it_ios(f, False, True, False) \
274 280
 		- list_mem_ios(f, False, True)
275 281
 	if signals:
276 282
 		r += "initial begin\n"
@@ -282,7 +288,8 @@ def _printinit(f, ios, ns):
282 288
 def convert(f, ios=None, name="top",
283 289
   clock_domains=None,
284 290
   return_ns=False,
285  
-  memory_handler=verilog_mem_behavioral.handler,
  291
+  memory_handler=behavioral.mem_handler,
  292
+  tristate_handler=behavioral.tristate_handler,
286 293
   display_run=False):
287 294
 	if ios is None:
288 295
 		ios = set()
@@ -297,7 +304,7 @@ def convert(f, ios=None, name="top",
297 304
 	f = lower_arrays(f)
298 305
 
299 306
 	ns = build_namespace(list_signals(f) \
300  
-		| list_inst_ios(f, True, True, True) \
  307
+		| list_it_ios(f, True, True, True) \
301 308
 		| list_mem_ios(f, True, True) \
302 309
 		| ios)
303 310
 
@@ -306,6 +313,7 @@ def convert(f, ios=None, name="top",
306 313
 	r += _printcomb(f, ns, display_run)
307 314
 	r += _printsync(f, ns, clock_domains)
308 315
 	r += _printinstances(f, ns, clock_domains)
  316
+	r += _printtristates(f, ns, tristate_handler)
309 317
 	r += _printmemories(f, ns, memory_handler, clock_domains)
310 318
 	r += _printinit(f, ios, ns)
311 319
 	r += "endmodule\n"
14  migen/fhdl/verilog_mem_behavioral.py → migen/fhdl/verilog_behavioral.py
... ...
@@ -1,6 +1,7 @@
1 1
 from migen.fhdl.structure import *
  2
+from migen.fhdl.tools import *
2 3
 
3  
-def handler(memory, ns, clock_domains):
  4
+def mem_handler(memory, ns, clock_domains):
4 5
 	r = ""
5 6
 	gn = ns.get_name
6 7
 	adrbits = bits_for(memory.depth-1)
@@ -72,3 +73,14 @@ def handler(memory, ns, clock_domains):
72 73
 		r += "end\n\n"
73 74
 	
74 75
 	return r
  76
+
  77
+def tristate_handler(tristate, ns):
  78
+	gn = ns.get_name
  79
+	w, s = value_bits_sign(tristate.target)
  80
+	r = "assign " + gn(tristate.target) + " = " \
  81
+		+ gn(tristate.oe) + " ? " + gn(tristate.o) \
  82
+		+ " : " + str(w) + "'bz;\n"
  83
+	if tristate.i is not None:
  84
+		r += "assign " + gn(tristate.i) + " = " + gn(tristate.target) + ";\n"
  85
+	r += "\n"
  86
+	return r

0 notes on commit dc93a23

Please sign in to comment.
Something went wrong with that request. Please try again.