Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
ec3a4e63
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
9 个月 前同步成功
通知
1183
Star
3914
Fork
526
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
X
XiangShan
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
未验证
提交
ec3a4e63
编写于
12月 22, 2020
作者:
Y
Yinan Xu
提交者:
GitHub
12月 22, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #348 from RISCVERS/coverage
Coverage
上级
dc98c21c
8efe06a8
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
191 addition
and
57 deletion
+191
-57
scripts/coverage/coverage.py
scripts/coverage/coverage.py
+55
-11
scripts/coverage/statistics.py
scripts/coverage/statistics.py
+119
-46
src/test/csrc/emu.cpp
src/test/csrc/emu.cpp
+15
-0
src/test/scala/cache/L2CacheTest.scala
src/test/scala/cache/L2CacheTest.scala
+2
-0
未找到文件。
scripts/coverage/coverage.py
浏览文件 @
ec3a4e63
...
...
@@ -11,6 +11,8 @@ if __name__ == "__main__":
lines
=
[]
line_count
=
0
synthesis_nest_level
=
0
reg_init_nest_level
=
0
mem_init_nest_level
=
0
with
open
(
input_file
)
as
f
:
for
line
in
f
:
line_count
+=
1
...
...
@@ -18,30 +20,72 @@ if __name__ == "__main__":
ifdef
=
re
.
compile
(
'`ifdef'
)
ifndef
=
re
.
compile
(
'`ifndef'
)
endif
=
re
.
compile
(
'`endif'
)
# remove the line coverage results of not synthesizable code(mostly assert and fwrite)
synthesis
=
re
.
compile
(
'`ifndef SYNTHESIS'
)
line_coverage
=
re
.
compile
(
'^\s*([%]?\d+)\s+if'
)
# remove the coverage results of random init variables
reg_init
=
re
.
compile
(
'`ifdef RANDOMIZE_REG_INIT'
)
mem_init
=
re
.
compile
(
'`ifdef RANDOMIZE_MEM_INIT'
)
coverage
=
re
.
compile
(
'^\s*(%?\d+)\s+'
)
ifdef_match
=
ifdef
.
search
(
line
)
ifndef_match
=
ifndef
.
search
(
line
)
endif_match
=
endif
.
search
(
line
)
synthesis_match
=
synthesis
.
search
(
line
)
line_coverage_match
=
line_coverage
.
search
(
line
)
reg_init_match
=
reg_init
.
search
(
line
)
mem_init_match
=
mem_init
.
search
(
line
)
coverage_match
=
coverage
.
search
(
line
)
# enter synthesis block
if
synthesis_match
:
assert
synthesis_nest_level
==
0
,
"Should not nest SYNTHESIS macro"
synthesis_nest_level
=
1
if
ifdef_match
or
(
ifndef_match
and
not
synthesis_match
):
synthesis_nest_level
+=
1
if
endif_match
:
synthesis_nest_level
-=
1
assert
synthesis_nest_level
>=
0
,
"Macro nest level should be >= 0"
if
synthesis_nest_level
>
0
:
if
ifdef_match
or
(
ifndef_match
and
not
synthesis_match
):
synthesis_nest_level
+=
1
if
endif_match
:
synthesis_nest_level
-=
1
assert
synthesis_nest_level
>=
0
,
"Macro nest level should be >= 0"
# remove line coverage results in systhesis block
if
coverage_match
:
coverage_stat
=
coverage_match
.
group
(
1
)
line
=
line
.
replace
(
coverage_match
.
group
(
1
),
" "
*
len
(
coverage_stat
))
# enter reg_init block
if
reg_init_match
:
assert
reg_init_nest_level
==
0
,
"Should not nest reg_init macro"
reg_init_nest_level
=
1
if
reg_init_nest_level
>
0
:
if
(
ifdef_match
and
not
reg_init_match
)
or
ifndef_match
:
reg_init_nest_level
+=
1
if
endif_match
:
reg_init_nest_level
-=
1
assert
reg_init_nest_level
>=
0
,
"Macro nest level should be >= 0"
# remove line coverage results in systhesis block
if
coverage_match
:
coverage_stat
=
coverage_match
.
group
(
1
)
line
=
line
.
replace
(
coverage_match
.
group
(
1
),
" "
*
len
(
coverage_stat
))
# enter mem_init block
if
mem_init_match
:
assert
mem_init_nest_level
==
0
,
"Should not nest mem_init macro"
mem_init_nest_level
=
1
if
mem_init_nest_level
>
0
:
if
(
ifdef_match
and
not
mem_init_match
)
or
ifndef_match
:
mem_init_nest_level
+=
1
if
endif_match
:
mem_init_nest_level
-=
1
assert
mem_init_nest_level
>=
0
,
"Macro nest level should be >= 0"
# remove line coverage results in systhesis block
if
synthesis_nest_level
>
0
and
line_
coverage_match
:
coverage_stat
=
line_
coverage_match
.
group
(
1
)
line
=
line
.
replace
(
line_
coverage_match
.
group
(
1
),
" "
*
len
(
coverage_stat
))
# remove line coverage results in systhesis block
if
coverage_match
:
coverage_stat
=
coverage_match
.
group
(
1
)
line
=
line
.
replace
(
coverage_match
.
group
(
1
),
" "
*
len
(
coverage_stat
))
lines
+=
line
...
...
scripts/coverage/statistics.py
浏览文件 @
ec3a4e63
...
...
@@ -5,19 +5,31 @@ import re
import
copy
import
pprint
COVERRED
=
"COVERRED"
NOT_COVERRED
=
"NOT_COVERRED"
LINE_COVERRED
=
"LINE_COVERRED"
NOT_LINE_COVERRED
=
"NOT_LINE_COVERRED"
TOGGLE_COVERRED
=
"TOGGLE_COVERRED"
NOT_TOGGLE_COVERRED
=
"NOT_TOGGLE_COVERRED"
DONTCARE
=
"DONTCARE"
BEGIN
=
"BEGIN"
END
=
"END"
CHILDREN
=
"CHILDREN"
MODULE
=
"MODULE"
INSTANCE
=
"INSTANCE"
TYPE
=
"TYPE"
ROOT
=
"ROOT"
NODE
=
"NODE"
SELFCOVERAGE
=
"SELFCOVERAGE"
TREECOVERAGE
=
"TREECOVERAGE"
TYPE
=
"TYPE"
ROOT
=
"ROOT"
NODE
=
"NODE"
SELFCOVERAGE
=
"SELFCOVERAGE"
TREECOVERAGE
=
"TREECOVERAGE"
LINECOVERAGE
=
0
TOGGLECOVERAGE
=
1
def
check_one_hot
(
l
):
cnt
=
0
for
e
in
l
:
if
e
:
cnt
+=
1
return
cnt
<=
1
def
get_lines
(
input_file
):
lines
=
[]
...
...
@@ -31,41 +43,85 @@ def get_line_annotation(lines):
# pattern_1: 040192 if(array_0_MPORT_en & array_0_MPORT_mask) begin
# pattern_2: 2218110 end else if (_T_30) begin // @[Conditional.scala 40:58]
# pattern_2: 000417 end else begin
coverred_pattern_1
=
re
.
compile
(
'^\s*(\d+)\s+if'
)
coverred_pattern_2
=
re
.
compile
(
'^\s*(\d+)\s+end else'
)
not_coverred_pattern_1
=
re
.
compile
(
'^\s*(%0+)\s+if'
)
not_coverred_pattern_2
=
re
.
compile
(
'^\s*(%0+)\s+end else'
)
line_coverred_pattern_1
=
re
.
compile
(
'^\s*(\d+)\s+if'
)
line_coverred_pattern_2
=
re
.
compile
(
'^\s*(\d+)\s+end else'
)
not_line_coverred_pattern_1
=
re
.
compile
(
'^\s*(%0+)\s+if'
)
not_line_coverred_pattern_2
=
re
.
compile
(
'^\s*(%0+)\s+end else'
)
toggle_coverred_pattern_1
=
re
.
compile
(
'^\s*(\d+)\s+reg'
)
toggle_coverred_pattern_2
=
re
.
compile
(
'^\s*(\d+)\s+wire'
)
toggle_coverred_pattern_3
=
re
.
compile
(
'^\s*(\d+)\s+input'
)
toggle_coverred_pattern_4
=
re
.
compile
(
'^\s*(\d+)\s+output'
)
not_toggle_coverred_pattern_1
=
re
.
compile
(
'^\s*(%0+)\s+reg'
)
not_toggle_coverred_pattern_2
=
re
.
compile
(
'^\s*(%0+)\s+wire'
)
not_toggle_coverred_pattern_3
=
re
.
compile
(
'^\s*(%0+)\s+input'
)
not_toggle_coverred_pattern_4
=
re
.
compile
(
'^\s*(%0+)\s+output'
)
line_cnt
=
0
for
line
in
lines
:
coverred_match
=
coverred_pattern_1
.
search
(
line
)
or
coverred_pattern_2
.
search
(
line
)
not_coverred_match
=
not_coverred_pattern_1
.
search
(
line
)
or
not_coverred_pattern_2
.
search
(
line
)
line_coverred_match
=
line_coverred_pattern_1
.
search
(
line
)
or
line_coverred_pattern_2
.
search
(
line
)
not_line_coverred_match
=
not_line_coverred_pattern_1
.
search
(
line
)
or
not_line_coverred_pattern_2
.
search
(
line
)
assert
not
(
line_coverred_match
and
not_line_coverred_match
)
assert
not
(
coverred_match
and
not_coverred_match
)
toggle_coverred_match
=
toggle_coverred_pattern_1
.
search
(
line
)
or
toggle_coverred_pattern_2
.
search
(
line
)
or
\
toggle_coverred_pattern_3
.
search
(
line
)
or
toggle_coverred_pattern_4
.
search
(
line
)
not_toggle_coverred_match
=
not_toggle_coverred_pattern_1
.
search
(
line
)
or
not_toggle_coverred_pattern_2
.
search
(
line
)
or
\
not_toggle_coverred_pattern_3
.
search
(
line
)
or
not_toggle_coverred_pattern_4
.
search
(
line
)
assert
not
(
toggle_coverred_match
and
not_toggle_coverred_match
)
if
coverred_match
:
line_annotations
.
append
(
COVERRED
)
elif
not_coverred_match
:
line_annotations
.
append
(
NOT_COVERRED
)
all_match
=
(
line_coverred_match
,
not_line_coverred_match
,
toggle_coverred_match
,
not_toggle_coverred_match
)
if
not
check_one_hot
(
all_match
):
print
(
"not_one_hot"
)
print
(
line_cnt
)
print
(
all_match
)
assert
False
,
"This line matches multiple patterns"
if
line_coverred_match
:
line_annotations
.
append
(
LINE_COVERRED
)
elif
not_line_coverred_match
:
line_annotations
.
append
(
NOT_LINE_COVERRED
)
elif
toggle_coverred_match
:
line_annotations
.
append
(
TOGGLE_COVERRED
)
elif
not_toggle_coverred_match
:
line_annotations
.
append
(
NOT_TOGGLE_COVERRED
)
else
:
line_annotations
.
append
(
DONTCARE
)
line_cnt
+=
1
return
line_annotations
# get the line coverage statistics in line range [start, end)
def
get_coverage_statistics
(
line_annotations
,
start
,
end
):
coverred
=
0
not_coverred
=
0
line_coverred
=
0
not_line_coverred
=
0
toggle_coverred
=
0
not_toggle_coverred
=
0
for
i
in
range
(
start
,
end
):
if
line_annotations
[
i
]
==
COVERRED
:
coverred
+=
1
if
line_annotations
[
i
]
==
LINE_COVERRED
:
line_coverred
+=
1
if
line_annotations
[
i
]
==
NOT_LINE_COVERRED
:
not_line_coverred
+=
1
if
line_annotations
[
i
]
==
TOGGLE_COVERRED
:
toggle_coverred
+=
1
if
line_annotations
[
i
]
==
NOT_COVERRED
:
not_coverred
+=
1
if
line_annotations
[
i
]
==
NOT_
TOGGLE_
COVERRED
:
not_
toggle_
coverred
+=
1
# deal with divide by zero
coverage
=
1.0
if
coverred
+
not_coverred
!=
0
:
coverage
=
float
(
coverred
)
/
(
coverred
+
not_coverred
)
return
(
coverred
,
not_coverred
,
coverage
)
line_coverage
=
1.0
if
line_coverred
+
not_line_coverred
!=
0
:
line_coverage
=
float
(
line_coverred
)
/
(
line_coverred
+
not_line_coverred
)
toggle_coverage
=
1.0
if
toggle_coverred
+
not_toggle_coverred
!=
0
:
toggle_coverage
=
float
(
toggle_coverred
)
/
(
toggle_coverred
+
not_toggle_coverred
)
return
((
line_coverred
,
not_line_coverred
,
line_coverage
),
(
toggle_coverred
,
not_toggle_coverred
,
toggle_coverage
))
# get modules and all it's submodules
def
get_modules
(
lines
):
...
...
@@ -140,18 +196,26 @@ def get_tree_coverage(modules, coverage):
if
CHILDREN
not
in
modules
[
module
]:
modules
[
module
][
TREECOVERAGE
]
=
self_coverage
else
:
coverred
=
self_coverage
[
0
]
not_coverred
=
self_coverage
[
1
]
line_coverred
=
self_coverage
[
LINECOVERAGE
][
0
]
not_line_coverred
=
self_coverage
[
LINECOVERAGE
][
1
]
toggle_coverred
=
self_coverage
[
TOGGLECOVERAGE
][
0
]
not_toggle_coverred
=
self_coverage
[
TOGGLECOVERAGE
][
1
]
# the dfs part
for
child
in
modules
[
module
][
CHILDREN
]:
child_coverage
=
dfs
(
child
[
MODULE
])
coverred
+=
child_coverage
[
0
]
not_coverred
+=
child_coverage
[
1
]
line_coverred
+=
child_coverage
[
LINECOVERAGE
][
0
]
not_line_coverred
+=
child_coverage
[
LINECOVERAGE
][
1
]
toggle_coverred
+=
child_coverage
[
TOGGLECOVERAGE
][
0
]
not_toggle_coverred
+=
child_coverage
[
TOGGLECOVERAGE
][
1
]
# deal with divide by zero
coverage
=
1.0
if
coverred
+
not_coverred
!=
0
:
coverage
=
float
(
coverred
)
/
(
coverred
+
not_coverred
)
modules
[
module
][
TREECOVERAGE
]
=
(
coverred
,
not_coverred
,
coverage
)
line_coverage
=
1.0
if
line_coverred
+
not_line_coverred
!=
0
:
line_coverage
=
float
(
line_coverred
)
/
(
line_coverred
+
not_line_coverred
)
toggle_coverage
=
1.0
if
toggle_coverred
+
not_toggle_coverred
!=
0
:
toggle_coverage
=
float
(
toggle_coverred
)
/
(
toggle_coverred
+
not_toggle_coverred
)
modules
[
module
][
TREECOVERAGE
]
=
((
line_coverred
,
not_line_coverred
,
line_coverage
),
(
toggle_coverred
,
not_toggle_coverred
,
toggle_coverage
))
return
modules
[
module
][
TREECOVERAGE
]
for
module
in
modules
:
...
...
@@ -163,8 +227,8 @@ def get_tree_coverage(modules, coverage):
# arg1: tree coverage results
# arg2: coverage type
def
sort_coverage
(
coverage
,
coverage_type
):
l
=
[(
module
,
coverage
[
module
][
coverage_type
])
for
module
in
coverage
]
def
sort_coverage
(
coverage
,
self_or_tree
,
coverage_type
):
l
=
[(
module
,
coverage
[
module
][
self_or_tree
][
coverage_type
])
for
module
in
coverage
]
l
.
sort
(
key
=
lambda
x
:
x
[
1
][
2
])
return
l
...
...
@@ -174,10 +238,15 @@ def print_tree_coverage(tree_coverage):
tree
=
tree_coverage
[
module
][
TREECOVERAGE
]
self
=
tree_coverage
[
module
][
SELFCOVERAGE
]
print
(
" "
*
level
+
"- "
+
module
)
print
(
" "
*
level
+
" tree"
,
end
=
""
)
print
(
"(%d, %d, %.2f)"
%
(
tree
[
0
],
tree
[
1
],
tree
[
2
]
*
100.0
))
print
(
" "
*
level
+
" self"
,
end
=
""
)
print
(
"(%d, %d, %.2f)"
%
(
self
[
0
],
self
[
1
],
self
[
2
]
*
100.0
))
print
(
" "
*
level
+
" tree_line"
,
end
=
""
)
print
(
"(%d, %d, %.2f)"
%
(
tree
[
LINECOVERAGE
][
0
],
tree
[
LINECOVERAGE
][
1
],
tree
[
LINECOVERAGE
][
2
]
*
100.0
))
print
(
" "
*
level
+
" self_line"
,
end
=
""
)
print
(
"(%d, %d, %.2f)"
%
(
self
[
LINECOVERAGE
][
0
],
self
[
LINECOVERAGE
][
1
],
self
[
LINECOVERAGE
][
2
]
*
100.0
))
print
(
" "
*
level
+
" tree_toggle"
,
end
=
""
)
print
(
"(%d, %d, %.2f)"
%
(
tree
[
TOGGLECOVERAGE
][
0
],
tree
[
TOGGLECOVERAGE
][
1
],
tree
[
TOGGLECOVERAGE
][
2
]
*
100.0
))
print
(
" "
*
level
+
" self_toggle"
,
end
=
""
)
print
(
"(%d, %d, %.2f)"
%
(
self
[
TOGGLECOVERAGE
][
0
],
self
[
TOGGLECOVERAGE
][
1
],
self
[
TOGGLECOVERAGE
][
2
]
*
100.0
))
# print children nodes
if
CHILDREN
in
modules
[
module
]:
...
...
@@ -215,11 +284,15 @@ if __name__ == "__main__":
# print("tree_coverage:")
# pp.pprint(tree_coverage)
print
(
"SelfCoverage:"
)
pp
.
pprint
(
sort_coverage
(
tree_coverage
,
SELFCOVERAGE
))
print
(
"LineSelfCoverage:"
)
pp
.
pprint
(
sort_coverage
(
tree_coverage
,
SELFCOVERAGE
,
LINECOVERAGE
))
print
(
"LineTreeCoverage:"
)
pp
.
pprint
(
sort_coverage
(
tree_coverage
,
TREECOVERAGE
,
LINECOVERAGE
))
print
(
"TreeCoverage:"
)
pp
.
pprint
(
sort_coverage
(
tree_coverage
,
TREECOVERAGE
))
print
(
"ToggleSelfCoverage:"
)
pp
.
pprint
(
sort_coverage
(
tree_coverage
,
SELFCOVERAGE
,
TOGGLECOVERAGE
))
print
(
"ToggleTreeCoverage:"
)
pp
.
pprint
(
sort_coverage
(
tree_coverage
,
TREECOVERAGE
,
TOGGLECOVERAGE
))
print
(
"AllCoverage:"
)
print_tree_coverage
(
tree_coverage
)
src/test/csrc/emu.cpp
浏览文件 @
ec3a4e63
...
...
@@ -2,6 +2,8 @@
#include "sdcard.h"
#include "difftest.h"
#include <getopt.h>
#include<signal.h>
#include<unistd.h>
#include "ram.h"
#include "zlib.h"
#include "compress.h"
...
...
@@ -244,6 +246,16 @@ inline void Emulator::single_cycle() {
cycles
++
;
}
#if VM_COVERAGE == 1
uint64_t
*
max_cycle_ptr
=
NULL
;
// when interrupted, we set max_cycle to zero
// so that the emulator will stop gracefully
void
sig_handler
(
int
signo
)
{
if
(
signo
==
SIGINT
)
*
max_cycle_ptr
=
0
;
}
#endif
uint64_t
Emulator
::
execute
(
uint64_t
max_cycle
,
uint64_t
max_instr
)
{
extern
void
poll_event
(
void
);
extern
uint32_t
uptime
(
void
);
...
...
@@ -268,6 +280,9 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
// since we are not sure when an emu will stop
// we distinguish multiple dat files by emu start time
time_t
start_time
=
time
(
NULL
);
max_cycle_ptr
=
&
max_cycle
;
if
(
signal
(
SIGINT
,
sig_handler
)
==
SIG_ERR
)
printf
(
"
\n
can't catch SIGINT
\n
"
);
#endif
while
(
!
Verilated
::
gotFinish
()
&&
trapCode
==
STATE_RUNNING
)
{
...
...
src/test/scala/cache/L2CacheTest.scala
浏览文件 @
ec3a4e63
...
...
@@ -5,6 +5,7 @@ import chisel3._
import
chisel3.util._
import
chiseltest.experimental.TestOptionBuilder._
import
chiseltest.internal.
{
VerilatorBackendAnnotation
,
LineCoverageAnnotation
,
ToggleCoverageAnnotation
,
UserCoverageAnnotation
,
StructuralCoverageAnnotation
}
import
chiseltest.legacy.backends.verilator.VerilatorFlags
import
chiseltest._
import
chisel3.experimental.BundleLiterals._
import
firrtl.stage.RunFirrtlTransformAnnotation
...
...
@@ -262,6 +263,7 @@ class L2CacheTest extends AnyFlatSpec with ChiselScalatestTester with Matchers{
ToggleCoverageAnnotation
,
UserCoverageAnnotation
,
StructuralCoverageAnnotation
,
VerilatorFlags
(
Seq
(
"--output-split 5000"
,
"--output-split-cfuncs 5000"
)),
RunFirrtlTransformAnnotation
(
new
PrintModuleName
)
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录