draft ut charts

This commit is contained in:
yaozhicheng 2024-09-30 17:03:28 +08:00
parent 14c7250edc
commit b7e5726bcf
5 changed files with 2528 additions and 1773 deletions

31
comm/functions.py Normal file
View File

@ -0,0 +1,31 @@
#coding=utf8
#***************************************************************************************
# This project is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#
# See the Mulan PSL v2 for more details.
#**************************************************************************************/
def merge_dict(dict1, dict2):
"""
Merge two dictionaries
"""
if not dict1:
return dict2
if not dict2:
return dict1
for key in dict2:
if key in dict1:
if isinstance(dict1[key], dict) and isinstance(dict2[key], dict):
merge_dict(dict1[key], dict2[key])
else:
dict1[key] = dict2[key]
else:
dict1[key] = dict2[key]
return dict1

File diff suppressed because it is too large Load Diff

View File

@ -1,56 +1,146 @@
// UTs Progress Chart
function show_progress_chart(chart_id, data_url){
function show_progress_chart(chart_id, data_url) {
var chartDom = document.getElementById(chart_id);
var utChart = echarts.init(chartDom);
var option;
utChart.showLoading();
$.getJSON(data_url, function (graph) {
$.getJSON(data_url, function (graph_data) {
utChart.hideLoading();
option = {
tooltip: {},
legend: [
const formatUtil = echarts.format;
function getLevelOption() {
return [
{
data: graph.categories.map(function (a) {
return a.name;
})
itemStyle: {
borderColor: '#777',
borderWidth: 0,
gapWidth: 1
},
upperLabel: {
show: false
}
},
{
itemStyle: {
borderColor: '#555',
borderWidth: 5,
gapWidth: 1
},
emphasis: {
itemStyle: {
borderColor: '#ddd'
}
}
},
{
colorSaturation: [0.35, 0.5],
itemStyle: {
borderWidth: 5,
gapWidth: 1,
borderColorSaturation: 0.6
}
}
],
];
}
option = {
title: {
text: 'XiangShan-KMH Unit Verifaction Flatten Map',
left: 'center'
},
tooltip: {
formatter: function (info) {
var meta = info.data.meta;
var treePathInfo = info.treePathInfo;
var treePath = [];
for (var i = 1; i < treePathInfo.length; i++) {
treePath.push(treePathInfo[i].name);
}
return [
'<div class="tooltip-title">' +
formatUtil.encodeHTML(treePath.join('/')) +
'</div>',
'Test Cases: ' + formatUtil.addCommas(meta.cases.pass) + '/' +
formatUtil.addCommas(meta.cases.total) + '&nbsp(' +
formatUtil.addCommas(meta.cases.skip) + '&nbsp;skiped,&nbsp;&nbsp;' +
formatUtil.addCommas(meta.cases.fail) + '&nbsp;fail ) <br>',
'Line coverage: ' + formatUtil.addCommas(meta.cases.pass) + '<br>',
'Func coverage: ' + formatUtil.addCommas(meta.cases.pass) + '<br>',
].join('');
}
},
series: [
{
name: 'XiangShan UTs',
type: 'graph',
layout: 'force',
data: graph.nodes,
links: graph.links,
categories: graph.categories,
roam: true,
force: {
repulsion: 300
},
name: graph_data["name"],
type: 'treemap', // sunburst treemap
visibleMin: 300,
label: {
show: true,
position: 'right',
formatter: '{b}'
position: 'insideTopLeft',
formatter: function (params) { //formatter: '{b}'
if (params.data.children) {
return params.name;
}
let arr = [
'{name|' + params.name + '}'
]
if (params.data.meta.cases.fail > 0) {
arr.push(
'{fail|' + echarts.format.addCommas(params.data.meta.cases.fail) + '} {label|fail}'
);
}
if (params.data.meta.cases.pass > 0) {
let font_type = "pass";
if (params.data.meta.cases.pass >= params.data.meta.cases.total) {
font_type = "complete";
}
arr.push(
'{'+ font_type + '|' + echarts.format.addCommas(params.data.meta.cases.pass) + '/'+
echarts.format.addCommas(params.data.meta.cases.total) + '} {label|pass}'
)
}
return arr.join('\n');
},
rich: {
fail: {
fontSize: 22,
lineHeight: 30,
color: 'yellow'
},
complete: {
fontSize: 15,
color: 'green',
},
label: {
fontSize: 9,
backgroundColor: 'rgba(0,0,0,0.3)',
color: '#fff',
borderRadius: 2,
padding: [2, 4],
lineHeight: 25,
align: 'right'
},
name: {
fontSize: 12,
color: '#fff'
}
}
},
labelLayout: {
hideOverlap: true
upperLabel: {
show: true,
height: 30
},
scaleLimit: {
min: 0.4,
max: 2
itemStyle: {
borderColor: '#fff'
},
lineStyle: {
color: 'source',
curveness: 0.3
}
levels: getLevelOption(),
data: graph_data["children"],
}
]
};
utChart.setOption(option);
window.addEventListener('resize', function () {
utChart.resize();
});
});
});
option && utChart.setOption(option);
}

122
tools/dut_tree.py Normal file
View File

@ -0,0 +1,122 @@
#coding=utf8
#***************************************************************************************
# This project is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#
# See the Mulan PSL v2 for more details.
#**************************************************************************************/
import json
import copy
node_default_meta_data = {
"cases": {"total": 0, "pass": 0, "fail": 0, "skip": 0},
"functions": {"total": 0, "cover": 0},
"lines": {"total": 0, "cover": 0},
"paths": "",
"value": 1,
"light": False,
}
node_defaut_extern = {
"itemStyle": {
"colorAlpha": 0.1,
}
}
priority_critical = 0
priority_high = 1
priority_low = 2
dut_priority_low = {
"priority": priority_low
}
dut_priority_high = {
"priority": priority_high
}
dut_priority_critical = {
"priority": priority_critical
}
def update_dut_tree_node_meta(tree_data):
def _update_node_meta(node, parent_name):
if "children" in node:
meta = copy.deepcopy(node_default_meta_data)
meta["paths"] = parent_name + "/" + node["name"]
for child in node["children"]:
child_meta = _update_node_meta(child, meta["paths"])
meta["cases"]["total"] += child_meta["cases"]["total"]
meta["cases"]["pass"] += child_meta["cases"]["pass"]
meta["cases"]["fail"] += child_meta["cases"]["fail"]
meta["cases"]["skip"] += child_meta["cases"]["skip"]
meta["functions"]["total"] += child_meta["functions"]["total"]
meta["functions"]["cover"] += child_meta["functions"]["cover"]
meta["lines"]["total"] += child_meta["lines"]["total"]
meta["lines"]["cover"] += child_meta["lines"]["cover"]
meta["value"] += child_meta["value"]
node["meta"] = meta
node["value"] = node["meta"]["value"]
else:
node["meta"]["paths"] = parent_name + "/" + node["name"]
return node["meta"]
_update_node_meta(tree_data, "")
return tree_data
def init_dut_tree(tree_data):
def _append_meta_to_leaf(node):
if "children" not in node:
node["meta"] = copy.deepcopy(node_default_meta_data)
node["value"] = node["meta"]["value"]
node.update(copy.deepcopy(node_defaut_extern))
else:
for child in node["children"]:
_append_meta_to_leaf(child)
_append_meta_to_leaf(tree_data)
return tree_data
class DutTree(object):
def __init__(self, tree):
self.tree = init_dut_tree(copy.deepcopy(tree))
def as_json(self):
update_dut_tree_node_meta(self.tree)
return json.dumps(self.tree, indent=4)
def as_dict(self):
update_dut_tree_node_meta(self.tree)
return self.tree
def from_json(self, json_str):
self.tree = json.loads(json_str)
def update_leaf_meta(self, meta_path_values: dict):
# get all nodes mapping to meta_path_values
update_dut_tree_node_meta(self.tree)
leaf_map = {}
def seek_leaf_node(node):
if "children" not in node:
key = node["meta"]["paths"]
assert key not in leaf_map, "Duplicate key: %s" % key
leaf_map[key] = node
else:
for child in node["children"]:
seek_leaf_node(child)
seek_leaf_node(self.tree)
for path, meta in meta_path_values.items():
assert path in leaf_map, "Path not found: %s" % path
leaf_map[path]["meta"] = {**leaf_map[path]["meta"], **meta}
leaf_map[path]["value"] = leaf_map[path]["meta"]["value"]
total = leaf_map[path]["meta"]["cases"]["total"]
if total > 0:
leaf_map[path]["itemStyle"]["colorAlpha"] = min(1.0, float(total)/10.0)
leaf_map[path]["meta"]["light"] = total >= 10

301
tools/kmu_dut_tree.py Normal file
View File

@ -0,0 +1,301 @@
#coding=utf8
#***************************************************************************************
# This project is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
# http://license.coscl.org.cn/MulanPSL2
#
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#
# See the Mulan PSL v2 for more details.
#**************************************************************************************/
from dut_tree import *
kmh_dut_heriarchy = {
"name": "kmh_dut",
"children": [
{
"name": "frontend",
"children": [
{
"name": "bpu",
"children": [
{
"name": "ftb"
},
{
"name": "uftb"
},
{
"name": "ittage"
},
{
"name": "tagesc"
},
{
"name": "ras"
}
]
},
{
**dut_priority_critical,
"name": "ftq",
},
{
**dut_priority_high,
"name": "ibuffer",
},
{
**dut_priority_high,
"name": "icache",
},
{
"name": "ifu",
},
{
**dut_priority_high,
"name": "instr_uncache",
},
{
"name": "itlb",
},
{
"name": "pmp",
}
]
},
{
"name": "backend",
"children": [
{
"name": "ctrl_block",
"children": [
{
"name": "decode"
},
{
"name": "rename",
"children": [
{
"name": "rename_table"
},
{
"name": "freelist",
"children": [
{
"name": "int"
},
{
"name": "float"
},
{
"name": "vtype"
}
]
}
]
},
{
"name": "dispatch"
},
{
"name": "dispatch_queue",
"children": [
{
"name": "int"
},
{
"name": "float"
},
{
"name": "mem"
},
{
"name": "vector_float"
}
]
},
{
"name": "mem_ctrl"
},
{
**dut_priority_high,
"name": "redirect_gen"
},
{
**dut_priority_critical,
"name": "rob"
},
{
"name": "pc_gpa_mem"
}
]
},
{
**dut_priority_high,
"name": "data_path"
},
{
**dut_priority_high,
"name": "scheduler",
"children": [
{
"name": "int"
},
{
"name": "float"
},
{
"name": "mem"
},
{
"name": "vector_float"
}
]
},
{
"name": "exu_block",
"children": [
{
"name": "float"
},
{
"name": "int",
"children": [
{
**dut_priority_critical,
"name": "csr"
},
{
"name": "other"
}
]
},
{
**dut_priority_critical,
"name": "vector_float"
}
]
},
{
**dut_priority_critical,
"name": "og2_for_vector"
},
{
"name": "pc_target_mem"
},
{
**dut_priority_high,
"name": "wb_data_path"
},
{
**dut_priority_high,
"name": "wb_fu_busy_table"
},
{
**dut_priority_high,
"name": "bypass_network"
}
]
},
{
"name": "mem_block",
"children": [
{
"name": "lsq",
"children": [
{
**dut_priority_critical,
"name": "load_queue",
"children": [
{
"name": "virtual_load_queue",
},
{
"name": "raw_rar_queue",
},
{
"name": "uncache_queue",
},
{
"name": "exception_queue",
}
]
},
{
"name": "store_queue"
}
]
},
{
**dut_priority_critical,
"name": "dtlb"
},
{
**dut_priority_critical,
"name": "load_store_unit"
},
{
**dut_priority_critical,
"name": "dcache"
},
{
"name": "pmp"
},
{
"name": "prefetcher"
},
{
"name": "v_mem",
**dut_priority_critical,
"children": [
{
"name": "vl_split"
},
{
"name": "v_segment_unit"
},
{
"name": "vl_merger_buffer"
},
{
"name": "vs_merge_buffer"
}
]
},
{
"name": "ptw"
},
{
"name": "uncache"
},
{
"name": "sbuffer"
}
]
},
{
"name": "misc",
"children": [
{
**dut_priority_critical,
"name": "l2_cache",
},
{
**dut_priority_high,
"name": "mmio"
}
]
}
]
}
if __name__ == "__main__":
dut_tree = DutTree(kmh_dut_heriarchy)
dut_tree.update_leaf_meta({"/kmh_dut/misc/mmio": {"cases": {"total": 10, "pass": 12, "fail": 0, "skip": 0}},
"/kmh_dut/mem_block/ptw": {"cases": {"total": 10, "pass": 6, "fail": 2, "skip": 2}},
})
print(dut_tree.as_json())