fhdl: tristate support
This commit is contained in:
parent
63d399b6ad
commit
dc93a231c6
|
@ -0,0 +1,11 @@
|
|||
from migen.fhdl.structure import *
|
||||
from migen.fhdl import verilog
|
||||
|
||||
n = 6
|
||||
pad = Signal(n)
|
||||
o = Signal(n)
|
||||
oe = Signal()
|
||||
i = Signal(n)
|
||||
|
||||
f = Fragment(tristates={Tristate(pad, o, oe, i)})
|
||||
print(verilog.convert(f, ios={pad, o, oe, i}))
|
|
@ -229,6 +229,13 @@ class Array(list):
|
|||
else:
|
||||
return list.__getitem__(self, key)
|
||||
|
||||
class Tristate:
|
||||
def __init__(self, target, o, oe, i=None):
|
||||
self.target = target
|
||||
self.o = o
|
||||
self.oe = oe
|
||||
self.i = i
|
||||
|
||||
# extras
|
||||
|
||||
class Instance(HUID):
|
||||
|
@ -327,10 +334,11 @@ class Memory(HUID):
|
|||
#
|
||||
|
||||
class Fragment:
|
||||
def __init__(self, comb=None, sync=None, instances=None, memories=None, sim=None):
|
||||
def __init__(self, comb=None, sync=None, instances=None, tristates=None, memories=None, sim=None):
|
||||
if comb is None: comb = []
|
||||
if sync is None: sync = dict()
|
||||
if instances is None: instances = set()
|
||||
if tristates is None: tristates = set()
|
||||
if memories is None: memories = set()
|
||||
if sim is None: sim = []
|
||||
|
||||
|
@ -340,9 +348,9 @@ class Fragment:
|
|||
self.comb = comb
|
||||
self.sync = sync
|
||||
self.instances = set(instances)
|
||||
self.tristates = set(tristates)
|
||||
self.memories = set(memories)
|
||||
self.sim = sim
|
||||
|
||||
|
||||
def __add__(self, other):
|
||||
newsync = defaultdict(list)
|
||||
|
@ -352,6 +360,7 @@ class Fragment:
|
|||
newsync[k].extend(v)
|
||||
return Fragment(self.comb + other.comb, newsync,
|
||||
self.instances | other.instances,
|
||||
self.tristates | other.tristates,
|
||||
self.memories | other.memories,
|
||||
self.sim + other.sim)
|
||||
|
||||
|
|
|
@ -64,7 +64,7 @@ def list_inst_ios(i, ins, outs, inouts):
|
|||
return set.union(*(list_inst_ios(e, ins, outs, inouts) for e in i))
|
||||
else:
|
||||
return set()
|
||||
else:
|
||||
elif isinstance(i, Instance):
|
||||
subsets = [list_signals(item.expr) for item in filter(lambda x:
|
||||
(ins and isinstance(x, Instance.Input))
|
||||
or (outs and isinstance(x, Instance.Output))
|
||||
|
@ -74,6 +74,33 @@ def list_inst_ios(i, ins, outs, inouts):
|
|||
return set.union(*subsets)
|
||||
else:
|
||||
return set()
|
||||
else:
|
||||
return set()
|
||||
|
||||
def list_tristate_ios(i, ins, outs, inouts):
|
||||
if isinstance(i, Fragment):
|
||||
return list_tristate_ios(i.tristates, ins, outs, inouts)
|
||||
elif isinstance(i, set):
|
||||
if i:
|
||||
return set.union(*(list_tristate_ios(e, ins, outs, inouts) for e in i))
|
||||
else:
|
||||
return set()
|
||||
elif isinstance(i, Tristate):
|
||||
r = set()
|
||||
if inouts:
|
||||
r.update(list_signals(i.target))
|
||||
if ins:
|
||||
r.update(list_signals(i.o))
|
||||
r.update(list_signals(i.oe))
|
||||
if outs:
|
||||
r.update(list_signals(i.i))
|
||||
return r
|
||||
else:
|
||||
return set()
|
||||
|
||||
def list_it_ios(i, ins, outs, inouts):
|
||||
return list_inst_ios(i, ins, outs, inouts) \
|
||||
| list_tristate_ios(i, ins, outs, inouts)
|
||||
|
||||
def list_mem_ios(m, ins, outs):
|
||||
if isinstance(m, Fragment):
|
||||
|
|
|
@ -5,7 +5,7 @@ from migen.fhdl.structure import *
|
|||
from migen.fhdl.structure import _Operator, _Slice, _Assign
|
||||
from migen.fhdl.tools import *
|
||||
from migen.fhdl.namer import Namespace, build_namespace
|
||||
from migen.fhdl import verilog_mem_behavioral
|
||||
from migen.fhdl import verilog_behavioral as behavioral
|
||||
|
||||
def _printsig(ns, s):
|
||||
if s.signed:
|
||||
|
@ -135,11 +135,11 @@ def _list_comb_wires(f):
|
|||
return r
|
||||
|
||||
def _printheader(f, ios, name, ns):
|
||||
sigs = list_signals(f) | list_inst_ios(f, True, True, True) | list_mem_ios(f, True, True)
|
||||
inst_mem_outs = list_inst_ios(f, False, True, False) | list_mem_ios(f, False, True)
|
||||
inouts = list_inst_ios(f, False, False, True)
|
||||
targets = list_targets(f) | inst_mem_outs
|
||||
wires = _list_comb_wires(f) | inst_mem_outs
|
||||
sigs = list_signals(f) | list_it_ios(f, True, True, True) | list_mem_ios(f, True, True)
|
||||
it_mem_outs = list_it_ios(f, False, True, False) | list_mem_ios(f, False, True)
|
||||
inouts = list_it_ios(f, False, False, True)
|
||||
targets = list_targets(f) | it_mem_outs
|
||||
wires = _list_comb_wires(f) | it_mem_outs
|
||||
r = "module " + name + "(\n"
|
||||
firstp = True
|
||||
for sig in sorted(ios, key=lambda x: x.huid):
|
||||
|
@ -259,6 +259,12 @@ def _printinstances(f, ns, clock_domains):
|
|||
r += ");\n\n"
|
||||
return r
|
||||
|
||||
def _printtristates(f, ns, handler):
|
||||
r = ""
|
||||
for tristate in f.tristates:
|
||||
r += handler(tristate, ns)
|
||||
return r
|
||||
|
||||
def _printmemories(f, ns, handler, clock_domains):
|
||||
r = ""
|
||||
for memory in f.memories:
|
||||
|
@ -270,7 +276,7 @@ def _printinit(f, ios, ns):
|
|||
signals = list_signals(f) \
|
||||
- ios \
|
||||
- list_targets(f) \
|
||||
- list_inst_ios(f, False, True, False) \
|
||||
- list_it_ios(f, False, True, False) \
|
||||
- list_mem_ios(f, False, True)
|
||||
if signals:
|
||||
r += "initial begin\n"
|
||||
|
@ -282,7 +288,8 @@ def _printinit(f, ios, ns):
|
|||
def convert(f, ios=None, name="top",
|
||||
clock_domains=None,
|
||||
return_ns=False,
|
||||
memory_handler=verilog_mem_behavioral.handler,
|
||||
memory_handler=behavioral.mem_handler,
|
||||
tristate_handler=behavioral.tristate_handler,
|
||||
display_run=False):
|
||||
if ios is None:
|
||||
ios = set()
|
||||
|
@ -297,7 +304,7 @@ def convert(f, ios=None, name="top",
|
|||
f = lower_arrays(f)
|
||||
|
||||
ns = build_namespace(list_signals(f) \
|
||||
| list_inst_ios(f, True, True, True) \
|
||||
| list_it_ios(f, True, True, True) \
|
||||
| list_mem_ios(f, True, True) \
|
||||
| ios)
|
||||
|
||||
|
@ -306,6 +313,7 @@ def convert(f, ios=None, name="top",
|
|||
r += _printcomb(f, ns, display_run)
|
||||
r += _printsync(f, ns, clock_domains)
|
||||
r += _printinstances(f, ns, clock_domains)
|
||||
r += _printtristates(f, ns, tristate_handler)
|
||||
r += _printmemories(f, ns, memory_handler, clock_domains)
|
||||
r += _printinit(f, ios, ns)
|
||||
r += "endmodule\n"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from migen.fhdl.structure import *
|
||||
from migen.fhdl.tools import *
|
||||
|
||||
def handler(memory, ns, clock_domains):
|
||||
def mem_handler(memory, ns, clock_domains):
|
||||
r = ""
|
||||
gn = ns.get_name
|
||||
adrbits = bits_for(memory.depth-1)
|
||||
|
@ -72,3 +73,14 @@ def handler(memory, ns, clock_domains):
|
|||
r += "end\n\n"
|
||||
|
||||
return r
|
||||
|
||||
def tristate_handler(tristate, ns):
|
||||
gn = ns.get_name
|
||||
w, s = value_bits_sign(tristate.target)
|
||||
r = "assign " + gn(tristate.target) + " = " \
|
||||
+ gn(tristate.oe) + " ? " + gn(tristate.o) \
|
||||
+ " : " + str(w) + "'bz;\n"
|
||||
if tristate.i is not None:
|
||||
r += "assign " + gn(tristate.i) + " = " + gn(tristate.target) + ";\n"
|
||||
r += "\n"
|
||||
return r
|
Loading…
Reference in New Issue