forked from XS-MLVP/UnityChipForXiangShan
draft ut charts
This commit is contained in:
parent
14c7250edc
commit
b7e5726bcf
|
|
@ -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
|
|
@ -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) + ' (' +
|
||||
formatUtil.addCommas(meta.cases.skip) + ' skiped, ' +
|
||||
formatUtil.addCommas(meta.cases.fail) + ' 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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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())
|
||||
Loading…
Reference in New Issue