Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenXiangShan
XiangShan
提交
3476f400
X
XiangShan
项目概览
OpenXiangShan
/
XiangShan
12 个月 前同步成功
通知
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,发现更多精彩内容 >>
提交
3476f400
编写于
7月 26, 2020
作者:
Z
Zihao Yu
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
emu: move unnecessary out of the Emulator class
上级
68d56209
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
353 addition
and
422 deletion
+353
-422
src/test/csrc/common.h
src/test/csrc/common.h
+0
-28
src/test/csrc/emu.cpp
src/test/csrc/emu.cpp
+251
-0
src/test/csrc/emu.h
src/test/csrc/emu.h
+31
-238
src/test/csrc/main.cpp
src/test/csrc/main.cpp
+23
-28
src/test/csrc/snapshot.cpp
src/test/csrc/snapshot.cpp
+18
-128
src/test/csrc/snapshot.h
src/test/csrc/snapshot.h
+30
-0
未找到文件。
src/test/csrc/common.h
浏览文件 @
3476f400
...
...
@@ -7,13 +7,6 @@
#include <stdint.h>
#include <assert.h>
#ifdef __cplusplus
# include <stdexcept>
# define print_and_die(s) throw std::runtime_error(s)
#else
# define print_and_die(s) do { fprintf(stderr,"%s\n",s); abort(); } while(0)
#endif
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_YELLOW "\x1b[33m"
...
...
@@ -24,25 +17,4 @@
#define eprintf(...) fprintf(stdout, ## __VA_ARGS__)
#define demand(cond,str,...) \
do { if(!(cond)) { \
char __str[256]; \
snprintf(__str,256,"in %s, line %d: " str, \
__FILE__,__LINE__,##__VA_ARGS__); \
print_and_die(__str); \
} } while(0)
// for debugging
int
sc
(
unsigned
int
ncycle
,
int
*
ret_code
);
int
si
(
unsigned
int
ninstr
,
int
*
ret_code
);
unsigned
int
read_reg
(
int
reg_no
);
// device
void
init_device
(
void
);
bool
is_finished
(
void
);
int
get_exit_code
(
void
);
void
app_error
(
const
char
*
fmt
,
...);
int
monitor
(
void
);
#endif // __COMMON_H
src/test/csrc/emu.cpp
0 → 100644
浏览文件 @
3476f400
#include "emu.h"
#include "difftest.h"
void
*
get_ram_start
();
long
get_ram_size
();
uint64_t
get_nemu_this_pc
();
void
set_nemu_this_pc
(
uint64_t
pc
);
Emulator
::
Emulator
(
EmuArgs
&
args
)
:
dut_ptr
(
new
VXSSimTop
),
cycles
(
0
),
hascommit
(
0
)
{
// srand
srand
(
args
.
seed
);
srand48
(
args
.
seed
);
Verilated
::
randReset
(
2
);
// init ram
extern
void
init_ram
(
const
char
*
img
);
init_ram
(
args
.
image
);
// init device
extern
void
init_device
(
void
);
init_device
();
// init core
reset_ncycles
(
10
);
if
(
args
.
snapshot_path
!=
NULL
)
{
init_difftest
();
snapshot_load
(
args
.
snapshot_path
);
hascommit
=
1
;
}
// 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
;
}
Emulator
::~
Emulator
()
{
snapshot_slot
[
0
].
save
();
snapshot_slot
[
1
].
save
();
printf
(
"Please remove unused snapshots manually
\n
"
);
}
inline
void
Emulator
::
read_emu_regs
(
uint64_t
*
r
)
{
#define macro(x) r[x] = dut_ptr->io_difftest_r_##x
macro
(
0
);
macro
(
1
);
macro
(
2
);
macro
(
3
);
macro
(
4
);
macro
(
5
);
macro
(
6
);
macro
(
7
);
macro
(
8
);
macro
(
9
);
macro
(
10
);
macro
(
11
);
macro
(
12
);
macro
(
13
);
macro
(
14
);
macro
(
15
);
macro
(
16
);
macro
(
17
);
macro
(
18
);
macro
(
19
);
macro
(
20
);
macro
(
21
);
macro
(
22
);
macro
(
23
);
macro
(
24
);
macro
(
25
);
macro
(
26
);
macro
(
27
);
macro
(
28
);
macro
(
29
);
macro
(
30
);
macro
(
31
);
macro
(
32
);
macro
(
33
);
macro
(
34
);
macro
(
35
);
macro
(
36
);
macro
(
37
);
macro
(
38
);
macro
(
39
);
macro
(
40
);
macro
(
41
);
macro
(
42
);
macro
(
43
);
macro
(
44
);
macro
(
45
);
macro
(
46
);
macro
(
47
);
macro
(
48
);
macro
(
49
);
macro
(
50
);
macro
(
51
);
macro
(
52
);
macro
(
53
);
macro
(
54
);
macro
(
55
);
macro
(
56
);
macro
(
57
);
macro
(
58
);
macro
(
59
);
macro
(
60
);
macro
(
61
);
macro
(
62
);
macro
(
63
);
r
[
DIFFTEST_THIS_PC
]
=
dut_ptr
->
io_difftest_thisPC
;
r
[
DIFFTEST_MSTATUS
]
=
dut_ptr
->
io_difftest_mstatus
;
r
[
DIFFTEST_SSTATUS
]
=
dut_ptr
->
io_difftest_sstatus
;
r
[
DIFFTEST_MEPC
]
=
dut_ptr
->
io_difftest_mepc
;
r
[
DIFFTEST_SEPC
]
=
dut_ptr
->
io_difftest_sepc
;
r
[
DIFFTEST_MCAUSE
]
=
dut_ptr
->
io_difftest_mcause
;
r
[
DIFFTEST_SCAUSE
]
=
dut_ptr
->
io_difftest_scause
;
}
inline
void
Emulator
::
read_wb_info
(
uint64_t
*
wpc
,
uint64_t
*
wdata
,
uint32_t
*
wdst
)
{
#define dut_ptr_wpc(x) wpc[x] = dut_ptr->io_difftest_wpc_##x
#define dut_ptr_wdata(x) wdata[x] = dut_ptr->io_difftest_wdata_##x
#define dut_ptr_wdst(x) wdst[x] = dut_ptr->io_difftest_wdst_##x
dut_ptr_wpc
(
0
);
dut_ptr_wdata
(
0
);
dut_ptr_wdst
(
0
);
dut_ptr_wpc
(
1
);
dut_ptr_wdata
(
1
);
dut_ptr_wdst
(
1
);
dut_ptr_wpc
(
2
);
dut_ptr_wdata
(
2
);
dut_ptr_wdst
(
2
);
dut_ptr_wpc
(
3
);
dut_ptr_wdata
(
3
);
dut_ptr_wdst
(
3
);
dut_ptr_wpc
(
4
);
dut_ptr_wdata
(
4
);
dut_ptr_wdst
(
4
);
dut_ptr_wpc
(
5
);
dut_ptr_wdata
(
5
);
dut_ptr_wdst
(
5
);
}
inline
void
Emulator
::
reset_ncycles
(
size_t
cycles
)
{
for
(
int
i
=
0
;
i
<
cycles
;
i
++
)
{
dut_ptr
->
reset
=
1
;
dut_ptr
->
clock
=
0
;
dut_ptr
->
eval
();
dut_ptr
->
clock
=
1
;
dut_ptr
->
eval
();
dut_ptr
->
reset
=
0
;
}
}
inline
void
Emulator
::
single_cycle
()
{
dut_ptr
->
clock
=
0
;
dut_ptr
->
eval
();
dut_ptr
->
clock
=
1
;
dut_ptr
->
eval
();
#if VM_TRACE
tfp
->
dump
(
cycles
);
#endif
cycles
++
;
}
uint64_t
Emulator
::
execute
(
uint64_t
n
)
{
extern
bool
is_finish
();
extern
void
poll_event
(
void
);
extern
uint32_t
uptime
(
void
);
extern
void
set_abort
(
void
);
uint32_t
lasttime_poll
=
0
;
uint32_t
lasttime_snapshot
=
0
;
uint64_t
lastcommit
=
n
;
const
int
stuck_limit
=
500
;
static
uint32_t
wdst
[
DIFFTEST_WIDTH
];
static
uint64_t
wdata
[
DIFFTEST_WIDTH
];
static
uint64_t
wpc
[
DIFFTEST_WIDTH
];
extern
int
difftest_step
(
int
commit
,
uint64_t
*
reg_scala
,
uint32_t
this_inst
,
int
skip
,
int
isRVC
,
uint64_t
*
wpc
,
uint64_t
*
wdata
,
uint32_t
*
wdst
,
int
wen
,
uint64_t
intrNO
,
int
priviledgeMode
);
#if VM_TRACE
Verilated
::
traceEverOn
(
true
);
// Verilator must compute traced signals
VL_PRINTF
(
"Enabling waves...
\n
"
);
tfp
=
new
VerilatedVcdC
;
dut_ptr
->
trace
(
tfp
,
99
);
// Trace 99 levels of hierarchy
tfp
->
open
(
"vlt_dump.vcd"
);
// Open the dump file
#endif
while
(
!
is_finish
()
&&
n
>
0
)
{
single_cycle
();
n
--
;
if
(
is_finish
())
break
;
if
(
lastcommit
-
n
>
stuck_limit
&&
hascommit
)
{
eprintf
(
"No instruction commits for %d cycles, maybe get stuck
\n
"
"(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)
\n
"
,
stuck_limit
,
stuck_limit
);
#if VM_TRACE
tfp
->
close
();
#endif
// commit a fake inst to trigger error
uint64_t
reg
[
DIFFTEST_NR_REG
];
difftest_step
(
1
,
reg
,
0
,
0
,
0
,
wpc
,
wdata
,
wdst
,
0
,
0
,
0
);
set_abort
();
}
if
(
!
hascommit
&&
dut_ptr
->
io_difftest_commit
&&
dut_ptr
->
io_difftest_thisPC
==
0x80000000u
)
{
hascommit
=
1
;
uint64_t
reg
[
DIFFTEST_NR_REG
];
read_emu_regs
(
reg
);
init_difftest
();
void
*
get_img_start
();
long
get_img_size
();
ref_difftest_memcpy_from_dut
(
0x80000000
,
get_img_start
(),
get_img_size
());
ref_difftest_setregs
(
reg
);
}
// difftest
if
(
dut_ptr
->
io_difftest_commit
&&
hascommit
)
{
uint64_t
reg
[
DIFFTEST_NR_REG
];
read_emu_regs
(
reg
);
read_wb_info
(
wpc
,
wdata
,
wdst
);
if
(
difftest_step
(
dut_ptr
->
io_difftest_commit
,
reg
,
dut_ptr
->
io_difftest_thisINST
,
dut_ptr
->
io_difftest_skip
,
dut_ptr
->
io_difftest_isRVC
,
wpc
,
wdata
,
wdst
,
dut_ptr
->
io_difftest_wen
,
dut_ptr
->
io_difftest_intrNO
,
dut_ptr
->
io_difftest_priviledgeMode
))
{
#if VM_TRACE
tfp
->
close
();
#endif
set_abort
();
}
lastcommit
=
n
;
}
uint32_t
t
=
uptime
();
if
(
t
-
lasttime_poll
>
100
)
{
poll_event
();
lasttime_poll
=
t
;
}
if
(
t
-
lasttime_snapshot
>
1000
*
SNAPSHOT_INTERVAL
)
{
// save snapshot every 10s
time_t
now
=
time
(
NULL
);
snapshot_save
(
snapshot_filename
(
now
));
lasttime_snapshot
=
t
;
}
}
return
cycles
;
}
inline
char
*
Emulator
::
snapshot_filename
(
time_t
t
)
{
static
char
buf
[
1024
];
char
buf_time
[
64
];
strftime
(
buf_time
,
sizeof
(
buf_time
),
"%F@%T"
,
localtime
(
&
t
));
char
*
noop_home
=
getenv
(
"NOOP_HOME"
);
assert
(
noop_home
!=
NULL
);
snprintf
(
buf
,
1024
,
"%s/build/%s.snapshot"
,
noop_home
,
buf_time
);
return
buf
;
}
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
);
stream
.
unbuf_write
(
ref_r
,
sizeof
(
ref_r
));
uint64_t
nemu_this_pc
=
get_nemu_this_pc
();
stream
.
unbuf_write
(
&
nemu_this_pc
,
sizeof
(
nemu_this_pc
));
char
*
buf
=
new
char
[
size
];
ref_difftest_memcpy_from_ref
(
buf
,
0x80000000
,
size
);
stream
.
unbuf_write
(
buf
,
size
);
delete
buf
;
// actually write to file in snapshot_finalize()
}
void
Emulator
::
snapshot_load
(
const
char
*
filename
)
{
VerilatedRestore
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
);
uint64_t
nemu_this_pc
;
stream
.
read
(
&
nemu_this_pc
,
sizeof
(
nemu_this_pc
));
set_nemu_this_pc
(
nemu_this_pc
);
char
*
buf
=
new
char
[
size
];
stream
.
read
(
buf
,
size
);
ref_difftest_memcpy_from_dut
(
0x80000000
,
buf
,
size
);
delete
buf
;
}
src/test/csrc/emu.h
浏览文件 @
3476f400
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <memory>
#include <time.h>
#include "difftest.h"
//#include "VSimTop__Dpi.h"
#include "common.h"
#include "snapshot.h"
#include "VXSSimTop.h"
#if VM_TRACE
#include <verilated_vcd_c.h> // Trace file format header
#endif
...
...
@@ -18,243 +9,45 @@
#define DIFFTEST_WIDTH 6
#define SNAPSHOT_INTERVAL 10 // unit: second
static
char
mybuf
[
BUFSIZ
];
class
Emulator
{
const
char
*
image
;
const
char
*
mainargs
;
std
::
shared_ptr
<
VXSSimTop
>
dut_ptr
;
#if VM_TRACE
VerilatedVcdC
*
tfp
;
#endif
// emu control variable
struct
EmuArgs
{
uint32_t
seed
;
uint64_t
max_cycles
,
cycles
;
uint64_t
max_cycles
;
uint64_t
log_begin
,
log_end
;
const
char
*
image
;
const
char
*
snapshot_path
;
int
hascommit
;
std
::
vector
<
const
char
*>
parse_args
(
int
argc
,
const
char
*
argv
[]);
static
void
print_help
(
const
char
*
file
);
void
read_emu_regs
(
uint64_t
*
r
)
{
#define macro(x) r[x] = dut_ptr->io_difftest_r_##x
macro
(
0
);
macro
(
1
);
macro
(
2
);
macro
(
3
);
macro
(
4
);
macro
(
5
);
macro
(
6
);
macro
(
7
);
macro
(
8
);
macro
(
9
);
macro
(
10
);
macro
(
11
);
macro
(
12
);
macro
(
13
);
macro
(
14
);
macro
(
15
);
macro
(
16
);
macro
(
17
);
macro
(
18
);
macro
(
19
);
macro
(
20
);
macro
(
21
);
macro
(
22
);
macro
(
23
);
macro
(
24
);
macro
(
25
);
macro
(
26
);
macro
(
27
);
macro
(
28
);
macro
(
29
);
macro
(
30
);
macro
(
31
);
macro
(
32
);
macro
(
33
);
macro
(
34
);
macro
(
35
);
macro
(
36
);
macro
(
37
);
macro
(
38
);
macro
(
39
);
macro
(
40
);
macro
(
41
);
macro
(
42
);
macro
(
43
);
macro
(
44
);
macro
(
45
);
macro
(
46
);
macro
(
47
);
macro
(
48
);
macro
(
49
);
macro
(
50
);
macro
(
51
);
macro
(
52
);
macro
(
53
);
macro
(
54
);
macro
(
55
);
macro
(
56
);
macro
(
57
);
macro
(
58
);
macro
(
59
);
macro
(
60
);
macro
(
61
);
macro
(
62
);
macro
(
63
);
r
[
DIFFTEST_THIS_PC
]
=
dut_ptr
->
io_difftest_thisPC
;
r
[
DIFFTEST_MSTATUS
]
=
dut_ptr
->
io_difftest_mstatus
;
r
[
DIFFTEST_SSTATUS
]
=
dut_ptr
->
io_difftest_sstatus
;
r
[
DIFFTEST_MEPC
]
=
dut_ptr
->
io_difftest_mepc
;
r
[
DIFFTEST_SEPC
]
=
dut_ptr
->
io_difftest_sepc
;
r
[
DIFFTEST_MCAUSE
]
=
dut_ptr
->
io_difftest_mcause
;
r
[
DIFFTEST_SCAUSE
]
=
dut_ptr
->
io_difftest_scause
;
}
void
read_wb_info
(
uint64_t
*
wpc
,
uint64_t
*
wdata
,
uint32_t
*
wdst
)
{
#define dut_ptr_wpc(x) wpc[x] = dut_ptr->io_difftest_wpc_##x
#define dut_ptr_wdata(x) wdata[x] = dut_ptr->io_difftest_wdata_##x
#define dut_ptr_wdst(x) wdst[x] = dut_ptr->io_difftest_wdst_##x
dut_ptr_wpc
(
0
);
dut_ptr_wdata
(
0
);
dut_ptr_wdst
(
0
);
dut_ptr_wpc
(
1
);
dut_ptr_wdata
(
1
);
dut_ptr_wdst
(
1
);
dut_ptr_wpc
(
2
);
dut_ptr_wdata
(
2
);
dut_ptr_wdst
(
2
);
dut_ptr_wpc
(
3
);
dut_ptr_wdata
(
3
);
dut_ptr_wdst
(
3
);
dut_ptr_wpc
(
4
);
dut_ptr_wdata
(
4
);
dut_ptr_wdst
(
4
);
dut_ptr_wpc
(
5
);
dut_ptr_wdata
(
5
);
dut_ptr_wdst
(
5
);
return
;
EmuArgs
()
{
seed
=
0
;
max_cycles
=
-
1
;
log_begin
=
1
;
log_end
=
-
1
;
snapshot_path
=
NULL
;
image
=
NULL
;
}
};
public:
// argv decay to the secondary pointer
Emulator
(
int
argc
,
const
char
*
argv
[])
:
image
(
nullptr
),
dut_ptr
(
new
std
::
remove_reference
<
decltype
(
*
dut_ptr
)
>::
type
),
seed
(
0
),
max_cycles
(
-
1
),
cycles
(
0
),
log_begin
(
0
),
log_end
(
-
1
),
snapshot_path
(
NULL
),
hascommit
(
0
)
{
// init emu
auto
args
=
parse_args
(
argc
,
argv
);
setbuf
(
stderr
,
mybuf
);
// srand
srand
(
seed
);
srand48
(
seed
);
Verilated
::
randReset
(
2
);
// init ram
extern
void
init_ram
(
const
char
*
img
);
init_ram
(
image
);
// init device
extern
void
init_device
(
void
);
init_device
();
// init core
reset_ncycles
(
10
);
}
~
Emulator
()
{
snapshot_finalize
();
}
void
reset_ncycles
(
size_t
cycles
)
{
for
(
int
i
=
0
;
i
<
cycles
;
i
++
)
{
dut_ptr
->
reset
=
1
;
dut_ptr
->
clock
=
0
;
dut_ptr
->
eval
();
dut_ptr
->
clock
=
1
;
dut_ptr
->
eval
();
dut_ptr
->
reset
=
0
;
}
}
void
single_cycle
()
{
dut_ptr
->
clock
=
0
;
dut_ptr
->
eval
();
dut_ptr
->
clock
=
1
;
dut_ptr
->
eval
();
#if VM_TRACE
tfp
->
dump
(
cycles
);
#endif
cycles
++
;
}
void
execute_cycles
(
uint64_t
n
)
{
extern
bool
is_finish
();
extern
void
poll_event
(
void
);
extern
uint32_t
uptime
(
void
);
extern
void
set_abort
(
void
);
uint32_t
lasttime_poll
=
0
;
uint32_t
lasttime_snapshot
=
0
;
uint64_t
lastcommit
=
n
;
const
int
stuck_limit
=
500
;
static
uint32_t
wdst
[
DIFFTEST_WIDTH
];
static
uint64_t
wdata
[
DIFFTEST_WIDTH
];
static
uint64_t
wpc
[
DIFFTEST_WIDTH
];
extern
int
difftest_step
(
int
commit
,
uint64_t
*
reg_scala
,
uint32_t
this_inst
,
int
skip
,
int
isRVC
,
uint64_t
*
wpc
,
uint64_t
*
wdata
,
uint32_t
*
wdst
,
int
wen
,
uint64_t
intrNO
,
int
priviledgeMode
);
#if VM_TRACE
Verilated
::
traceEverOn
(
true
);
// Verilator must compute traced signals
VL_PRINTF
(
"Enabling waves...
\n
"
);
tfp
=
new
VerilatedVcdC
;
dut_ptr
->
trace
(
tfp
,
99
);
// Trace 99 levels of hierarchy
tfp
->
open
(
"vlt_dump.vcd"
);
// Open the dump file
#endif
while
(
!
is_finish
()
&&
n
>
0
)
{
single_cycle
();
n
--
;
if
(
is_finish
())
return
;
if
(
lastcommit
-
n
>
stuck_limit
&&
hascommit
)
{
eprintf
(
"No instruction commits for %d cycles, maybe get stuck
\n
"
"(please also check whether a fence.i instruction requires more than %d cycles to flush the icache)
\n
"
,
stuck_limit
,
stuck_limit
);
#if VM_TRACE
tfp
->
close
();
#endif
// commit a fake inst to trigger error
uint64_t
reg
[
DIFFTEST_NR_REG
];
difftest_step
(
1
,
reg
,
0
,
0
,
0
,
wpc
,
wdata
,
wdst
,
0
,
0
,
0
);
set_abort
();
}
//printf("xsstatus pc=%lx commit=%d\n", dut_ptr->io_difftest_thisPC, dut_ptr->io_difftest_commit);//FIXIT: delete me when dummy test is passed
if
(
!
hascommit
&&
dut_ptr
->
io_difftest_commit
&&
dut_ptr
->
io_difftest_thisPC
==
0x80000000u
)
{
hascommit
=
1
;
uint64_t
reg
[
DIFFTEST_NR_REG
];
read_emu_regs
(
reg
);
init_difftest
();
void
*
get_img_start
();
long
get_img_size
();
ref_difftest_memcpy_from_dut
(
0x80000000
,
get_img_start
(),
get_img_size
());
ref_difftest_setregs
(
reg
);
}
// difftest
if
(
dut_ptr
->
io_difftest_commit
&&
hascommit
)
{
uint64_t
reg
[
DIFFTEST_NR_REG
];
read_emu_regs
(
reg
);
read_wb_info
(
wpc
,
wdata
,
wdst
);
if
(
difftest_step
(
dut_ptr
->
io_difftest_commit
,
reg
,
dut_ptr
->
io_difftest_thisINST
,
dut_ptr
->
io_difftest_skip
,
dut_ptr
->
io_difftest_isRVC
,
wpc
,
wdata
,
wdst
,
dut_ptr
->
io_difftest_wen
,
dut_ptr
->
io_difftest_intrNO
,
dut_ptr
->
io_difftest_priviledgeMode
))
{
class
Emulator
{
VXSSimTop
*
dut_ptr
;
#if VM_TRACE
tfp
->
close
()
;
VerilatedVcdC
*
tfp
;
#endif
set_abort
();
}
lastcommit
=
n
;
}
uint32_t
t
=
uptime
();
if
(
t
-
lasttime_poll
>
100
)
{
poll_event
();
lasttime_poll
=
t
;
}
if
(
t
-
lasttime_snapshot
>
1000
*
SNAPSHOT_INTERVAL
)
{
// save snapshot every 10s
time_t
now
=
time
(
NULL
);
snapshot_save
(
snapshot_filename
(
my_strftime
(
now
)));
lasttime_snapshot
=
t
;
}
}
}
void
cache_test
(
uint64_t
n
)
{
while
(
n
>
0
)
{
single_cycle
();
n
--
;
}
}
void
execute
()
{
//#define CACHE_TEST
#ifdef CACHE_TEST
eprintf
(
ANSI_COLOR_MAGENTA
"This is random test for cache.
\n
"
ANSI_COLOR_RESET
);
cache_test
(
max_cycles
);
#else
if
(
snapshot_path
!=
NULL
)
{
init_difftest
();
snapshot_load
(
snapshot_path
);
hascommit
=
1
;
}
VerilatedSaveMem
snapshot_slot
[
2
];
// set log time range and log level
dut_ptr
->
io_logCtrl_log_begin
=
log_begin
;
dut_ptr
->
io_logCtrl_log_end
=
log_end
;
execute_cycles
(
max_cycles
);
#endif
}
uint64_t
get_cycles
()
const
{
return
cycles
;
}
uint64_t
get_max_cycles
()
const
{
return
max_cycles
;
}
uint32_t
get_seed
()
const
{
return
seed
;
}
// emu control variable
uint64_t
cycles
;
int
hascommit
;
char
*
my_strftime
(
time_t
time
);
char
*
snapshot_filename
(
const
char
*
name
);
inline
void
read_emu_regs
(
uint64_t
*
r
);
inline
void
read_wb_info
(
uint64_t
*
wpc
,
uint64_t
*
wdata
,
uint32_t
*
wdst
);
inline
void
reset_ncycles
(
size_t
cycles
);
inline
void
single_cycle
();
inline
char
*
snapshot_filename
(
time_t
t
);
void
snapshot_save
(
const
char
*
filename
);
void
snapshot_load
(
const
char
*
filename
);
void
snapshot_finalize
();
public:
Emulator
(
EmuArgs
&
args
);
~
Emulator
();
uint64_t
execute
(
uint64_t
n
);
uint64_t
get_cycles
()
const
{
return
cycles
;
}
};
src/test/csrc/main.cpp
浏览文件 @
3476f400
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include "emu.h"
#include <getopt.h>
#include <string.h>
#include <sys/time.h>
#include <iomanip>
#include <fstream>
#include <functional>
#include <inttypes.h>
#include "emu.h"
static
char
mybuf
[
BUFSIZ
];
// junk, link for verilator
std
::
function
<
double
()
>
get_sc_time_stamp
=
[]()
->
double
{
return
0
;
};
double
sc_time_stamp
()
{
return
get_sc_time_stamp
();
}
void
Emulator
::
print_help
(
const
char
*
file
)
{
static
inline
void
print_help
(
const
char
*
file
)
{
printf
(
"Usage: %s [OPTION...]
\n
"
,
file
);
printf
(
"
\n
"
);
printf
(
" -s, --seed=NUM use this seed
\n
"
);
...
...
@@ -27,8 +20,8 @@ void Emulator::print_help(const char *file) {
printf
(
"
\n
"
);
}
st
d
::
vector
<
const
char
*>
Emulator
::
parse_args
(
int
argc
,
const
char
*
argv
[])
{
std
::
vector
<
const
char
*>
args
=
{
argv
[
0
]
}
;
st
atic
inline
EmuArgs
parse_args
(
int
argc
,
const
char
*
argv
[])
{
EmuArgs
args
;
int
long_index
=
0
;
const
struct
option
long_options
[]
=
{
{
"load-snapshot"
,
1
,
NULL
,
0
},
...
...
@@ -47,7 +40,7 @@ std::vector<const char *> Emulator::parse_args(int argc, const char *argv[]) {
switch
(
o
)
{
case
0
:
if
(
long_index
==
0
)
{
snapshot_path
=
optarg
;
args
.
snapshot_path
=
optarg
;
break
;
}
// fall through
...
...
@@ -56,40 +49,42 @@ std::vector<const char *> Emulator::parse_args(int argc, const char *argv[]) {
exit
(
0
);
case
's'
:
if
(
std
::
string
(
optarg
)
!=
"NO_SEED"
)
{
seed
=
atoll
(
optarg
);
printf
(
"Using seed = %d
\n
"
,
seed
);
args
.
seed
=
atoll
(
optarg
);
printf
(
"Using seed = %d
\n
"
,
args
.
seed
);
}
break
;
case
'C'
:
max_cycles
=
atoll
(
optarg
);
break
;
case
'i'
:
image
=
optarg
;
args
.
push_back
(
"-i"
);
args
.
push_back
(
optarg
);
break
;
case
'b'
:
log_begin
=
atoll
(
optarg
);
break
;
case
'e'
:
log_end
=
atoll
(
optarg
);
break
;
case
'C'
:
args
.
max_cycles
=
atoll
(
optarg
);
break
;
case
'i'
:
args
.
image
=
optarg
;
break
;
case
'b'
:
args
.
log_begin
=
atoll
(
optarg
);
break
;
case
'e'
:
args
.
log_end
=
atoll
(
optarg
);
break
;
}
}
return
args
;
// optimized by rvo
return
args
;
}
int
main
(
int
argc
,
const
char
**
argv
)
{
auto
emu
=
Emulator
(
argc
,
argv
);
setbuf
(
stderr
,
mybuf
);
auto
args
=
parse_args
(
argc
,
argv
);
auto
emu
=
new
Emulator
(
args
);
get_sc_time_stamp
=
[
&
emu
]()
->
double
{
return
emu
.
get_cycles
();
return
emu
->
get_cycles
();
};
emu
.
execute
();
uint64_t
cycles
=
emu
->
execute
(
args
.
max_cycles
);
delete
emu
;
extern
uint32_t
uptime
(
void
);
uint32_t
ms
=
uptime
();
int
display_trapinfo
(
uint64_t
max_cycles
);
int
ret
=
display_trapinfo
(
emu
.
get_max_cycles
()
);
int
ret
=
display_trapinfo
(
args
.
max_cycles
);
eprintf
(
ANSI_COLOR_BLUE
"Seed=%d Guest cycle spent: %"
PRIu64
" (this will be different from cycleCnt if emu loads a snapshot)
\n
"
ANSI_COLOR_RESET
,
emu
.
get_seed
(),
emu
.
get_cycles
()
);
" (this will be different from cycleCnt if emu loads a snapshot)
\n
"
ANSI_COLOR_RESET
,
args
.
seed
,
cycles
);
eprintf
(
ANSI_COLOR_BLUE
"Host time spent: %dms
\n
"
ANSI_COLOR_RESET
,
ms
);
return
ret
;
}
src/test/csrc/snapshot.cpp
浏览文件 @
3476f400
#include "emu.h"
#include <verilated_save.h>
#include "difftest.h"
class
VerilatedSaveMem
:
public
VerilatedSave
{
const
static
long
buf_size
=
1024
*
1024
*
1024
;
uint8_t
*
buf
;
long
size
;
public:
VerilatedSaveMem
()
{
buf
=
new
uint8_t
[
buf_size
];
size
=
0
;
}
~
VerilatedSaveMem
()
{
delete
buf
;
}
void
init
(
const
char
*
filename
)
{
size
=
0
;
m_filename
=
filename
;
header
();
}
void
mywrite
(
const
void
*
__restrict
datap
,
size_t
size
)
VL_MT_UNSAFE_ONE
{
memcpy
(
buf
+
this
->
size
,
datap
,
size
);
this
->
size
+=
size
;
}
void
close
()
{
}
void
flush
()
{
long
flush_size
=
m_cp
-
m_bufp
;
assert
(
buf_size
-
size
>
flush_size
);
memcpy
(
buf
+
size
,
m_bufp
,
flush_size
);
size
+=
flush_size
;
m_cp
=
m_bufp
;
}
void
clear
()
{
size
=
0
;
}
void
save
()
{
if
(
size
==
0
)
return
;
trailer
();
flush
();
FILE
*
fp
=
fopen
(
m_filename
.
c_str
(),
"w"
);
assert
(
fp
!=
NULL
);
fwrite
(
buf
,
size
,
1
,
fp
);
fclose
(
fp
);
size
=
0
;
printf
(
"save snapshot to %s...
\n
"
,
m_filename
.
c_str
());
}
};
static
VerilatedSaveMem
snapshot_slot
[
2
];
void
*
get_ram_start
();
long
get_ram_size
();
uint64_t
get_nemu_this_pc
();
void
set_nemu_this_pc
(
uint64_t
pc
);
extern
void
(
*
ref_difftest_memcpy_from_dut
)(
paddr_t
dest
,
void
*
src
,
size_t
n
);
extern
void
(
*
ref_difftest_memcpy_from_ref
)(
void
*
dest
,
paddr_t
src
,
size_t
n
);
char
*
Emulator
::
my_strftime
(
time_t
time
)
{
static
char
buf
[
64
];
strftime
(
buf
,
sizeof
(
buf
),
"%F@%T"
,
localtime
(
&
time
));
return
buf
;
}
char
*
Emulator
::
snapshot_filename
(
const
char
*
name
)
{
static
char
buf
[
1024
];
char
*
noop_home
=
getenv
(
"NOOP_HOME"
);
assert
(
noop_home
!=
NULL
);
snprintf
(
buf
,
1024
,
"%s/build/%s.snapshot"
,
noop_home
,
name
);
return
buf
;
}
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
.
mywrite
(
&
size
,
sizeof
(
size
));
stream
.
mywrite
(
get_ram_start
(),
size
);
uint64_t
ref_r
[
DIFFTEST_NR_REG
];
ref_difftest_getregs
(
&
ref_r
);
stream
.
mywrite
(
ref_r
,
sizeof
(
ref_r
));
uint64_t
nemu_this_pc
=
get_nemu_this_pc
();
stream
.
mywrite
(
&
nemu_this_pc
,
sizeof
(
nemu_this_pc
));
char
*
buf
=
new
char
[
size
];
ref_difftest_memcpy_from_ref
(
buf
,
0x80000000
,
size
);
stream
.
mywrite
(
buf
,
size
);
delete
buf
;
// actually write to file in snapshot_finalize()
}
void
Emulator
::
snapshot_load
(
const
char
*
filename
)
{
VerilatedRestore
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
);
uint64_t
nemu_this_pc
;
stream
.
read
(
&
nemu_this_pc
,
sizeof
(
nemu_this_pc
));
set_nemu_this_pc
(
nemu_this_pc
);
char
*
buf
=
new
char
[
size
];
stream
.
read
(
buf
,
size
);
ref_difftest_memcpy_from_dut
(
0x80000000
,
buf
,
size
);
delete
buf
;
#include "snapshot.h"
void
VerilatedSaveMem
::
flush
()
{
long
flush_size
=
m_cp
-
m_bufp
;
assert
(
buf_size
-
size
>
flush_size
);
memcpy
(
buf
+
size
,
m_bufp
,
flush_size
);
size
+=
flush_size
;
m_cp
=
m_bufp
;
}
void
Emulator
::
snapshot_finalize
()
{
snapshot_slot
[
0
].
save
();
snapshot_slot
[
1
].
save
();
printf
(
"Please remove unused snapshots manually
\n
"
);
void
VerilatedSaveMem
::
save
()
{
if
(
size
==
0
)
return
;
trailer
();
flush
();
FILE
*
fp
=
fopen
(
m_filename
.
c_str
(),
"w"
);
assert
(
fp
!=
NULL
);
fwrite
(
buf
,
size
,
1
,
fp
);
fclose
(
fp
);
size
=
0
;
printf
(
"save snapshot to %s...
\n
"
,
m_filename
.
c_str
());
}
src/test/csrc/snapshot.h
0 → 100644
浏览文件 @
3476f400
#include "VXSSimTop.h"
#include <verilated_save.h>
class
VerilatedSaveMem
:
public
VerilatedSave
{
const
static
long
buf_size
=
1024
*
1024
*
1024
;
uint8_t
*
buf
;
long
size
;
public:
VerilatedSaveMem
()
{
buf
=
new
uint8_t
[
buf_size
];
size
=
0
;
}
~
VerilatedSaveMem
()
{
delete
buf
;
}
void
init
(
const
char
*
filename
)
{
size
=
0
;
m_filename
=
filename
;
header
();
}
void
unbuf_write
(
const
void
*
__restrict
datap
,
size_t
size
)
VL_MT_UNSAFE_ONE
{
memcpy
(
buf
+
this
->
size
,
datap
,
size
);
this
->
size
+=
size
;
}
void
close
()
{
}
void
flush
();
void
save
();
};
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录