XSIM 43-4099:模块缺 timescale 报错排查与修复
更新时间:2026-10-22。面向 FPGA 入门 阶段用命令行跑 Vivado 仿真的同学。症状很典型:
xvlog编译全绿,一到xelab就甩出ERROR: [XSIM 43-4099] ... Module counter4 doesn't have a timescale but at least one module in design has a timescale.——明明每个文件语法都没问题,为什么 elaborate 不过?本文用一个 4 位计数器在 Vivado 2017.4 上把这条错真实触发了一遍,讲清它检查的到底是什么、怎么修才彻底。这是继 XSim 找不到设计单元(XSIM 43-3225) 之后,XSim 命令行三连里 xelab 阶段的第二条高频报错。
本文要回答的问题
`timescale这行指令到底管什么,缺了会怎样?- XSIM 43-4099 为什么在
xvlog通过后才在xelab爆出来? - 「有的模块有、有的模块没有」timescale 为什么是错误而不是警告?
- 修复时时间单位和时间精度(1ns/1ps)应该怎么选?
一、先看清报错现场
报错来自本次真实实验(完整日志见文末实验环境):DUT 是 4 位异步复位计数器 counter4,TB 是带 10ns 时钟和 timescale 1ns/1ps 的 tb_counter4。第一次实验故意让 counter4.v 不带 timescale,两步命令的结果:
xvlog exit=0
Running: D:/Xilinx/Vivado/2017.4/bin/unwrapped/win64.o/xelab.exe -debug typical tb_counter4 -s sim_err
Starting simulation data flow analysis
ERROR: [XSIM 43-4099] "C:/eda-lab/elab-ts/err/counter4.v" Line 1. Module counter4 doesn't have a timescale but at least one module in design has a timescale.
xelab exit=1注意三个细节:xvlog exit=0——编译阶段完全不检查 timescale 一致性;报错发生在 xelab 的「simulation data flow analysis」阶段,而不是更早的 static elaboration;报错信息里明确给了文件名和 Line 1,告诉你去哪补。这条错和 XSIM 43-3225 一样,都属于「xvlog 管不着、xelab 才检查」的那一类——单文件视角没问题,整个设计拼起来才有问题。
读这张漏斗卡抓住收敛路径:报错本身已经给了文件名和行号,所以排查不用翻库、不用查快照,直接对照「设计里哪些文件写了 timescale、哪些没写」即可。真正的坑不在「怎么找到」,而在「为什么这么规定」——这正是下一节的内容。
二、timescale 到底管什么
Verilog 源文件开头的 `timescale 1ns/1ps 由两个数组成:前者是时间单位(time unit),后者是时间精度(time precision)。它管两件事:
- 代码里的延迟字面量怎么解释:
#5到底是 5ns 还是 5ps?答案由时间单位决定,没写 timescale 的模块,这个数字根本没有确定含义。 - 仿真时间轴的最小刻度:精度是 1ps 时,仿真器以 1ps 为步长推进事件队列;波形上小于精度的延迟会被舍入。
关键在于:这两个数是模块级的,不是工程级的。Verilog 标准允许不同模块用不同 timescale(比如 TB 用 1ns/1ps,某个行为模型用 1us/1ns),仿真器内部会统一换算。但「有的模块写了、有的模块没写」这个组合是标准里的灰色地带:没写的模块延迟单位无从确定,有的工具取「前一个编译单元的 timescale」、有的取默认值,行为因工具而异。XSim 的选择最干脆——直接拒绝 elaborate,报 43-4099 让你把设计补齐,而不是猜一个可能错的单位继续跑。
这就解释了为什么它必须是 ERROR 而不是 WARNING:一旦猜错单位,TB 里 #10 产生 10ns 时钟、DUT 里 #1 被当成 1ns 还是 1ps,整个时序关系全错,而仿真会「正常」跑完给你一个错误的结果——静默错误远比报错可怕。
三、为什么 xvlog 不拦、xelab 才拦
XSim 命令行三连(xvlog 编译 → xelab 细化 → xsim 运行)的分工在 XSim 找不到设计单元 里详细讲过,这里只补与 timescale 相关的部分:xvlog 逐文件分析进 work 库,只看单文件语法,此刻它看不到「别的模块有没有 timescale」,自然无从报一致性错误;xelab 把全部模块按层次拼成一棵实例树时,才拥有全设计视角,一致性检查只能在这里做。
读这张流程图注意颜色语义:红是报错现象,蓝是排查动作,绿是判定分支,橙是修复动作,紫是防复发沉淀。主干只有三步——确认编译已过、核对全设计 timescale 清单、统一补齐后重跑。图上「全缺」那个分支值得展开:所有模块都不写 timescale 是合法的(XSim 会给个默认精度继续跑),真正非法的只有「混用」这一种形态。所以修复原则一句话:要么全有,要么全无,工程实践里选「全有」。
四、修复实验:补上 timescale 一次跑通
修复动作很小:给 counter4.v 第一行补上 `timescale 1ns/1ps(与 TB 保持一致),其他一个字不动,重跑三连:
读这张终端卡抓三处证据:xelab 阶段打出 Time Resolution for simulation is 1ps 并 Built simulation snapshot sim_ok,xelab exit=0;xsim 接管后 run -all,$monitor 逐拍打印 count 从 0 递增到 0xf 再回卷;最后 TEST PASS: counter wrapped, final count=0x4 与 $finish called at time : 225 ns,xsim exit=0。和第一节的报错现场对比,区别只有 counter4.v 第一行多了那一行指令——这条错从触发到修复的全部成本就是一行代码,但前提是你读懂了它在检查什么。
五、易混淆的三类 timescale 问题对照
43-4099 不是 timescale 相关问题的全部,实际工程里还有两类长得很像的坑,用一张表分清:
| 现象 | 触发场景 | 本质 | 处置 |
|---|---|---|---|
| XSIM 43-4099(本文) | 部分模块有 timescale、部分没有 | 一致性检查不过,xelab 拒绝猜单位 | 全设计统一补齐 |
| 延迟全不对但仿真能跑 | 全设计都没写 timescale,用了工具默认值 | 合法但单位是工具猜的,换工具行为变 | 显式补 timescale,别依赖默认值 |
| TB 时钟周期是预期的 1000 倍 | TB 写 1ns/1ps、某个行为模型写 1us/1ns | 混用本身合法,但两边的 #数字 量级差千倍 | 核对每个文件的单位列,统一到 1ns |
第一行是 ERROR、工具替你兜底;后两行不报错、结果静默错误,危害更大。判读口诀:报错的是「有没有写齐」,不报错的是「写的对不对」——前者靠 xelab,后者只能靠你自己核对文件头。
六、时间单位和精度怎么选
修复时顺手会遇到一个选择题:1ns/1ps、1ns/1ns、1ps/1ps 用哪个?经验法则:
| 写法 | 含义 | 适用场景 |
|---|---|---|
timescale 1ns/1ps | 单位 1ns,精度 1ps | 绝大多数 RTL 仿真的默认推荐,TB 与 DUT 统一用它 |
timescale 1ns/1ns | 单位精度都是 1ns | 只关心拍级行为、不在意亚 ns 毛刺时可用,仿真略快 |
timescale 1ps/1ps | 皮秒级单位 | 门级时序仿真、需要精细延迟建模的场景 |
| 全部不写 | 工具默认 | 合法但不推荐:不同工具默认值不同,换仿真器行为可能变 |
两个注意点。其一,精度决定仿真速度:精度越细,事件队列刻度越密,同样仿真时长开销越大,所以别无脑上 1ps/1ps。其二,TB 和 DUT 的单位必须一致地看——TB 用 1ns 产生 #5 半周期(10ns 时钟),如果 DUT 用 1us,DUT 内部的 #1 延迟就是 1us,时序完全对不上;统一写成 1ns/1ps 是避免这类扯皮的最省心事。
七、防复发清单
- 工程模板(文件头 snippet)里固化
`timescale 1ns/1ps,新建源文件自动带上,不靠人记。 - 三连脚本每一步判退出码(bat 里
%ERRORLEVEL%),xelab 非零立即停,别把报错刷过去。 - 第三方代码(IP 例化模板、网上抄的行为模型)进工程第一件事查文件头有没有 timescale。
- CI 里把 xelab 的 ERROR 计数做成断言,43-4099 这类一致性错误绝不允许带病进仿真。
实验环境
- 机器/系统:Windows 10 工作站(Vivado 2017.4 实机)
- 工具版本:Vivado Simulator 2017.4(
xvlog.bat/xelab.bat/xsim.bat,D:\Xilinx\Vivado\2017.4) - 日期:2026-10-22
- 完整命令:
xvlog.bat counter4.v tb_counter4.v;xelab.bat -debug typical tb_counter4 -s sim_err(counter4.v 不带 timescale,触发 43-4099);修复后xvlog.bat counter4.v tb_counter4.v+xelab.bat -debug typical tb_counter4 -s sim_ok+xsim.bat sim_ok -R
代码获取:本实验完整代码(带/不带 timescale 两个版本的
counter4.v、tb_counter4.v、复现命令说明)见公开仓库 derekzhuo/geek-doc.cn 的experiments/ts-xsim-elab-timescale/。把命令里的 Vivado 路径改成本机安装目录即可复现。
这一篇在知识体系里的位置
本篇是 FPGA 入门 排错支线上 xelab 阶段的第二条报错,与 XSim 找不到设计单元(XSIM 43-3225)(顶层名/快照类报错)、Vivado 模块找不到(VRFC 10-2063)(编译期同类问题)互为姊妹篇;修通报错后把整条命令行仿真跑顺的方法见 Vivado 命令行批处理仿真,仿真入门主线在 Testbench 与仿真。
一句话总结
XSIM 43-4099 是 xelab 在全设计视角下做的一致性检查:设计里一部分模块写了 timescale、另一部分没写时,缺的那部分延迟单位无法确定,仿真器宁可报错也不猜——修复就是给所有源文件统一补上 `timescale 1ns/1ps(全有或全无,不能混),记住「xvlog 只管语法、一致性归 xelab」,并把 timescale 固化进工程模板,这条错从此与你无关。