Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

New 'specials' API

  • Loading branch information...
commit 49cfba50fabfed542980e7dca4683bef2fbb4110 1 parent e82ea19
@sbourdeauducq sbourdeauducq authored
View
80 examples/basic/lm32_inst.py
@@ -1,50 +1,60 @@
from migen.fhdl.structure import *
+from migen.fhdl.specials import Instance
+from migen.bus import wishbone
from migen.fhdl import verilog
class LM32:
def __init__(self):
- self.inst = Instance("lm32_top",
+ self.ibus = i = wishbone.Interface()
+ self.dbus = d = wishbone.Interface()
+ self.interrupt = Signal(32)
+ self.ext_break = Signal()
+ self._i_adr_o = Signal(32)
+ self._d_adr_o = Signal(32)
+ self._inst = Instance("lm32_top",
Instance.ClockPort("clk_i"),
Instance.ResetPort("rst_i"),
-
- Instance.Input("interrupt", 32),
- Instance.Input("ext_break", 1),
-
- Instance.Output("I_ADR_O", 32),
- Instance.Output("I_DAT_O", 32),
- Instance.Output("I_SEL_O", 4),
- Instance.Output("I_CYC_O", 1),
- Instance.Output("I_STB_O", 1),
- Instance.Output("I_WE_O", 1),
- Instance.Output("I_CTI_O", 3),
- Instance.Output("I_LOCK_O", 1),
- Instance.Output("I_BTE_O", 1),
- Instance.Input("I_DAT_I", 32),
- Instance.Input("I_ACK_I", 1),
- Instance.Input("I_ERR_I", 1),
- Instance.Input("I_RTY_I", 1),
- Instance.Output("D_ADR_O", 32),
- Instance.Output("D_DAT_O", 32),
- Instance.Output("D_SEL_O", 4),
- Instance.Output("D_CYC_O", 1),
- Instance.Output("D_STB_O", 1),
- Instance.Output("D_WE_O", 1),
- Instance.Output("D_CTI_O", 3),
- Instance.Output("D_LOCK_O", 1),
- Instance.Output("D_BTE_O", 1),
- Instance.Input("D_DAT_I", 32),
- Instance.Input("D_ACK_I", 1),
- Instance.Input("D_ERR_I", 1),
- Instance.Input("D_RTY_I", 1),
+ Instance.Input("interrupt", self.interrupt),
+ #Instance.Input("ext_break", self.ext_break),
+
+ Instance.Output("I_ADR_O", self._i_adr_o),
+ Instance.Output("I_DAT_O", i.dat_w),
+ Instance.Output("I_SEL_O", i.sel),
+ Instance.Output("I_CYC_O", i.cyc),
+ Instance.Output("I_STB_O", i.stb),
+ Instance.Output("I_WE_O", i.we),
+ Instance.Output("I_CTI_O", i.cti),
+ Instance.Output("I_LOCK_O"),
+ Instance.Output("I_BTE_O", i.bte),
+ Instance.Input("I_DAT_I", i.dat_r),
+ Instance.Input("I_ACK_I", i.ack),
+ Instance.Input("I_ERR_I", i.err),
+ Instance.Input("I_RTY_I", 0),
- name="lm32")
-
+ Instance.Output("D_ADR_O", self._d_adr_o),
+ Instance.Output("D_DAT_O", d.dat_w),
+ Instance.Output("D_SEL_O", d.sel),
+ Instance.Output("D_CYC_O", d.cyc),
+ Instance.Output("D_STB_O", d.stb),
+ Instance.Output("D_WE_O", d.we),
+ Instance.Output("D_CTI_O", d.cti),
+ Instance.Output("D_LOCK_O"),
+ Instance.Output("D_BTE_O", d.bte),
+ Instance.Input("D_DAT_I", d.dat_r),
+ Instance.Input("D_ACK_I", d.ack),
+ Instance.Input("D_ERR_I", d.err),
+ Instance.Input("D_RTY_I", 0))
+
def get_fragment(self):
- return Fragment(instances=[self.inst])
+ comb = [
+ self.ibus.adr.eq(self._i_adr_o[2:]),
+ self.dbus.adr.eq(self._d_adr_o[2:])
+ ]
+ return Fragment(comb=comb, specials={self._inst})
cpus = [LM32() for i in range(4)]
frag = Fragment()
for cpu in cpus:
frag += cpu.get_fragment()
-print(verilog.convert(frag, set([cpus[0].inst.get_io("interrupt"), cpus[0].inst.get_io("I_WE_O")])))
+print(verilog.convert(frag, {cpus[0].interrupt}))
View
5 examples/basic/memory.py
@@ -1,11 +1,12 @@
-from migen.fhdl.structure import *
+from migen.fhdl.structure import Fragment
+from migen.fhdl.specials import Memory
from migen.fhdl import verilog
mem = Memory(32, 100, init=[5, 18, 32])
p1 = mem.get_port(write_capable=True, we_granularity=8)
p2 = mem.get_port(has_re=True, clock_domain="rd")
-f = Fragment(memories=[mem])
+f = Fragment(specials={mem})
v = verilog.convert(f, ios={p1.adr, p1.dat_r, p1.we, p1.dat_w,
p2.adr, p2.dat_r, p2.re})
print(v)
View
3  examples/basic/tristate.py
@@ -1,4 +1,5 @@
from migen.fhdl.structure import *
+from migen.fhdl.specials import Tristate
from migen.fhdl import verilog
n = 6
@@ -7,5 +8,5 @@
oe = Signal()
i = Signal(n)
-f = Fragment(tristates={Tristate(pad, o, oe, i)})
+f = Fragment(specials={Tristate(pad, o, oe, i)})
print(verilog.convert(f, ios={pad, o, oe, i}))
View
1  examples/pytholite/uio.py
@@ -7,6 +7,7 @@
from migen.pytholite.transel import Register
from migen.pytholite.compiler import make_pytholite
from migen.sim.generic import Simulator
+from migen.fhdl.specials import Memory
from migen.fhdl import verilog
layout = [("r", 32)]
View
3  examples/sim/memory.py
@@ -2,6 +2,7 @@
# License: GPLv3 with additional permissions (see README).
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.sim.generic import Simulator
class Mem:
@@ -24,7 +25,7 @@ def do_simulation(self, s):
s.interrupt = True
def get_fragment(self):
- return Fragment(memories=[self.mem], sim=[self.do_simulation])
+ return Fragment(specials={self.mem}, sim=[self.do_simulation])
def main():
dut = Mem()
View
3  migen/actorlib/spi.py
@@ -1,6 +1,7 @@
# Simple Processor Interface
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.bank.description import *
from migen.flow.actor import *
@@ -117,4 +118,4 @@ def get_fragment(self):
self._reg_rd.field.w.eq(rp.dat_r)
]
- return Fragment(comb, memories=[mem])
+ return Fragment(comb, specials={mem})
View
3  migen/bus/csr.py
@@ -1,4 +1,5 @@
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.bus.simple import *
from migen.bus.transactions import *
from migen.sim.generic import PureSimulable
@@ -97,4 +98,4 @@ def get_fragment(self):
pv = self._page.field.r
comb.append(port.adr.eq(Cat(self.bus.adr[:len(port.adr)-len(pv)], pv)))
- return Fragment(comb, sync, memories=[self.mem])
+ return Fragment(comb, sync, specials={self.mem})
View
3  migen/bus/wishbone.py
@@ -1,4 +1,5 @@
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.corelogic import roundrobin
from migen.corelogic.misc import optree
from migen.bus.simple import *
@@ -228,4 +229,4 @@ def get_fragment(self):
self.bus.ack.eq(1)
)
]
- return Fragment(comb, sync, memories=[self.mem])
+ return Fragment(comb, sync, specials={self.mem})
View
5 migen/bus/wishbone2asmi.py
@@ -1,5 +1,6 @@
-from migen.bus import wishbone
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
+from migen.bus import wishbone
from migen.corelogic.fsm import FSM
from migen.corelogic.misc import split, displacer, chooser
from migen.corelogic.record import Record
@@ -136,5 +137,5 @@ def get_fragment(self):
fsm.next_state(fsm.TEST_HIT)
)
- return Fragment(comb, sync, memories=[data_mem, tag_mem]) \
+ return Fragment(comb, sync, specials={data_mem, tag_mem}) \
+ fsm.get_fragment()
View
9 migen/fhdl/namer.py
@@ -131,13 +131,10 @@ def __init__(self, pnd):
self.pnd = pnd
def get_name(self, sig):
- if isinstance(sig, Memory):
- sig_name = "mem"
+ if sig.name_override is not None:
+ sig_name = sig.name_override
else:
- if sig.name_override is not None:
- sig_name = sig.name_override
- else:
- sig_name = self.pnd[sig]
+ sig_name = self.pnd[sig]
try:
n = self.sigs[sig]
except KeyError:
View
311 migen/fhdl/specials.py
@@ -0,0 +1,311 @@
+from migen.fhdl.structure import *
+from migen.fhdl.tools import list_signals, value_bits_sign
+
+from migen.fhdl.verilog import _printexpr as verilog_printexpr
+
+class Special(HUID):
+ def rename_clock_domain(self):
+ pass
+
+ def get_clock_domains(self):
+ return set()
+
+class Tristate(Special):
+ def __init__(self, target, o, oe, i=None):
+ Special.__init__(self)
+ self.target = target
+ self.o = o
+ self.oe = oe
+ self.i = i
+
+ def list_ios(self, ins, outs, inouts):
+ r = set()
+ if inouts:
+ r.update(list_signals(self.target))
+ if ins:
+ r.update(list_signals(self.o))
+ r.update(list_signals(self.oe))
+ if outs:
+ r.update(list_signals(self.i))
+ return r
+
+ @staticmethod
+ def emit_verilog(tristate, ns, clock_domains):
+ def pe(e):
+ return verilog_printexpr(ns, e)[0]
+ w, s = value_bits_sign(tristate.target)
+ r = "assign " + pe(tristate.target) + " = " \
+ + pe(tristate.oe) + " ? " + pe(tristate.o) \
+ + " : " + str(w) + "'bz;\n"
+ if tristate.i is not None:
+ r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n"
+ r += "\n"
+ return r
+
+class TSTriple:
+ def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
+ self.o = Signal(bits_sign, min=min, max=max, reset=reset_o)
+ self.oe = Signal(reset=reset_oe)
+ self.i = Signal(bits_sign, min=min, max=max)
+
+ def get_tristate(self, target):
+ return Tristate(target, self.o, self.oe, self.i)
+
+class Instance(Special):
+ def __init__(self, of, *items, name=""):
+ Special.__init__(self)
+ self.of = of
+ if name:
+ self.name_override = name
+ else:
+ self.name_override = of
+ self.items = items
+
+ class _IO:
+ def __init__(self, name, expr=None):
+ self.name = name
+ if expr is None:
+ expr = Signal()
+ self.expr = expr
+ class Input(_IO):
+ pass
+ class Output(_IO):
+ pass
+ class InOut(_IO):
+ pass
+
+ class Parameter:
+ def __init__(self, name, value):
+ self.name = name
+ self.value = value
+
+ class _CR:
+ def __init__(self, name_inst, domain="sys", invert=False):
+ self.name_inst = name_inst
+ self.domain = domain
+ self.invert = invert
+ class ClockPort(_CR):
+ pass
+ class ResetPort(_CR):
+ pass
+
+ def get_io(self, name):
+ for item in self.items:
+ if isinstance(item, Instance._IO) and item.name == name:
+ return item.expr
+
+ def rename_clock_domain(self):
+ for cr in filter(lambda x: isinstance(x, Instance._CR), self.items):
+ if cr.domain == old:
+ cr.domain = new
+
+ def get_clock_domains(self):
+ return set(cr.domain
+ for cr in filter(lambda x: isinstance(x, Instance._CR), self.items))
+
+ def list_ios(self, ins, outs, inouts):
+ subsets = [list_signals(item.expr) for item in filter(lambda x:
+ (ins and isinstance(x, Instance.Input))
+ or (outs and isinstance(x, Instance.Output))
+ or (inouts and isinstance(x, Instance.InOut)),
+ self.items)]
+ if subsets:
+ return set.union(*subsets)
+ else:
+ return set()
+
+ @staticmethod
+ def emit_verilog(instance, ns, clock_domains):
+ r = instance.of + " "
+ parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items))
+ if parameters:
+ r += "#(\n"
+ firstp = True
+ for p in parameters:
+ if not firstp:
+ r += ",\n"
+ firstp = False
+ r += "\t." + p.name + "("
+ if isinstance(p.value, (int, bool)):
+ r += _printintbool(p.value)[0]
+ elif isinstance(p.value, float):
+ r += str(p.value)
+ elif isinstance(p.value, str):
+ r += "\"" + p.value + "\""
+ else:
+ raise TypeError
+ r += ")"
+ r += "\n) "
+ r += ns.get_name(instance)
+ if parameters: r += " "
+ r += "(\n"
+ firstp = True
+ for p in instance.items:
+ if isinstance(p, Instance._IO):
+ name_inst = p.name
+ name_design = verilog_printexpr(ns, p.expr)[0]
+ elif isinstance(p, Instance.ClockPort):
+ name_inst = p.name_inst
+ name_design = ns.get_name(clock_domains[p.domain].clk)
+ if p.invert:
+ name_design = "~" + name_design
+ elif isinstance(p, Instance.ResetPort):
+ name_inst = p.name_inst
+ name_design = ns.get_name(clock_domains[p.domain].rst)
+ else:
+ continue
+ if not firstp:
+ r += ",\n"
+ firstp = False
+ r += "\t." + name_inst + "(" + name_design + ")"
+ if not firstp:
+ r += "\n"
+ r += ");\n\n"
+ return r
+
+(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
+
+class _MemoryPort:
+ def __init__(self, adr, dat_r, we=None, dat_w=None,
+ async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
+ clock_domain="sys"):
+ self.adr = adr
+ self.dat_r = dat_r
+ self.we = we
+ self.dat_w = dat_w
+ self.async_read = async_read
+ self.re = re
+ self.we_granularity = we_granularity
+ self.mode = mode
+ self.clock_domain = clock_domain
+
+class Memory(Special):
+ def __init__(self, width, depth, init=None):
+ Special.__init__(self)
+ self.width = width
+ self.depth = depth
+ self.ports = []
+ self.init = init
+
+ def get_port(self, write_capable=False, async_read=False,
+ has_re=False, we_granularity=0, mode=WRITE_FIRST,
+ clock_domain="sys"):
+ if we_granularity >= self.width:
+ we_granularity = 0
+ adr = Signal(max=self.depth)
+ dat_r = Signal(self.width)
+ if write_capable:
+ if we_granularity:
+ we = Signal(self.width//we_granularity)
+ else:
+ we = Signal()
+ dat_w = Signal(self.width)
+ else:
+ we = None
+ dat_w = None
+ if has_re:
+ re = Signal()
+ else:
+ re = None
+ mp = _MemoryPort(adr, dat_r, we, dat_w,
+ async_read, re, we_granularity, mode,
+ clock_domain)
+ self.ports.append(mp)
+ return mp
+
+ def rename_clock_domain(self):
+ for port in self.ports:
+ if port.clock_domain == old:
+ port.clock_domain = new
+
+ def get_clock_domains(self):
+ return set(port.clock_domain for port in self.ports)
+
+ def list_ios(self, ins, outs, inouts):
+ s = set()
+ def add(*sigs):
+ for sig in sigs:
+ if sig is not None:
+ s.add(sig)
+ for p in self.ports:
+ if ins:
+ add(p.adr, p.we, p.dat_w, p.re)
+ if outs:
+ add(p.dat_r)
+ return s
+
+ name_override = "mem"
+
+ @staticmethod
+ def emit_verilog(memory, ns, clock_domains):
+ r = ""
+ gn = ns.get_name # usable instead of verilog_printexpr as ports contain only signals
+ 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
View
147 migen/fhdl/structure.py
@@ -229,126 +229,11 @@ def __getitem__(self, key):
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
-
-class TSTriple:
- def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0):
- self.o = Signal(bits_sign, min=min, max=max, reset=reset_o)
- self.oe = Signal(reset=reset_oe)
- self.i = Signal(bits_sign, min=min, max=max)
-
- def get_tristate(self, target):
- return Tristate(target, self.o, self.oe, self.i)
-
-# extras
-
-class Instance(HUID):
- def __init__(self, of, *items, name=""):
- HUID.__init__(self)
- self.of = of
- if name:
- self.name_override = name
- else:
- self.name_override = of
- self.items = items
-
- class _IO:
- def __init__(self, name, expr=None):
- self.name = name
- if expr is None:
- expr = Signal()
- self.expr = expr
- class Input(_IO):
- pass
- class Output(_IO):
- pass
- class InOut(_IO):
- pass
-
- class Parameter:
- def __init__(self, name, value):
- self.name = name
- self.value = value
-
- class _CR:
- def __init__(self, name_inst, domain="sys", invert=False):
- self.name_inst = name_inst
- self.domain = domain
- self.invert = invert
- class ClockPort(_CR):
- pass
- class ResetPort(_CR):
- pass
-
- def get_io(self, name):
- for item in self.items:
- if isinstance(item, Instance._IO) and item.name == name:
- return item.expr
-
-(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3)
-
-class _MemoryPort:
- def __init__(self, adr, dat_r, we=None, dat_w=None,
- async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST,
- clock_domain="sys"):
- self.adr = adr
- self.dat_r = dat_r
- self.we = we
- self.dat_w = dat_w
- self.async_read = async_read
- self.re = re
- self.we_granularity = we_granularity
- self.mode = mode
- self.clock_domain = clock_domain
-
-class Memory(HUID):
- def __init__(self, width, depth, init=None):
- HUID.__init__(self)
- self.width = width
- self.depth = depth
- self.ports = []
- self.init = init
-
- def get_port(self, write_capable=False, async_read=False,
- has_re=False, we_granularity=0, mode=WRITE_FIRST,
- clock_domain="sys"):
- if we_granularity >= self.width:
- we_granularity = 0
- adr = Signal(max=self.depth)
- dat_r = Signal(self.width)
- if write_capable:
- if we_granularity:
- we = Signal(self.width//we_granularity)
- else:
- we = Signal()
- dat_w = Signal(self.width)
- else:
- we = None
- dat_w = None
- if has_re:
- re = Signal()
- else:
- re = None
- mp = _MemoryPort(adr, dat_r, we, dat_w,
- async_read, re, we_granularity, mode,
- clock_domain)
- self.ports.append(mp)
- return mp
-
-#
-
class Fragment:
- def __init__(self, comb=None, sync=None, instances=None, tristates=None, memories=None, sim=None):
+ def __init__(self, comb=None, sync=None, specials=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 specials is None: specials = set()
if sim is None: sim = []
if isinstance(sync, list):
@@ -356,9 +241,7 @@ def __init__(self, comb=None, sync=None, instances=None, tristates=None, memorie
self.comb = comb
self.sync = sync
- self.instances = set(instances)
- self.tristates = set(tristates)
- self.memories = set(memories)
+ self.specials = set(specials)
self.sim = sim
def __add__(self, other):
@@ -368,32 +251,14 @@ def __add__(self, other):
for k, v in other.sync.items():
newsync[k].extend(v)
return Fragment(self.comb + other.comb, newsync,
- self.instances | other.instances,
- self.tristates | other.tristates,
- self.memories | other.memories,
+ self.specials | other.specials,
self.sim + other.sim)
def rename_clock_domain(self, old, new):
self.sync["new"] = self.sync["old"]
del self.sync["old"]
- for inst in self.instances:
- for cr in filter(lambda x: isinstance(x, Instance._CR), inst.items):
- if cr.domain == old:
- cr.domain = new
- for mem in self.memories:
- for port in mem.ports:
- if port.clock_domain == old:
- port.clock_domain = new
-
- def get_clock_domains(self):
- r = set(self.sync.keys())
- r |= set(cr.domain
- for inst in self.instances
- for cr in filter(lambda x: isinstance(x, Instance._CR), inst.items))
- r |= set(port.clock_domain
- for mem in self.memories
- for port in mem.ports)
- return r
+ for special in self.specials:
+ special.rename_clock_domain(old, new)
def call_sim(self, simulator):
for s in self.sim:
View
71 migen/fhdl/tools.py
@@ -56,68 +56,17 @@ def group_by_targets(sl):
groups.append((targets, [statement]))
return groups
-def list_inst_ios(i, ins, outs, inouts):
- if isinstance(i, Fragment):
- return list_inst_ios(i.instances, ins, outs, inouts)
- elif isinstance(i, set):
- if i:
- return set.union(*(list_inst_ios(e, ins, outs, inouts) for e in i))
- else:
- return set()
- 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))
- or (inouts and isinstance(x, Instance.InOut)),
- i.items)]
- if subsets:
- return set.union(*subsets)
- else:
- return set()
- else:
- return set()
+def list_special_ios(f, ins, outs, inouts):
+ r = set()
+ for special in f.specials:
+ r |= special.list_ios(ins, outs, inouts)
+ return r
-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):
- return list_mem_ios(m.memories, ins, outs)
- else:
- s = set()
- def add(*sigs):
- for sig in sigs:
- if sig is not None:
- s.add(sig)
- for x in m:
- for p in x.ports:
- if ins:
- add(p.adr, p.we, p.dat_w, p.re)
- if outs:
- add(p.dat_r)
- return s
+def list_clock_domains(f):
+ r = set(f.sync.keys())
+ for special in f.specials:
+ r |= special.get_clock_domains()
+ return r
def is_variable(node):
if isinstance(node, Signal):
View
83 migen/fhdl/verilog.py
@@ -5,7 +5,6 @@
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_behavioral as behavioral
def _printsig(ns, s):
if s.signed:
@@ -135,9 +134,9 @@ def _list_comb_wires(f):
return r
def _printheader(f, ios, name, ns):
- 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)
+ sigs = list_signals(f) | list_special_ios(f, True, True, True)
+ it_mem_outs = list_special_ios(f, False, True, False)
+ inouts = list_special_ios(f, False, False, True)
targets = list_targets(f) | it_mem_outs
wires = _list_comb_wires(f) | it_mem_outs
r = "module " + name + "(\n"
@@ -209,66 +208,10 @@ def _printsync(f, ns, clock_domains):
r += "end\n\n"
return r
-def _printinstances(f, ns, clock_domains):
+def _printspecials(f, ns, clock_domains):
r = ""
- for x in f.instances:
- parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), x.items))
- r += x.of + " "
- if parameters:
- r += "#(\n"
- firstp = True
- for p in parameters:
- if not firstp:
- r += ",\n"
- firstp = False
- r += "\t." + p.name + "("
- if isinstance(p.value, (int, bool)):
- r += _printintbool(p.value)[0]
- elif isinstance(p.value, float):
- r += str(p.value)
- elif isinstance(p.value, str):
- r += "\"" + p.value + "\""
- else:
- raise TypeError
- r += ")"
- r += "\n) "
- r += ns.get_name(x)
- if parameters: r += " "
- r += "(\n"
- firstp = True
- for p in x.items:
- if isinstance(p, Instance._IO):
- name_inst = p.name
- name_design = _printexpr(ns, p.expr)[0]
- elif isinstance(p, Instance.ClockPort):
- name_inst = p.name_inst
- name_design = ns.get_name(clock_domains[p.domain].clk)
- if p.invert:
- name_design = "~" + name_design
- elif isinstance(p, Instance.ResetPort):
- name_inst = p.name_inst
- name_design = ns.get_name(clock_domains[p.domain].rst)
- else:
- continue
- if not firstp:
- r += ",\n"
- firstp = False
- r += "\t." + name_inst + "(" + name_design + ")"
- if not firstp:
- r += "\n"
- 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:
- r += handler(memory, ns, clock_domains)
+ for special in sorted(f.specials, key=lambda x: x.huid):
+ r += special.emit_verilog(special, ns, clock_domains)
return r
def _printinit(f, ios, ns):
@@ -276,8 +219,7 @@ def _printinit(f, ios, ns):
signals = list_signals(f) \
- ios \
- list_targets(f) \
- - list_it_ios(f, False, True, False) \
- - list_mem_ios(f, False, True)
+ - list_special_ios(f, False, True, False)
if signals:
r += "initial begin\n"
for s in sorted(signals, key=lambda x: x.huid):
@@ -288,14 +230,12 @@ def _printinit(f, ios, ns):
def convert(f, ios=None, name="top",
clock_domains=None,
return_ns=False,
- memory_handler=behavioral.mem_handler,
- tristate_handler=behavioral.tristate_handler,
display_run=False):
if ios is None:
ios = set()
if clock_domains is None:
clock_domains = dict()
- for d in f.get_clock_domains():
+ for d in list_clock_domains(f):
cd = ClockDomain(d)
clock_domains[d] = cd
ios.add(cd.clk)
@@ -304,17 +244,14 @@ def convert(f, ios=None, name="top",
f = lower_arrays(f)
ns = build_namespace(list_signals(f) \
- | list_it_ios(f, True, True, True) \
- | list_mem_ios(f, True, True) \
+ | list_special_ios(f, True, True, True) \
| ios)
r = "/* Machine-generated using Migen */\n"
r += _printheader(f, ios, name, ns)
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 += _printspecials(f, ns, clock_domains)
r += _printinit(f, ios, ns)
r += "endmodule\n"
View
86 migen/fhdl/verilog_behavioral.py
@@ -1,86 +0,0 @@
-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
View
1  migen/pytholite/io.py
@@ -2,6 +2,7 @@
from itertools import zip_longest
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.uio.ioo import UnifiedIOObject
from migen.flow.actor import Source, Sink
from migen.flow.transactions import *
View
1  migen/sim/generic.py
@@ -2,6 +2,7 @@
# License: GPLv3 with additional permissions (see README).
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.fhdl import verilog
from migen.sim.ipc import *
from migen.sim import icarus
View
3  migen/uio/ioo.py
@@ -1,4 +1,5 @@
from migen.fhdl.structure import *
+from migen.fhdl.specials import Memory
from migen.flow.actor import *
from migen.flow.transactions import *
from migen.actorlib.sim import TokenExchanger
@@ -14,7 +15,7 @@ def __init__(self, dataflow=None, buses={}):
self._memories = set(v for v in self.buses.values() if isinstance(v, Memory))
def get_fragment(self):
- return Fragment(memories=self._memories)
+ return Fragment(specials={self._memories})
(_WAIT_COMPLETE, _WAIT_POLL) = range(2)
Please sign in to comment.
Something went wrong with that request. Please try again.