lasmicon: bandwidth monitoring
This commit is contained in:
parent
13bf6f51f3
commit
3644d2a6ef
|
@ -62,3 +62,6 @@ class LASMIcon(Module):
|
||||||
self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings,
|
self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings,
|
||||||
self.bank_machines, self.refresher,
|
self.bank_machines, self.refresher,
|
||||||
self.dfi, self.lasmic)
|
self.dfi, self.lasmic)
|
||||||
|
|
||||||
|
def get_csrs(self):
|
||||||
|
return self.multiplexer.get_csrs()
|
||||||
|
|
|
@ -2,6 +2,9 @@ from migen.fhdl.std import *
|
||||||
from migen.genlib.roundrobin import *
|
from migen.genlib.roundrobin import *
|
||||||
from migen.genlib.misc import optree
|
from migen.genlib.misc import optree
|
||||||
from migen.genlib.fsm import FSM
|
from migen.genlib.fsm import FSM
|
||||||
|
from migen.bank.description import AutoCSR
|
||||||
|
|
||||||
|
from milkymist.lasmicon.perf import Bandwidth
|
||||||
|
|
||||||
class CommandRequest:
|
class CommandRequest:
|
||||||
def __init__(self, a, ba):
|
def __init__(self, a, ba):
|
||||||
|
@ -79,7 +82,7 @@ class _Steerer(Module):
|
||||||
phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
|
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):
|
def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic):
|
||||||
assert(phy_settings.nphases == len(dfi.phases))
|
assert(phy_settings.nphases == len(dfi.phases))
|
||||||
if phy_settings.nphases != 2:
|
if phy_settings.nphases != 2:
|
||||||
|
@ -180,3 +183,5 @@ class Multiplexer(Module):
|
||||||
)
|
)
|
||||||
# FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
|
# FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
|
||||||
self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH)
|
self.comb += refresher.ack.eq(fsm._state == fsm.REFRESH)
|
||||||
|
|
||||||
|
self.submodules.bandwidth = Bandwidth(choose_req.cmd)
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
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)
|
||||||
|
)
|
||||||
|
]
|
|
@ -90,6 +90,24 @@ static void fb_service(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
int main(void)
|
||||||
{
|
{
|
||||||
irq_setmask(0);
|
irq_setmask(0);
|
||||||
|
@ -109,6 +127,7 @@ int main(void)
|
||||||
dvisampler1_service();
|
dvisampler1_service();
|
||||||
pots_service();
|
pots_service();
|
||||||
fb_service();
|
fb_service();
|
||||||
|
membw_service();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
15
top.py
15
top.py
|
@ -75,13 +75,14 @@ class SoC(Module):
|
||||||
"timer0": 4,
|
"timer0": 4,
|
||||||
"minimac": 5,
|
"minimac": 5,
|
||||||
"fb": 6,
|
"fb": 6,
|
||||||
"dvisampler0": 7,
|
"lasmicon": 7,
|
||||||
"dvisampler0_edid_mem": 8,
|
"dvisampler0": 8,
|
||||||
"dvisampler1": 9,
|
"dvisampler0_edid_mem": 9,
|
||||||
"dvisampler1_edid_mem": 10,
|
"dvisampler1": 10,
|
||||||
"pots": 11,
|
"dvisampler1_edid_mem": 11,
|
||||||
"buttons": 12,
|
"pots": 12,
|
||||||
"leds": 13
|
"buttons": 13,
|
||||||
|
"leds": 14
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt_map = {
|
interrupt_map = {
|
||||||
|
|
Loading…
Reference in New Issue