litex/migen/flow/isd.py

96 lines
2.8 KiB
Python
Raw Normal View History

2012-08-03 12:49:04 -04:00
from migen.fhdl.structure import *
from migen.bank.description import *
from migen.flow.hooks import DFGHook
ISD_MAGIC = 0x6ab4
class EndpointReporter:
def __init__(self, endpoint, nbits):
self.endpoint = endpoint
2012-08-04 17:39:52 -04:00
self.nbits = nbits
2012-08-03 12:49:04 -04:00
self.reset = Signal()
2012-08-04 17:39:52 -04:00
self.freeze = Signal()
2012-08-03 12:49:04 -04:00
2012-08-04 17:39:52 -04:00
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)
2012-08-03 12:49:04 -04:00
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])
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)
2012-08-03 12:49:04 -04:00
comb = [
self._cur_stb.w.eq(stb),
self._cur_ack.w.eq(ack)
]
sync = [
# register monitored signals
stb.eq(self.endpoint.stb),
ack.eq(self.endpoint.ack),
# count operations
If(self.reset,
ack_count.eq(0),
nack_count.eq(0)
).Else(
If(stb,
If(ack,
ack_count.eq(ack_count + 1)
).Else(
nack_count.eq(nack_count + 1)
)
)
2012-08-04 17:39:52 -04:00
),
If(~self.freeze,
self._ack_count.field.w.eq(ack_count),
self._nack_count.field.w.eq(nack_count)
2012-08-03 12:49:04 -04:00
)
]
return Fragment(comb, sync)
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)
2012-08-04 17:39:52 -04:00
self._r_freeze = RegisterField("freeze", 1)
2012-08-03 12:49:04 -04:00
self._r_reset = RegisterRaw("reset", 1)
self.order = []
2012-12-18 08:54:33 -05:00
DFGHook.__init__(self, dfg, self._create)
2012-08-03 12:49:04 -04:00
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):
2012-08-04 17:39:52 -04:00
registers = [self._r_magic, self._r_neps, self._r_nbits,
self._r_freeze, self._r_reset]
2012-08-03 12:49:04 -04:00
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)
]
2012-08-04 17:39:52 -04:00
for h in self.hooks_iter():
comb += [
h.freeze.eq(self._r_freeze.field.r),
h.reset.eq(self._r_reset.re)
]
2012-12-18 08:54:33 -05:00
return Fragment(comb) + DFGHook.get_fragment(self)