--- /dev/null
+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}))
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):
#
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 = []
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)
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)
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))
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):
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:
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):
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:
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"
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()
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)
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"
--- /dev/null
+from migen.fhdl.structure import *
+from migen.fhdl.tools import *
+
+def mem_handler(memory, ns, clock_domains):
+ r = ""
+ gn = ns.get_name
+ adrbits = bits_for(memory.depth-1)
+
+ r += "reg [" + str(memory.width-1) + ":0] " \
+ + gn(memory) \
+ + "[0:" + str(memory.depth-1) + "];\n"
+
+ adr_regs = {}
+ data_regs = {}
+ for port in memory.ports:
+ if not port.async_read:
+ if port.mode == WRITE_FIRST and port.we is not None:
+ adr_reg = Signal(name_override="memadr")
+ r += "reg [" + str(adrbits-1) + ":0] " \
+ + gn(adr_reg) + ";\n"
+ adr_regs[id(port)] = adr_reg
+ else:
+ data_reg = Signal(name_override="memdat")
+ r += "reg [" + str(memory.width-1) + ":0] " \
+ + gn(data_reg) + ";\n"
+ data_regs[id(port)] = data_reg
+
+ for port in memory.ports:
+ r += "always @(posedge " + gn(clock_domains[port.clock_domain].clk) + ") begin\n"
+ if port.we is not None:
+ if port.we_granularity:
+ n = memory.width//port.we_granularity
+ for i in range(n):
+ m = i*port.we_granularity
+ M = (i+1)*port.we_granularity-1
+ sl = "[" + str(M) + ":" + str(m) + "]"
+ r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
+ r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
+ else:
+ r += "\tif (" + gn(port.we) + ")\n"
+ r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
+ if not port.async_read:
+ if port.mode == WRITE_FIRST and port.we is not None:
+ rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
+ else:
+ bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
+ if port.mode == READ_FIRST or port.we is None:
+ rd = "\t" + bassign
+ elif port.mode == NO_CHANGE:
+ rd = "\tif (!" + gn(port.we) + ")\n" \
+ + "\t\t" + bassign
+ if port.re is None:
+ r += rd
+ else:
+ r += "\tif (" + gn(port.re) + ")\n"
+ r += "\t" + rd.replace("\n\t", "\n\t\t")
+ r += "end\n\n"
+
+ for port in memory.ports:
+ if port.async_read:
+ r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
+ else:
+ if port.mode == WRITE_FIRST and port.we is not None:
+ r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
+ else:
+ r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
+ r += "\n"
+
+ if memory.init is not None:
+ r += "initial begin\n"
+ for i, c in enumerate(memory.init):
+ r += "\t" + gn(memory) + "[" + str(i) + "] <= " + str(memory.width) + "'d" + str(c) + ";\n"
+ 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
+++ /dev/null
-from migen.fhdl.structure import *
-
-def handler(memory, ns, clock_domains):
- r = ""
- gn = ns.get_name
- adrbits = bits_for(memory.depth-1)
-
- r += "reg [" + str(memory.width-1) + ":0] " \
- + gn(memory) \
- + "[0:" + str(memory.depth-1) + "];\n"
-
- adr_regs = {}
- data_regs = {}
- for port in memory.ports:
- if not port.async_read:
- if port.mode == WRITE_FIRST and port.we is not None:
- adr_reg = Signal(name_override="memadr")
- r += "reg [" + str(adrbits-1) + ":0] " \
- + gn(adr_reg) + ";\n"
- adr_regs[id(port)] = adr_reg
- else:
- data_reg = Signal(name_override="memdat")
- r += "reg [" + str(memory.width-1) + ":0] " \
- + gn(data_reg) + ";\n"
- data_regs[id(port)] = data_reg
-
- for port in memory.ports:
- r += "always @(posedge " + gn(clock_domains[port.clock_domain].clk) + ") begin\n"
- if port.we is not None:
- if port.we_granularity:
- n = memory.width//port.we_granularity
- for i in range(n):
- m = i*port.we_granularity
- M = (i+1)*port.we_granularity-1
- sl = "[" + str(M) + ":" + str(m) + "]"
- r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n"
- r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n"
- else:
- r += "\tif (" + gn(port.we) + ")\n"
- r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n"
- if not port.async_read:
- if port.mode == WRITE_FIRST and port.we is not None:
- rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n"
- else:
- bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n"
- if port.mode == READ_FIRST or port.we is None:
- rd = "\t" + bassign
- elif port.mode == NO_CHANGE:
- rd = "\tif (!" + gn(port.we) + ")\n" \
- + "\t\t" + bassign
- if port.re is None:
- r += rd
- else:
- r += "\tif (" + gn(port.re) + ")\n"
- r += "\t" + rd.replace("\n\t", "\n\t\t")
- r += "end\n\n"
-
- for port in memory.ports:
- if port.async_read:
- r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n"
- else:
- if port.mode == WRITE_FIRST and port.we is not None:
- r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n"
- else:
- r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n"
- r += "\n"
-
- if memory.init is not None:
- r += "initial begin\n"
- for i, c in enumerate(memory.init):
- r += "\t" + gn(memory) + "[" + str(i) + "] <= " + str(memory.width) + "'d" + str(c) + ";\n"
- r += "end\n\n"
-
- return r