设备建模语言(DML)是一种用于为虚拟平台编写快速功能或事务级设备模型的领域特定语言。DML 提供了适合功能设备模型的高级抽象,包括寄存器组、寄存器、位域、事件发布、模型间接口以及日志记录等结构。DML 代码由 DML 编译器(DMLC)编译,生成针对特定模拟器定制 API 调用的 C 代码。
目前,编译器支持为 Intel® Simics® 模拟器构建模型,但未来可能会添加其他后端。
要构建 DMLC,您需要安装 Simics 模拟器并设置一个 Simics 项目。
如果您尚未安装 Simics 模拟器,或无法通过商业渠道获取 Simics 模拟器,请安装 Intel Simics 模拟器的公开发行版 并创建一个 Simics 项目(在默认安装流程中会自动创建)。
在您的 Simics 项目中,将 DML 仓库检出到 modules/dmlc 目录。在项目顶层执行 make dmlc(Windows 上为 bin\make dmlc)。
要运行 DMLC 附带的单元测试,在项目顶层执行 make test-dmlc 或 bin/test-runner --suite modules/dmlc/test。
以下环境变量在开发 DMLC 时非常有用。如果您经常使用本地构建的 DMLC,可以考虑将变量 DMLC_DIR、T126_JOBS、DMLC_PATHSUBST 和 PY_SYMLINKS 设置在您的 .bashrc 中。其余变量最好仅在需要时启用。
构建 DMLC 后,您需要在后续的 make 调用中设置 DMLC_DIR 为 <your-project>/<hosttype>/bin,以便使用本地构建的编译器构建设备。<hosttype> 根据您的主机类型可以是 linux64 或 win64。
设置后,指定数量的测试将并行运行。
DMLC 构建会将一些 DML 库文件(例如 dml-builtins.dml)复制到 <hosttype>/bin。当发生编译错误时,错误消息通常会指向这个副本而不是源文件。通过将 DMLC_PATHSUBST 设置为 <hosttype>/bin/dml=modules/dmlc/lib,错误消息将被重写以指向源文件。<hosttype> 根据您的主机类型可以是 linux64 或 win64。
当设置为 1 时,make dmlc 将创建 Python 文件的符号链接而不是复制它们。这有两个效果:Python 回溯会将您带到仓库中的源文件,并且编辑 Python 文件后无需重新运行 make。
当设置为 1 时,编译器中未预期的异常将回显到 stderr。默认情况下,回溯信息会隐藏到 dmlc-error.log 文件中。
在单元测试中覆盖默认编译器。
当设置时,DMLC 进行自分析并将分析结果写入一个 .prof 文件。
当设置时,DMLC 会生成一个 .tar.bz2 归档文件,包含所有 DML 源文件,打包成可以独立编译的形式。当 DML 问题出现在复杂的构建环境中,并且您希望独立重现问题时,这非常有用。在创建的归档文件中,所有 DML 文件都位于同一目录(顶层目录或一系列名为 _ 的子目录下),并通过在归档文件中同时包含符号链接来处理相对导入。在 Windows 上,DMLC 有时无法正确解析这些符号链接;因此,建议仅在 Linux 上解压和编译该归档文件。
当设置时,DMLC 会输出一个以 -size-stats.json 结尾的文件,其中显示了有助于减少生成代码大小并提高编译速度的代码生成统计信息。该文件列出了每个 DML 方法生成了多少 C 代码。输出是一个三元组 [tot_size, location, num] 的列表,其中 tot_size 是从一个方法声明生成的 C 代码的总字节数,num 是此声明生成 C 代码的次数(因为它被模板扩展),location 是该声明的源位置。
一个 tot_size 和 num 都很大的条目可以通过将方法声明为 shared 来减少;这大致会将大小除以 num。一个 tot_size 很大但 num 等于 1 的条目通常意味着该方法主要被 #foreach 或 #select 这样的结构支配,可以通过将循环体提取到一个单独的方法中,或者将循环重构为其他结构(如 foreach)来减少。
请注意,统计信息仅包括直接从方法声明生成的代码;总代码大小包含的内容更多。来自方法声明的代码大小每达到一兆字节,通常会增加几秒的编译时间。