Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/migen
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3c75121783e5
Choose a base ref
...
head repository: m-labs/migen
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 04df076fba63
Choose a head ref
  • 3 commits
  • 6 files changed
  • 1 contributor

Commits on Mar 12, 2013

  1. fhdl/tracer: recognize LOAD_DEREF opcode

    Sebastien Bourdeauducq committed Mar 12, 2013
    Copy the full SHA
    12158ce View commit details
  2. fhdl/tracer: recognize CALL_FUNCTION_VAR opcode

    Sebastien Bourdeauducq committed Mar 12, 2013
    Copy the full SHA
    7e2581b View commit details
  3. bank: automatic register naming

    Sebastien Bourdeauducq committed Mar 12, 2013
    Copy the full SHA
    04df076 View commit details
Showing with 72 additions and 48 deletions.
  1. +16 −17 migen/actorlib/spi.py
  2. +21 −14 migen/bank/description.py
  3. +3 −4 migen/bank/eventmanager.py
  4. +1 −1 migen/bus/csr.py
  5. +21 −2 migen/fhdl/tracer.py
  6. +10 −10 migen/flow/isd.py
33 changes: 16 additions & 17 deletions migen/actorlib/spi.py
Original file line number Diff line number Diff line change
@@ -40,8 +40,7 @@ def _create_registers_assign(layout, target, atomic, prefix=""):
alignment = element[3]
else:
alignment = 0
reg = RegisterField(prefix + name, nbits + alignment,
reset=reset, atomic_write=atomic)
reg = RegisterField(nbits + alignment, reset=reset, atomic_write=atomic, name=prefix + name)
registers.append(reg)
assigns.append(getattr(target, name).eq(reg.field.r[alignment:]))
return registers, assigns
@@ -57,11 +56,11 @@ def __init__(self, layout, mode):
if mode == MODE_EXTERNAL:
self.trigger = Signal()
elif mode == MODE_SINGLE_SHOT:
shoot = RegisterRaw("shoot")
shoot = RegisterRaw()
self._registers.insert(0, shoot)
self.trigger = shoot.re
elif mode == MODE_CONTINUOUS:
enable = RegisterField("enable")
enable = RegisterField()
self._registers.insert(0, enable)
self.trigger = enable.field.r
else:
@@ -86,36 +85,36 @@ def __init__(self, layout, depth=1024):
self._depth = depth
self._dw = sum(len(s) for s in self.token("sink").flatten())

self._reg_wa = RegisterField("write_address", bits_for(self._depth-1), access_bus=READ_WRITE, access_dev=READ_WRITE)
self._reg_wc = RegisterField("write_count", bits_for(self._depth), access_bus=READ_WRITE, access_dev=READ_WRITE, atomic_write=True)
self._reg_ra = RegisterField("read_address", bits_for(self._depth-1), access_bus=READ_WRITE, access_dev=READ_ONLY)
self._reg_rd = RegisterField("read_data", self._dw, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_wa = RegisterField(bits_for(self._depth-1), READ_WRITE, READ_WRITE)
self._r_wc = RegisterField(bits_for(self._depth), READ_WRITE, READ_WRITE, atomic_write=True)
self._r_ra = RegisterField(bits_for(self._depth-1), READ_WRITE, READ_ONLY)
self._r_rd = RegisterField(self._dw, READ_ONLY, WRITE_ONLY)

def get_registers(self):
return [self._reg_wa, self._reg_wc, self._reg_ra, self._reg_rd]
return [self._r_wa, self._r_wc, self._r_ra, self._r_rd]

def get_fragment(self):
mem = Memory(self._dw, self._depth)
wp = mem.get_port(write_capable=True)
rp = mem.get_port()

comb = [
If(self._reg_wc.field.r != 0,
If(self._r_wc.field.r != 0,
self.endpoints["sink"].ack.eq(1),
If(self.endpoints["sink"].stb,
self._reg_wa.field.we.eq(1),
self._reg_wc.field.we.eq(1),
self._r_wa.field.we.eq(1),
self._r_wc.field.we.eq(1),
wp.we.eq(1)
)
),
self._reg_wa.field.w.eq(self._reg_wa.field.r + 1),
self._reg_wc.field.w.eq(self._reg_wc.field.r - 1),
self._r_wa.field.w.eq(self._r_wa.field.r + 1),
self._r_wc.field.w.eq(self._r_wc.field.r - 1),

wp.adr.eq(self._reg_wa.field.r),
wp.adr.eq(self._r_wa.field.r),
wp.dat_w.eq(Cat(*self.token("sink").flatten())),

rp.adr.eq(self._reg_ra.field.r),
self._reg_rd.field.w.eq(rp.dat_r)
rp.adr.eq(self._r_ra.field.r),
self._r_rd.field.w.eq(rp.dat_r)
]

return Fragment(comb, specials={mem})
35 changes: 21 additions & 14 deletions migen/bank/description.py
Original file line number Diff line number Diff line change
@@ -2,14 +2,20 @@

from migen.fhdl.structure import *
from migen.fhdl.specials import Memory
from migen.fhdl.tracer import get_obj_var_name

class _Register(HUID):
pass
def __init__(self, name):
HUID.__init__(self)
self.name = get_obj_var_name(name)
if self.name is None:
raise ValueError("Cannot extract register name from code, need to specify.")
if len(self.name) > 2 and self.name[:2] == "r_":
self.name = self.name[2:]

class RegisterRaw(_Register):
def __init__(self, name, size=1):
_Register.__init__(self)
self.name = name
def __init__(self, size=1, name=None):
_Register.__init__(self, name)
self.size = size
self.re = Signal()
self.r = Signal(self.size)
@@ -18,8 +24,10 @@ def __init__(self, name, size=1):
(READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3)

class Field:
def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False):
self.name = name
def __init__(self, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False, name=None):
self.name = get_obj_var_name(name)
if self.name is None:
raise ValueError("Cannot extract field name from code, need to specify.")
self.size = size
self.access_bus = access_bus
self.access_dev = access_dev
@@ -35,15 +43,14 @@ def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, re
self.we = Signal()

class RegisterFields(_Register):
def __init__(self, name, fields):
_Register.__init__(self)
self.name = name
def __init__(self, *fields, name=None):
_Register.__init__(self, name)
self.fields = fields

class RegisterField(RegisterFields):
def __init__(self, name, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False):
self.field = Field(name, size, access_bus, access_dev, reset, atomic_write)
RegisterFields.__init__(self, name, [self.field])
def __init__(self, size=1, access_bus=READ_WRITE, access_dev=READ_ONLY, reset=0, atomic_write=False, name=None):
self.field = Field(size, access_bus, access_dev, reset, atomic_write, name="")
RegisterFields.__init__(self, self.field, name=name)

def regprefix(prefix, registers):
r = []
@@ -140,7 +147,7 @@ def expand_description(description, busword):
if mode == ALIAS_ATOMIC_HOLD:
commit_list.append(alias)
top -= slice1
d.append(RegisterFields(reg.name, f))
d.append(RegisterFields(*f, name=reg.name))
alias = FieldAlias(mode, field, top - slice2, top, commit_list)
f = [alias]
if mode == ALIAS_ATOMIC_HOLD:
@@ -150,7 +157,7 @@ def expand_description(description, busword):
else:
f.append(field)
if f:
d.append(RegisterFields(reg.name, f))
d.append(RegisterFields(*f, name=reg.name))
else:
raise TypeError
return d
7 changes: 3 additions & 4 deletions migen/bank/eventmanager.py
Original file line number Diff line number Diff line change
@@ -23,10 +23,9 @@ def do_finalize(self):
sources_u = [v for v in self.__dict__.values() if isinstance(v, _EventSource)]
sources = sorted(sources_u, key=lambda x: x.huid)
n = len(sources)
self.status = RegisterRaw("status", n)
self.pending = RegisterRaw("pending", n)
self.enable = RegisterFields("enable",
[Field("s" + str(i), access_bus=READ_WRITE, access_dev=READ_ONLY) for i in range(n)])
self.status = RegisterRaw(n)
self.pending = RegisterRaw(n)
self.enable = RegisterFields(*(Field(1, READ_WRITE, READ_ONLY, name="e" + str(i)) for i in range(n)))

# status
for i, source in enumerate(sources):
2 changes: 1 addition & 1 deletion migen/bus/csr.py
Original file line number Diff line number Diff line change
@@ -68,7 +68,7 @@ def __init__(self, mem_or_size, address, read_only=None, bus=None):
self.word_bits = 0
page_bits = _compute_page_bits(self.mem.depth + self.word_bits)
if page_bits:
self._page = RegisterField(self.mem.name_override + "_page", page_bits)
self._page = RegisterField(page_bits, name=self.mem.name_override + "_page")
else:
self._page = None
if read_only is None:
23 changes: 21 additions & 2 deletions migen/fhdl/tracer.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,8 @@
def get_var_name(frame):
code = frame.f_code
call_index = frame.f_lasti
if opname[code.co_code[call_index]] != "CALL_FUNCTION":
call_opc = opname[code.co_code[call_index]]
if call_opc != "CALL_FUNCTION" and call_opc != "CALL_FUNCTION_VAR":
return None
index = call_index+3
while True:
@@ -19,7 +20,7 @@ def get_var_name(frame):
elif opc == "STORE_DEREF":
name_index = int(code.co_code[index+1])
return code.co_cellvars[name_index]
elif opc == "LOAD_GLOBAL" or opc == "LOAD_ATTR" or opc == "LOAD_FAST":
elif opc == "LOAD_GLOBAL" or opc == "LOAD_ATTR" or opc == "LOAD_FAST" or opc == "LOAD_DEREF":
index += 3
elif opc == "DUP_TOP":
index += 1
@@ -33,6 +34,24 @@ def remove_underscore(s):
s = s[1:]
return s

def get_obj_var_name(override=None, default=None):
if override:
return override

frame = inspect.currentframe().f_back
# We can be called via derived classes. Go back the stack frames
# until we reach the first class that does not inherit from us.
ourclass = frame.f_locals["self"].__class__
while "self" in frame.f_locals and isinstance(frame.f_locals["self"], ourclass):
frame = frame.f_back

vn = get_var_name(frame)
if vn is None:
vn = default
else:
vn = remove_underscore(vn)
return vn

name_to_idx = defaultdict(int)
classname_to_objs = dict()

20 changes: 10 additions & 10 deletions migen/flow/isd.py
Original file line number Diff line number Diff line change
@@ -11,11 +11,11 @@ def __init__(self, endpoint, nbits):
self.reset = Signal()
self.freeze = Signal()

self._ack_count = RegisterField("ack_count", self.nbits, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._nack_count = RegisterField("nack_count", self.nbits, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._cur_stb = Field("cur_stb", 1, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._cur_ack = Field("cur_ack", 1, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._cur_status = RegisterFields("cur_status", [self._cur_stb, self._cur_ack])
self._ack_count = RegisterField(self.nbits, READ_ONLY, WRITE_ONLY)
self._nack_count = RegisterField(self.nbits, READ_ONLY, WRITE_ONLY)
self._cur_stb = Field(1, READ_ONLY, WRITE_ONLY)
self._cur_ack = Field(1, READ_ONLY, WRITE_ONLY)
self._cur_status = RegisterFields(self._cur_stb, self._cur_ack)

def get_registers(self):
return [self._ack_count, self._nack_count, self._cur_status]
@@ -57,11 +57,11 @@ class DFGReporter(DFGHook):
def __init__(self, dfg, nbits):
self._nbits = nbits

self._r_magic = RegisterField("magic", 16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_neps = RegisterField("neps", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_nbits = RegisterField("nbits", 8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_freeze = RegisterField("freeze", 1)
self._r_reset = RegisterRaw("reset", 1)
self._r_magic = RegisterField(16, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_neps = RegisterField(8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_nbits = RegisterField(8, access_bus=READ_ONLY, access_dev=WRITE_ONLY)
self._r_freeze = RegisterField()
self._r_reset = RegisterRaw()

self.order = []
DFGHook.__init__(self, dfg, self._create)