【DVCon-US-2020】基于多线程UVM测试平台的仿真加速方法

简介: 【DVCon-US-2020】基于多线程UVM测试平台的仿真加速方法

论文概述


 本文题目 Multithreading a UVM Testbench for Faster Simulation,作者是 Intel 的加拿大验证工程师。


 本文提出了一种C/C++ model和simulation并行的方法,来提升 UVM 测试平台的仿真速度。




研究目的


 为了验证仿真结果的正确性,simulation 中常用UVM来创建predictor和scoreboard组件。predictor可以用SV直接写,但对于偏算法的、较为复杂的DUT,尤其是Vender提供的IP,常采用DPI调用C/C++ model等软件模型作为参考模型(如图1)。


 正常情况下,SV DPI调用C/C++ model时,simulation会停在原地等待C model执行完毕,从而影响simulation效率。即便目前先进的simulator支持多线程的DUT仿真,但对于整个UVM测试平台而言,CPU内仍然时按照单线程运行的。本文目的便是为了提升这种DPI 调用软件模型的simulation效率,为了突破单线程桎梏,来进一步提升 UVM 测试平台的仿真速度。


a5111908e17a42ecbc70794d9b298775.png

图1 UVM testbench using a C++ Predictor Model




新方法


方法提出


本文提出一种方法(图2),开辟一个甚至多个新线程单独跑C/C++ model(其他任何软件模型),与原有的UVM TB并行,能够缩短仿真耗时。运行中的simulation和C/C++ model采用进程间通信机制来交换数据。


 为了对多进程启动顺序、数据交换等进行管理,本文构建了一个线程池 管理器(thread pool manager)。线程池是一个可配置线程数目的软件对象,其中的每个线程都可以单独执行所分配的任务(Job)。Job通过输入队列丢到线程池,由线程池中的空闲线程执行该Job。执行完毕后线程池采用异步方式返回Job执行结果。


641cd6b6b9b3471dacd746b953acf9e1.png


图2 Modified UVM testbench with an asynchronous predictor model




方法实现


线程池的初始化及访问


通过单独开辟新线程的方式来初始化及访问thread_pool class。这种设计隐藏了初始化行为及全局状态,为人所诟病。但该方法使得thread pool class能够响应多个不同组件的调度请求,多个传输单元的code只做微调即可轻松获取 thread pool instance,总体而言是利大于弊的。C++惰性计算的特性也保证了thread pool object只在初次执行thread_pool::get_instance进行调用的时候进行一次初始化。


 线程池类的实现需要 :


  1. 一个私有默认构建函数(private default constructor)


  1. get_instance 函数,以返回thread_pool静态实例的引用
class thread_pool {
public:
    static thread_pool& get_instance()
    {
        static thread_pool inst; //Class will be initialized a single time
        return inst;
    }
private:
    thread_pool() = default; //Prevent creation of other instances
}



线程调度


 线程池初始化时即生成了制定数量的线程 std::thread,初始化完毕后进入idle状态。线程由std::condition_variable唤醒,从输入任务队列中pop出job然后执行job,Input Job Queue的保证了线程的执行顺序。若线程池所有线程处于忙碌状态,则暂时停止从任务队列中pop job,待有job执行完毕、线程ilde之后再行pop。


多个job虽然是按照既定顺序开始执行的,但不同job的执行时间不同,并不能保证按顺序完成job。对于scoreboard等对job反馈结果有严格顺序要求的情况,需按照顺序同步返回job执行结果。本文采用std::packaged_task返回值std::future来解决该问题。


 std::future具有按序立即返回的特性,因此可以在调用线程池时把std::future压入一个特殊队列,在scoreboard需获取新数据时检查std::future队列相关job是否完成并将其弹出,便于scoreboard区分其所需的data,也避免了早前丢出的多个任务抢同一个返回结果。




线程池集成到UVM TB


 为了实现model和UVM并排走,需要把线程池集成到原有的UVM环境中,需要对C model和UVM TB做响应调整。


C/C++的改动


 需要对原有的C/C++ 代码做点微调才能把线程池集成到UVM环境中,主要改动如下:


   添加std::future及其队列std::queue<std::future> futures


   添加predictor中调用的function predict_call()


   添加scoreboard中调用的scoreboard_call()


 示意代码如下:

//C++ Code
//Store futures in the order they are created for a particular task type
std::queue<std::future<int>> futures;
//Function that would have previously been called by the predictor
//Returns the expected result from a single integer input
int calc_result(int num)
{
    int result = 0;
    //Do complex math work or any other modelling here
    return result;
}
//New function called from the UVM Predictor
extern "C" void predict_call(const int num)
{
    thread_pool& tp = thread_pool::get_instance();
    //Queue the job on the thread_pool and store the std::future
    futures.emplace(tp.add_job(calc_result, num));
}
//New function called from the UVM Scoreboard
extern "C" int scoreboard_call()
{
    int num = futures.front().get();
    futures.pop();
    return num;
}



SV/UVM的改动


 之前的方式是在UVM中 predictor中DPI调用C/C++ model,等model执行完毕后通过 analysis fifo 把结果传递给scoreboard。为了实现C/C++ model与UVM TB的并行,UVM环境中原有model调用方式改为在predictor中调用model(丢job)然后立即退出,在scoreboard中调用model(丢job)收集job计算结果,不再通过analysis fifo收结果。


//Predictor
//DPI call to submit work to the thread pool
import "DPI-C" function void predict_call(input int num);
class my_predictor extends uvm_subscriber #(my_item);
    //Predictor code
    function void write(my_item item);
        predict_call(item.data);
    endfunction
endclass : my_predictor
//Scoreboard
//DPI call to retrieve the next predicted value
import "DPI-C" function int scoreboard_call();
class my_scoreboard #(type T = my_item) extends uvm_scoreboard;
    uvm_analysis_imp_received #(T, my_scoreboard) received_export;
    //Scoreboard code
    virtual function void write_received(T txn);
        int rx_data;
        int pred = scoreboard_call(); //Get predicted data
        rx_data = txn.data;
        if (rx_data != pred) begin
            `uvm_error("Scoreboard", "Failure")
        end
    endfunction
endclass : my_scoreboard




实验结果


  本文以不同predictor time和有无thread pool为变量做了几组对比试验,证明了本文所提出的方法的确能够加速仿真。predictor time越大,提升效果越明显。


17523377b7954846b19bb5f64759f732.png



讨论


  根据本文实验结果,该方法对于predictor time 2~20ms的仿真,提速效果为3~4x。对于1ms以内的仿真,提速效果并不明显。鉴于复杂度并不高,无论如何大家都可以试一下,学点新知识嘛。 😀

目录
相关文章
|
9月前
|
关系型数据库 MySQL 测试技术
【分享】AgileTC测试用例管理平台使用分享
AgileTC 是一个脑图样式测试用例管理平台,支持用例设计、执行与团队协作,帮助测试人员高效管理测试流程。
456 116
【分享】AgileTC测试用例管理平台使用分享
|
9月前
|
测试技术 开发者 Python
Python单元测试入门:3个核心断言方法,帮你快速定位代码bug
本文介绍Python单元测试基础,详解`unittest`框架中的三大核心断言方法:`assertEqual`验证值相等,`assertTrue`和`assertFalse`判断条件真假。通过实例演示其用法,帮助开发者自动化检测代码逻辑,提升测试效率与可靠性。
587 1
|
9月前
|
人工智能 数据可视化 测试技术
AI测试平台自动遍历:低代码也能玩转全链路测试
AI测试平台的自动遍历功能,通过低代码配置实现Web和App的自动化测试。用户只需提供入口链接或安装包及简单配置,即可自动完成页面结构识别、操作验证,并生成可视化报告,大幅提升测试效率,特别适用于高频迭代项目。
|
9月前
|
人工智能 测试技术 调度
写用例写到怀疑人生?AI 智能测试平台帮你一键生成!
霍格沃兹测试开发学社推出AI智能测试用例生成功能,结合需求文档一键生成高质量测试用例,大幅提升效率,减少重复劳动。支持自定义提示词、多文档分析与批量管理,助力测试人员高效完成测试设计,释放更多时间投入核心分析工作。平台已开放内测,欢迎体验!
|
9月前
|
人工智能 测试技术 项目管理
测试不再碎片化:AI智能体平台「项目资料套件」功能上线!
在实际项目中,需求文档分散、整理费时、测试遗漏等问题常困扰测试工作。霍格沃兹推出AI智能体测试平台全新功能——项目资料套件,可将多个关联文档打包管理,并一键生成测试用例,提升测试完整性与效率。支持套件创建、文档关联、编辑删除及用例生成,适用于复杂项目、版本迭代等场景,助力实现智能化测试协作,让测试更高效、更专业。
|
10月前
|
存储 人工智能 算法
AI测试平台实战:深入解析自动化评分和多模型对比评测
在AI技术迅猛发展的今天,测试工程师面临着如何高效评估大模型性能的全新挑战。本文将深入探讨AI测试平台中自动化评分与多模型对比评测的关键技术与实践方法,为测试工程师提供可落地的解决方案。
|
9月前
|
机器学习/深度学习 人工智能 自然语言处理
如何让AI更“聪明”?VLM模型的优化策略与测试方法全解析​
本文系统解析视觉语言模型(VLM)的核心机制、推理优化、评测方法与挑战。涵盖多模态对齐、KV Cache优化、性能测试及主流基准,助你全面掌握VLM技术前沿。建议点赞收藏,深入学习。
2939 8
|
9月前
|
存储 Oracle Java
|
9月前
|
人工智能 自然语言处理 测试技术
AI测试平台的用例管理实践:写得清晰,管得高效,执行更智能
在测试过程中,用例分散、步骤模糊、回归测试效率低等问题常困扰团队。霍格沃兹测试开发学社推出的AI测试平台,打通“用例编写—集中管理—智能执行”全流程,提升测试效率与覆盖率。平台支持标准化用例编写、统一管理操作及智能执行,助力测试团队高效协作,释放更多精力优化测试策略。目前平台已开放内测,欢迎试用体验!
|
10月前
|
存储 人工智能 文字识别
从零开始打造AI测试平台:文档解析与知识库构建详解
AI时代构建高效测试平台面临新挑战。本文聚焦AI问答系统知识库建设,重点解析文档解析关键环节,为测试工程师提供实用技术指导和测试方法论