芯芒科技研发的Mosim仿真平台是用软件模拟的虚拟平台,可以模拟SOC及周边系统的各个组件,包括处理器、存储器、SOC自研逻辑、激励主机等。开发人员可以基于Mosim平台运行、调试和测试firmware、OS device driver等相关软件,而不需要实际的硬件系统。
【A】当前MOSIM平台(服务器端)运行在X86下的LINUX操作系统,请提前告知OS版本,如ubuntu 22.04
【B】MOSIM IDE可以运行在任何VSCODE支持的平台上(包括Windows, Linux, MacOS),请参考VSCOD官网的安装说明
提示:直接从微软官方下载VSCODE有时会很慢,可以通过国内微软的cdn加速下载
参考: https://zhuanlan.zhihu.com/p/536236143
Visual Studio Code在官网的下载速度感人,即使开了代理也很慢,几乎下载不了,以下是国内镜像下载地址:
以下载Mac版(universal)的VS Code为例,大家需要什么版本去官网找一下,把下载地址替换一下即可:
国内镜像地址:https://vscode.cdn.azure.cn
只需将https://az764295.vo.msecnd.net替换成https://vscode.cdn.azure.cn即可!
下载解压后,运行VSCODE,然后进行基础的插件安装
提示:安装在服务器上,如VSCODE安装在本地PC请先连接上服务器后再安装,否则直接安装即可。连接服务器请参考2.2.3 连接到开发服务器
首先安装Remote SSH,连接上服务器后(参考2.3.3连接到开发服务器),再安装其他插件,完成后,可以进行远程开发,必要的远程配置参考vscode帮助说明或者google搜索
VSCode Remote 体验 | 远程Linux环境开发真香 https://zhuanlan.zhihu.com/p/64849549
手把手教你配置VS Code远程开发工具 https://zhuanlan.zhihu.com/p/141344165
VS Code Remote Development https://code.visualstudio.com/docs/remote/remote-overview
如VSCode直接安装在服务器端,忽略如下方法,通过远程桌面连接服务器,直接打开即可;
如VSCode安装在本地PC,可以通过如下方法打开VSCode;
方法一:打开VSCode,点击右下角的“Open a Remote Window”,连接到开发服务器;
方法二【推荐】:
1) 在客户端电脑配置好“~/.ssh/config”
Host serv-name
HostName X.X.X.X
User user_name
Port X
2)打开VSCode,导航打开"Remote Explorer",在"Remote Explorer"顶部选择“Remotes(Tunnels/SSH)”,在对应的开发服务器,点击“Connect in Current Window...” 。
导航打开"Extensions",在"Extensions"顶部点击“…”打开“Install from VSIX...”,在路径输入框输入(或选择)正确的路径和vsix文件: /home/user_name/mosim-xxx-RELEASE/mosim-vsc-X.X.X.vsix
安装成功后,左侧功能导航栏将出现一个芯片形状的Icon,名称为:“MOSIM”。远程方式下:右下角会出现提示窗口,点击按钮“Reload Now”或重启vscode,安装完成。
请联系芯芒科技 Sylvia sylvia.hu@simango.cn 获取run安装包,比如
mosim-v2.0.0-20250301-f32ba08-Release-UFS-LIB.run
执行如下命令, 如果系统第一次安装,默认的安装路径是用户的$HOME/mosim
注 可以指定其他安装路径(选择2, 然后输入安装路径, 请注意安装路径读写权限,如果本用户没有写权限,那需要sudo 进行安装)
stone@server-234:~/mosim_show$ chmod +x mosim-v2.0.0-20250301-f32ba08-Release-UFS-LIB.run
./mosim-v2.0.0-20240301-f32ba08-Release-UFS-LIB.run
Verifying archive integrity... 100% MD5 checksums are OK. All good.
Uncompressing mosim安装... 100%
Usage:
install_mosim_release.sh [-p mosimhome]
Select an operation
1.Use this installation directory: /home/stone/mosim
2.Specify installation directory
1
select install path:/home/stone/mosim
......
安装会自动在~/.bashrc添加以下内容:
export MOSIM_HOME=/home/stone/mosim
export LD_LIBRARY_PATH=$MOSIM_HOME/lib:$MOSIM_HOME/3rd/systemc234/lib:
运行source ~/.bashrc, 或重新打开terminal使其生效
注3:涉及环境变量变更时,ps aux | grep main.js, kill掉本用户对应的进程,重启VSCODE
如果没有许可,执行mosim会报错,如下
stone@server-234:~/mosim/bin$ ./mosim-top
许可错误 : environment variable not defined
运行平台签名信息 : "AFee-TGAA-AAA=" 请提供此签名信息,联系杭州芯芒科技获取授权许可
请带上运行平台的签名信息上面的"AFee-TGAA-AAA=", 联系我们, 芯芒会生成一个许可文件,mosim_AFee.lic
收到许可文件后在 ~/.bashrc 配置许可文件路径:
export MOSIM_LICENSE_LOCATION=/home/stone/mosim_AAEE.lic
source ~/.bashrc
注意:这里项目所在目录和项目名称是分2次输入的。
导航打开“MOSIM”,在“WELCOME”面板中,点击“New Project”,在路径输入框选择项目所在路径:/home/user_name/workspace
注: 项目所在路径必须已经存在
接着输入项目名称,回车。项目正式创建
导航打开“MOSIM”,在“WELCOME”面板中,点击“New SOC”,在输入框中输入SOC的名称,如: soc1
至此,项目和SOC创建成功。整个项目目录结构和说明如下:
prj1
├── .lib // 编译链接库和运行时动态库
├── .mosim // 编译参数等配置文件
├── include // 用户模型头文件
├── models // 用户模型代码
└── soc // soc目录
└── soc1 // soc示例目录
├── conf // 配置文件目录
│ ├── layout.json // 布局,在可视化编辑页面中的大小、位置等信息
│ ├── libs.json // 使用到的lib内容
│ ├── log_config.toml // 日志配置
│ └── top.json // soc中model、model参数,model间互连信息等
├── fw // 固件存放目录,固件也可以放其他位置,soc中指定具体路径即可
└── logs // soc的运行日志
├── CMakeLists.txt // cmake文件
打开SOC可视化编辑界面:
方法一:导航打开“MOSIM”,在“ARCHIITECTURE VIEW”面板中,选择 soc1
。
方法二:导航打开“EXplorer”,在“EXPLORER”面板中,单击右键soc/soc1/conf/top.json,在弹出菜单选择“MOSIM:Open SOC”
选择“Libs”,把需要的模型拖入画布,设置属性、连接信号线。
切换到“Libs”,鼠标点所需Model,并按住左键,拖入画布,在弹出窗口中(或双击Model, 或右键点击Model选择“Edit”)修改Model参数,修改完成后点击菜单“File->Save”保存对SOC的修改。
MOSIM支持模块的端口可以调整位置,便于连线:
1)调整端口所在的边(上下左右):
通过Model属性中“Position”切换到left、right、top、bottom边上
2)调整端口在边上的位置:
鼠标移入端口icon,此时端口的icon会放大,鼠标指示变为“十字架”(图中1),点击端口,鼠标指示变为“上下移动”或“左右移动”(图中2),移动鼠标的位置,在需要的位置再次点击鼠标,移动操作完成。
将两个模块的端口互相连线即可实现模块间的端口绑定。
插件会对连接的端口做一些合法性检测,比如输入端口连接到输入端口是不允许的。
方法一:图形操作。鼠标移入端口,按住鼠标左键,拖动到要连接的另外一个端口,完成连接。
操作技巧:选中待连接的Model(通常选择多条输出的Model,比如clock、reset),比较容易操作。
注意:连线无选中状态,只有鼠标移入状态。
方法二:选择操作。作为快速连线操作,特别适合clock、reset这类一个端口连接多个模块端口的场景。
鼠标移入连线,线变色:
右键单击连线,选择“Delete Edge”。
复杂soc的模块、连线很多,为了让页面更加突出重点,可以隐藏某些连线,比如clock、reset的连线。
在Model属性页面的“Bus Rules”中设置,需要注意的是入口、出口保证正确,并且不要有地址是重叠的。
双击Model或鼠标右键点击Model后选择“Edit”,打开Model的属性设置页面,修改模型(或模型端口)的参数,如:
1、在bus port上配置rules、image文件的路径及文件名等参数
/home/user_name/prj1/fw/AISC_BE_DISK.axf,/home/user_name/prj1/bin/coremark_arm.bin@0x00064000"
注意:不同的axf,bin之间用逗号“,”分隔,bin文件要说明加载地址@addres
2、修改cpu model的gdb_wait=false,表示CPU不等待gdb调试连接,将直接执行fw
(如果需要调试FW的boot.S阶段,建议gdb_wait=true,这样可以在启动fw前先attach上调试器)
3、对于支持性能模式的模块,配置模型运行模式:
将run_mode设置为对应的模式:
PV - 功能(fast)模式
CX - cycle近似精确模式,通常为用systemC建的性能模型
CA - cycle精确模式,通常是RTL代码转换生成的性能模型
修改SOC各种属性和参数,可以点击上图右上角的“Setting Top Parameters”按钮,编辑属性和参数后,点击“File->Save”保存(操作类似model属性和参数的修改)。
点击SOC右侧运行按钮;在下方TERMINAL中将看到SOC串口输出:
在SOC目录的logs目录下将生成仿真日志、波形等;
你也可以自定义运行命令:
比如在运行MOSIM平台前,需要运行emmc host(qemu主机系统)
运行mosim平台前,定制start/Stop Extask 命令,如在Start Extask框中填入如下内容,在soc运行时同步启动host:
sleep 15 ;
cd /home/<user>/work/simango/emmc_host;
./start_emmc_host.sh
可以直接在shell中运行某个soc, 假设你的项目目录在 你的home目录下;那可以运行以下命令,将运行soc1
cd ~/prj1/soc/soc1
$MOSIM_HOME/bin/mosim-top instance -d ./conf -g ./conf/log_config.toml -n soc1
方法一,点击插件SOC右侧停止按钮
方法二,如果是shell直接运行模式,ctrl+c即可
方法三,如果VSCODE调试中,那么点击停止按钮即可,FW或MOSIM的调试停止按钮都可以。
点击Vscode左侧栏的调试按钮(三角箭头,见3.4.4图示),launch.json配置参考如下:
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "cppdbg",
"request": "launch",
"name": "cppdbg-fw-r5-0",
"program": "${workspaceFolder}/soc/r5_mp_demo_soc/fw/wfe.elf",
"miDebuggerServerAddress": "localhost:7307",
"cwd": "${workspaceFolder}/soc/r5_mp_demo_soc",
"linux": {
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb-multiarch",
"stopAtEntry": true
},
},
{
"type": "cppdbg",
"request": "launch",
"name": "cppdbg-fw-r5-1",
"program": "${workspaceFolder}/soc/r5_mp_demo_soc/fw/wfe.elf",
"miDebuggerServerAddress": "localhost:7308",
"cwd": "${workspaceFolder}/soc/r5_mp_demo_soc",
"linux": {
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb-multiarch",
"stopAtEntry": true
},
},
{ // SOC硬件模型调试配置
"type": "cppdbg",
"request": "launch",
"name": "r5_mp_demo_soc-debug",
"program": "${env:MOSIM_HOME}/bin/mosim-top", //mosim程序
"args": [
"instance",
"-d",
"${workspaceFolder}/soc/r5_mp_demo_soc/conf", //运行配置文件
"-g",
"${workspaceFolder}/soc/r5_mp_demo_soc/conf/log_config.toml",
"-n",
"r5_mp_demo_soc"
],
"environment": [{"name":"LD_LIBRARY_PATH", "value": "${env:LD_LIBRARY_PATH}:${workspaceFolder}/.lib"}],
"cwd": "${workspaceFolder}/soc/r5_mp_demo_soc",
"preLaunchTask": "vDelLogs_r5" // 调试前运行的shell命令,可以添加到task.json中,见下面附task.json参考
},
]
}
注:
如果FW源码路径和二进制build路径不一致,比如fw.axf是在/home/my_name/dev/fw下构建的,但现在调试的源码在/home/user_name/dev/fw下,那么需要配置下sourceFileMap,如上。在debug停止(比如遇到断点)的时候,点击调用栈的函数,可以看到fw原始build路径。
附:tasks.json参考:
{
"version": "0.2.0",
"tasks": [
{
"label": "runShellCommand",
"type": "shell",
"command": "rm -rf /home/user_name/prj1/logs" // 删除日志
}
]
}
参考 6.3
调试前确认修改配置文件,如果需要从启动地址开始调试FW,修改cpu的参数 - gdb_wait=true
1、调试功能一览:
2、DEBUG CONSOLE窗口(fw调试窗口下)可以执行gdb命令,注意前面要加-exec
如图中命令,可以修改0x201000地址的值,为timer的timern_load_count寄存器。
正常编译firmware,将生成的firmware放在合适路径备用
使用正常编译的firmware,配置SOC使用上述生成的firmware
在SOC界面中,双击CPU模型节点,打开参数设置页面,设置trace_cov
为true
运行SOC将生成相应的CPU TRACE日志,如:arm_pc.log,其内容如下:
=== trace_cpu_marker:0 name:cortex_r5_0 cpu_model:Cortex-R5 coreid:0 ===
=== trace_cpu_marker:1 name:cortex_r5_1 cpu_model:Cortex-R5 coreid:1 ===
1 0 s 0x0
1 0 s 0x4
1 0 s 0x8
...
...
再次编译firmware,并在编译时添加--coverage,例如Makefile中:
CFLAGS += --coverage
编译后将生成源码对应的.o及.gcno文件,保留备用
使用芯芒提供的工具mos-gcovr
生成代码覆盖率报告:
./mos-gcovr --addr2line /path/to/addr2line --gcov /path/to/gcov --src-path /path/to/src --log-file /path/to/arm_pc.log --images /path/to/image1.elf /path/to/image2.elf -o /path/to/report
参数说明:
--addr2line: 编译firmware的GNU工具链中提供的addr2line工具,如:arm-none-eabi-addr2line
--gcov: 编译firmware的GNU工具链中提供的gcov工具,如:arm-none-eabi-gcov
--src-path: firmware源码路径
--log-file: SOC生成CPU TRACE日志
--images: firmware运行文件
-o: 生成报告路径
生成的报告保存在html文件夹中,用浏览器打开即可
在firmware测试用例源码中包含芯芒提供的头文件:<tau/tau.h>
无自定义main函数
直接使用宏:
#include <tau/tau.h>
TAU_MAIN()
有自定义main函数
#include <tau/tau.h>
TAU_NO_MAIN()
int main(int argc, char** argv) {
/* do others */
static_init();
return tau_main(argc, argv);
}
测试用例使用宏TEST定义,例如:
TEST(c, CHECK_TF) {
// 添加测试代码
// check结果
CHECK_FALSE(0);
CHECK_TRUE(1);
}
TAU提供了多个用于check的宏定义,如:
CHECK_FALSE:期望值为false
CHECK_TRUE:期望值为trues
更多说明可参考:https://github.com/jasmcaus/tau
参考输出如下:
Copyright (c) 2023 by Simango Inc,
ALL RIGHTS RESERVED
Mosim 1.1.0 (59b5b1b@) --- Feb 6 2024 18:18:35
license to sign [MOSIM-1.0.0.BWlic_ver200valid-to2024-02-28]
芯芒平台-仿真核心激活
license to sign [MOS_FN_FVDKlic_ver200valid-to2024-02-28]
芯芒平台-功能仿真激活
[02-23 11:23:49.845] [0 s] [info]
------------Mosim: Semiport Emmc Demo----------------
Info: (I703) tracing timescale unit set: 1 ns (./logs/mosim_wave.vcd)
[02-23 11:23:49.850] [0 s] [info] ---- start gdb server port 53500 ----
[==========] Running 46 test suites.
[ RUN ] c.CHECK_TF
[ OK ] c.CHECK_TF ()
[ RUN ] c.REQUIRE_TF
[ OK ] c.REQUIRE_TF ()
[ RUN ] c.MemAlloc
[ OK ] c.MemAlloc ()
[ RUN ] c.ForLoop
[ OK ] c.ForLoop ()
[ RUN ] c.CHECK
[ OK ] c.CHECK ()
[ RUN ] c.REQUIRE_LT
[ OK ] c.REQUIRE_LT ()
[ RUN ] c.REQUIRE_LE
[ OK ] c.REQUIRE_LE ()
...
...
[ RUN ] c11.CHECK_SUBSTREQ
[ OK ] c11.CHECK_SUBSTREQ ()
[ RUN ] c11.no_double_eval
[ OK ] c11.no_double_eval ()
[ RUN ] c11.CHECK_BUF_EQ
[ OK ] c11.CHECK_BUF_EQ ()
[ RUN ] c11.CHECK_BUF_NE
[ OK ] c11.CHECK_BUF_NE ()
[ RUN ] c11.REQUIRE_BUF_EQ
[ OK ] c11.REQUIRE_BUF_EQ ()
[ RUN ] c11.REQUIRE_BUF_NE
[ OK ] c11.REQUIRE_BUF_NE ()
[ RUN ] MyTestF.c
[ OK ] MyTestF.c ()
[ RUN ] MyTestF.c2
[ OK ] MyTestF.c2 ()
[==========] 46 test suites ran
[ PASSED ] 46 suites
[ FAILED ] 0 suites
Summary:
Total test suites: 46
Total suites run: 46
Total warnings generated: 0
Total suites skipped: 0
Total suites failed: 0
使用mosim平台构建的模型,可以提供dfx接口实现故障注入等后台控制硬件的能力(见“建模指南”)。
dfx接口的调用有2种方式:
1)见10.1.4,在monitor界面输入dfx命令
2)mosim提供了dfx_injector设备,Firmware通过该设备可以发送dfx命令,具体说明如下:
在top中添加dfx_injector设备,挂接到总线上。
dfx_injector实现了2个寄存器:
reg(4Byte) | offset | field | 功能 |
---|---|---|---|
command | 0 | [7:0] | 逐字符输入命令,以回车结尾,类似uart输出 |
complete | 4 | [0:0] | 1 - dfx命令执行完成 |
1)FW通过command下发命令给dfx_injector
例如循环写入:"emmc_demo.rom p 0 10\n"与monitor中执行下列命令相同:
mosim> dfx emmc_demo.rom p 0 10
进入monitor:1)mosim启动界面按ctrl+a快捷键;2)也可以通过telnet方式进入(见章节3.5.1)。
退出monitor:输入exit命令回车;
【注】: 若已通过ctrl+a进入monitor,需要退出monitor(exit)后,才可以使用telnet
offset为设备内部每个region的起始打印地址
mosim> dump emmc_demo.rom 0 30
region 0
18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5
18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5
78 01 00 00 a0 00 00 00 b0 00 00 00 c0 00 00 00
mosim> dump emmc_demo.rom 10 30
region 0
18 f0 9f e5 18 f0 9f e5 18 f0 9f e5 18 f0 9f e5
78 01 00 00 a0 00 00 00 b0 00 00 00 c0 00 00 00
d0 00 00 00 e0 00 00 00 54 00 00 00 90 00 00 00
mosim> dump emmc_demo.ibm 0 20
region 0
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
region 1
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
region 2
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
注:该功能已集成到IDE插件:tools - Memory
该功能调用模型故障注入等后台操作(也提供了FW调用方法,见4.6)
device_name为需要操作的模型名称
args为模型dfx接口实现的自定义参数(需要在访问的模型中实现dfx接口)
mosim> dfx emmc_demo.rom p 0 10
emmc_demo.rom dfx - p: addr 0x0 - size 0xa
【注】Mosim将持续提供更多能力......
Mosim提供丰富的日志信息,分析日志信息是一个比较好的定位问题的途径。
比如bus.log
bus.log记录了cpu等master访问device的行为,包括读写命令类型、访问地址、访问内容等。
如上,表示cpu写uart的地址0寄存器,写入值0x34,长度1个字节。
Mosim在硬件建模时,一些异常的地方增加Assert能力,比如cpu访问了非法的地址时,平台会进入asser loop状态,用于现场定位。
在调试时建议在平台增加b mosim_assert_loop断点,那么出现问题时,平台会直接停在第一现场,停止运行,方便定位。
日期 | 章节 | 修改内容 |
---|---|---|
2024.09.30 | new | |
2024.10.20 | 8.5 | 移除x、d命令,使用dump |
2024.11.28 | 2.4 | 增加注3:涉及环境变量变更时,需要删除main.js, 重启VSCODE |
2025.04.21 | all | 更新示例图 |
杭州芯芒科技有限公司
联系人:Sylvia
邮箱:sylvia.hu@simango.cn
电话:18958182179