10from rich.table
import Table
11from rich.logging
import RichHandler
16from pprint
import pprint
27 t.add_column(
'value', style=
'green')
28 for k,v
in vals.items():
50 for i
in sorted(node.getNodes()):
51 regs[i] = node.getNode(i).read()
52 node.getClient().dispatch()
54 return {k: v.value()
for k, v
in regs.items()}
60 node.getClient().dispatch()
61 return {node.getId(): v.value()}
72 magic = self.
node.getNode(
'info.magic').read()
75 if self.
magic != 0xdeadbeef:
76 raise ValueError(f
"Magic number check failed. Expected '0xdeadbeef', found '{hex(self.magic)}'")
80 n_mgt = self.
node.getNode(
'info.generics.n_mgts').read()
81 n_src = self.
node.getNode(
'info.generics.n_srcs').read()
82 ref_freq = self.
node.getNode(
'info.generics.ref_freq').read()
93 return self.
node.getNode(id)
96 return self.
node.getNodes(regex)
102 self.
node.getNode(
'samp.ctrl.samp').write(
True)
103 self.
node.getNode(
'samp.ctrl.samp').write(
False)
107 self.
node.getNode(
'samp.ctrl.samp').write(
False)
108 self.
node.getNode(
'samp.ctrl.samp').write(
False)
115 raise ValueError(f
"Link {i} does not exist ({self.n_mgt})")
117 self.
get_node(
'tx_path.csr_tx_mux.ctrl.tx_mux_sel').write(i)
119 j = self.
get_node(
'tx_path.csr_tx_mux.ctrl.tx_mux_sel').read()
121 print(f
"Link {j} selected")
127 raise ValueError(f
"Input buffer {i} does not exist ({self.n_src})")
129 self.
node.getNode(
'tx_path.tx_mux.csr.ctrl.sel_buf').write(i)
135 raise ValueError(f
"Link {i} does not exist ({self.n_mgt})")
137 self.
node.getNode(
'tx_path.csr_udp_core.ctrl.udp_core_sel').write(i)
146mgts_all = tuple(str(i)
for i
in range(MAX_MGT))
148CONTEXT_SETTINGS = dict(help_option_names=[
'-h',
'--help'])
158 lDevices = ctx.obj.cm.getDevices()
159 if value
and (value
not in lDevices):
160 raise click.BadParameter(
161 'Device must be one of '+
162 ', '.join([
"'"+lId+
"'" for lId
in lDevices])
170 uhal.setLogLevelTo(uhal.LogLevel.WARNING)
183 is_zcu = hw.getNodes(
'tx.info')
184 is_wib = hw.getNodes(
'info')
188 tx_mux = hw.getNode(
'tx')
191 tx_mux = hw.getNode()
193 raise ValueError(f
"{self.device_id} is neither a zcu nor a wib")
209@click.group(chain=True, context_settings=CONTEXT_SETTINGS)
210@click.option('-c', '--connection-file', default=None, help="IPBus connection file ")
211@click.option('-d', '--device', callback=validate_device, help="IPBus device")
214def cli(obj, connection_file, device):
216 obj.connection_file_path = connection_file
217 obj.device_id = device
223 t = Table(title=
"Control hosts")
226 for h
in obj.cm.getDevices():
230 t = Table(title=
"Receivers")
232 t.add_column(
'mac', style=
'green')
233 t.add_column(
'ip', style=
'blue')
234 t.add_column(
'port', style=
'blue')
235 for h,d
in rx_endpoints.items():
236 t.add_row(h, f
"0x{d['mac']:012x}", f
"{d['ip']}", str(d[
'port']))
239 t = Table(title=
"Transmitters")
241 t.add_column(
'mac', style=
'green')
242 t.add_column(
'ip', style=
'blue')
243 t.add_column(
'port', style=
'blue')
244 for h,d
in tx_endpoints.items():
245 t.add_row(h, f
"0x{d['mac']:012x}", f
"{d['ip']}", str(d[
'port']))
250@click.option('--nuke', is_flag=True, default=None)
257 hrms.get_node(
'csr.ctrl.nuke').write(0x1)
262 hrms.get_node(
'csr.ctrl.nuke').write(0x0)
265 hrms.get_node(
'csr.ctrl.soft_rst').write(0x1)
270 hrms.get_node(
'csr.ctrl.soft_rst').write(0x0)
275@click.option('--en/--dis', 'enable', default=None)
276@click.option('--buf-en/--buf-dis', 'buf_en', default=None)
277@click.option('--tx-en/--tx-dis', 'tx_en', default=None)
278@click.option('-l', '--link', type=int, default=0)
280def enable(obj, enable, buf_en, tx_en, link):
287 raise ValueError(f
"MGT {link} not instantiated")
289 hrms.sel_tx_mux(link)
293 tx_en = tx_en
if tx_en
is not None else enable
294 buf_en = buf_en
if buf_en
is not None else enable
296 if tx_en
is not None:
297 print(f
"- {'Enabling' if tx_en else 'Disabling'} 'tx block'")
298 hrms.get_node(
'tx_path.tx_mux.csr.ctrl.tx_en').write(tx_en)
301 if buf_en
is not None:
302 print(f
"- {'Enabling' if buf_en else 'Disabling'} 'input buffers'")
303 hrms.get_node(
'tx_path.tx_mux.csr.ctrl.en_buf').write(buf_en)
307 if enable
is not None:
308 print(f
"- {'Enabling' if enable else 'Disabling'} 'mux'")
309 hrms.get_node(
'tx_path.tx_mux.csr.ctrl.en').write(enable)
316 top_ctrl =
dump_sub_regs(hrms.get_node(
'tx_path.tx_mux.csr.ctrl'))
319 dict_to_table(top_ctrl, title=f
'Link {link} ctrls', show_header=
False),
323@cli.command("mux-config")
324@click.argument('detid', type=int)
325@click.argument('crate', type=int)
326@click.argument('slot', type=int)
327@click.option('-l', '--link', type=int, default=0)
330 """Configure the UDP blocks """
334 hrms.sel_tx_mux(link)
336 hrms.get_node(
'tx_path.tx_mux.mux.ctrl.detid').write(detid)
337 hrms.get_node(
'tx_path.tx_mux.mux.ctrl.crate').write(crate)
338 hrms.get_node(
'tx_path.tx_mux.mux.ctrl.slot').write(slot)
340 mux_ctrl =
dump_sub_regs(hrms.get_node(
'tx_path.tx_mux.mux.ctrl'))
343 dict_to_table(mux_ctrl, title=f
'Link {link} mux cfg', show_header=
False),
347@cli.command("udp-config")
348@click.argument('src_id', type=click.Choice(tx_endpoints.keys()))
349@click.argument('dst_id', type=click.Choice(rx_endpoints.keys()))
350@click.option('-l', '--link', type=int, default=0)
353 """Configure the UDP blocks """
355 filter_control = 0x07400307
358 if link >= hrms.n_mgt:
359 raise ValueError(f
"Link {link} not instantiated")
362 dst = rx_endpoints[dst_id]
363 src = tx_endpoints[src_id]
365 udp_core_ctrl = f
'tx_path.udp_core.udp_core_control'
367 hrms.get_node(f
'{udp_core_ctrl}.ctrl.filter_control').write(filter_control)
369 hrms.get_node(f
'{udp_core_ctrl}.src_addr_ctrl.use_external').write(0);
373 src_u32 = int.from_bytes(socket.inet_aton(src[
'ip']),
"big")
374 print(f
"Our ip address: {src['ip']} (0x{src_u32:08x})")
376 hrms.get_node(f
'{udp_core_ctrl}.src_addr_ctrl.src_ip_addr').write(src_u32)
380 dst_u32 = int.from_bytes(socket.inet_aton(dst[
'ip']),
"big")
381 print(f
"Their ip address: {dst['ip']} (0x{dst_u32:08x})")
382 hrms.get_node(f
'{udp_core_ctrl}.ctrl.dst_ip_addr').write(dst_u32)
386 print(f
"Our mac address: 0x{src['mac']:012x}")
387 hrms.get_node(f
'{udp_core_ctrl}.src_addr_ctrl.src_mac_addr_lower').write(src[
'mac'] & 0xffffffff)
388 hrms.get_node(f
'{udp_core_ctrl}.src_addr_ctrl.src_mac_addr_upper').write((src[
'mac'] >> 32) & 0xffff)
391 print(f
"Their mac address: 0x{dst['mac']:012x}")
392 hrms.get_node(f
'{udp_core_ctrl}.ctrl.dst_mac_addr_lower').write(dst[
'mac'] & 0xffffffff)
393 hrms.get_node(f
'{udp_core_ctrl}.ctrl.dst_mac_addr_upper').write((dst[
'mac'] >> 32) & 0xffff)
396 hrms.get_node(f
'{udp_core_ctrl}.src_addr_ctrl.src_port').write(src[
'port'])
397 hrms.get_node(f
'{udp_core_ctrl}.ctrl.dst_port').write(dst[
'port'])
402@cli.command("zcu-src-config")
403@click.option('-l', '--link', type=int, default=0)
404@click.option('-n', '--en-n-src', type=click.IntRange(0, MAX_SRCS_P_MGT), default=1)
405@click.option('-d', '--dlen', type=click.IntRange(0, 0xfff), default=0x383)
406@click.option('-r', '--rate-rdx', type=click.IntRange(0, 0x3f), default=0xa)
409 """Configure trivial data sources"""
411 hw = obj.cm.getDevice(obj.device_id)
424 if link >= hrms.n_mgt:
425 raise ValueError(f
"MGT {link} not instantiated")
427 if en_n_src > hrms.n_srcs_p_mgt:
428 raise ValueError(f
"{en_n_src} must be lower than the number of generators per link ({hrms.n_srcs_p_mgt})")
430 for i
in range(hrms.n_srcs_p_mgt):
431 src_id = hrms.n_srcs_p_mgt*link+i
432 hw.getNode(
'src.csr.ctrl.sel').write(src_id)
433 src_en = (i<en_n_src)
434 print(f
'Configuring generator {src_id} : {src_en}')
448 for i
in range(hrms.n_srcs_p_mgt):
449 hw.getNode(
'src.csr.ctrl.sel').write(i)
454 grid.add_column(
"ctrl")
455 grid.add_column(
"stat")
457 dict_to_table(src_regs, title=
'src_ctrl', show_header=
False),
460 for j
in range(hrms.n_srcs_p_mgt):
462 dict_to_table(data_src_regs, title=
'data_src_ctrl', show_header=
False)
486@cli.command("fakesrc-config")
487@click.option('-l', '--link', type=int, default=0)
488@click.option('-n', '--n-src', type=click.IntRange(0, MAX_SRCS_P_MGT), default=1)
489@click.option('-s', '--src', type=click.IntRange(0, MAX_SRCS_P_MGT), default=
None, multiple=
True)
490@click.option('-k', '--data-len', type=click.IntRange(0, 0xfff), default=0x383)
491@click.option('-r', '--rate-rdx', type=click.IntRange(0, 0x3f), default=0xa)
494 """Configure trivial data sources"""
498 all_srcs = set(range(hrms.n_srcs_p_mgt))
501 if en_srcs != set.intersection(all_srcs, en_srcs):
502 raise ValueError(
"AAARGH")
507 hrms.sel_tx_mux(link)
509 if n_src > hrms.n_srcs_p_mgt:
510 raise ValueError(f
"{n_src} must be lower than the number of generators per link ({n_srcs_p_mgt})")
512 was_en = hrms.get_node(
'tx_path.tx_mux.csr.ctrl.en_buf').read()
514 hrms.get_node(
'tx_path.tx_mux.csr.ctrl.en_buf').write(0x0)
517 for src_id
in range(hrms.n_srcs_p_mgt):
518 hrms.sel_tx_mux_buf(src_id)
521 src_en = (src_id
in en_srcs)
522 print(f
'Configuring generator {src_id} : {src_en}')
524 hrms.get_node(
'tx_path.tx_mux.buf.ctrl.fake_en').write(src_en)
528 hrms.get_node(
'tx_path.tx_mux.buf.ctrl.dlen').write(data_len)
530 hrms.get_node(
'tx_path.tx_mux.buf.ctrl.rate_rdx').write(rate_rdx)
533 hrms.get_node(
'tx_path.tx_mux.csr.ctrl.en_buf').write(was_en.value())
539@click.option('-l', '--links', 'sel_links', type=click.Choice(mgts_all), multiple=
True, default=
None)
540@click.option('-s', '--seconds', type=int, default=0)
541@click.option('-u/-U', '--show-udp/--hide-udp', 'show_udp', default=True)
542@click.option('-b/-B', '--show-buf/--hide-buf', 'show_buf', default=True)
544def stats(obj, sel_links, seconds, show_udp, show_buf):
545 """Simple program that greets NAME for a total of COUNT times."""
549 mgts = list(range(hrms.n_mgt))
555 sel_links = [int(s)
for s
in sel_links]
559 if not set(sel_links).issubset(mgts):
560 print(sel_links, mgts)
561 raise ValueError(f
"MGTs {set(sel_links)-set(mgts)} are not instantiated")
565 print(f
"Sampling hermes counters for {seconds}s")
566 hrms.sample_ctrs(seconds)
569 print(
dict_to_table(info_data, title=
'hermes info', show_header=
False))
574 print(f
'---Tx Mux {i} Status---')
580 top_ctrl =
dump_sub_regs(hrms.get_node(
'tx_path.tx_mux.csr.ctrl'))
581 top_stat =
dump_sub_regs(hrms.get_node(
'tx_path.tx_mux.csr.stat'))
582 ctrl_mux =
dump_sub_regs(hrms.get_node(
'tx_path.tx_mux.mux.ctrl'))
583 stat_mux =
dump_sub_regs(hrms.get_node(
'tx_path.tx_mux.mux.stat'))
586 grid.add_column(
"ctrl")
587 grid.add_column(
"stat")
589 dict_to_table(top_ctrl, title=
'tx_mux ctrl', show_header=
False),
590 dict_to_table(top_stat, title=
'tx mux stat', show_header=
False),
591 dict_to_table(ctrl_mux, title=
"mux ctrl", show_header=
False),
592 dict_to_table(stat_mux, title=
"mux stat", show_header=
False),
599 ctrl_udp_src =
dump_sub_regs(hrms.get_node(f
'tx_path.udp_core.udp_core_control.src_addr_ctrl'))
600 ctrl_udp =
dump_sub_regs(hrms.get_node(f
'tx_path.udp_core.udp_core_control.ctrl'))
601 ctrl_flt_udp =
dump_sub_regs(hrms.get_node(f
'tx_path.udp_core.udp_core_control.ctrl.filter_control'))
602 if hrms.get_nodes(f
'tx_path.udp_core.udp_core_control.rx_packet_counters'):
603 print(
"New tx counters found")
604 stat_rx_udp =
dump_sub_regs(hrms.get_node(f
'tx_path.udp_core.udp_core_control.rx_packet_counters'))
605 stat_tx_udp =
dump_sub_regs(hrms.get_node(f
'tx_path.udp_core.udp_core_control.tx_packet_counters'))
607 print(
"No new tx counters found")
608 stat_rx_udp =
dump_sub_regs(hrms.get_node(f
'tx_path.udp_core.udp_core_control.tx_packet_counters'))
609 stat_tx_udp = {
'-':0}
613 ctrl_srcdst[
'src_ip'] = ctrl_udp_src[
'src_ip_addr']
614 ctrl_srcdst[
'dst_ip'] = ctrl_udp[
'dst_ip_addr']
615 ctrl_srcdst[
'src_mac'] = (ctrl_udp_src[
'src_mac_addr_upper'] << 32) + ctrl_udp_src[
'src_mac_addr_lower']
616 ctrl_srcdst[
'dst_mac'] = (ctrl_udp[
'dst_mac_addr_upper'] << 32) + ctrl_udp[
'dst_mac_addr_lower']
617 ctrl_srcdst[
'src_port'] = ctrl_udp_src[
'src_port']
618 ctrl_srcdst[
'dst_port'] = ctrl_udp[
'dst_port']
621 grid.add_column(
"ctrl")
622 grid.add_column(
"stat")
625 dict_to_table(ctrl_srcdst, title=
"udp src/dst", show_header=
False),
626 dict_to_table(ctrl_flt_udp, title=
"udp filter", show_header=
False),
627 dict_to_table(stat_rx_udp, title=
"udp rx stat", show_header=
False),
628 dict_to_table(stat_tx_udp, title=
"udp tx stat", show_header=
False),
635 src_ids = tuple(range(hrms.n_srcs_p_mgt))
638 hrms.sel_tx_mux_buf(j)
640 s[
'blk_acc'] = (s[
'blk_acc_h']<<32)+s[
'blk_acc_l']
641 s[
'blk_oflow'] = (s[
'blk_oflow_h']<<32)+s[
'blk_oflow_l']
642 s[
'blk_rej'] = (s[
'blk_rej_h']<<32)+s[
'blk_rej_l']
643 s[
'ts'] = (s[
'ts_h']<<32)+s[
'ts_l']
644 s[
'vol'] = (s[
'vol_h']<<32)+s[
'vol_l']
645 s[
'blk_longlast'] = (s[
'blk_longlast_h']<<32)+s[
'blk_longlast_l']
646 s[
'blk_lastnotval'] = (s[
'blk_lastnotval_h']<<32)+s[
'blk_lastnotval_l']
648 for k
in tuple(s.keys()):
649 for n
in (
'blk_acc_',
'blk_oflow_',
'blk_rej_',
'ts_',
'vol_',
'blk_longlast_',
'blk_lastnotval_'):
653 for k
in (
'ctrl',
'stat',
'buf_mon'):
665 t.add_column(f
'Buf {j}', style=
'green')
669 for k,v
in ibuf_stats.items():
670 reg_names = reg_names.union(v.keys())
672 for n
in sorted(reg_names):
673 t.add_row(n,*(hex(ibuf_stats[j][n])
for j
in src_ids))
679@click.option('-r', '--phy-reset', is_flag=True, default=None, help="Reset the phy block")
683 pcs_pma_node = hrms.get_node(
'pcs_pma')
686 print(
"[cyan]Resetting pty[/cyan]")
687 pcs_pma_node.getNode(
'debug.csr.ctrl.phy_reset').write(0x1)
688 pcs_pma_node.getNode(
'debug.csr.ctrl.phy_reset').write(0x0)
689 pcs_pma_node.getClient().dispatch()
698 print(pcs_pma_node.getNode(
'debug.csr.stat').getNodes())
699 stats = { n: pcs_pma_node.getNode(
'debug.csr.stat.'+n).read()
for n
in pcs_pma_node.getNode(
'debug.csr.stat').getNodes() }
700 pcs_pma_node.getClient().dispatch()
702 for n,v
in stats.items():
706 for idx, clk_id
in enumerate(clk_ids):
708 fn = pcs_pma_node.getNode(
'freq')
709 fn.getNode(
'ctrl.chan_sel').write(idx)
710 fn.getNode(
'ctrl.en_crap_mode').write(0x0)
711 fn.getClient().dispatch()
714 c = fn.getNode(
'freq.count').read()
715 v = fn.getNode(
'freq.valid').read()
716 fn.getClient().dispatch()
719 print(f
'[red]Failed to measure frequency of clock {clk_id}[/red]')
724 true_count = int(c)*64
726 clk_freq = true_count/denominator*ipb_freq
727 print(f
"Measured {clk_id} clock freq {clk_freq/1000000:04} MHz")
730if __name__ ==
'__main__':
731 FORMAT =
"%(message)s"
733 level=
"INFO", format=FORMAT, datefmt=
"[%X]", handlers=[RichHandler()]
sample_ctrs(self, int seconds)
sel_udp_core(self, int i)
sel_tx_mux_buf(self, int i)
dict_to_table(dict vals, **kwargs)
stats(obj, sel_links, seconds, show_udp, show_buf)
cli(obj, connection_file, device)
fakesrc_config(obj, link, n_src, src, data_len, rate_rdx)
udp_config(obj, src_id, dst_id, link)
mux_config(obj, detid, crate, slot, link)
read_and_print(hw, reg_list)
validate_device(ctx, param, value)
zcu_src_config(obj, link, en_n_src, dlen, rate_rdx)