from migen.fhdl import verilog
from migen.genlib.cdc import MultiReg
from migen.bank import description, csrgen
-from migen.bank.description import READ_ONLY, WRITE_ONLY
class Example(Module):
def __init__(self, ninputs=32, noutputs=32):
- r_o = description.RegisterField(noutputs, atomic_write=True)
- r_i = description.RegisterField(ninputs, READ_ONLY, WRITE_ONLY)
+ r_o = description.CSRStorage(noutputs, atomic_write=True)
+ r_i = description.CSRStatus(ninputs)
self.submodules.bank = csrgen.Bank([r_o, r_i])
self.gpio_in = Signal(ninputs)
###
gpio_in_s = Signal(ninputs)
- self.specials += MultiReg(self.gpio_in, gpio_in_s, "sys")
+ self.specials += MultiReg(self.gpio_in, gpio_in_s)
self.comb += [
- r_i.field.w.eq(gpio_in_s),
- self.gpio_out.eq(r_o.field.r)
+ self.gpio_out.eq(r_o.storage),
+ r_i.status.eq(gpio_in_s)
]
example = Example()
r.append((element[0], element[1]))
return r
-def _create_registers_assign(layout, target, atomic, prefix=""):
- registers = []
+def _create_csrs_assign(layout, target, atomic, prefix=""):
+ csrs = []
assigns = []
for element in layout:
if isinstance(element[1], list):
- r_registers, r_assigns = _create_registers_assign(element[1],
+ r_csrs, r_assigns = _create_csrs_assign(element[1],
atomic,
getattr(target, element[0]),
element[0] + "_")
- registers += r_registers
+ csrs += r_csrs
assigns += r_assigns
else:
name = element[0]
alignment = element[3]
else:
alignment = 0
- 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
+ reg = CSRStorage(nbits + alignment, reset=reset, atomic_write=atomic, name=prefix + name)
+ csrs.append(reg)
+ assigns.append(getattr(target, name).eq(reg.storage[alignment:]))
+ return csrs, assigns
(MODE_EXTERNAL, MODE_SINGLE_SHOT, MODE_CONTINUOUS) = range(3)
def __init__(self, layout, mode):
self._mode = mode
Actor.__init__(self, ("source", Source, _convert_layout(layout)))
- self._registers, self._assigns = _create_registers_assign(layout,
+ self._csrs, self._assigns = _create_csrs_assign(layout,
self.token("source"), self._mode != MODE_SINGLE_SHOT)
if mode == MODE_EXTERNAL:
self.trigger = Signal()
elif mode == MODE_SINGLE_SHOT:
- shoot = RegisterRaw()
- self._registers.insert(0, shoot)
+ shoot = CSR()
+ self._csrs.insert(0, shoot)
self.trigger = shoot.re
elif mode == MODE_CONTINUOUS:
- enable = RegisterField()
- self._registers.insert(0, enable)
- self.trigger = enable.field.r
+ enable = CSRStorage()
+ self._csrs.insert(0, enable)
+ self.trigger = enable.storage
else:
raise ValueError
- def get_registers(self):
- return self._registers
+ def get_csrs(self):
+ return self._csrs
def get_fragment(self):
stb = self.endpoints["source"].stb
sync = [If(ack | ~stb, *stmts)]
return Fragment(comb, sync)
-class Collector(Actor):
+class Collector(Actor, AutoCSR):
def __init__(self, layout, depth=1024):
Actor.__init__(self, ("sink", Sink, layout))
self._depth = depth
self._dw = sum(len(s) for s in self.token("sink").flatten())
- 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._r_wa, self._r_wc, self._r_ra, self._r_rd]
+ self._r_wa = CSRStorage(bits_for(self._depth-1), write_from_dev=True)
+ self._r_wc = CSRStorage(bits_for(self._depth), write_from_dev=True, atomic_write=True)
+ self._r_ra = CSRStorage(bits_for(self._depth-1))
+ self._r_rd = CSRStatus(self._dw)
def get_fragment(self):
mem = Memory(self._dw, self._depth)
rp = mem.get_port()
comb = [
- If(self._r_wc.field.r != 0,
+ If(self._r_wc.r != 0,
self.endpoints["sink"].ack.eq(1),
If(self.endpoints["sink"].stb,
- self._r_wa.field.we.eq(1),
- self._r_wc.field.we.eq(1),
+ self._r_wa.we.eq(1),
+ self._r_wc.we.eq(1),
wp.we.eq(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),
+ self._r_wa.dat_w.eq(self._r_wa.storage + 1),
+ self._r_wc.dat_w.eq(self._r_wc.storage - 1),
- wp.adr.eq(self._r_wa.field.r),
+ wp.adr.eq(self._r_wa.storage),
wp.dat_w.eq(Cat(*self.token("sink").flatten())),
- rp.adr.eq(self._r_ra.field.r),
- self._r_rd.field.w.eq(rp.dat_r)
+ rp.adr.eq(self._r_ra.storage),
+ self._r_rd.status.eq(rp.dat_r)
]
return Fragment(comb, specials={mem})
from operator import itemgetter
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bus import csr
from migen.bank.description import *
-class Bank:
+class Bank(Module):
def __init__(self, description, address=0, bus=None):
- self.description = description
- self.address = address
if bus is None:
bus = csr.Interface()
self.bus = bus
-
- def get_fragment(self):
- comb = []
- sync = []
- sel = Signal()
- comb.append(sel.eq(self.bus.adr[9:] == self.address))
+ ###
+
+ if not description:
+ return
- desc_exp = expand_description(self.description, csr.data_width)
- nbits = bits_for(len(desc_exp)-1)
+ # Turn description into simple CSRs and claim ownership of compound CSR modules
+ simple_csrs = []
+ for c in description:
+ if isinstance(c, CSR):
+ simple_csrs.append(c)
+ else:
+ c.finalize(csr.data_width)
+ simple_csrs += c.get_simple_csrs()
+ self.submodules += c
+ nbits = bits_for(len(simple_csrs)-1)
+
+ # Decode selection
+ sel = Signal()
+ self.comb += sel.eq(self.bus.adr[9:] == address)
# Bus writes
- bwcases = {}
- for i, reg in enumerate(desc_exp):
- if isinstance(reg, RegisterRaw):
- comb.append(reg.r.eq(self.bus.dat_w[:reg.size]))
- comb.append(reg.re.eq(sel & \
+ for i, c in enumerate(simple_csrs):
+ self.comb += [
+ c.r.eq(self.bus.dat_w[:c.size]),
+ c.re.eq(sel & \
self.bus.we & \
- (self.bus.adr[:nbits] == i)))
- elif isinstance(reg, RegisterFields):
- bwra = []
- offset = 0
- for field in reg.fields:
- if field.access_bus == WRITE_ONLY or field.access_bus == READ_WRITE:
- bwra.append(field.storage.eq(self.bus.dat_w[offset:offset+field.size]))
- offset += field.size
- if bwra:
- bwcases[i] = bwra
- # commit atomic writes
- for field in reg.fields:
- if isinstance(field, FieldAlias) and field.commit_list:
- commit_instr = [hf.commit_to.eq(hf.storage) for hf in field.commit_list]
- sync.append(If(sel & self.bus.we & self.bus.adr[:nbits] == i, *commit_instr))
- else:
- raise TypeError
- if bwcases:
- sync.append(If(sel & self.bus.we, Case(self.bus.adr[:nbits], bwcases)))
+ (self.bus.adr[:nbits] == i))
+ ]
# Bus reads
- brcases = {}
- for i, reg in enumerate(desc_exp):
- if isinstance(reg, RegisterRaw):
- brcases[i] = [self.bus.dat_r.eq(reg.w)]
- elif isinstance(reg, RegisterFields):
- brs = []
- reg_readable = False
- for field in reg.fields:
- if field.access_bus == READ_ONLY or field.access_bus == READ_WRITE:
- brs.append(field.storage)
- reg_readable = True
- else:
- brs.append(Replicate(0, field.size))
- if reg_readable:
- brcases[i] = [self.bus.dat_r.eq(Cat(*brs))]
- else:
- raise TypeError
- if brcases:
- sync.append(self.bus.dat_r.eq(0))
- sync.append(If(sel, Case(self.bus.adr[:nbits], brcases)))
- else:
- comb.append(self.bus.dat_r.eq(0))
-
- # Device access
- for reg in self.description:
- if isinstance(reg, RegisterFields):
- for field in reg.fields:
- if field.access_bus == READ_ONLY and field.access_dev == WRITE_ONLY:
- comb.append(field.storage.eq(field.w))
- else:
- if field.access_dev == READ_ONLY or field.access_dev == READ_WRITE:
- comb.append(field.r.eq(field.storage))
- if field.access_dev == WRITE_ONLY or field.access_dev == READ_WRITE:
- sync.append(If(field.we, field.storage.eq(field.w)))
-
- return Fragment(comb, sync)
+ brcases = dict((i, self.bus.dat_r.eq(c.w)) for i, c in enumerate(simple_csrs))
+ self.sync += [
+ self.bus.dat_r.eq(0),
+ If(sel, Case(self.bus.adr[:nbits], brcases))
+ ]
# address_map(name, memory) returns the CSR offset at which to map
# the CSR object (register bank or memory).
# Otherwise, it is a memory object belonging to source.name.
# address_map is called exactly once for each object at each call to
# scan(), so it can have side effects.
-class BankArray:
+class BankArray(Module):
def __init__(self, source, address_map):
self.source = source
self.address_map = address_map
self.banks = []
self.srams = []
for name, obj in sorted(self.source.__dict__.items(), key=itemgetter(0)):
- if hasattr(obj, "get_registers"):
- registers = obj.get_registers()
+ if hasattr(obj, "get_csrs"):
+ csrs = obj.get_csrs()
else:
- registers = []
+ csrs = []
if hasattr(obj, "get_memories"):
memories = obj.get_memories()
for memory in memories:
mapaddr = self.address_map(name, memory)
mmap = csr.SRAM(memory, mapaddr)
- registers += mmap.get_registers()
- self.srams.append((name, memory, mmap))
- if registers:
+ self.submodules += mmap
+ csrs += mmap.get_csrs()
+ self.srams.append((name, memory, mapaddr, mmap))
+ if csrs:
mapaddr = self.address_map(name, None)
- rmap = Bank(registers, mapaddr)
- self.banks.append((name, rmap))
+ rmap = Bank(csrs, mapaddr)
+ self.submodules += rmap
+ self.banks.append((name, csrs, mapaddr, rmap))
def get_rmaps(self):
- return [rmap for name, rmap in self.banks]
+ return [rmap for name, csrs, mapaddr, rmap in self.banks]
def get_mmaps(self):
- return [mmap for name, memory, mmap in self.srams]
+ return [mmap for name, memory, mapaddr, mmap in self.srams]
def get_buses(self):
return [i.bus for i in self.get_rmaps() + self.get_mmaps()]
-
- def get_fragment(self):
- return sum([i.get_fragment() for i in self.get_rmaps() + self.get_mmaps()], Fragment())
from migen.fhdl.structure import *
from migen.fhdl.specials import Memory
+from migen.fhdl.module import *
from migen.fhdl.tracer import get_obj_var_name
-class _Register(HUID):
- def __init__(self, name):
+class _CSRBase(HUID):
+ def __init__(self, size, 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.")
+ raise ValueError("Cannot extract CSR name from code, need to specify.")
if len(self.name) > 2 and self.name[:2] == "r_":
self.name = self.name[2:]
+ self.size = size
-class RegisterRaw(_Register):
+class CSR(_CSRBase):
def __init__(self, size=1, name=None):
- _Register.__init__(self, name)
- self.size = size
- self.re = Signal()
- self.r = Signal(self.size)
- self.w = Signal(self.size)
+ _CSRBase.__init__(self, size, name)
+ self.re = Signal(name=self.name + "_re")
+ self.r = Signal(self.size, name=self.name + "_r")
+ self.w = Signal(self.size, name=self.name + "_w")
- def get_size(self):
- return self.size
+class _CompoundCSR(_CSRBase, Module):
+ def __init__(self, size, name):
+ _CSRBase.__init__(self, size, name)
+ self.simple_csrs = []
-(READ_ONLY, WRITE_ONLY, READ_WRITE) = range(3)
+ def get_simple_csrs(self):
+ if not self.finalized:
+ raise FinalizeError
+ return self.simple_csrs
-class Field:
- 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
+ def do_finalize(self, busword):
+ raise NotImplementedError
+
+class CSRStatus(_CompoundCSR):
+ def __init__(self, size=1, name=None):
+ _CompoundCSR.__init__(self, size, name)
+ self.status = Signal(self.size)
+
+ def do_finalize(self, busword):
+ nwords = (self.size + busword - 1)//busword
+ for i in reversed(range(nwords)):
+ nbits = min(self.size - i*busword, busword)
+ sc = CSR(nbits, self.name + str(i) if nwords > 1 else self.name)
+ self.comb += sc.w.eq(self.status[i*busword:i*busword+nbits])
+ self.simple_csrs.append(sc)
+
+class CSRStorage(_CompoundCSR):
+ def __init__(self, size=1, reset=0, atomic_write=False, write_from_dev=False, name=None):
+ _CompoundCSR.__init__(self, size, name)
self.storage = Signal(self.size, reset=reset)
self.atomic_write = atomic_write
- if self.access_bus == READ_ONLY and self.access_dev == WRITE_ONLY:
- self.w = Signal(self.size)
- else:
- if self.access_dev == READ_ONLY or self.access_dev == READ_WRITE:
- self.r = Signal(self.size, reset=reset)
- if self.access_dev == WRITE_ONLY or self.access_dev == READ_WRITE:
- self.w = Signal(self.size)
- self.we = Signal()
-
-class RegisterFields(_Register):
- def __init__(self, *fields, name=None):
- _Register.__init__(self, name)
- self.fields = fields
+ if write_from_dev:
+ self.we = Signal()
+ self.dat_w = Signal(self.size)
+ self.sync += If(self.we, self.storage.eq(self.dat_w))
- def get_size(self):
- return sum(field.size for field in self.fields)
+ def do_finalize(self, busword):
+ nwords = (self.size + busword - 1)//busword
+ if nwords > 1 and self.atomic_write:
+ backstore = Signal(self.size - busword, name=self.name + "_backstore")
+ for i in reversed(range(nwords)):
+ nbits = min(self.size - i*busword, busword)
+ sc = CSR(nbits, self.name + str(i) if nwords else self.name)
+ lo = i*busword
+ hi = lo+nbits
+ # read
+ self.comb += sc.w.eq(self.storage[lo:hi])
+ # write
+ if nwords > 1 and self.atomic_write:
+ if i:
+ self.sync += If(sc.re, backstore[lo-busword:hi-busword].eq(sc.r))
+ else:
+ self.sync += If(sc.re, self.storage.eq(Cat(sc.r, backstore)))
+ else:
+ self.sync += If(sc.re, self.storage[lo:hi].eq(sc.r))
-class RegisterField(RegisterFields):
- 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)
+ self.simple_csrs.append(sc)
-def regprefix(prefix, registers):
- for register in registers:
- register.name = prefix + register.name
+def csrprefix(prefix, csrs):
+ for csr in csrs:
+ csr.name = prefix + csr.name
def memprefix(prefix, memories):
for memory in memories:
memory.name_override = prefix + memory.name_override
-class AutoReg:
+class AutoCSR:
def get_memories(self):
r = []
for k, v in self.__dict__.items():
r += memories
return sorted(r, key=lambda x: x.huid)
- def get_registers(self):
+ def get_csrs(self):
r = []
for k, v in self.__dict__.items():
- if isinstance(v, _Register):
+ if isinstance(v, _CSRBase):
r.append(v)
- elif hasattr(v, "get_registers") and callable(v.get_registers):
- registers = v.get_registers()
- regprefix(k + "_", registers)
- r += registers
+ elif hasattr(v, "get_csrs") and callable(v.get_csrs):
+ csrs = v.get_csrs()
+ csrprefix(k + "_", csrs)
+ r += csrs
return sorted(r, key=lambda x: x.huid)
-
-(ALIAS_NON_ATOMIC, ALIAS_ATOMIC_HOLD, ALIAS_ATOMIC_COMMIT) = range(3)
-
-class FieldAlias:
- def __init__(self, mode, f, start, end, commit_list):
- self.mode = mode
- self.size = end - start
- self.access_bus = f.access_bus
- self.access_dev = f.access_dev
- if mode == ALIAS_ATOMIC_HOLD:
- self.storage = Signal(end-start, name="atomic_hold")
- self.commit_to = f.storage[start:end]
- else:
- self.storage = f.storage[start:end]
- if mode == ALIAS_ATOMIC_COMMIT:
- self.commit_list = commit_list
- else:
- self.commit_list = []
- # device access is through the original field
-
-def expand_description(description, busword):
- d = []
- for reg in description:
- if isinstance(reg, RegisterRaw):
- if reg.size > busword:
- raise ValueError("Raw register larger than a bus word")
- d.append(reg)
- elif isinstance(reg, RegisterFields):
- f = []
- offset = 0
- totalsize = 0
- for field in reg.fields:
- offset += field.size
- totalsize += field.size
- if offset > busword:
- # add padding
- padding = busword - (totalsize % busword)
- if padding != busword:
- totalsize += padding
- offset += padding
-
- top = field.size
- commit_list = []
- while offset > busword:
- if field.atomic_write:
- if offset - busword > busword:
- mode = ALIAS_ATOMIC_HOLD
- else:
- # last iteration
- mode = ALIAS_ATOMIC_COMMIT
- else:
- mode = ALIAS_NON_ATOMIC
-
- slice1 = busword - offset + top
- slice2 = min(offset - busword, busword)
- if slice1:
- alias = FieldAlias(mode, field, top - slice1, top, commit_list)
- f.append(alias)
- if mode == ALIAS_ATOMIC_HOLD:
- commit_list.append(alias)
- top -= slice1
- d.append(RegisterFields(*f, name=reg.name))
- alias = FieldAlias(mode, field, top - slice2, top, commit_list)
- f = [alias]
- if mode == ALIAS_ATOMIC_HOLD:
- commit_list.append(alias)
- top -= slice2
- offset -= busword
- else:
- f.append(field)
- if f:
- d.append(RegisterFields(*f, name=reg.name))
- else:
- raise TypeError
- return d
class EventSourceLevel(_EventSource):
pass
-class EventManager(Module, AutoReg):
+class EventManager(Module, AutoCSR):
def __init__(self):
self.irq = Signal()
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(n)
- self.pending = RegisterRaw(n)
- self.enable = RegisterFields(*(Field(1, READ_WRITE, READ_ONLY, name="e" + str(i)) for i in range(n)))
+ self.status = CSR(n)
+ self.pending = CSR(n)
+ self.enable = CSRStorage(n)
# status
for i, source in enumerate(sources):
self.comb += self.pending.w[i].eq(source.pending)
# IRQ
- irqs = [self.pending.w[i] & field.r for i, field in enumerate(self.enable.fields)]
+ irqs = [self.pending.w[i] & self.enable.storage[i] for i in range(n)]
self.comb += self.irq.eq(optree("|", irqs))
def __setattr__(self, name, value):
from migen.fhdl.module import Module
from migen.bus.simple import *
from migen.bus.transactions import *
-from migen.bank.description import RegisterField
+from migen.bank.description import CSRStorage
from migen.genlib.misc import chooser
data_width = 8
self.word_bits = 0
page_bits = _compute_page_bits(self.mem.depth + self.word_bits)
if page_bits:
- self._page = RegisterField(page_bits, name=self.mem.name_override + "_page")
+ self._page = CSRStorage(page_bits, name=self.mem.name_override + "_page")
else:
self._page = None
if read_only is None:
bus = Interface()
self.bus = bus
- def get_registers(self):
+ def get_csrs(self):
if self._page is None:
return []
else:
if self._page is None:
comb.append(port.adr.eq(self.bus.adr[self.word_bits:len(port.adr)]))
else:
- pv = self._page.field.r
+ pv = self._page.storage
comb.append(port.adr.eq(Cat(self.bus.adr[self.word_bits:len(port.adr)-len(pv)], pv)))
return Fragment(comb, sync, specials={self.mem})
+from collections import defaultdict
+
from migen.fhdl.structure import *
from migen.fhdl.module import Module
from migen.flow.actor import *
else:
self.on_inactive()
-class DFGHook:
+class DFGHook(Module):
def __init__(self, dfg, create):
assert(not dfg.is_abstract())
- self.nodepair_to_ep = dict()
- for u, v, data in dfg.edges_iter(data=True):
- if (u, v) in self.nodepair_to_ep:
- ep_to_hook = self.nodepair_to_ep[(u, v)]
- else:
- ep_to_hook = dict()
- self.nodepair_to_ep[(u, v)] = ep_to_hook
+ self.nodepair_to_ep = defaultdict(dict)
+ for hookn, (u, v, data) in dfg.edges_iter(data=True):
+ ep_to_hook = self.nodepair_to_ep[(u, v)]
ep = data["source"]
- ep_to_hook[ep] = create(u, ep, v)
+ h = create(u, ep, v)
+ ep_to_hook[ep] = h
+ setattr(self.submodules, "hook"+str(hookn), h)
def hooks_iter(self):
for v1 in self.nodepair_to_ep.values():
for v2 in v1.values():
yield v2
-
- def get_fragment(self):
- return sum([h.get_fragment() for h in self.hooks_iter()], Fragment())
from migen.fhdl.structure import *
+from migen.fhdl.module import Module
from migen.bank.description import *
from migen.flow.hooks import DFGHook
ISD_MAGIC = 0x6ab4
-class EndpointReporter:
+class EndpointReporter(Module, AutoCSR):
def __init__(self, endpoint, nbits):
- self.endpoint = endpoint
- self.nbits = nbits
self.reset = Signal()
self.freeze = Signal()
- 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)
+ self._ack_count = CSRStatus(nbits)
+ self._nack_count = CSRStatus(nbits)
+ self._cur_status = CSRStatus(2)
- def get_registers(self):
- return [self._ack_count, self._nack_count, self._cur_status]
-
- def get_fragment(self):
+ ###
+
stb = Signal()
ack = Signal()
- ack_count = Signal(self.nbits)
- nack_count = Signal(self.nbits)
- comb = [
- self._cur_stb.w.eq(stb),
- self._cur_ack.w.eq(ack)
- ]
- sync = [
+ self.comb += self._cur_status.status.eq(Cat(stb, ack))
+ ack_count = Signal(nbits)
+ nack_count = Signal(nbits)
+ self.sync += [
# register monitored signals
- stb.eq(self.endpoint.stb),
- ack.eq(self.endpoint.ack),
+ stb.eq(endpoint.stb),
+ ack.eq(endpoint.ack),
# count operations
If(self.reset,
ack_count.eq(0),
)
),
If(~self.freeze,
- self._ack_count.field.w.eq(ack_count),
- self._nack_count.field.w.eq(nack_count)
+ self._ack_count.status.eq(ack_count),
+ self._nack_count.status.eq(nack_count)
)
]
- return Fragment(comb, sync)
-class DFGReporter(DFGHook):
+class DFGReporter(DFGHook, AutoCSR):
def __init__(self, dfg, nbits):
- self._nbits = nbits
+ self._r_magic = CSRStatus(16)
+ self._r_neps = CSRStatus(8)
+ self._r_nbits = CSRStatus(8)
+ self._r_freeze = CSRStorage()
+ self._r_reset = CSR()
- 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)
-
- def _create(self, u, ep, v):
- self.order.append((u, ep, v))
- return EndpointReporter(u.actor.endpoints[ep], self._nbits)
-
- def print_map(self):
- for n, (u, ep, v) in enumerate(self.order):
- print("#" + str(n) + ": " + str(u) + ":" + ep + " -> " + str(v))
-
- def get_registers(self):
- registers = [self._r_magic, self._r_neps, self._r_nbits,
- self._r_freeze, self._r_reset]
- for u, ep, v in self.order:
- registers += self.nodepair_to_ep[(u, v)][ep].get_registers()
- return registers
-
- def get_fragment(self):
- comb = [
- self._r_magic.field.w.eq(ISD_MAGIC),
- self._r_neps.field.w.eq(len(self.order)),
- self._r_nbits.field.w.eq(self._nbits)
+ ###
+
+ DFGHook.__init__(self, dfg,
+ lambda u, ep, v: EndpointReporter(u.endpoints[ep], nbits))
+
+ self.comb += [
+ self._r_magic.status.eq(ISD_MAGIC),
+ self._r_neps.status.eq(len(self.hooks_iter())),
+ self._r_nbits.status.eq(nbits)
]
for h in self.hooks_iter():
- comb += [
- h.freeze.eq(self._r_freeze.field.r),
+ self.comb += [
+ h.freeze.eq(self._r_freeze.storage),
h.reset.eq(self._r_reset.re)
]
- return Fragment(comb) + DFGHook.get_fragment(self)
self.debugger = DFGReporter(self.dfg, debugger_nbits)
Actor.__init__(self)
- def get_registers(self):
+ def get_csrs(self):
if hasattr(self, "debugger"):
- return self.debugger.get_registers()
+ return self.debugger.get_csrs()
else:
return []