Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
a8373f31
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
11 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
a8373f31
编写于
12月 28, 2020
作者:
L
Lingrui98
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/debian-gogogo' into ifu-timing
上级
fac40754
6d4530ec
变更
17
展开全部
显示空白变更内容
内联
并排
Showing
17 changed file
with
1207 addition
and
394 deletion
+1207
-394
scripts/coverage/coverage.py
scripts/coverage/coverage.py
+55
-11
scripts/coverage/statistics.py
scripts/coverage/statistics.py
+119
-46
src/main/scala/utils/DataModuleTemplate.scala
src/main/scala/utils/DataModuleTemplate.scala
+64
-0
src/main/scala/utils/DebugIdentityNode.scala
src/main/scala/utils/DebugIdentityNode.scala
+1
-1
src/main/scala/utils/Pipeline.scala
src/main/scala/utils/Pipeline.scala
+1
-0
src/main/scala/utils/TLDump.scala
src/main/scala/utils/TLDump.scala
+443
-14
src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
...main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
+28
-4
src/main/scala/xiangshan/backend/fu/fpu/divsqrt/DivSqrt.scala
...main/scala/xiangshan/backend/fu/fpu/divsqrt/DivSqrt.scala
+1
-0
src/main/scala/xiangshan/backend/fu/fpu/divsqrt/MantDivSqrt.scala
.../scala/xiangshan/backend/fu/fpu/divsqrt/MantDivSqrt.scala
+2
-0
src/main/scala/xiangshan/backend/roq/Roq.scala
src/main/scala/xiangshan/backend/roq/Roq.scala
+387
-273
src/main/scala/xiangshan/cache/ptw.scala
src/main/scala/xiangshan/cache/ptw.scala
+3
-3
src/main/scala/xiangshan/frontend/IFU.scala
src/main/scala/xiangshan/frontend/IFU.scala
+2
-2
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
+35
-16
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
+47
-24
src/main/scala/xiangshan/package.scala
src/main/scala/xiangshan/package.scala
+1
-0
src/test/csrc/emu.cpp
src/test/csrc/emu.cpp
+16
-0
src/test/scala/cache/L2CacheTest.scala
src/test/scala/cache/L2CacheTest.scala
+2
-0
未找到文件。
scripts/coverage/coverage.py
浏览文件 @
a8373f31
...
...
@@ -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,20 +20,28 @@ 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
synthesis_nest_level
>
0
:
if
ifdef_match
or
(
ifndef_match
and
not
synthesis_match
):
synthesis_nest_level
+=
1
if
endif_match
:
...
...
@@ -39,9 +49,43 @@ if __name__ == "__main__":
assert
synthesis_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
))
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
coverage_match
:
coverage_stat
=
coverage_match
.
group
(
1
)
line
=
line
.
replace
(
coverage_match
.
group
(
1
),
" "
*
len
(
coverage_stat
))
lines
+=
line
...
...
scripts/coverage/statistics.py
浏览文件 @
a8373f31
...
...
@@ -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'
)
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
)
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'
)
assert
not
(
coverred_match
and
not_coverred_match
)
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'
)
if
coverred_match
:
line_annotations
.
append
(
COVERRED
)
elif
not_coverred_match
:
line_annotations
.
append
(
NOT_COVERRED
)
line_cnt
=
0
for
line
in
lines
:
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
)
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
)
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_COVERRED
:
not_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_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/main/scala/utils/DataModuleTemplate.scala
0 → 100644
浏览文件 @
a8373f31
package
utils
import
chisel3._
import
chisel3.util._
class
DataModuleTemplate
[
T
<:
Data
](
gen
:
T
,
numEntries
:
Int
,
numRead
:
Int
,
numWrite
:
Int
,
useBitVec
:
Boolean
=
false
)
extends
Module
{
val
io
=
IO
(
new
Bundle
{
val
raddr
=
Vec
(
numRead
,
Input
(
UInt
(
log2Up
(
numEntries
).
W
)))
val
rdata
=
Vec
(
numRead
,
Output
(
gen
))
val
wen
=
Vec
(
numWrite
,
Input
(
Bool
()))
val
waddr
=
Vec
(
numWrite
,
Input
(
UInt
(
log2Up
(
numEntries
).
W
)))
val
wdata
=
Vec
(
numWrite
,
Input
(
gen
))
})
val
data
=
Mem
(
numEntries
,
gen
)
// read ports
for
(
i
<-
0
until
numRead
)
{
io
.
rdata
(
i
)
:=
data
(
io
.
raddr
(
i
))
}
if
(
useBitVec
)
{
// waddr_dec(i)(j): waddr(i) is target at entry(j)
val
waddr_dec
=
VecInit
(
io
.
waddr
.
map
(
UIntToOH
(
_
)(
numEntries
-
1
,
0
)))
// waddr_dec_with_en(i)(j): entry(j) is written by io.wdata(i)
val
waddr_dec_with_en
=
VecInit
(
io
.
wen
.
zip
(
waddr_dec
).
map
{
case
(
en
,
addr
)
=>
Fill
(
numEntries
,
en
)
&
addr
})
val
wen_dec
=
VecInit
((
0
until
numEntries
).
map
(
j
=>
{
val
data_wen
=
VecInit
(
waddr_dec_with_en
.
map
(
en
=>
en
(
j
)))
data_wen
.
suggestName
(
s
"data_wen_$j"
)
data_wen
.
asUInt
.
orR
}))
val
wdata_dec
=
VecInit
((
0
until
numEntries
).
map
(
j
=>
waddr_dec_with_en
.
zip
(
io
.
wdata
).
map
{
case
(
en
,
data
)
=>
Fill
(
gen
.
getWidth
,
en
(
j
))
&
data
.
asUInt
}.
reduce
(
_
|
_
).
asTypeOf
(
gen
)
))
waddr_dec
.
suggestName
(
"waddr_dec"
)
waddr_dec_with_en
.
suggestName
(
"waddr_dec_with_en"
)
wen_dec
.
suggestName
(
"wen_dec"
)
wdata_dec
.
suggestName
(
"wdata_dec"
)
// write ports
for
(
i
<-
0
until
numEntries
)
{
when
(
wen_dec
(
i
))
{
data
(
i
)
:=
wdata_dec
(
i
)
}
}
}
else
{
// below is the write ports (with priorities)
for
(
i
<-
0
until
numWrite
)
{
when
(
io
.
wen
(
i
))
{
data
(
io
.
waddr
(
i
))
:=
io
.
wdata
(
i
)
}
}
}
// DataModuleTemplate should not be used when there're any write conflicts
for
(
i
<-
0
until
numWrite
)
{
for
(
j
<-
i
+
1
until
numWrite
)
{
assert
(!(
io
.
wen
(
i
)
&&
io
.
wen
(
j
)
&&
io
.
waddr
(
i
)
===
io
.
waddr
(
j
)))
}
}
}
src/main/scala/utils/DebugIdentityNode.scala
浏览文件 @
a8373f31
...
...
@@ -31,7 +31,7 @@ class DebugIdentityNode()(implicit p: Parameters) extends LazyModule {
}
)
}
debug
(
in
,
tru
e
)
debug
(
in
,
fals
e
)
}
}
...
...
src/main/scala/utils/Pipeline.scala
浏览文件 @
a8373f31
...
...
@@ -6,6 +6,7 @@ import chisel3.util._
object
PipelineConnect
{
def
apply
[
T
<:
Data
](
left
:
DecoupledIO
[
T
],
right
:
DecoupledIO
[
T
],
rightOutFire
:
Bool
,
isFlush
:
Bool
)
=
{
val
valid
=
RegInit
(
false
.
B
)
valid
.
suggestName
(
"pipeline_valid"
)
when
(
rightOutFire
)
{
valid
:=
false
.
B
}
when
(
left
.
valid
&&
right
.
ready
)
{
valid
:=
true
.
B
}
when
(
isFlush
)
{
valid
:=
false
.
B
}
...
...
src/main/scala/utils/TLDump.scala
浏览文件 @
a8373f31
package
utils
import
chisel3._
import
chisel3.util._
import
freechips.rocketchip.tilelink.TLMessages._
import
freechips.rocketchip.tilelink.TLPermissions._
import
freechips.rocketchip.tilelink.
{
TLBundle
,
TLBundleA
,
TLBundleB
,
TLBundleC
,
TLBundleD
,
TLBundleE
,
TLChannel
}
import
xiangshan.HasXSLog
trait
HasTLDump
{
this:
HasXSLog
=>
trait
HasTLDump
{
this:
HasXSLog
=>
implicit
class
TLDump
(
channel
:
TLChannel
)
{
def
dump
=
channel
match
{
case
a
:
TLBundleA
=>
printChannelA
(
a
)
case
b
:
TLBundleB
=>
printChannelB
(
b
)
case
c
:
TLBundleC
=>
printChannelC
(
c
)
case
d
:
TLBundleD
=>
printChannelD
(
d
)
case
e
:
TLBundleE
=>
printChannelE
(
e
)
}
}
def
printChannelA
(
a
:
TLBundleA
)
:
Unit
=
{
switch
(
a
.
opcode
)
{
is
(
PutFullData
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
"
opcode: %x
param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
opcode
,
a
.
param
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
a
.
channelName
+
"
PutFullData
param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
param
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
case
b
:
TLBundleB
=>
}
is
(
PutPartialData
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" opcode: %x
param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
opcode
,
b
.
param
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
a
.
channelName
+
" PutPartialData
param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
param
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
case
c
:
TLBundleC
=>
}
is
(
ArithmeticData
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" opcode: %x param: %x size: %x source: %d address
: %x data: %x corrupt: %b\n"
,
c
.
opcode
,
c
.
param
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
a
.
channelName
+
" ArithmeticData param: %x size: %x source: %d address: %x mask
: %x data: %x corrupt: %b\n"
,
a
.
param
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
case
d
:
TLBundleD
=>
}
is
(
LogicalData
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" opcode: %x param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
opcode
,
d
.
param
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
a
.
channelName
+
" LogicalData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
param
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
is
(
Get
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" Get param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
param
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
is
(
Hint
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" Intent param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
param
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
is
(
AcquireBlock
)
{
switch
(
a
.
param
)
{
is
(
NtoB
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" AcquireBlock NtoB size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
is
(
NtoT
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" AcquireBlock NtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
is
(
BtoT
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" AcquireBlock BtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
}
}
is
(
AcquirePerm
)
{
switch
(
a
.
param
)
{
is
(
NtoB
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" AcquirePerm NtoB size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
is
(
NtoT
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" AcquirePerm NtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
is
(
BtoT
)
{
XSDebug
(
false
,
true
.
B
,
a
.
channelName
+
" AcquirePerm BtoT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
a
.
size
,
a
.
source
,
a
.
address
,
a
.
mask
,
a
.
data
,
a
.
corrupt
)
}
}
}
}
}
def
printChannelB
(
b
:
TLBundleB
)
:
Unit
=
{
switch
(
b
.
opcode
)
{
is
(
PutFullData
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" PutFullData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
param
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
is
(
PutPartialData
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" PutPartialData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
param
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
is
(
ArithmeticData
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" ArithmeticData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
param
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
is
(
LogicalData
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" LogicalData param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
param
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
is
(
Get
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" Get param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
param
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
is
(
Hint
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" Intent param: %x size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
param
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
is
(
Probe
)
{
switch
(
b
.
param
)
{
is
(
toN
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" Probe toN size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
case
e
:
TLBundleE
=>
XSDebug
(
false
,
true
.
B
,
e
.
channelName
+
" sink: %d\n"
,
e
.
sink
)
}
is
(
toB
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" Probe toB size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
is
(
toT
)
{
XSDebug
(
false
,
true
.
B
,
b
.
channelName
+
" Probe toT size: %x source: %d address: %x mask: %x data: %x corrupt: %b\n"
,
b
.
size
,
b
.
source
,
b
.
address
,
b
.
mask
,
b
.
data
,
b
.
corrupt
)
}
}
}
}
}
def
printChannelC
(
c
:
TLBundleC
)
:
Unit
=
{
switch
(
c
.
opcode
)
{
is
(
AccessAck
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" AccessAck param: %x size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
param
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
AccessAckData
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" AccessAckData param: %x size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
param
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
HintAck
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" HintAck param: %x size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
param
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
ProbeAck
)
{
switch
(
c
.
param
)
{
is
(
TtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAck TtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAck TtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAck BtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoT
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAck TtoT size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAck BtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
NtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAck NtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
}
}
is
(
ProbeAckData
)
{
switch
(
c
.
param
)
{
is
(
TtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAckData TtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAckData TtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAckData BtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoT
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAckData TtoT size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAckData BtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
NtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ProbeAckData NtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
}
}
is
(
Release
)
{
switch
(
c
.
param
)
{
is
(
TtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" Release TtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" Release TtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" Release BtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoT
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" Release TtoT size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" Release BtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
NtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" Release NtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
}
}
is
(
ReleaseData
)
{
switch
(
c
.
param
)
{
is
(
TtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ReleaseData TtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ReleaseData TtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ReleaseData BtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
TtoT
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ReleaseData TtoT size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
BtoB
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ReleaseData BtoB size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
is
(
NtoN
)
{
XSDebug
(
false
,
true
.
B
,
c
.
channelName
+
" ReleaseData NtoN size: %x source: %d address: %x data: %x corrupt: %b\n"
,
c
.
size
,
c
.
source
,
c
.
address
,
c
.
data
,
c
.
corrupt
)
}
}
}
}
}
def
printChannelD
(
d
:
TLBundleD
)
:
Unit
=
{
switch
(
d
.
opcode
)
{
is
(
AccessAck
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" AccessAck param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
param
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
is
(
AccessAckData
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" AccessAckData param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
param
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
is
(
HintAck
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" HintAck param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
param
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
is
(
Grant
)
{
switch
(
d
.
param
)
{
is
(
toT
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" Grant toT size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
is
(
toB
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" Grant toB size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
is
(
toN
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" Grant toN size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
}
}
is
(
GrantData
)
{
switch
(
d
.
param
)
{
is
(
toT
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" GrantData toT size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
is
(
toB
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" GrantData toB size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
is
(
toN
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" GrantData toN size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
}
}
is
(
ReleaseAck
)
{
XSDebug
(
false
,
true
.
B
,
d
.
channelName
+
" ReleaseAck param: %x size: %x source: %d sink: %d denied: %b data: %x corrupt: %b\n"
,
d
.
param
,
d
.
size
,
d
.
source
,
d
.
sink
,
d
.
denied
,
d
.
data
,
d
.
corrupt
)
}
}
}
def
printChannelE
(
e
:
TLBundleE
)
:
Unit
=
{
XSDebug
(
false
,
true
.
B
,
e
.
channelName
+
"GrantAck sink: %d\n"
,
e
.
sink
)
}
}
src/main/scala/xiangshan/backend/dispatch/DispatchQueue.scala
浏览文件 @
a8373f31
...
...
@@ -20,7 +20,6 @@ class DispatchQueueIO(enqnum: Int, deqnum: Int) extends XSBundle {
// dispatch queue: accepts at most enqnum uops from dispatch1 and dispatches deqnum uops at every clock cycle
class
DispatchQueue
(
size
:
Int
,
enqnum
:
Int
,
deqnum
:
Int
)
extends
XSModule
with
HasCircularQueuePtrHelper
{
val
io
=
IO
(
new
DispatchQueueIO
(
enqnum
,
deqnum
))
val
indexWidth
=
log2Ceil
(
size
)
val
s_invalid
::
s_valid
::
Nil
=
Enum
(
2
)
...
...
@@ -34,10 +33,12 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int) extends XSModule with H
// tail: first invalid entry (free entry)
val
tailPtr
=
RegInit
(
VecInit
((
0
until
enqnum
).
map
(
_
.
U
.
asTypeOf
(
new
CircularQueuePtr
(
size
)))))
val
tailPtrMask
=
UIntToMask
(
tailPtr
(
0
).
value
,
size
)
// valid entries counter
val
validCounter
=
RegInit
(
0.
U
(
log2Ceil
(
size
+
1
).
W
))
val
allowEnqueue
=
RegInit
(
true
.
B
)
val
validEntries
=
distanceBetween
(
tailPtr
(
0
),
headPtr
(
0
))
val
isTrueEmpty
=
~
Cat
((
0
until
size
).
map
(
i
=>
stateEntries
(
i
)
===
s_valid
)).
orR
val
canEnqueue
=
validEntries
<=
(
size
-
enqnum
).
U
val
canEnqueue
=
allowEnqueue
val
canActualEnqueue
=
canEnqueue
&&
!
io
.
redirect
.
valid
/**
...
...
@@ -93,7 +94,8 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int) extends XSModule with H
*/
// dequeue
val
numDeqTry
=
Mux
(
validEntries
>
deqnum
.
U
,
deqnum
.
U
,
validEntries
)
val
currentValidCounter
=
distanceBetween
(
tailPtr
(
0
),
headPtr
(
0
))
val
numDeqTry
=
Mux
(
currentValidCounter
>
deqnum
.
U
,
deqnum
.
U
,
currentValidCounter
)
val
numDeqFire
=
PriorityEncoder
(
io
.
deq
.
zipWithIndex
.
map
{
case
(
deq
,
i
)
=>
// For dequeue, the first entry should never be s_invalid
// Otherwise, there should be a redirect and tail walks back
...
...
@@ -146,6 +148,28 @@ class DispatchQueue(size: Int, enqnum: Int, deqnum: Int) extends XSModule with H
)
}
// update valid counter and allowEnqueue reg
validCounter
:=
Mux
(
exceptionValid
,
0.
U
,
Mux
(
io
.
redirect
.
valid
,
validCounter
,
Mux
(
lastLastCycleMisprediction
,
currentValidCounter
,
validCounter
+
numEnq
-
numDeq
)
)
)
allowEnqueue
:=
Mux
(
io
.
redirect
.
valid
,
false
.
B
,
Mux
(
lastLastCycleMisprediction
,
currentValidCounter
<=
(
size
-
enqnum
).
U
,
// To optimize timing, we don't use numDeq here.
// It affects cases when validCount + numEnq - numDeq <= (size - enqnum).U.
// For example, there're 10 empty entries with 6 enqueue and 2 dequeue.
// However, since dispatch queue size > (numEnq + numDeq),
// even if we allow enqueue, they cannot be dispatched immediately.
validCounter
+
numEnq
<=
(
size
-
enqnum
).
U
)
)
/**
* Part 3: set output and input
...
...
src/main/scala/xiangshan/backend/fu/fpu/divsqrt/DivSqrt.scala
浏览文件 @
a8373f31
...
...
@@ -140,6 +140,7 @@ class DivSqrt extends FPUSubModule {
// 53 + 2 + 2 = 57 bits are needed, but 57 % log2(4) != 0, use 58 bits instead
val
mantDivSqrt
=
Module
(
new
MantDivSqrt
(
D_MANT_WIDTH
+
2
+
2
+
1
))
mantDivSqrt
.
io
.
kill
:=
kill
mantDivSqrt
.
io
.
out
.
ready
:=
true
.
B
mantDivSqrt
.
io
.
in
.
valid
:=
state
===
s_start
mantDivSqrt
.
io
.
in
.
bits
.
a
:=
Mux
(
isDivReg
||
aIsOddExp
,
Cat
(
aMantReg
,
0.
U
(
5.
W
)),
Cat
(
0.
U
(
1.
W
),
aMantReg
,
0.
U
(
4.
W
)))
...
...
src/main/scala/xiangshan/backend/fu/fpu/divsqrt/MantDivSqrt.scala
浏览文件 @
a8373f31
...
...
@@ -11,6 +11,7 @@ class MantDivSqrt(len: Int) extends Module{
val
a
,
b
=
UInt
(
len
.
W
)
val
isDiv
=
Bool
()
}))
val
kill
=
Input
(
Bool
())
val
out
=
DecoupledIO
(
new
Bundle
()
{
val
quotient
=
UInt
(
len
.
W
)
val
isZeroRem
=
Bool
()
...
...
@@ -45,6 +46,7 @@ class MantDivSqrt(len: Int) extends Module{
when
(
io
.
out
.
fire
()){
state
:=
s_idle
}
}
}
when
(
io
.
kill
){
state
:=
s_idle
}
val
ws
,
wc
=
Reg
(
UInt
((
len
+
4
).
W
))
...
...
src/main/scala/xiangshan/backend/roq/Roq.scala
浏览文件 @
a8373f31
此差异已折叠。
点击以展开。
src/main/scala/xiangshan/cache/ptw.scala
浏览文件 @
a8373f31
...
...
@@ -501,11 +501,11 @@ class PTWImp(outer: PTW) extends PtwModule(outer){
}
.
otherwise
{
when
(
sfence
.
bits
.
rs2
)
{
// specific leaf of addr && all asid
tlbv
:=
tlbv
&
~
UIntToOH
(
sfence
.
bits
.
addr
(
log2Up
(
TlbL2EntrySize
)-
1
+
offLen
,
0
+
offLen
))
tlbg
:=
tlbg
&
~
UIntToOH
(
sfence
.
bits
.
addr
(
log2Up
(
TlbL2EntrySize
)-
1
+
offLen
,
0
+
offLen
))
tlbv
:=
tlbv
&
~
UIntToOH
(
genTlbL2Idx
(
sfence
.
bits
.
addr
(
sfence
.
bits
.
addr
.
getWidth
-
1
,
offLen
)
))
tlbg
:=
tlbg
&
~
UIntToOH
(
genTlbL2Idx
(
sfence
.
bits
.
addr
(
sfence
.
bits
.
addr
.
getWidth
-
1
,
offLen
)
))
}
.
otherwise
{
// specific leaf of addr && specific asid
tlbv
:=
tlbv
&
(~
UIntToOH
(
sfence
.
bits
.
addr
(
log2Up
(
TlbL2EntrySize
)-
1
+
offLen
,
0
+
offLen
))
|
tlbg
)
tlbv
:=
tlbv
&
(~
UIntToOH
(
genTlbL2Idx
(
sfence
.
bits
.
addr
(
sfence
.
bits
.
addr
.
getWidth
-
1
,
offLen
)))
|
tlbg
)
}
}
}
...
...
src/main/scala/xiangshan/frontend/IFU.scala
浏览文件 @
a8373f31
...
...
@@ -127,7 +127,7 @@ class IFU extends XSModule with HasIFUConst
val
if1_npc
=
WireInit
(
0.
U
(
VAddrBits
.
W
))
val
if2_ready
=
WireInit
(
false
.
B
)
val
if2_allReady
=
WireInit
(
if2_ready
&&
icache
.
io
.
req
.
ready
)
val
if1_fire
=
if1_valid
&&
(
if2_allReady
||
if
1
_flush
)
val
if1_fire
=
if1_valid
&&
(
if2_allReady
||
if
2
_flush
)
// val if2_newPtr, if3_newPtr, if4_newPtr = Wire(UInt(log2Up(ExtHistoryLength).W))
...
...
@@ -401,7 +401,7 @@ class IFU extends XSModule with HasIFUConst
if1_npc
:=
npcGen
()
icache
.
io
.
req
.
valid
:=
if1_valid
&&
(
if2_ready
||
if
1
_flush
)
icache
.
io
.
req
.
valid
:=
if1_valid
&&
(
if2_ready
||
if
2
_flush
)
icache
.
io
.
resp
.
ready
:=
if4_ready
icache
.
io
.
req
.
bits
.
addr
:=
if1_npc
icache
.
io
.
req
.
bits
.
mask
:=
mask
(
if1_npc
)
...
...
src/main/scala/xiangshan/mem/lsqueue/LoadQueue.scala
浏览文件 @
a8373f31
...
...
@@ -62,6 +62,9 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
val
enqPtrExt
=
RegInit
(
VecInit
((
0
until
RenameWidth
).
map
(
_
.
U
.
asTypeOf
(
new
LqPtr
))))
val
deqPtrExt
=
RegInit
(
0.
U
.
asTypeOf
(
new
LqPtr
))
val
validCounter
=
RegInit
(
0.
U
(
log2Ceil
(
LoadQueueSize
+
1
).
W
))
val
allowEnqueue
=
RegInit
(
true
.
B
)
val
enqPtr
=
enqPtrExt
(
0
).
value
val
deqPtr
=
deqPtrExt
.
value
val
sameFlag
=
enqPtrExt
(
0
).
flag
===
deqPtrExt
.
flag
...
...
@@ -80,10 +83,8 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
*
* Currently, LoadQueue only allows enqueue when #emptyEntries > RenameWidth(EnqWidth)
*/
val
validEntries
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
)
val
firedDispatch
=
io
.
enq
.
req
.
map
(
_
.
valid
)
io
.
enq
.
canAccept
:=
validEntries
<=
(
LoadQueueSize
-
RenameWidth
).
U
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(Cat(firedDispatch))}\n"
)
io
.
enq
.
canAccept
:=
allowEnqueue
for
(
i
<-
0
until
RenameWidth
)
{
val
offset
=
if
(
i
==
0
)
0.
U
else
PopCount
(
io
.
enq
.
needAlloc
.
take
(
i
))
val
lqIdx
=
enqPtrExt
(
offset
)
...
...
@@ -100,13 +101,7 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
}
io
.
enq
.
resp
(
i
)
:=
lqIdx
}
// when io.brqRedirect.valid, we don't allow eneuque even though it may fire.
when
(
Cat
(
firedDispatch
).
orR
&&
io
.
enq
.
canAccept
&&
io
.
enq
.
sqCanAccept
&&
!
io
.
brqRedirect
.
valid
)
{
val
enqNumber
=
PopCount
(
firedDispatch
)
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
+
enqNumber
))
XSInfo
(
"dispatched %d insts to lq\n"
,
enqNumber
)
}
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(Cat(io.enq.req.map(_.valid)))}\n"
)
/**
* Writeback load from load units
...
...
@@ -335,7 +330,6 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
XSDebug
(
"load commit %d: idx %d %x\n"
,
i
.
U
,
mcommitIdx
(
i
),
uop
(
mcommitIdx
(
i
)).
cf
.
pc
)
}
})
deqPtrExt
:=
deqPtrExt
+
PopCount
(
loadCommit
)
def
getFirstOne
(
mask
:
Vec
[
Bool
],
startMask
:
UInt
)
=
{
val
length
=
mask
.
length
...
...
@@ -549,13 +543,38 @@ class LoadQueue extends XSModule with HasDCacheParameters with HasCircularQueueP
allocated
(
i
)
:=
false
.
B
}
}
// we recover the pointers in the next cycle after redirect
val
needCancelReg
=
RegNext
(
needCancel
)
/**
* update pointers
*/
val
lastCycleCancelCount
=
PopCount
(
RegNext
(
needCancel
))
// when io.brqRedirect.valid, we don't allow eneuque even though it may fire.
val
enqNumber
=
Mux
(
io
.
enq
.
canAccept
&&
io
.
enq
.
sqCanAccept
&&
!
io
.
brqRedirect
.
valid
,
PopCount
(
io
.
enq
.
req
.
map
(
_
.
valid
)),
0.
U
)
when
(
lastCycleRedirect
.
valid
)
{
val
cancelCount
=
PopCount
(
needCancelReg
)
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
-
cancelCount
))
// we recover the pointers in the next cycle after redirect
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
-
lastCycleCancelCount
))
}.
otherwise
{
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
+
enqNumber
))
}
val
commitCount
=
PopCount
(
loadCommit
)
deqPtrExt
:=
deqPtrExt
+
commitCount
val
lastLastCycleRedirect
=
RegNext
(
lastCycleRedirect
.
valid
)
val
trueValidCounter
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
)
validCounter
:=
Mux
(
lastLastCycleRedirect
,
trueValidCounter
,
validCounter
+
enqNumber
-
commitCount
)
allowEnqueue
:=
Mux
(
io
.
brqRedirect
.
valid
,
false
.
B
,
Mux
(
lastLastCycleRedirect
,
trueValidCounter
<=
(
LoadQueueSize
-
RenameWidth
).
U
,
validCounter
+
enqNumber
<=
(
LoadQueueSize
-
RenameWidth
).
U
)
)
// debug info
XSDebug
(
"enqPtrExt %d:%d deqPtrExt %d:%d\n"
,
enqPtrExt
(
0
).
flag
,
enqPtr
,
deqPtrExt
.
flag
,
deqPtr
)
...
...
src/main/scala/xiangshan/mem/lsqueue/StoreQueue.scala
浏览文件 @
a8373f31
...
...
@@ -58,6 +58,9 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
require
(
StoreQueueSize
>
RenameWidth
)
val
enqPtrExt
=
RegInit
(
VecInit
((
0
until
RenameWidth
).
map
(
_
.
U
.
asTypeOf
(
new
SqPtr
))))
val
deqPtrExt
=
RegInit
(
VecInit
((
0
until
StorePipelineWidth
).
map
(
_
.
U
.
asTypeOf
(
new
SqPtr
))))
val
validCounter
=
RegInit
(
0.
U
(
log2Ceil
(
LoadQueueSize
+
1
).
W
))
val
allowEnqueue
=
RegInit
(
true
.
B
)
val
enqPtr
=
enqPtrExt
(
0
).
value
val
deqPtr
=
deqPtrExt
(
0
).
value
...
...
@@ -69,10 +72,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
*
* Currently, StoreQueue only allows enqueue when #emptyEntries > RenameWidth(EnqWidth)
*/
val
validEntries
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
(
0
))
val
firedDispatch
=
io
.
enq
.
req
.
map
(
_
.
valid
)
io
.
enq
.
canAccept
:=
validEntries
<=
(
StoreQueueSize
-
RenameWidth
).
U
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(Cat(firedDispatch))}\n"
)
io
.
enq
.
canAccept
:=
allowEnqueue
for
(
i
<-
0
until
RenameWidth
)
{
val
offset
=
if
(
i
==
0
)
0.
U
else
PopCount
(
io
.
enq
.
needAlloc
.
take
(
i
))
val
sqIdx
=
enqPtrExt
(
offset
)
...
...
@@ -87,12 +87,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
}
io
.
enq
.
resp
(
i
)
:=
sqIdx
}
when
(
Cat
(
firedDispatch
).
orR
&&
io
.
enq
.
canAccept
&&
io
.
enq
.
lqCanAccept
&&
!
io
.
brqRedirect
.
valid
)
{
val
enqNumber
=
PopCount
(
firedDispatch
)
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
+
enqNumber
))
XSInfo
(
"dispatched %d insts to sq\n"
,
enqNumber
)
}
XSDebug
(
p
"(ready, valid): ${io.enq.canAccept}, ${Binary(Cat(io.enq.req.map(_.valid)))}\n"
)
/**
* Writeback store from store units
...
...
@@ -246,7 +241,7 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
when
(
io
.
mmioStout
.
fire
())
{
writebacked
(
deqPtr
)
:=
true
.
B
allocated
(
deqPtr
)
:=
false
.
B
deqPtrExt
:=
VecInit
(
deqPtrExt
.
map
(
_
+
1.
U
))
}
/**
...
...
@@ -284,14 +279,10 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
XSDebug
(
"sbuffer "
+
i
+
" fire: ptr %d\n"
,
ptr
)
}
}
// note that sbuffer will not accept req(1) if req(0) is not accepted.
when
(
Cat
(
io
.
sbuffer
.
map
(
_
.
fire
())).
orR
)
{
val
stepForward
=
Mux
(
io
.
sbuffer
(
1
).
fire
(),
2.
U
,
1.
U
)
deqPtrExt
:=
VecInit
(
deqPtrExt
.
map
(
_
+
stepForward
))
when
(
io
.
sbuffer
(
1
).
fire
())
{
assert
(
io
.
sbuffer
(
0
).
fire
())
}
}
if
(!
env
.
FPGAPlatform
)
{
val
storeCommit
=
PopCount
(
io
.
sbuffer
.
map
(
_
.
fire
()))
val
waddr
=
VecInit
(
io
.
sbuffer
.
map
(
req
=>
SignExt
(
req
.
bits
.
addr
,
64
)))
...
...
@@ -316,13 +307,45 @@ class StoreQueue extends XSModule with HasDCacheParameters with HasCircularQueue
allocated
(
i
)
:=
false
.
B
}
}
/**
* update pointers
*/
val
lastCycleRedirect
=
RegNext
(
io
.
brqRedirect
.
valid
)
val
lastCycleCancelCount
=
PopCount
(
RegNext
(
needCancel
))
// when io.brqRedirect.valid, we don't allow eneuque even though it may fire.
val
enqNumber
=
Mux
(
io
.
enq
.
canAccept
&&
io
.
enq
.
lqCanAccept
&&
!
io
.
brqRedirect
.
valid
,
PopCount
(
io
.
enq
.
req
.
map
(
_
.
valid
)),
0.
U
)
when
(
lastCycleRedirect
)
{
// we recover the pointers in the next cycle after redirect
val
lastCycleRedirectValid
=
RegNext
(
io
.
brqRedirect
.
valid
)
val
needCancelCount
=
PopCount
(
RegNext
(
needCancel
))
when
(
lastCycleRedirectValid
)
{
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
-
needCancelCount
))
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
-
lastCycleCancelCount
))
}.
otherwise
{
enqPtrExt
:=
VecInit
(
enqPtrExt
.
map
(
_
+
enqNumber
))
}
deqPtrExt
:=
Mux
(
io
.
sbuffer
(
1
).
fire
(),
VecInit
(
deqPtrExt
.
map
(
_
+
2.
U
)),
Mux
(
io
.
sbuffer
(
0
).
fire
()
||
io
.
mmioStout
.
fire
(),
VecInit
(
deqPtrExt
.
map
(
_
+
1.
U
)),
deqPtrExt
)
)
val
lastLastCycleRedirect
=
RegNext
(
lastCycleRedirect
)
val
dequeueCount
=
Mux
(
io
.
sbuffer
(
1
).
fire
(),
2.
U
,
Mux
(
io
.
sbuffer
(
0
).
fire
()
||
io
.
mmioStout
.
fire
(),
1.
U
,
0.
U
))
val
trueValidCounter
=
distanceBetween
(
enqPtrExt
(
0
),
deqPtrExt
(
0
))
validCounter
:=
Mux
(
lastLastCycleRedirect
,
trueValidCounter
-
dequeueCount
,
validCounter
+
enqNumber
-
dequeueCount
)
allowEnqueue
:=
Mux
(
io
.
brqRedirect
.
valid
,
false
.
B
,
Mux
(
lastLastCycleRedirect
,
trueValidCounter
<=
(
StoreQueueSize
-
RenameWidth
).
U
,
validCounter
+
enqNumber
<=
(
StoreQueueSize
-
RenameWidth
).
U
)
)
// debug info
XSDebug
(
"enqPtrExt %d:%d deqPtrExt %d:%d\n"
,
enqPtrExt
(
0
).
flag
,
enqPtr
,
deqPtrExt
(
0
).
flag
,
deqPtr
)
...
...
src/main/scala/xiangshan/package.scala
浏览文件 @
a8373f31
...
...
@@ -93,6 +93,7 @@ package object xiangshan {
def
apply
()
=
UInt
(
2.
W
)
def
isLoadStore
(
commitType
:
UInt
)
=
commitType
(
1
)
def
lsInstIsStore
(
commitType
:
UInt
)
=
commitType
(
0
)
def
isStore
(
commitType
:
UInt
)
=
isLoadStore
(
commitType
)
&&
lsInstIsStore
(
commitType
)
def
isBranch
(
commitType
:
UInt
)
=
commitType
(
0
)
&&
!
commitType
(
1
)
}
...
...
src/test/csrc/emu.cpp
浏览文件 @
a8373f31
...
...
@@ -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
)
{
...
...
@@ -407,6 +422,7 @@ inline char* Emulator::waveform_filename(time_t t) {
static
char
buf
[
1024
];
char
*
p
=
timestamp_filename
(
t
,
buf
);
strcpy
(
p
,
".vcd"
);
printf
(
"dump wave to %s...
\n
"
,
buf
);
return
buf
;
}
...
...
src/test/scala/cache/L2CacheTest.scala
浏览文件 @
a8373f31
...
...
@@ -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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录