self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings,
self.bank_machines, self.refresher,
self.dfi, self.lasmic)
+
+ def get_csrs(self):
+ return self.multiplexer.get_csrs()
from migen.genlib.roundrobin import *
from migen.genlib.misc import optree
from migen.genlib.fsm import FSM
+from migen.bank.description import AutoCSR
+
+from milkymist.lasmicon.perf import Bandwidth
class CommandRequest:
def __init__(self, a, ba):
phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
]
-class Multiplexer(Module):
+class Multiplexer(Module, AutoCSR):
def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic):
assert(phy_settings.nphases == len(dfi.phases))
if phy_settings.nphases != 2:
)
# FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH)
+
+ self.submodules.bandwidth = Bandwidth(choose_req.cmd)
--- /dev/null
+from migen.fhdl.std import *
+from migen.bank.description import *
+
+class Bandwidth(Module, AutoCSR):
+ def __init__(self, cmd, period_bits=24):
+ self._r_update = CSR()
+ self._r_nreads = CSRStatus(period_bits)
+ self._r_nwrites = CSRStatus(period_bits)
+
+ ###
+
+ cmd_stb = Signal()
+ cmd_ack = Signal()
+ cmd_is_read = Signal()
+ cmd_is_write = Signal()
+ self.sync += [
+ cmd_stb.eq(cmd.stb),
+ cmd_ack.eq(cmd.ack),
+ cmd_is_read.eq(cmd.is_read),
+ cmd_is_write.eq(cmd.is_write)
+ ]
+
+ counter = Signal(period_bits)
+ period = Signal()
+ nreads = Signal(period_bits)
+ nwrites = Signal(period_bits)
+ nreads_r = Signal(period_bits)
+ nwrites_r = Signal(period_bits)
+ self.sync += [
+ Cat(counter, period).eq(counter + 1),
+ If(period,
+ nreads_r.eq(nreads),
+ nwrites_r.eq(nwrites),
+ nreads.eq(0),
+ nwrites.eq(0)
+ ).Elif(cmd_stb & cmd_ack,
+ If(cmd_is_read, nreads.eq(nreads + 1)),
+ If(cmd_is_write, nwrites.eq(nwrites + 1)),
+ ),
+ If(self._r_update.re,
+ self._r_nreads.status.eq(nreads_r),
+ self._r_nwrites.status.eq(nwrites_r)
+ )
+ ]
}
}
+static void membw_service(void)
+{
+ static int last_event;
+ unsigned long long int nr, nw;
+ unsigned long long int f;
+ unsigned int rdb, wrb;
+
+ if(elapsed(&last_event, identifier_frequency_read())) {
+ lasmicon_bandwidth_update_write(1);
+ nr = lasmicon_bandwidth_nreads_read();
+ nw = lasmicon_bandwidth_nwrites_read();
+ f = identifier_frequency_read();
+ rdb = nr*f >> (24LL - 7ULL);
+ wrb = nw*f >> (24LL - 7ULL);
+ printf("read: %4dMbps write: %4dMbps\n", rdb/1000000, wrb/1000000);
+ }
+}
+
int main(void)
{
irq_setmask(0);
dvisampler1_service();
pots_service();
fb_service();
+ membw_service();
}
return 0;
"timer0": 4,
"minimac": 5,
"fb": 6,
- "dvisampler0": 7,
- "dvisampler0_edid_mem": 8,
- "dvisampler1": 9,
- "dvisampler1_edid_mem": 10,
- "pots": 11,
- "buttons": 12,
- "leds": 13
+ "lasmicon": 7,
+ "dvisampler0": 8,
+ "dvisampler0_edid_mem": 9,
+ "dvisampler1": 10,
+ "dvisampler1_edid_mem": 11,
+ "pots": 12,
+ "buttons": 13,
+ "leds": 14
}
interrupt_map = {