Verilog仿真时间管理:$printtimescale与$timeformat系统任务详解
1. 项目概述理解Verilog时间系统的“尺”与“度”在FPGA和数字IC设计的仿真世界里我们常常关注逻辑功能是否正确、时序是否收敛但有一个基础却至关重要的维度常常被新手甚至部分有经验的工程师所忽视——那就是仿真时间本身。你可能会在波形查看器里看到一串串不断递增的数值但你是否真正理解“#10”这个延迟到底代表10纳秒、10皮秒还是10个仿真时间单位当多个模块使用不同的timescale编译指令时仿真时间的报告会不会让你感到困惑这正是Verilog语言内置的$printtimescale和$timeformat系统任务所要解决的核心问题。它们不是用来设计逻辑的而是用来管理和解读仿真“时空”的标尺与格式是确保设计、验证、调试各方对时间理解一致的基石。简单来说$printtimescale是你的时间单位“检测仪”它能告诉你当前仿真上下文中的时间单位和精度而$timeformat则是你的时间“格式化打印机”它允许你自定义诸如$display、$strobe、$monitor等任务输出时间信息时的显示格式。对于一个严谨的设计流程尤其是在大型、多模块、多IP集成的项目中清晰统一的时间表达能极大提升调试效率避免因时间单位误解导致的时序分析错误。无论你是在用Verilog实现一个PID控制器、编写I2C EEPROM读写逻辑还是设计DDR3控制器或异步FIFO理解并善用这两个任务都能让你的仿真日志和调试输出更加专业、清晰。2. 时间系统的基石timescale编译指令解析在深入系统任务之前我们必须先夯实基础理解Verilog仿真时间的源头——timescale编译指令。这条指令定义了仿真器处理时间延迟如#delay和计算仿真推进所依据的基本单位。2.1timescale的语法与语义timescale指令的语法格式是固定的timescale 。它由两部分组成时间单位决定了#后面数字所代表的时间量。例如timescale 1ns/1ps表示#5 代表5纳秒的延迟。时间精度决定了仿真器内部计算时间的最小步进值。它必须小于或等于时间单位。同样在1ns/1ps的例子中仿真器可以处理的最小时间变化是1皮秒。这个指令通常放在Verilog源文件的开头影响该文件及其之后编译的所有模块直到遇到下一个timescale指令。一个项目中混用不同的timescale是非常常见的场景比如一个高速SerDes IP核可能使用timescale 1ps/1fs以获得极高的时序精度而顶层的系统集成模块可能使用timescale 1ns/100ps以平衡仿真速度和精度需求。2.2 多timescale环境下的仿真挑战当设计中存在多个timescale时仿真器会建立一个全局的仿真时间队列。所有的时间延迟都会被转换到一个统一的内部时间表示通常是最高精度的时间单位。但这带来了可读性问题// File: clk_gen.v timescale 1ns/100ps module clk_gen(output reg clk); always #5 clk ~clk; // 延迟5纳秒 endmodule // File: data_proc.v timescale 10ns/1ns module data_proc(input clk); reg [7:0] data; always (posedge clk) begin #3 data data 1; // 延迟30纳秒因为这里的#3对应30ns $display(“Time: %t, Data: %d”, $time, data); end endmodule在上面的例子中data_proc模块里的#3由于受其自身timescale 10ns/1ns的影响实际代表30纳秒的延迟而不是3纳秒。如果不清楚当前模块的timescale直接看$display输出的%t格式时间值很容易产生误解。这时$printtimescale 就派上了用场。注意timescale是编译指令不是语句。它不参与仿真执行而是在代码编译或解析阶段生效。因此你无法在initial或always块中动态改变它。3. 系统任务深度剖析$printtimescale与$timeformat掌握了时间基准我们就可以来使用管理时间的工具了。这两个系统任务通常配合使用一个用于诊断一个用于定制输出。3.1$printtimescale你的仿真时间“探针”$printtimescale任务用于打印调用该任务时所在模块的timescale设置。它的调用方式极其简单$printtimescale; // 或者带一个可选参数通常不使用 $printtimescale();这个任务没有返回值它的作用就是向标准输出通常是仿真器的日志窗口或控制台打印一行信息。例如在上一节的data_proc模块中加入module data_proc(input clk); initial $printtimescale; // 在仿真开始时打印 reg [7:0] data; always (posedge clk) begin #3 data data 1; $display(“Time: %t, Data: %d”, $time, data); end endmodule仿真运行后你可能会看到类似这样的输出Time scale of data_proc is 10 ns / 1 ns这行输出明确告诉你当前data_proc模块的时间单位是10纳秒时间精度是1纳秒。这就解释了为什么#3是30纳秒。在调试跨模块信号延迟或分析波形中时间戳含义时在关键模块的initial块中插入$printtimescale是一种非常有效的“自文档化”和调试手段。实操心得在大型测试平台Testbench的顶层或重要的验证组件中养成在仿真开始阶段initial块开头调用$printtimescale的习惯。这能让你和你的团队在查看仿真日志的第一时间就明确当前的时间基准避免后续分析中出现时间单位的混淆。特别是在集成第三方IP时这一招能快速确认IP供应商提供的时间尺度是否符合你的系统预期。3.2$timeformat定制你的时间“显示格式”如果说$printtimescale是告诉你尺子的刻度那么$timeformat就是让你决定如何把尺子上的读数用文字写出来。$timeformat任务用于改变%t格式符在$display,$write,$strobe,$monitor等任务中的输出格式。它的语法相对复杂参数也较多$timeformat(units, precision, suffix, minimum_field_width);units一个整数指定时间单位。其含义是将仿真时间除以10^units秒后再进行输出。-12表示皮秒ps, 10^-12秒-9表示纳秒ns, 10^-9秒-6表示微秒us, 10^-6秒-3表示毫秒ms, 10^-3秒0表示秒s3表示千秒ks, 10^3秒precision一个整数指定小数点后显示的位数。例如0表示显示整数3表示显示到小数点后3位。suffix一个字符串指定附加在时间数值后的单位后缀。例如“ ns”。minimum_field_width一个整数指定输出时间值的最小字段宽度。如果实际数值宽度小于此值会在左侧填充空格。一个核心机制$timeformat的设置是层次化的。当在一个模块或任务中调用$timeformat后该设置会对其内部所有后续的%t格式输出生效直到被新的$timeformat调用覆盖。它不会影响其他模块的格式除非你在那些模块里也调用了它。4. 实战演练从配置到输出的完整流程理解了理论我们通过一个综合性的例子将$printtimescale、$timeformat、$time和$realtime串联起来展示一个完整的调试信息输出流程。4.1 搭建一个多时间尺度的测试环境我们创建一个包含两个不同timescale模块的小系统并在测试平台中灵活控制时间格式。// 模块A高精度时钟生成 timescale 1ns/10ps module module_a (output reg clk_a); initial begin $printtimescale; // 打印Time scale of module_a is 1 ns / 10 ps clk_a 0; forever #5 clk_a ~clk_a; // 5纳秒周期即200MHz end endmodule // 模块B数据处理较低精度 timescale 10ns/1ns module module_b (input clk, output reg [7:0] data_out); reg [7:0] counter 0; initial $printtimescale; // 打印Time scale of module_b is 10 ns / 1 ns always (posedge clk) begin // 在模块B的timescale下#1代表10ns #1; // 等待10ns counter counter 1; data_out counter; // 使用默认格式输出可能不易读 $display(“[Module B Default] Time%t, data_out%d”, $time, data_out); end endmodule // 测试平台顶层 timescale 1ns/1ps module tb_timescale_demo; wire clk_from_a; wire [7:0] data_from_b; module_a u_a (.clk_a(clk_from_a)); module_b u_b (.clk(clk_from_a), .data_out(data_from_b)); reg [7:0] tb_counter 0; initial begin $printtimescale; // 打印Time scale of tb_timescale_demo is 1 ns / 1 ps // 设置全局时间格式以纳秒为单位显示3位小数后缀为“ns”最小宽度10字符 $timeformat(-9, 3, “ ns”, 10); // 监控信号变化使用自定义格式 $monitor(“[TB Monitor] T%t, clk%b, data0x%h”, $realtime, clk_from_a, data_from_b); // 定期以不同格式打印时间 #500; // 延迟500ns $display(“[TB Checkpoint 1] Absolute simulation time is %t”, $time); // 临时改变格式为皮秒整数显示 $timeformat(-12, 0, “ ps”, 8); #1000; // 再延迟1000ns (即1us) $display(“[TB Checkpoint 2] Time in ps: %t”, $time); // 恢复纳秒显示格式 $timeformat(-9, 3, “ ns”, 10); #2000; $display(“[TB Checkpoint 3] Final time: %t”, $time); $finish; end // 在测试平台中以更高频率采样数据使用顶层的timescale always (posedge clk_from_a) begin tb_counter tb_counter 1; // 每10个时钟周期打印一次详细时间 if (tb_counter % 10 0) begin // $realtime返回实数时间配合%t格式显示更精确 $display(“[TB Sample] Real-time: %t, Sampled Data: %d”, $realtime, data_from_b); end end endmodule4.2 仿真输出分析与解读运行上述仿真你可能会得到类似以下的输出具体数值取决于仿真器Time scale of module_a is 1 ns / 10 ps Time scale of module_b is 10 ns / 1 ns Time scale of tb_timescale_demo is 1 ns / 1 ps [Module B Default] Time 10, data_out1 [TB Monitor] T 10.000 ns, clk1, data0x01 [TB Sample] Real-time 10.000 ns, Sampled Data: 1 [Module B Default] Time 30, data_out2 [TB Monitor] T 30.000 ns, clk1, data0x02 ... [TB Checkpoint 1] Absolute simulation time is 500.000 ns [Module B Default] Time 510, data_out... [TB Checkpoint 2] Time in ps: 1500000 ps [TB Checkpoint 3] Final time: 3500.000 ns我们来解读关键点$printtimescale输出清晰展示了三个不同模块的时间基准这是理解后续所有时间值的基础。模块B的默认输出[Module B Default] Time 10。这里的10是仿真时间但其单位是模块B的时间单位10ns。所以这个“10”代表100纳秒的仿真时间。这种裸数字非常不直观。测试平台的格式化输出[TB Monitor] T 10.000 ns。由于我们在测试平台顶层调用了$timeformat(-9, 3, “ ns”, 10)所有在测试平台中使用的%t格式符都会将仿真时间转换为以纳秒为单位、保留3位小数、并附加“ns”后缀、总宽度至少10字符的字符串。这使得时间信息一目了然。格式的动态切换在[TB Checkpoint 2]我们临时将格式切换为皮秒(-12)整数显示(0)输出变成了“1500000 ps”。这验证了$timeformat的动态作用范围。$timevs$realtime注意我们在$monitor中使用了$realtime。$time返回的是根据当前时间精度四舍五入后的整数时间单位值在timescale 1ns/1ps下它返回的是皮秒为单位的整数。而$realtime返回的是**实数**能更精确地表示时间。当使用%t格式输出时两者都会遵循$timeformat的规则进行格式化但$realtime 能保留小数部分在需要高精度时间戳时更准确。重要提示$timeformat只影响%t格式符的显示不影响$time和$realtime函数返回的数值本身。它仅仅是一个“显示层”的格式化工具。5. 高级应用与调试技巧掌握了基本用法后我们可以探索一些更进阶的场景和调试技巧这些在实际项目中能解决不少头疼的问题。5.1 在UVM等验证方法学中的应用在现代基于SystemVerilog的UVM验证环境中虽然UVM提供了强大的报告宏uvm_info,uvm_error等它们自带时间戳但其格式有时是固定的。如果你需要将特定时间信息以自定义格式嵌入到传输事务transaction的日志中或者需要在自定义的记分板、监视器里输出特殊格式的时间$timeformat结合$sformatf就非常有用。class my_driver extends uvm_driver #(my_transaction); virtual task run_phase(uvm_phase phase); forever begin seq_item_port.get_next_item(req); // 记录驱动事务的精确开始时间实数 begin real drive_start_time; drive_start_time $realtime; // 设置我们想要的格式微秒2位小数 $timeformat(-6, 2, “ us”, 8); uvm_info(“DRV”, $sformatf(“Driving transaction at t%t, addr0x%h”, drive_start_time, req.addr), UVM_MEDIUM) // 恢复UVM默认的时间格式如果需要 // 通常UVM有自己的时间格式设置在report catcher或环境顶层配置 end // ... 驱动信号的具体逻辑 ... seq_item_port.item_done(); end endtask endclass技巧为了避免$timeformat的临时设置影响验证环境中其他组件的日志输出最佳实践是将其使用限制在局部代码块中如上面的begin...end块或者在使用后立即恢复为环境默认格式。UVM的默认时间格式通常通过$timeformat在测试基类或环境基类的run_test之前设置。5.2 波形文件中的时间信息关联当你使用$dumpfile和$dumpvars生成VCD或FSDB等波形文件时仿真时间信息会被完整记录。然而在查看波形时波形工具显示的时间单位通常取决于仿真时全局最小的精度或工具自身的设置。在仿真日志中输出的、经过$timeformat格式化的时间戳可以与波形中的时间点进行精确对应这对于定位特定时刻发生的事件至关重要。例如在日志中看到[ERROR] At time 12345.678 ns: Packet checksum mismatch!你可以直接在波形查看器中跳转到12345.678 ns附近观察相关信号的变化快速定位错误源。确保仿真日志中的时间格式与波形查看器的时间显示单位一致例如都用纳秒能极大提升调试效率。5.3 处理时间单位不匹配的警告和错误仿真器如VCS、Xcelium、ModelSim/QuestaSIM在编译和仿真多timescale设计时可能会产生警告。例如Warning: [TFMPC] In module ‘module_b’, the previous timescale ‘1ns/10ps’ is redefined to ‘10ns/1ns’.这不是错误但提醒你时间尺度发生了变化。更需要注意的是由于精度损失导致的问题。考虑以下情况timescale 10ns/1ns module coarse; event trigger; initial #1.5 - trigger; // 延迟15ns不精度是1ns所以#1.5会被舍入为#2即20ns延迟 endmodule timescale 1ns/100ps module fine; event trigger; initial #1.55 - trigger; // 延迟1.55ns精度是100ps(0.1ns)所以#1.55会被舍入为#1.6即1.6ns延迟。 endmodule排查技巧当你发现延迟行为与预期不符时首先使用$printtimescale确认当前模块的精度。然后在代码中关键延迟处前后打印$realtime用高精度格式显示可以精确测量实际延迟。initial begin $timeformat(-12, 3, “ ps”, 12); // 皮秒显示 $display(“Start: %t”, $realtime); #1.55; // 有疑问的延迟 $display(“After delay: %t”, $realtime); end6. 常见问题与避坑指南在实际使用中工程师们经常会遇到一些关于时间系统和这两个任务的典型问题。这里我总结了一份速查表并附上我的个人经验。问题现象可能原因排查步骤与解决方案%t格式输出显示为巨大的整数如10000000没有调用$timeformat或格式单位设置过小如用-12皮秒单位显示微秒级时间。1. 在仿真开始如Testbench的initial块调用$timeformat设置合适的单位如-9纳秒。2. 检查$timeformat的units参数是否与你的仿真时间量级匹配。不同模块打印的时间值单位似乎不一致各模块使用了不同的 timescale且$display中的%t依赖于各自模块内生效的$timeformat 设置或无设置。1. 在每个模块的initial块使用$printtimescale确认其时间基准。2.统一输出口径建议在测试平台顶层统一设置一次$timeformat并确保所有需要友好时间显示的输出尤其是通过层次化引用跨模块信号时的输出都在顶层或一个公共打印任务中完成。$time和$realtime用%t输出看起来一样在时间精度较粗如1ns/1ns或仿真时间点恰好是精度整数倍时两者四舍五入后相同。1. 提高仿真精度如改为1ns/1ps可以看到区别。2. 需要观察亚精度时间事件时如检查窄脉冲务必使用$realtime。修改$timeformat后某些$display的时间格式没变$timeformat的作用是层次化的。在子模块或任务中调用的$display其格式取决于该模块/任务作用域内最后一次$timeformat的调用。理解“层次化”概念。如果希望全局统一在最高层次如Testbench顶层的initial块开始处设置。如果需要在不同上下文用不同格式就在进入该上下文时设置离开时恢复。第三方IP仿真时时间相关逻辑出错IP内部使用了与顶层不同的、更精细的 timescale导致顶层提供的延迟或时钟在IP内部被解释错误。1. 仔细阅读IP文档确认其要求的timescale。br2. 在实例化IP的模块中**在实例化语句之前**使用与IP相同的timescale指令。br3. 使用$printtimescale 在IP实例内部打印确认。个人避坑经验项目启动时确立规范在团队项目开始时就约定好整个仿真环境的基准timescale例如 1ns/1ps。对于必须使用不同尺度的第三方IP将其封装在单独的Wrapper模块内并在Wrapper文件首行定义正确的timescale隔离其对其他代码的影响。Testbench顶层统一管理时间格式我的习惯是在Testbench顶层的initial块最开始就调用$timeformat(-9, 3, “ ns”, 10)将全局默认格式定为纳秒显示。所有测试用例和验证组件都默认使用这个格式输出时间。如果某个特定测试需要更精细的格式就在该测试的代码块内局部修改。将$printtimescale作为调试头文件我经常创建一个名为debug_init.vh的头文件里面包含// debug_init.vh initial begin $display(“[DEBUG] Simulation started at hierarchy: %m”); $printtimescale; // 可以在这里设置默认时间格式 // $timeformat(-9, 3, “ ns”, 10); end然后在需要调试的关键模块里 include 它。这样能快速在日志中定位每个模块的时间上下文。波形与日志时间对齐在仿真命令行或脚本中我会记录下本次仿真使用的最精细时间精度。在查看波形时将波形工具的时间显示单位设置为与之相同通常是皮秒或纳秒这样可以保证在日志中看到的时间戳123.456 ns能直接在波形中找到对应的精确位置实现“日志-波形”联动调试效率倍增。时间系统是仿真的骨架$printtimescale和$timeformat就是让你看清这副骨架的X光机和解剖刀。花一点时间掌握它们能让你在复杂的仿真调试中对时间的流逝拥有精确的掌控感从而更从容地定位那些与时序相关的幽灵般的Bug。

相关新闻

射频功放记忆效应:从物理机理到DPD补偿的实战解析

射频功放记忆效应:从物理机理到DPD补偿的实战解析

1. 项目概述:从“三问”切入射频功放的核心痛点 最近在整理射频功率放大器(PA)的设计笔记,一个绕不开的“老大难”问题就是记忆效应。无论是刚入行的新人,还是像我这样摸爬滚打多年的工程师,每次调试PA线性…

2026/10/7 6:48:59 阅读更多 →
小鼠标网站建设:从零基础到精通,普通人的数字化突围指南

小鼠标网站建设:从零基础到精通,普通人的数字化突围指南

在如今这个万物互联、数字化的时代,我们似乎进入了一个全新的纪元。打开手机,指尖轻触;打开电脑,鼠标轻点。那小小的、在掌心或桌面上滑动的“小鼠标”,早已不再仅仅是一个输入设备,它更像是一把钥匙,一把开启数字世界大门、连接现实与虚拟、个体与全球的钥匙。然而,对…

2026/10/13 10:38:30 阅读更多 →
独立产品何时不该用 LLM:规则能解决的事别交给概率

独立产品何时不该用 LLM:规则能解决的事别交给概率

独立产品何时不该用 LLM:规则能解决的事别交给概率说明:成本与延迟对比是说明性示例。规则、传统算法或 LLM 的选择,应按真实输入、错误成本与预算验证。月度账单寄来时,服务器费用不到 30 美元,API Token 的消耗却砸了…

2026/10/13 1:47:05 阅读更多 →

最新新闻

Inception-v3迁移学习实战:花卉图像识别模型训练与部署复盘

Inception-v3迁移学习实战:花卉图像识别模型训练与部署复盘

接到这个图像识别项目时,需求其实不复杂:把一批花卉照片按品种自动分类,先跑一个能用的原型出来。当时我翻了一圈模型库,最终拍板用 TensorFlow 的 Inception-v3 配合迁移学习来做,前后一周多点就交付了可用的 Demo。这…

2026/10/13 22:20:57 阅读更多 →
PyTorch实现简单分类网络:MNIST手写数字识别全流程教程

PyTorch实现简单分类网络:MNIST手写数字识别全流程教程

写个简单的分类网络,没想到成了我这些年被问得最多的一篇教程。倒不是说它有多高深,而是很多刚接触PyTorch的朋友,恰恰需要这样一个“足够简单又不敷衍”的完整例子——把全流程跑通,再回头啃文档,效率高得多。这篇东西…

2026/10/13 22:20:57 阅读更多 →
PS5控制器Linux HID协议兼容性实践

PS5控制器Linux HID协议兼容性实践

我无法基于当前输入生成符合要求的博文。 原因如下: 项目标题“AnyPS5”缺乏明确指向性,未说明是硬件改装、模拟器方案、跨平台兼容层、开发工具链,还是其他技术方向; 项目正文为空,无任何功能描述、技术目标、实现…

2026/10/13 22:20:57 阅读更多 →
AnyPS5:面向PS5的轻量级增强工具链设计与实践

AnyPS5:面向PS5的轻量级增强工具链设计与实践

1. 项目概述:一个被误读的命名现象,而非技术实体“AnyPS5”这个词最近在多个内容平台频繁出现,但如果你点进去看,大概率会发现它既不是某款新发布的硬件设备,也不是索尼官方推出的软件工具,更不是某个开源社…

2026/10/13 22:20:57 阅读更多 →
光储一体化系统Simulink仿真:VSG构网型控制与直流母线稳压策略

光储一体化系统Simulink仿真:VSG构网型控制与直流母线稳压策略

1. 项目定位与整体架构思路先交代一下这个模型解决的实际问题。光伏和储能单独做,大家都会:光伏那边是MPPT加Boost,储能那边是双向Buck-Boost加并网逆变器,两边独立建模,仿真各跑各的,看不到多少交互。但真…

2026/10/13 22:20:57 阅读更多 →
PHP Excel导入导出实战:PhpSpreadsheet选型、内存优化与踩坑记录

PHP Excel导入导出实战:PhpSpreadsheet选型、内存优化与踩坑记录

最近这段时间一直在捣鼓一个内部报表系统的收尾工作,核心功能就是大家经常挂在嘴边的“PHP Excel导入导出”。标题写了“亲测成功”,真不是标题党——从最开始选型、搭环境,到后来导出报表、导入批量数据,再到中途被内存溢出和文件…

2026/10/13 22:19:57 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →