SystemVerilog测试套件从IP到SoC的重用:架构设计与工程实践

news2026/5/21 2:11:05
1. 项目概述从IP到SoC的验证鸿沟在芯片设计行业里摸爬滚打十几年我见过太多团队在项目后期被验证工作拖得焦头烂额。一个典型的场景是某个IP知识产权核比如一个USB控制器或一个DDR内存控制器在独立验证阶段表现完美通过了所有单元测试和子系统测试。然而一旦这个IP被集成到一个复杂的SoC片上系统中整个验证流程仿佛要重新开始。工程师们不得不花费数周甚至数月的时间去重新搭建SoC级的测试环境、编写新的测试用例、调试那些在IP级从未出现过的集成问题。这不仅仅是时间的浪费更是验证资产测试平台、测试用例、覆盖率模型的巨大浪费。“SystemVerilog测试套件加速IP到SoC的重用”这个项目直指的就是这个行业痛点。它的核心目标是建立一套方法论和配套的实践技巧让我们在IP级别精心开发的SystemVerilog验证环境我们通常称之为UVM验证平台或测试套件能够平滑、高效地“升级”或“迁移”到SoC级别的验证中。这不仅仅是代码的拷贝粘贴而是一个涉及架构设计、组件解耦、配置管理和流程集成的系统工程。成功的重用意味着SoC验证可以站在巨人的肩膀上直接利用IP验证阶段积累的成熟测试场景和覆盖率数据将验证焦点从“IP功能对不对”转移到“IP在SoC中集成得好不好”这个更高层次的问题上从而将SoC验证周期缩短30%甚至更多。2. 核心挑战与设计思路拆解2.1 为何IP测试套件难以直接重用在动手搭建可重用框架之前我们必须先理解阻碍重用的几座大山。只有清楚了问题所在我们的设计方案才能有的放矢。第一座山验证环境的“视野”不同。IP级验证环境是“显微镜”它聚焦于IP内部每一个接口、每一个状态机、每一个数据路径的精确行为。它的测试激励Testbench通常直接驱动IP的物理接口Pin Level其检查器Checker和记分板Scoreboard也紧密耦合于IP的内部协议和数据结构。而SoC级验证是“广角镜”它关注的是多个IP通过片上总线如AXI、AHB、片上网络NoC或专用接口互联后的系统级行为。在SoC中IP往往被包装成具有标准接口的“黑盒”其物理引脚对SoC验证环境不可见取而代之的是通过总线功能模型BFM进行访问。第二座山配置与初始化的复杂性剧增。一个独立的IP可能只有几种工作模式其配置寄存器数量有限。但在SoC中该IP的时钟、复位、电源域可能由SoC级的控制器动态管理它的基地址由系统内存映射决定它的中断需要路由到特定的处理器核心它可能还需要与其他IP协同工作例如一个图像处理IP需要从DDR控制器读取数据再通过显示接口输出。IP级测试中那些写死的配置参数和初始化序列在SoC环境下几乎全部需要动态化、参数化。第三座山激励与检查的“上下文”丢失。IP级测试用例是“自包含”的它自己生成数据自己驱动接口自己检查结果。但在SoC中一个完整的事务可能跨越多个IP。例如测试一个视频编解码的流程需要CPU配置编解码IPDMA从外部存储器搬运原始视频帧到编解码IP的输入缓冲区编解码IP处理完成后触发中断CPU再通过DMA将处理后的数据搬走。IP级的测试用例无法模拟这个多IP协作的“故事线”其检查器也无法验证跨IP的数据一致性和时序关系。2.2 可重用测试套件的顶层设计哲学基于以上挑战我们的设计思路必须从“为IP验证而设计”转变为“为集成验证而设计”。这要求我们在IP验证阶段就提前为SoC集成埋下伏笔。核心设计哲学可以概括为三点分层、解耦、适配。分层意味着将测试套件清晰地划分为“IP代理层”和“系统场景层”。IP代理层封装了与该IP直接交互的所有组件如驱动器Driver、监视器Monitor、序列Sequence和配置对象Configuration Object。这一层对IP的内部细节了如指掌。系统场景层则位于更高层级它不关心某个IP内部如何工作只负责编排多个IP代理共同完成一个系统级任务如“播放一段视频”、“完成一次网络包收发”。这两层通过定义良好的抽象接口进行通信。解耦是重用的技术关键。我们必须将测试环境中所有与具体验证平台Testbench拓扑强绑定的部分剥离出来。具体来说物理接口绑定解耦IP级的驱动器不应直接绑定到virtual interface上而应通过一个抽象的“通信代理”。这样在SoC环境中我们可以将这个代理替换为通过总线访问IP寄存器的BFM。配置信息解耦IP的地址、时钟频率、工作模式等不应是代码中的常量或宏而应来自一个可被上层环境动态设置和传递的配置类uvm_config_db。检查逻辑解耦IP内部数据正确性的检查白盒检查应封装在IP代理层内而跨IP的系统级功能检查黑盒检查应上移到系统场景层或独立的系统级检查组件中。适配是重用的最后一步。我们需要设计一套“适配器”Adapter或“包装器”Wrapper它们的作用是将SoC级的环境信号和访问方式“翻译”成IP代理层能够理解的语言。例如一个AXI总线到IP内部寄存器的适配器可以将SoC环境中发起的AXI读写事务转换成IP代理层期待的寄存器访问序列。提示不要试图设计一个“万能”的、一次性满足所有层次验证需求的超级测试平台。那会变得异常复杂且难以维护。正确的思路是保证每一层IP层、子系统层、SoC层的测试环境相对独立且完整然后通过清晰的接口和适配机制让低层的环境能够作为组件被高层环境“调用”和“控制”。3. 构建可重用测试套件的关键技术实践3.1 UVM架构的适应性改造UVMUniversal Verification Methodology是目前业界基于SystemVerilog的事实标准验证方法学。要让基于UVM的IP测试套件可重用我们必须对其标准架构做一些关键性的改造。首先是环境uvm_env的模块化。传统的IP UVM环境通常是一个“大而全”的整体。我们需要将其拆分为核心组件包ip_agent_pkg和一个或多个环境包装类。ip_agent_pkg中包含了该IP所有的可重用组件ip_sequencer,ip_driver,ip_monitor,ip_config,ip_sequence_lib等。这个包应该不包含任何顶层连接信息即没有virtual interface的赋值没有uvm_env的connect_phase。然后我们创建一个ip_env类它的唯一职责就是在build_phase中实例化这些组件并在connect_phase中根据传入的配置对象将它们正确地连接起来。这个ip_env就像一个乐高积木可以在SoC的顶层环境中被轻松实例化。// 示例可重用的IP Agent Package package ip_agent_pkg; include “uvm_macros.svh” import uvm_pkg::*; class ip_config extends uvm_object; virtual ip_if vif; // 配置对象持有接口而非驱动器中 int base_addr; // ... 其他配置参数 endclass class ip_driver extends uvm_driver #(ip_transaction); uvm_component_utils(ip_driver) virtual ip_if vif; // 驱动器通过config获取vif function void build_phase(uvm_phase phase); super.build_phase(phase); if(!uvm_config_db#(virtual ip_if)::get(this, “”, “vif”, vif)) uvm_fatal(“NOVIF”, “No virtual interface specified for this driver”) endfunction // ... drive task endclass // ... 其他组件定义 endpackage // 示例可重用的IP环境包装器 module ip_env_wrapper #(parameter int ADDR_WIDTH32) (input logic clk, rst_n); ip_if ip_if_inst(.*); // 物理接口 ip_env #(.ADDR_WIDTH(ADDR_WIDTH)) ip_env_inst; initial begin // 通过config_db将物理接口传递给环境内的组件 uvm_config_db#(virtual ip_if)::set(null, “uvm_test_top.soc_env.ip_env_inst.*”, “vif”, ip_if_inst); // 启动UVM测试 run_test(); end endmodule其次是序列Sequence的层次化设计。IP级的序列我们称之为“原子序列”应该只完成最基本的、与IP直接相关的操作比如“配置寄存器A为值X”、“发送一个类型为Y的数据包”。这些序列不应该包含任何关于系统拓扑如地址映射或协同IP的信息。在SoC级我们会创建“系统级序列”这些序列的body任务中会启动多个IP的原子序列并协调它们之间的顺序和依赖关系。UVM的uvm_do_on宏和uvm_config_db机制可以很好地支持这种跨组件的序列调用。3.2 配置与注册表的动态管理配置管理是可重用性的生命线。我们需要建立一个中心化的、层次化的配置管理系统。创建分层的配置对象为每个IP定义一个ip_config类包含其所有可配置参数地址、时钟、工作模式等。在SoC顶层定义一个soc_config类其中包含所有IP配置对象的实例作为其成员。使用UVM配置数据库进行传播在SoC测试的顶层创建并随机化soc_config对象然后通过uvm_config_db#(soc_config)::set将其设置到全局。在各个IP环境的build_phase中通过uvm_config_db#(soc_config)::get获取到这个顶层配置对象并从中提取出属于自己的那部分ip_config信息再设置给自己的组件。地址映射的抽象绝对避免在序列或驱动器中硬编码寄存器地址。地址应该是配置对象的一部分。更好的做法是在IP代理层内部提供一个“地址转换器”它接收一个逻辑偏移量如REG_CTRL结合配置对象中提供的基地址base_addr计算出实际的物理地址。在SoC级这个基地址由系统内存映射决定在IP级可以设置为0或一个默认值。// 示例SoC级配置与传播 class soc_config extends uvm_object; rand ip_config ip_cfg; rand dma_config dma_cfg; // ... 其他IP配置 function void post_randomize(); // 建立配置间的约束关系例如DMA源地址指向IP的缓冲区 dma_cfg.src_addr ip_cfg.buf_base_addr; endfunction endclass class soc_test extends uvm_test; soc_config soc_cfg; function void build_phase(uvm_phase phase); super.build_phase(phase); soc_cfg soc_config::type_id::create(“soc_cfg”); // 随机化整个SoC配置 assert(soc_cfg.randomize()); // 将整个配置对象放入config_db供所有子环境获取 uvm_config_db#(soc_config)::set(this, “*”, “soc_config”, soc_cfg); endfunction endclass class ip_env extends uvm_env; ip_config cfg; function void build_phase(uvm_phase phase); super.build_phase(phase); // 从全局获取SoC配置 uvm_config_db#(soc_config)::get(this, “”, “soc_config”, soc_cfg); if (soc_cfg ! null) begin // 从SoC配置中提取本IP的配置 cfg soc_cfg.ip_cfg; end else begin // 如果没有SoC配置如在IP级测试中则创建默认配置 cfg ip_config::type_id::create(“cfg”); cfg.base_addr ‘h0000_0000; // 默认基地址 end // 将本IP的配置设置给下属组件 uvm_config_db#(ip_config)::set(this, “agent”, “config”, cfg); endfunction endclass3.3 从物理接口到虚拟接口的抽象这是技术上的一个难点也是决定重用性的关键。IP级测试通常使用virtual interface直接绑定到RTL的模块端口。但在SoC中该IP的端口被集成在内部对外不可见。解决方案是引入“总线功能模型BFM层”或“事务处理器Transaction Processor”。在IP代理层我们的驱动器和监视器并不直接与virtual interface对话而是与一个抽象的“命令接口”通常是一个uvm_tlm_analysis_port或uvm_blocking_put_port通信。在IP级测试中我们实现一个“直通适配器”它接收事务通过virtual interface直接驱动RTL。在SoC级测试中我们则实现一个“总线适配器”例如AXI Adapter它接收同样的事务但将其翻译成一系列符合总线协议如AXI读写的信号通过一个总线BFM去访问IP的寄存器空间。// 示例抽象的命令接口和适配器模式 // 在ip_driver内部 class ip_driver extends uvm_driver #(ip_transaction); uvm_blocking_put_port #(ip_reg_transaction) cmd_port; // 抽象的命令端口 task run_phase(uvm_phase phase); forever begin ip_transaction req; seq_item_port.get_next_item(req); // 从序列获取事务 // 将事务转换为寄存器访问事务 ip_reg_transaction reg_tr convert_to_reg_tr(req); // 通过抽象端口发送而不是直接写interface cmd_port.put(reg_tr); seq_item_port.item_done(); end endtask endclass // IP级适配器直通模式 class ip_pin_adapter extends uvm_component; uvm_blocking_put_imp #(ip_reg_transaction, ip_pin_adapter) cmd_imp; virtual ip_if vif; task put(ip_reg_transaction tr); // 直接驱动物理接口 vif.addr tr.addr; vif.wdata tr.wdata; vif.wr tr.is_write; (posedge vif.clk); // ... endtask endclass // SoC级适配器总线模式 class ip_axi_adapter extends uvm_component; uvm_blocking_put_imp #(ip_reg_transaction, ip_axi_adapter) cmd_imp; axi_master_bfm axi_bfm; // AXI总线功能模型 task put(ip_reg_transaction tr); axi_transaction axi_tr; axi_tr new(); axi_tr.addr soc_cfg.ip_cfg.base_addr tr.addr; // 合成完整地址 axi_tr.data tr.wdata; axi_tr.cmd tr.is_write ? AXI_WRITE : AXI_READ; axi_bfm.drive_transaction(axi_tr); // 通过AXI BFM访问 endtask endclass这样IP代理层的核心逻辑完全不用改变只需在集成时替换不同的适配器就实现了从引脚级到总线级访问的无缝切换。4. SoC集成与系统级测试构建4.1 集成可重用IP环境当各个IP的可重用测试套件准备就绪后SoC级验证环境的搭建就变成了一个“组装”的过程。顶层SoC验证环境soc_env的主要任务就是实例化所有需要的IP环境ip_env,dma_env,cpu_model_env等并通过配置系统将它们有机地组织起来。class soc_env extends uvm_env; uvm_component_utils(soc_env) ip_env ip_env_inst; dma_env dma_env_inst; // ... 其他IP环境实例 soc_config cfg; function void build_phase(uvm_phase phase); super.build_phase(phase); // 获取顶层配置 if(!uvm_config_db#(soc_config)::get(this, “”, “soc_config”, cfg)) begin uvm_fatal(“CFG”, “Failed to get soc_config”) end // 根据配置创建并设置子环境 ip_env_inst ip_env::type_id::create(“ip_env_inst”, this); uvm_config_db#(ip_config)::set(this, “ip_env_inst”, “config”, cfg.ip_cfg); // ... 实例化并配置其他环境 endfunction function void connect_phase(uvm_phase phase); super.connect_phase(phase); // 连接跨环境的TLM端口例如将IP的中断监视器连接到CPU模型的中断输入端口 ip_env_inst.agent.monitor.intr_port.connect(cpu_model_env_inst.intr_export); // 连接DMA完成端口到IP的数据缓冲区准备好端口 dma_env_inst.agent.monitor.done_port.connect(ip_env_inst.agent.sequencer.buf_ready_export); endfunction endclass关键一步是适配器的连接。在SoC环境的connect_phase我们需要将每个IP代理层的抽象命令端口连接到对应的总线适配器如ip_axi_adapter上。这个适配器本身需要连接到SoC级的总线BFM或寄存器模型Register Model。UVM的寄存器模型uvm_reg在这里能发挥巨大作用它可以提供一个统一的、事务级的寄存器访问前端并自动处理地址映射和后端适配是直接前门访问还是通过总线BFM极大地简化了集成。4.2 编写系统级场景与测试用例系统级测试用例soc_test的编写思路与IP级截然不同。它不再关心某个IP内部的状态跳转而是关注数据流和控制流在多个IP之间的正确传递。数据流测试这是最常见的系统测试。例如测试一个图像处理流水线CPU配置DMA从外部模型如uvm_mem读取原始图像数据到共享内存CPU配置图像处理IPIPP从共享内存读取数据并处理IPP处理完成后触发中断CPU响应中断再配置DMA将处理后的数据写回外部模型或另一个输出缓冲区。整个测试用例的检查点在于最终输出的图像数据是否与软件算法仿真的结果一致。我们需要在系统级构建一个“黄金参考模型”它模拟了数据流经过各个IP后的正确结果。控制流与并发测试测试多个主设备如多核CPU、DMA、硬件加速器并发访问共享资源如DDR控制器、片上网络时的正确性。例如同时发起多个高优先级的实时音频DMA传输和低优先率的批量数据搬移验证仲裁逻辑、带宽分配和实时性是否满足要求。这类测试需要精心设计序列的同步机制如fork…join,uvm_event。功耗与性能场景测试在SoC级我们可以构建复杂的场景来验证功耗管理单元PMU和动态电压频率调整DVFS功能。例如编写一个序列让系统从休眠状态被唤醒CPU快速处理一个紧急任务然后各个IP根据负载依次进入低功耗状态。测试需要检查唤醒时间、状态切换过程中的功能正确性以及功耗是否符合预算。// 示例一个简单的系统级数据流测试序列 class video_encode_stream_seq extends uvm_sequence #(uvm_sequence_item); uvm_object_utils(video_encode_stream_seq) rand int num_frames; task body(); // 1. CPU配置视频输入IPVIP和编码IPENC的寄存器 vip_config_seq vip_cfg_seq vip_config_seq::type_id::create(“vip_cfg_seq”); enc_config_seq enc_cfg_seq enc_config_seq::type_id::create(“enc_cfg_seq”); uvm_config_db#(vip_config)::set(null, {get_full_name(), “vip_cfg_seq”}, “cfg”, p_sequencer.soc_cfg.vip_cfg); uvm_config_db#(enc_config)::set(null, {get_full_name(), “enc_cfg_seq”}, “cfg”, p_sequencer.soc_cfg.enc_cfg); vip_cfg_seq.start(p_sequencer.vip_seqr); enc_cfg_seq.start(p_sequencer.enc_seqr); // 2. 启动DMA将原始视频帧从外部内存搬运到VIP的输入缓冲区 dma_vip_transfer_seq dma_seq dma_vip_transfer_seq::type_id::create(“dma_seq”); dma_seq.num_transfers num_frames; dma_seq.start(p_sequencer.dma_seqr); // 3. 等待编码完成中断并处理这里简化实际可能需循环处理多帧 fork begin // 在CPU序列器上运行中断服务程序序列 cpu_isr_seq isr_seq cpu_isr_seq::type_id::create(“isr_seq”); isr_seq.start(p_sequencer.cpu_seqr); end begin // 同时监视器检查编码输出的码流是否符合标准 p_sequencer.enc_scoreboard.enable_checking(); end join // 4. 验证通过记分板或后处理比较确认编码输出的文件与黄金参考一致 if (!p_sequencer.sys_scoreboard.stream_match) begin uvm_error(“STREAM_CHK”, “Encoded video stream mismatch with golden reference!”) end else begin uvm_info(“STREAM_CHK”, $sformatf(“Successfully encoded %0d frames”, num_frames), UVM_LOW) end endtask endclass4.3 覆盖率模型的合并与提升覆盖率驱动验证CDV是可重用策略的最终价值体现。在IP级我们收集代码覆盖率Code Coverage和功能覆盖率Functional Coverage确保IP内部逻辑被充分测试。在SoC级我们重用这些覆盖率模型但更重要的是扩展它们。重用将IP级的功能覆盖率收集器Coverage Collector作为子组件实例化到SoC环境的对应IP环境中。这样当SoC级测试运行时IP内部状态的覆盖率依然会被收集确保集成过程没有破坏IP原有的功能。扩展在SoC级我们需要定义新的、系统级的交叉覆盖率Cross Coverage。例如将CPU的工作频率、DMA的传输带宽、总线仲裁器的优先级策略、以及目标IP的工作模式进行交叉覆盖。我们需要回答这样的问题“当CPU处于高频模式、同时有高优先级DMA传输、且IP处于低功耗模式唤醒过程中系统功能是否依然正确”这种场景在IP级是无法构造的正是SoC验证的价值所在。注意合并覆盖率数据库时需注意命名空间冲突。建议在IP级覆盖率组和覆盖点的命名中加入IP名前缀如ip_a_cfg_mode在SoC级则使用系统级命名如soc_power_state。使用验证管理工具如Cadence vManager, Siemens Questa Verification Management可以很好地管理和合并不同层次的覆盖率数据生成清晰的验证进度报告。5. 实战中的挑战与解决方案实录5.1 时钟、复位与电源域的处理这是SoC集成验证中最棘手的物理问题之一。IP级测试通常假设单一的、稳定的时钟和复位。但在SoC中IP可能位于不同的时钟域Clock Domain和电源域Power Domain。挑战1多时钟域同步。IP的接口时钟clk_ip可能来源于SoC的时钟发生器PLL与测试平台的主时钟clk_tb不同频甚至不同源。IP内部的监视器Monitor和记分板Scoreboard若仍使用clk_tb采样必然会导致数据丢失或亚稳态。解决方案在SoC测试平台中必须为每个IP环境提供其真实的时钟和复位信号。这通常通过从RTL顶层引出这些时钟复位信号连接到测试平台的virtual interface。更规范的做法是使用时钟复位BFM它可以动态生成和配置不同频率、相位的时钟以及同步或异步的复位信号并通过UVM配置数据库传递给各个IP环境。挑战2电源域与隔离。当IP所在电源域被关闭时其输出信号应被隔离单元Isolation Cell钳位到安全值。验证平台需要模拟这种上下电行为。解决方案在virtual interface中增加模拟电源状态的控制信号如power_on,iso_enable。在测试序列中可以控制这些信号模拟IP的下电和上电过程。同时IP代理层需要感知电源状态当power_on为低时驱动器应停止驱动监视器应忽略输入。这需要在组件中加入相应的状态机。// 示例支持多时钟和电源状态的接口与驱动 interface ip_soc_if (input logic clk_ip, input logic rst_n_ip, input logic power_good); // IP的功能信号 logic [31:0] data; logic valid; // 测试平台控制信号 logic clk_tb; // 测试平台主时钟用于同步验证组件 logic iso_en; // 隔离使能模拟电源关断 endinterface class ip_driver_soc extends ip_driver; virtual ip_soc_if vif; task run_phase(uvm_phase phase); forever begin seq_item_port.get_next_item(req); // 只有在电源正常且未隔离时才驱动信号 if (vif.power_good !vif.iso_en) begin // 使用IP的时钟域进行驱动 (posedge vif.clk_ip); vif.data req.data; vif.valid 1‘b1; (posedge vif.clk_ip); vif.valid 1’b0; end else begin uvm_warning(“DRV”, “IP is powered down or isolated, transaction held”) // 可以选择将事务暂存等电源恢复后继续处理 end seq_item_port.item_done(); end endtask endclass5.2 调试与排查日志、事务记录与波形分析当SoC级测试失败时由于系统复杂性定位问题根源远比IP级困难。一套强大的调试基础设施至关重要。分层日志与事务记录充分利用UVM的报告机制uvm_info,uvm_warning,uvm_error并为不同组件和不同严重程度的信息设置不同的冗余度verbosity。在IP代理层日志可以详细记录每个寄存器读写和数据包在系统场景层日志则记录高层的场景步骤和关键检查点。同时鼓励所有监视器将捕获到的事务Transaction通过uvm_analysis_port发送到一个全局的事务记录器uvm_tr_database这样可以在波形查看器中同步看到事务流直观地追踪数据在系统中的传递路径。基于Waveform的调试这是最强大的调试手段。必须养成在关键测试中全程记录波形的习惯。为了在浩瀚的信号中找到关键信息信号分组在波形窗口中按IP、按总线、按功能对信号进行分组和重命名。事务标记利用仿真工具如Verdi, SimVision的Transaction Debug功能将UVM中记录的事务标记在波形上让抽象的软件事务与具体的硬件信号一一对应。断言Assertion嵌入在RTL代码或绑定Bind文件中加入关键的系统级断言。例如“当DMA传输完成信号有效时对应的中断信号必须在N个周期内拉高”。断言失败会立即在波形上标记出来能快速定位违反协议或设计假设的精确时刻。后处理与自动化分析对于长时间运行的稳定性测试或性能测试人工看波形不现实。需要编写脚本自动解析仿真日志和事务记录文件提取关键指标如吞吐量、延迟、错误计数并与预期值进行比较生成测试报告。5.3 性能与可扩展性考量当SoC规模很大包含数十个IP时一个包含所有IP完整验证环境的顶层测试平台可能会编译缓慢、仿真效率低下。按需实例化不是所有测试都需要所有IP的完整环境。对于只测试部分IP交互的场景可以在顶层环境soc_env中使用条件编译ifdef或配置开关只实例化相关的IP环境。对于不相关的IP可以用一个空的桩Stub环境或简单的行为模型来代替。抽象模型替代对于一些复杂但非验证焦点的IP如一个成熟且经过充分验证的CPU核可以使用其事务级TLM模型或指令集仿真器ISS来代替其完整的RTL或UVM环境这可以极大提升仿真速度。仿真加速与硬件仿真对于超大规模SoC软件仿真如Questa, VCS可能太慢。需要考虑采用仿真加速Palladium, ZeBu或硬件仿真FPGA Prototyping平台。这就要求我们的测试套件不仅是可重用的还得是可移植的。这意味着要尽量减少对仿真器特定特性的依赖并将测试激励的生成与发送层抽象出来以便适配不同的执行平台。构建一个真正可重用的SystemVerilog测试套件前期投入的精力会比只做一个一次性IP测试平台多出50%甚至更多。你需要思考更多关于抽象、接口和配置的问题。但这份投入在第一个SoC集成验证周期结束时就会开始产生回报。当你的团队能够将主要精力从重复搭建环境转向设计更复杂的系统级场景和 corner-case 测试时当覆盖率合并报告显示系统级覆盖率在项目早期就快速爬升时你会确信这一切都是值得的。这不仅仅是技术的提升更是验证理念和团队协作模式的升级。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2630083.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

SpringBoot-17-MyBatis动态SQL标签之常用标签

文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站,会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后,网站没有变化的情况。 不熟悉siteground主机的新手,遇到这个问题,就很抓狂,明明是哪都没操作错误&#x…

网络编程(Modbus进阶)

思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…

UE5 学习系列(二)用户操作界面及介绍

这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…

利用最小二乘法找圆心和半径

#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明

LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器专为工业环境精心打造&#xff0c;完美适配AGV和无人叉车。同时&#xff0c;集成以太网与语音合成技术&#xff0c;为各类高级系统&#xff08;如MES、调度系统、库位管理、立库等&#xff09;提供高效便捷的语音交互体验。 L…

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…

【Axure高保真原型】引导弹窗

今天和大家中分享引导弹窗的原型模板&#xff0c;载入页面后&#xff0c;会显示引导弹窗&#xff0c;适用于引导用户使用页面&#xff0c;点击完成后&#xff0c;会显示下一个引导弹窗&#xff0c;直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…

接口测试中缓存处理策略

在接口测试中&#xff0c;缓存处理策略是一个关键环节&#xff0c;直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性&#xff0c;避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明&#xff1a; 一、缓存处理的核…

龙虎榜——20250610

上证指数放量收阴线&#xff0c;个股多数下跌&#xff0c;盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型&#xff0c;指数短线有调整的需求&#xff0c;大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的&#xff1a;御银股份、雄帝科技 驱动…

观成科技:隐蔽隧道工具Ligolo-ng加密流量分析

1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具&#xff0c;该工具基于TUN接口实现其功能&#xff0c;利用反向TCP/TLS连接建立一条隐蔽的通信信道&#xff0c;支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式&#xff0c;适应复杂网…

铭豹扩展坞 USB转网口 突然无法识别解决方法

当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…

Linux应用开发之网络套接字编程(实例篇)

服务端与客户端单连接 服务端代码 #include <sys/socket.h> #include <sys/types.h> #include <netinet/in.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <arpa/inet.h> #include <pthread.h> …

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…