Skip to content

Commit dc93a23

Browse files
author
Sebastien Bourdeauducq
committedFeb 14, 2013
fhdl: tristate support
1 parent 63d399b commit dc93a23

File tree

5 files changed

+80
-13
lines changed

5 files changed

+80
-13
lines changed
 

‎examples/basic/tristate.py

+11
Original file line numberDiff line numberDiff line change
@@ -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}))

‎migen/fhdl/structure.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,13 @@ def __getitem__(self, key):
229229
else:
230230
return list.__getitem__(self, key)
231231

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+
232239
# extras
233240

234241
class Instance(HUID):
@@ -327,10 +334,11 @@ def get_port(self, write_capable=False, async_read=False,
327334
#
328335

329336
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):
331338
if comb is None: comb = []
332339
if sync is None: sync = dict()
333340
if instances is None: instances = set()
341+
if tristates is None: tristates = set()
334342
if memories is None: memories = set()
335343
if sim is None: sim = []
336344

@@ -340,9 +348,9 @@ def __init__(self, comb=None, sync=None, instances=None, memories=None, sim=None
340348
self.comb = comb
341349
self.sync = sync
342350
self.instances = set(instances)
351+
self.tristates = set(tristates)
343352
self.memories = set(memories)
344353
self.sim = sim
345-
346354

347355
def __add__(self, other):
348356
newsync = defaultdict(list)
@@ -352,6 +360,7 @@ def __add__(self, other):
352360
newsync[k].extend(v)
353361
return Fragment(self.comb + other.comb, newsync,
354362
self.instances | other.instances,
363+
self.tristates | other.tristates,
355364
self.memories | other.memories,
356365
self.sim + other.sim)
357366

‎migen/fhdl/tools.py

+28-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ def list_inst_ios(i, ins, outs, inouts):
6464
return set.union(*(list_inst_ios(e, ins, outs, inouts) for e in i))
6565
else:
6666
return set()
67-
else:
67+
elif isinstance(i, Instance):
6868
subsets = [list_signals(item.expr) for item in filter(lambda x:
6969
(ins and isinstance(x, Instance.Input))
7070
or (outs and isinstance(x, Instance.Output))
@@ -74,6 +74,33 @@ def list_inst_ios(i, ins, outs, inouts):
7474
return set.union(*subsets)
7575
else:
7676
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)
77104

78105
def list_mem_ios(m, ins, outs):
79106
if isinstance(m, Fragment):

‎migen/fhdl/verilog.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from migen.fhdl.structure import _Operator, _Slice, _Assign
66
from migen.fhdl.tools import *
77
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
99

1010
def _printsig(ns, s):
1111
if s.signed:
@@ -135,11 +135,11 @@ def _list_comb_wires(f):
135135
return r
136136

137137
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
143143
r = "module " + name + "(\n"
144144
firstp = True
145145
for sig in sorted(ios, key=lambda x: x.huid):
@@ -259,6 +259,12 @@ def _printinstances(f, ns, clock_domains):
259259
r += ");\n\n"
260260
return r
261261

262+
def _printtristates(f, ns, handler):
263+
r = ""
264+
for tristate in f.tristates:
265+
r += handler(tristate, ns)
266+
return r
267+
262268
def _printmemories(f, ns, handler, clock_domains):
263269
r = ""
264270
for memory in f.memories:
@@ -270,7 +276,7 @@ def _printinit(f, ios, ns):
270276
signals = list_signals(f) \
271277
- ios \
272278
- list_targets(f) \
273-
- list_inst_ios(f, False, True, False) \
279+
- list_it_ios(f, False, True, False) \
274280
- list_mem_ios(f, False, True)
275281
if signals:
276282
r += "initial begin\n"
@@ -282,7 +288,8 @@ def _printinit(f, ios, ns):
282288
def convert(f, ios=None, name="top",
283289
clock_domains=None,
284290
return_ns=False,
285-
memory_handler=verilog_mem_behavioral.handler,
291+
memory_handler=behavioral.mem_handler,
292+
tristate_handler=behavioral.tristate_handler,
286293
display_run=False):
287294
if ios is None:
288295
ios = set()
@@ -297,7 +304,7 @@ def convert(f, ios=None, name="top",
297304
f = lower_arrays(f)
298305

299306
ns = build_namespace(list_signals(f) \
300-
| list_inst_ios(f, True, True, True) \
307+
| list_it_ios(f, True, True, True) \
301308
| list_mem_ios(f, True, True) \
302309
| ios)
303310

@@ -306,6 +313,7 @@ def convert(f, ios=None, name="top",
306313
r += _printcomb(f, ns, display_run)
307314
r += _printsync(f, ns, clock_domains)
308315
r += _printinstances(f, ns, clock_domains)
316+
r += _printtristates(f, ns, tristate_handler)
309317
r += _printmemories(f, ns, memory_handler, clock_domains)
310318
r += _printinit(f, ios, ns)
311319
r += "endmodule\n"

‎migen/fhdl/verilog_mem_behavioral.py renamed to ‎migen/fhdl/verilog_behavioral.py

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from migen.fhdl.structure import *
2+
from migen.fhdl.tools import *
23

3-
def handler(memory, ns, clock_domains):
4+
def mem_handler(memory, ns, clock_domains):
45
r = ""
56
gn = ns.get_name
67
adrbits = bits_for(memory.depth-1)
@@ -72,3 +73,14 @@ def handler(memory, ns, clock_domains):
7273
r += "end\n\n"
7374

7475
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 commit comments

Comments
 (0)
Please sign in to comment.