Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
a3838d2b
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
8 个月 前同步成功
通知
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 搜索 >>
提交
a3838d2b
编写于
6月 17, 2021
作者:
J
JinYue
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
recover snapshot function
上级
3a3a0d80
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
139 addition
and
3 deletion
+139
-3
src/test/csrc/verilator/emu.cpp
src/test/csrc/verilator/emu.cpp
+129
-3
src/test/csrc/verilator/emu.h
src/test/csrc/verilator/emu.h
+4
-0
verilator.mk
verilator.mk
+6
-0
未找到文件。
src/test/csrc/verilator/emu.cpp
浏览文件 @
a3838d2b
...
...
@@ -123,7 +123,7 @@ Emulator::Emulator(int argc, const char *argv[]):
// init ram
init_ram
(
args
.
image
);
#if
(VM_TRACE == 1)
#if
VM_TRACE == 1
#ifndef EN_FORKWAIT
enable_waveform
=
args
.
enable_waveform
;
if
(
enable_waveform
)
{
...
...
@@ -142,6 +142,14 @@ Emulator::Emulator(int argc, const char *argv[]):
enable_waveform
=
false
;
#endif
#ifdef VM_SAVABLE
if
(
args
.
snapshot_path
!=
NULL
)
{
printf
(
"loading from snapshot `%s`...
\n
"
,
args
.
snapshot_path
);
snapshot_load
(
args
.
snapshot_path
);
printf
(
"model cycleCnt = %"
PRIu64
"
\n
"
,
dut_ptr
->
io_trap_cycleCnt
);
}
#endif
// set log time range and log level
dut_ptr
->
io_logCtrl_log_begin
=
args
.
log_begin
;
dut_ptr
->
io_logCtrl_log_end
=
args
.
log_end
;
...
...
@@ -150,6 +158,15 @@ Emulator::Emulator(int argc, const char *argv[]):
Emulator
::~
Emulator
()
{
ram_finish
();
assert_finish
();
#ifdef VM_SAVABLE
if
(
args
.
enable_snapshot
&&
trapCode
!=
STATE_GOODTRAP
&&
trapCode
!=
STATE_LIMIT_EXCEEDED
)
{
printf
(
"Saving snapshots to file system. Please wait.
\n
"
);
snapshot_slot
[
0
].
save
();
snapshot_slot
[
1
].
save
();
printf
(
"Please remove unused snapshots manually
\n
"
);
}
#endif
}
inline
void
Emulator
::
reset_ncycles
(
size_t
cycles
)
{
...
...
@@ -271,7 +288,6 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
break
;
}
}
// assertions
if
(
assert_count
>
0
)
{
// for (int i = 0; )
...
...
@@ -324,6 +340,22 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
}
if
(
trapCode
!=
STATE_RUNNING
)
break
;
#ifdef VM_SAVABLE
static
int
snapshot_count
=
0
;
if
(
args
.
enable_snapshot
&&
trapCode
!=
STATE_GOODTRAP
&&
t
-
lasttime_snapshot
>
1000
*
SNAPSHOT_INTERVAL
)
{
// save snapshot every 60s
time_t
now
=
time
(
NULL
);
snapshot_save
(
snapshot_filename
(
now
));
lasttime_snapshot
=
t
;
// dump one snapshot to file every 60 snapshots
snapshot_count
++
;
if
(
snapshot_count
==
60
)
{
snapshot_slot
[
0
].
save
();
snapshot_count
=
0
;
}
}
#endif
#ifdef EN_FORKWAIT
timer
=
uptime
();
if
(
timer
-
lasttime_snapshot
>
1000
*
FORK_INTERVAL
&&
!
waitProcess
){
//time out need to fork
...
...
@@ -374,9 +406,12 @@ uint64_t Emulator::execute(uint64_t max_cycle, uint64_t max_instr) {
forkshm
.
info
->
resInfo
=
trapCode
;
#endif
display_trapinfo
();
return
cycles
;
}
inline
char
*
Emulator
::
timestamp_filename
(
time_t
t
,
char
*
buf
)
{
char
buf_time
[
64
];
strftime
(
buf_time
,
sizeof
(
buf_time
),
"%F@%T"
,
localtime
(
&
t
));
...
...
@@ -386,12 +421,21 @@ inline char* Emulator::timestamp_filename(time_t t, char *buf) {
return
buf
+
len
;
}
#ifdef VM_SAVABLE
inline
char
*
Emulator
::
snapshot_filename
(
time_t
t
)
{
static
char
buf
[
1024
];
char
*
p
=
timestamp_filename
(
t
,
buf
);
strcpy
(
p
,
".snapshot"
);
return
buf
;
}
#endif
inline
char
*
Emulator
::
waveform_filename
(
time_t
t
)
{
static
char
buf
[
1024
];
char
*
p
=
timestamp_filename
(
t
,
buf
);
strcpy
(
p
,
".vcd"
);
printf
(
"
[%d]dump wave to %s...
\n
"
,
getpid
()
,
buf
);
printf
(
"
dump wave to %s...
\n
"
,
buf
);
return
buf
;
}
...
...
@@ -497,3 +541,85 @@ void ForkShareMemory::shwait(){
}
}
#endif
#ifdef VM_SAVABLE
void
Emulator
::
snapshot_save
(
const
char
*
filename
)
{
static
int
last_slot
=
0
;
VerilatedSaveMem
&
stream
=
snapshot_slot
[
last_slot
];
last_slot
=
!
last_slot
;
stream
.
init
(
filename
);
stream
<<
*
dut_ptr
;
stream
.
flush
();
long
size
=
get_ram_size
();
stream
.
unbuf_write
(
&
size
,
sizeof
(
size
));
stream
.
unbuf_write
(
get_ram_start
(),
size
);
uint64_t
ref_r
[
DIFFTEST_NR_REG
];
ref_difftest_getregs
(
&
ref_r
,
0
);
stream
.
unbuf_write
(
ref_r
,
sizeof
(
ref_r
));
uint64_t
nemu_this_pc
=
get_nemu_this_pc
(
0
);
stream
.
unbuf_write
(
&
nemu_this_pc
,
sizeof
(
nemu_this_pc
));
char
*
buf
=
(
char
*
)
mmap
(
NULL
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_ANON
|
MAP_PRIVATE
,
-
1
,
0
);
ref_difftest_memcpy_from_ref
(
buf
,
0x80000000
,
size
,
0
);
stream
.
unbuf_write
(
buf
,
size
);
munmap
(
buf
,
size
);
struct
SyncState
sync_mastate
;
ref_difftest_get_mastatus
(
&
sync_mastate
,
0
);
stream
.
unbuf_write
(
&
sync_mastate
,
sizeof
(
struct
SyncState
));
uint64_t
csr_buf
[
4096
];
ref_difftest_get_csr
(
csr_buf
,
0
);
stream
.
unbuf_write
(
&
csr_buf
,
sizeof
(
csr_buf
));
long
sdcard_offset
;
if
(
fp
)
sdcard_offset
=
ftell
(
fp
);
else
sdcard_offset
=
0
;
stream
.
unbuf_write
(
&
sdcard_offset
,
sizeof
(
sdcard_offset
));
// actually write to file in snapshot_finalize()
}
void
Emulator
::
snapshot_load
(
const
char
*
filename
)
{
VerilatedRestoreMem
stream
;
stream
.
open
(
filename
);
stream
>>
*
dut_ptr
;
long
size
;
stream
.
read
(
&
size
,
sizeof
(
size
));
assert
(
size
==
get_ram_size
());
stream
.
read
(
get_ram_start
(),
size
);
uint64_t
ref_r
[
DIFFTEST_NR_REG
];
stream
.
read
(
ref_r
,
sizeof
(
ref_r
));
ref_difftest_setregs
(
&
ref_r
,
0
);
uint64_t
nemu_this_pc
;
stream
.
read
(
&
nemu_this_pc
,
sizeof
(
nemu_this_pc
));
set_nemu_this_pc
(
nemu_this_pc
,
0
);
char
*
buf
=
(
char
*
)
mmap
(
NULL
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_ANON
|
MAP_PRIVATE
,
-
1
,
0
);
stream
.
read
(
buf
,
size
);
ref_difftest_memcpy_from_dut
(
0x80000000
,
buf
,
size
,
0
);
munmap
(
buf
,
size
);
struct
SyncState
sync_mastate
;
stream
.
read
(
&
sync_mastate
,
sizeof
(
struct
SyncState
));
ref_difftest_set_mastatus
(
&
sync_mastate
,
0
);
uint64_t
csr_buf
[
4096
];
stream
.
read
(
&
csr_buf
,
sizeof
(
csr_buf
));
ref_difftest_set_csr
(
csr_buf
,
0
);
long
sdcard_offset
=
0
;
stream
.
read
(
&
sdcard_offset
,
sizeof
(
sdcard_offset
));
if
(
fp
)
fseek
(
fp
,
sdcard_offset
,
SEEK_SET
);
}
#endif
src/test/csrc/verilator/emu.h
浏览文件 @
a3838d2b
...
...
@@ -32,6 +32,7 @@
#define SLOT_SIZE 3
#define FAIT_EXIT exit(EXIT_FAILURE);
#define WAIT_INTERVAL 1
#define SNAPSHOT_INTERVAL 60 // unit: second
typedef
struct
shinfo
{
int
exitNum
;
...
...
@@ -88,6 +89,9 @@ private:
VSimTop
*
dut_ptr
;
VerilatedVcdC
*
tfp
;
bool
enable_waveform
;
#ifdef VM_SAVABLE
VerilatedSaveMem
snapshot_slot
[
2
];
#endif
EmuArgs
args
;
#ifdef EN_FORKWAIT
ForkShareMemory
forkshm
;
...
...
verilator.mk
浏览文件 @
a3838d2b
...
...
@@ -42,6 +42,12 @@ ifneq ($(EMU_THREADS),0)
VEXTRA_FLAGS
+=
--threads
$(EMU_THREADS)
--threads-dpi
all
endif
# Verilator savable
EMU_SNAPSHOT
?=
ifeq
($(EMU_SNAPSHOT),1)
VEXTRA_FLAGS
+=
--savable
EMU_CXXFLAGS
+=
-DVM_SAVABLE
# Fork-wait
EMU_FORKWAIT
?=
ifeq
($(EMU_FORKWAIT),1)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录