在其他文件不变的前提下,如果即将生成的mk文件和已有的mk文件不一样,就更新全部的源文件

这个事情说起来就有点诡异了,我们解释一下

  1. 我们只使用--exe,完成到生成全部的源文件,以及获取生成可执行文件的makefile文件这一步
  2. 编译的命令保持不变,例如 verilator --cc --exe Top.v main.cpp
  3. 命令中提及的文件全都保持不变,例如Top.v main.cpp,这里的保持不变,是指其时间戳保持不变
  4. 对于生成的VTop.mk文件,是本次测试唯一的变量,我们接下来看一看
测试一:不改变mk文件

假设,我们已经运行了指令verilator --cc --exe Top.v main.cpp,生成了相关的文件。

接下来:

首先,我们运行

ls obj_dir/ --full-time > 1.txt

把测试前的文件时间戳存储起来

total 128
-rw-rw-r-- 1 jht jht 19595 2022-04-17 11:44:49.941869470 +0800 VTop___024root.cpp
-rw-rw-r-- 1 jht jht  1846 2022-04-17 11:44:49.941869470 +0800 VTop___024root.h
-rw-rw-r-- 1 jht jht 11606 2022-04-17 11:44:49.941869470 +0800 VTop___024root__Slow.cpp
...

这里展示一小部分,太多了没必要展示。

接下来,我们再次运行verilator --cc --exe Top.v main.cpp,然后运行ls obj_dir/ --full-time > 2.txt,把新的时间戳存储起来。

紧接着,使用colordiff 1.txt 2.txt进行对比,没有任何输出,说明前后文件时间戳完全一样,这意味着,第二次运行的指令,没有导致生成结果的更新!

要知道,生成的结果

  1. 是从外面其他文件(c/cpp)拷贝过来的
  2. 是编译Verilog文件生成的

而第二次没有更新,没有重新编译和拷贝,证明verilator本身是有检测机制的,不会每次无脑编译更新

测试2:修改mk文件

接下来,做一个新的测试。

假设,我们已经运行了指令verilator --cc --exe Top.v main.cpp,生成了相关的文件。

  1. 运行ls obj_dir/ --full-time > 1.txt
  2. 修改VTop.mk文件,比如给其任意位置,加一个注释,运行sed -i "1 i # test" obj_dir/VTop.mk或者手动修改该文件
  3. 再次运行verilator --cc --exe Top.v main.cpp
  4. 运行ls obj_dir/ --full-time > 2.txt
  5. 使用colordiff 1.txt 2.txt进行对比

神奇的事情发生了!,所有的源文件,都被修改了时间戳,也就是说这些源文件都是新生成或者新拷贝的!

2,16c2,16
< -rw-rw-r-- 1 jht jht 19595 2022-04-17 11:52:02.256126245 +0800 VTop___024root.cpp
< -rw-rw-r-- 1 jht jht  1846 2022-04-17 11:52:02.252126217 +0800 VTop___024root.h
< -rw-rw-r-- 1 jht jht 11606 2022-04-17 11:52:02.256126245 +0800 VTop___024root__Slow.cpp
...
---
> -rw-rw-r-- 1 jht jht 19595 2022-04-17 11:52:16.824228142 +0800 VTop___024root.cpp
> -rw-rw-r-- 1 jht jht  1846 2022-04-17 11:52:16.824228142 +0800 VTop___024root.h
> -rw-rw-r-- 1 jht jht 11606 2022-04-17 11:52:16.824228142 +0800 VTop___024root__Slow.cpp
...

这里只展示一部分,事实上,是所有的源文件都更新了。

另外经过测试,给mk文件加个空行也可以达到该效果。

这就意味着什么呢……至少

在生成文件更新的检测机制上,verilator会检测,当前命令生成的mk文件和已有的mk文件是否有不同,如果不同,就重新生成和更新全部源文件。
实验3:仅修改Verilog文件

这里,同样是命令verilator --cc --exe Top.v main.cpp,我们单独修改Top.v,再查看前后对比结果。

发现也是全部更新源文件,和上面一样。

实验4:仅修改cpp文件

仅仅修改main.cpp,发现也是更新全部源文件,和上面一样。

实验5:修改obj_dir中任意一个文件

随便修改一个文件,前后对比,发现仍然是更新全部源文件。

结论

经过这么多的测试,你就应该明白了,对于verilator的--cc --exe阶段,也就是生成可执行文件之前的阶段,无论你是修改命令中给出的源文件,还是修改生成之后的任意一个文件,都会导致下一次重新运行该命令的时候,全部重新编译和更新。

注意,修改生成的文件,是指的运行VTop.mk之前的那些文件,运行make之后生成内些文件不会跟着更新,它们的更新依靠的是make规则。

应用

好了,这个在文档没有找到,估计只能在源码中找了,先不管,反正测试结果就是这样!

我们看一下,这个特性能够让我们有什么应用呢?

  1. VTop.mk文件,生成VTop的规则,是依赖于obj_dir文件夹中源文件的,外部文件它是不管的!
  2. 如果你引入了外部生成的.o文件,这个文件不会被放在obj_dir文件夹中,只是在VTop.mk中提供外部.o文件的路径,以供链接使用
  3. 也就是说,如果你更新了外部的.o文件,按照生成规则来说,verilator的不知道这件事的,它会默认你的.o文件是一直不变的,这就意味着,你需要额外的规则来改变这件事
  4. 我们的放在工程,会在外部直接编译.c文件到.o文件,但是verilator不知道这件事,我们有两种方法
    1. 强制每次都重新编译Verilog和拷贝cpp源文件,这种方式就用了我们上面提到的那个特点,你只需要编译完成之后,再给VTop.mk随便编辑一下,下一次编译一定会全部更新的。但是这样似乎不太好……
      2.通过makefile来执行编译指令,并且识别.o文件是否更新,如果更新,则可以

      1. 强制编译和更新源文件,但是没有必要这么做,毕竟其他文件又没变
      2. 删除掉生成的VTop可执行文件,重新进行链接即可。这种方式是可取的,如果其他的都没变的话,只是外部的.o文件改变,只需要重新链接就可以

加粗部分,是提倡采取的方案。

下面是提供的复杂工程的示例

simulate
├── csrc # c/cpp 源文件和可重定位目标文件
│   ├── build # 由 .c 文件生成,.o文件提供给verilator
│   │   ├── memory
│   │   │   └── mem.o
│   │   └── monitor
│   │       ├── monitor.o
│   │       └── sdb
│   │           └── sdb.o
│   ├── include # 头文件
│   │   ├── common.h
│   │   ├── main.h
│   │   └── mem.h
│   ├── main.cpp # 提供给verilator的cpp文件
│   ├── Makefile  # 生成 build 的规则
│   ├── memory  # c 源文件
│   │   └── mem.c
│   ├── monitor
│   │   ├── monitor.c
│   │   └── sdb
│   │       └── sdb.c
│   └── utils
├── Makefile # verilator编译和生成规则
└── obj_dir   # verilator生成目录
# 备注:Verilog文件在其他路径,可由verilator来指定位置和文件

verilator编译 更新文件的规则相关推荐

  1. Makefile不再编译已经编译过的未更新文件

    提到Makefile我就想起了中美合拍的<西游记>,偶,不对,提到Makefile不得不说是一种非常牛叉的编译工具了,他比cmake要易懂直观很多,可是,当我们编写大型软件时候,往往伴随着 ...

  2. sass webpack_如何在Visual Studio和Webpack中编译Sass文件

    sass webpack Sass is a very popular CSS pre-processor. The intent of this tutorial is to show you ho ...

  3. makefile文件:编译工程文件

    其本质是用来编译工程文件(内部可以理解为g++命令),用make命令,实现自动化编译.格式如下: 目标:依赖 (tab) 命令 介绍makefile的最初级版本 当前目录下有 main.cpp tem ...

  4. Android 重新编译资源文件

    在开发过程中,尤其是Framework相关开发时,有时候需要重新编译资源文件.编译顺序和注意事项如下: 1,资源文件位置:frameworks/base/core/res 2,编译后生成的文件:fra ...

  5. C++ 预编译头文件

    1.解决什么问题? C++ 编译器是单独,分别编译的,每个cpp文件,进行预编译(也就是对#include,define 等进行文本替换),生成编译单元.编译单元是一个自包含文件,C++编译器对编译单 ...

  6. Android笔记 apk的反编译 | 更新于2017/7/25

    反编译工具下载 http://download.csdn.net/detail/u011109881/8068441 以上图片来自传智播客张泽华视频 我传的资源解压即可 无需安装 1.反编译图片 非常 ...

  7. apktool 反编译 java_APK文件使用ApkTool解包反编译和重新打包及签名

    前段使用一直使用一个手机APK软件,不过最近软件更新,出现了一个很讨厌的语音提示,于是想通过重新编译把语音提示去掉. [准备工作] 配置JAVA环境,到http://www.java.com/下载并进 ...

  8. 流媒体-H264协议-编码-x264学习-相关概念x264编译及文件解析(一)

    流媒体-H264协议-编码-x264学习-相关概念x264编译及文件解析(一) 流媒体-H264协议-编码-x264学习-主要结构体(二) 流媒体-H264协议-编码-x264学习-主要函数(三) 流 ...

  9. CCleaner 垃圾文件清理规则 编写指南

    以下内容的英文版本来源于 CCleaner 官方论坛,仅供参考.欢迎大家编写并分享针对常用国产软件的垃圾文件清理规则! 需要说明的是规则文件(Winapp2.ini)需和程序文件放于同一文件夹下,才能 ...

最新文章

  1. IDEA报错解决:Error:(33, 35) java: -source 7 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)
  2. Rsession: R sessions wrapping for Java
  3. mac编译openresty报Undefined symbols for architecture x86_64
  4. 微信一次发两个ajax请求,微信浏览器发送ajax请求执行多次解决方法
  5. jset编写测试vue代码_详解使用jest对vue项目进行单元测试
  6. mybatis教程--映射之一对一查询
  7. boost::geometry::sym_difference用法的测试程序
  8. ITK:图像的置换轴
  9. android支付平台,android移动支付
  10. 深度学习笔记(30) Inception网络
  11. 安装插件设置Intellij IDEA背景图片
  12. 如何设置app字体跟随系统_Android中App字体大小不随系统改变而改变
  13. 线性代数第6章答案(仅供参考!!!)
  14. php 爬虫图片代码,python爬虫入门教程之糗百图片爬虫代码分享
  15. 获取连接设备的SN号
  16. 干货!交换机常用的光模块及光接口
  17. python怎么清理垃圾和缓存_怎么才能正确清理电脑的缓存垃圾?
  18. iOS 三方app读取苹果健康数据
  19. 看得更近,监督得更好:通过基于组件的鉴别器一次性生成字体
  20. xxljob默认登录_三千字带你搞懂XXL-JOB任务调度平台

热门文章

  1. springmvc学习笔记--mybatis--使用插件自动生成实体和mapper
  2. MySQL 5.7.10 免安装配置
  3. setTimeout里如果有$(this),$(this)指的是谁?
  4. TClientDataSet使用要点
  5. hdu1247(Hat’s Words)
  6. Open Source Blog 开源ASP.NET/C# 博客平台 v2.5 发布(提供源码下载)
  7. 【转】Sql server锁,独占锁,共享锁,更新锁,乐观锁,悲观锁
  8. 在struts2中push方法的使用_电脑使用中怎么截屏的几种方法
  9. sqlalchemy mysql_使用SQLAlchemy操作MySQL
  10. c++ for循环 流程图_python 零基础必知--条件控制与循环语句