SV学习笔记(六)

文章目录

  • 覆盖率类型
    • 写在前面
    • 代码覆盖率
    • 断言覆盖率
    • 功能覆盖率
    • 漏洞率曲线
  • 功能覆盖策略
    • 收集信息而非数据
    • 只测量需要的内容
    • 验证的完备性
  • 覆盖组
    • 写在前面
    • 在类里定义covergroup
  • 数据采样
    • 写在前面
    • coverpoint和bin
    • bin的创建和应用
    • 命名coverpoint和bin
    • 条件覆盖率
    • 翻转覆盖率
    • wildcard覆盖率
    • 忽略bin
    • 非法的bin
    • 交叉覆盖率
    • 排除部分cross bin
    • 指定精细的交叉覆盖率
  • 覆盖选项
    • 单个实例的覆盖率
    • 注释
    • 覆盖次数限定
    • 覆盖率目标
    • covergroup方法
  • 数据分析
  • 参考资料

覆盖率类型

写在前面

  • 覆盖率是 衡量设计验证完备性 的一个通用词。
  • 随着测试逐步覆盖各种合理的场景,仿真过程会慢慢勾画出你的设计情况。
  • 覆盖率工具会 在仿真过程中收集信息 ,然后进行后续处理并且得到覆盖率报告。
  • 通过这个报告找出覆盖之外的盲区,然后修改现有的测试或者创建新的测试来填补这些盲区。
  • 这个过程可以一直迭代进行,直到你对覆盖率满意为止。
    • 可以使用一个反馈回路来分析覆盖率的结果,并决定采取哪种行动来达到100%的覆盖率。
    • 首要的选择是使用更多的种子来运行现有的测试程序
    • 大量种子依然对于覆盖率增长没有帮助时,需要建立新的约束。
    • 只有在确实需要的时候才会求助于创建定向测试。

代码覆盖率

  • 不添加任何额外的HDL代码,工具会通过分析源代码和增加隐藏代码来自动完成代码覆盖率的统计。

  • 当运行完所有测试,代码覆盖率工具便会创建相应的数据库。

  • 仿真器都带有代码覆盖率的工具,覆盖率数据也可被转换为可读格式。

  • 行覆盖率:多少行代码已经被执行过。

  • 路径覆盖率:在穿过代码和表达式的路径中有哪些已经被执行过。

  • 翻转覆盖率:哪些单位比特变量的值为0或1。

  • 状态机覆盖率:状态机哪些状态和状态转换已经被访问过。

  • 代码覆盖率最终的结果用于衡量你执行了设计中的多少代码。

  • 关注点应该放在设计代码的分析上,而不是测试平台。

  • 未经测试的设计代码里可能隐藏硬件漏洞,也可能仅仅就是冗余的代码。

  • 代码覆盖率衡量的是测试对于硬件设计描述的”实现”究竟测试得有多彻底,而非针对验证计划。

  • 代码覆盖率达到了100%,并不意味着验证的工作已经完成,但代码覆盖率100%是验证工作完备性的必要条件。

断言覆盖率

  • 断言是用于一次性地或在一段时间对一个或者多个设计信号在逻辑或者时序上的声明性代码。
  • 断言可以跟随设计和测试平台一起仿真,也可以被形式验证工具所证实。
  • 你可以使用SV的程序性代码编写等效性检查, 但使用SVA(SV断言)来表达会更容易。
  • 断言最常用于查找错误,例如两个信号是否应该互斥,或者请求与许可信号之间的时序等。
  • 一旦检测到问题,仿真就可以立即停止。
  • 有些断言可以用于查找感兴趣的信号值或者设计状态。
  • 可以使用cover property来测量这些关心的信号值或者状态是否发生。
  • 在仿真结束时,仿真工具可以自动生成断言覆盖率数据。
  • 断言覆盖率数据以及其它覆盖率数据都会被集成在同一个覆盖率数据库中,verifier可以对其展开分析。

功能覆盖率

  • 验证的目的就是确保设计在实际环境中的行为正确。
  • 功能描述文档详细说明了设计应该如何运行,而验证计划则列出了相应的功能应该如何激励、验证和测量。
  • 当你收集测量数据希望找出那些功能已经被覆盖时,你其实就是在计算”设计”的覆盖率。
  • 功能覆盖率是和功能设计意图紧密相连的,有时也被称为”描述覆盖率”,而代码覆盖率则是衡量设计的实现情况。
  • 某个功能在设计中可以被遗漏,代码覆盖率不能发现这个错误,但是功能覆盖率可以。

  • 每一次仿真都会产生一个带有覆盖率信息的数据库,记录随机游走的轨迹。
  • 把这些信息全部合并在一起就可以得到功能覆盖率,从而衡量整体的进展程度。
  • 通过分析覆盖率数据可以决定如何修改回归测试集。
  • 如果覆盖率在稳步增长,那么添加新种子或者加长测试实际即可。
  • 如果覆盖率增速放缓,那么需要添加额外的约束来产生更多”有意思”的激励。
  • 如果覆盖率停止增长,然而设计某些测试点没有被覆盖到,那么就需要创建新的测试了。
  • 如果覆盖率为100%但依然有新的设计漏洞,那么覆盖率可能没有覆盖到设计中的某些设计功能区域。

漏洞率曲线

  • 在一个项目实施期间,你应该保持追踪每周有多少个漏洞被发现。
  • 一开始,当你创建测试程序时,通过观察可能就会发现很多漏洞。
  • 当设计逐渐稳定时,你需要利用自动化的检查方式来协助发现可能的漏洞。
  • 在设计临近流片时,漏洞率会下降,甚至有望为零。即便如此,验证工作仍然不能结束。
  • 每次漏洞率下降时,就应该寻找各种不同的办法去测试可能的边界情况(corner case)。
  • 漏洞率可能每周都有变化,这跟很多因素都有关。不过漏洞率如果出现意外的变化,可能预示着潜在的问题。

功能覆盖策略

收集信息而非数据

  • 比如MCDF, 你需要关心的是合法的寄存器地址和非法的寄存器地址,可写的寄存器域和非法的寄存器域,而不是具体的寄存器地址数值
  • 一旦关注的地方着眼于感兴趣的状态,而不是具体数值,那么这对于你如何定义功能覆盖率,以及如何收集信息会减轻很大的负担。
  • 设计信号如果数量范围太大,应该拆分为多个小范围再加上边界情况。

只测量需要的内容

  • Verifier需要懂得, 在使能覆盖率收集时, 这一特性会降低很大的仿真性能。
  • 由于收集功能覆盖率数据的开销很大,所以应该只测量你会用来分析并且改进测试的那部分数据。
  • 同时也需要设定合理的覆盖率采样的事件一方面提升采样效率,一方面也可以降低收集覆盖率的开销。

验证的完备性

  • 完备的覆盖率测量结果和漏洞增长曲线,可以帮助确认设计是否被完整地验证过。
  • 如果代码覆盖率低但功能覆盖率高,这说明验证计划不完整,测试没有执行设计的所有代码。
  • 如果代码覆盖率高但功能覆盖率低,这说明即使测试平台很好地执行了设计所有代码,但是测试还是没有把设计定位到所有感兴趣的状态上。
  • 你的目标是同时驱动高的代码覆盖率和功能覆盖率。

覆盖组

写在前面

  • 覆盖组(covergroup) 与类相似, 一次定义后便可以多次实例化。
  • covergroup可以包含一个或者多个coverpoint, 且全都在同一时间采集。
  • covergroup可以定义在类中,也可以定义在interface或者module中。
  • covergroup可以采样任何可见的变量,例如程序变量、接口信号或者设计端口。
  • 一个类里可以包含多个covergroup。
  • 当你拥有多个独立的covergroup时, 每个covergroup可以根据需要自行使能或者禁止。
  • 每个covergroup可以定义单独的触发采样事件,允许从多个源头收集数据。
  • covergroup必须被例化才可以用来收集数据。

在类里定义covergroup

class Transactor;
    Transaction tr;
    mailbox mbx_in;
    covergroup CovPort;
        coverpoint tr.port;
    endgroup

    function new(mailbox mbx_in) ;
        //CovPort = new() ;
        CovPort cg1 = new() ; //使用这种例化方式可以给对象设定名字
        this.mbx_in=mbx_in;
    endfunction

    task main;
        forever begin
            tr=mbx_in.get;
            ifc.cb.port <= tr.port;
            ifc.cb.data <= tr.data;
            CovPort.sample() ;
        end
    endtask
endclass

白话一刻

  • Transaction tr;:定义一个类型为Transaction的变量tr,用来存储事务对象。

  • mailbox mbx_in;:定义一个mailbox类型的变量mbx_in,通常用于在模拟环境中作为消息队列或通道。

  • covergroup CovPort;:定义一个覆盖组CovPort,用于收集覆盖信息,常用于验证测试中。

  • coverpoint tr.port;:在CovPort覆盖组内定义一个覆盖点,用于监控tr对象的port字段的取值情况。

    function new(mailbox mbx_in) ;这是Transactor类的构造函数,当创建Transactor对象时会被调用。

  • CovPort cg1 = new() ;:创建一个新的CovPort覆盖组实例,并命名为cg1

  • this.mbx_in=mbx_in;:将传递给构造函数的mbx_in参数赋值给类的成员变量mbx_in

  • tr=mbx_in.get;:从mbx_in邮箱中获取一个事务对象,并赋值给tr

  • ifc.cb.port <= tr.port;ifc.cb.data <= tr.data;:将tr对象中的portdata字段的值分别赋给ifc.cb(可能是一个接口或组件)的portdata字段。

  • CovPort.sample() ;:对覆盖组CovPort进行采样,以收集覆盖信息。

这个Transactor类主要用于从mailbox中接收事务对象,将事务对象的数据写入某个接口或组件,并收集相关的覆盖信息。

  • covergroup由采样的数据和数据被采样的事件构成。
  • 当这两个条件都准备好以后,测试平台便会触发covergroup。
  • 这个过程可以通过直接使用sample() 函数完成, 也可以在covergroup中采样阻塞表达式或者使用wait或@实现在信号或事件上的阻塞。
  • 如果你希望在代码中显式地触发covergroup采样, 或者不存在采样时刻的信号或事件, 又或者一个covergroup被例化为多个实例需要单独触发, 那么可以使用sample()方法。
  • 如果你想借助已有的事件或者信号触发covergroup, 可以在covergroup声明中使用阻塞语句。
event trans_ready;
covergroup CovPort @(trans_ready);
    coverpoint ifc.cb.port;
endgroup
  • 与直接调用sample() 相比, 使用事件触发的好处在于你能够借助已有的事件。

数据采样

写在前面

  • 当你在coverpoint指定采样一个变量或表达式时, SV会创建很多的”仓(bin) ”来记录每个数值被捕捉到的次数。
    这些bin是衡量功能覆盖率的基本单位。
  • covergroup中可以定义多个coverpoint, coverpoint中可以自定义多个cover bin或者SV帮助自动定义多个cover bin(建议自己定义,原因有两点:一是工具可能会多定义其他的bin,二是工具定义的bin不能很好的命名,基于这两点,自己定义bin在覆盖率分析时更容易)。
  • 每次covergroup采样, SV都会在一个或者多个cover bin中留下标记, 用来记录采样时变量的数值和匹配的cover bin。
  • 在仿真之后,可以使用分析工具读取这些数据库来生成覆盖率报告,包含了各部分和总体的覆盖率。

coverpoint和bin

  • 为了计算一个coverpoint上的覆盖率, 首先需要确定可能数值的个数,这也被称为域。
  • 覆盖率就是采样值的数目除以bin的数目。例如一个3比特变量的域是0:7, 正常情况下会自动分配8个bin。如果仿真过程中有7个值被采样到, 那么最终该coverpoint的覆盖率是7/8。
  • 所有的coverpoint的覆盖率最终构成一个covergroup的覆盖率。
  • 所有的covergroup的覆盖率构成了整体的功能覆盖率。

bin的创建和应用

  • SV会默认为某个cover point创建bin, 用户也可以自己定义bin的采样域。
  • 如果采样变量的域范围过大而又没有指定bin, 那么系统会默认分配64个bin, 将值域范围平均分配给这64个bin。
  • 用户可以通过covergroup的选项auto_bin_max来指定自动创建bin的最大数目(默认64)。
  • 实际操作中, 自动创建bin的方法不实用, 建议用户自行定义bin,或者减小auto_bin_max的数值。
covergroup CovPort;
    options.auto_bin_max=8; //所有cover point auto_bin数量=8
    coverpoint tr.port
        {options.auto_bin_maxm 2; } //特定cover point auto_bin数量=2
endgroup

命名coverpoint和bin

covergroup CovKind;
    coverpoint tr.kind{
        bins zero=(0) ; //1个仓代表kind==0
        bins lo=([1:3] , 5) ; //1个仓代表1:3和5
        bins hi[] =([8:S] 1; //8个独立的仓代表8:15
        bins misc=default; //1个仓代表剩余的所有值
    }//没有分号
endgroup
  • 注意coverpoint定义使用{} 而不是begin…end。大括号的结尾没有带分号, 这和end一样。

条件覆盖率

  • 可以使用关键词iff给coverpoint添加条件。
  • 这种做法常用于在复位期间关闭覆盖以忽略不合理的条件触发。
  • 也可以使用start和stop函数来控制covergroup各个独立实例。
covergroup CoverPort;
    coverpoint port iff (!bus_if.reset);
endgroup

//===========================================

initial begin
    CovPort ck = new();
    #1ns;
    ck.stop();
    bus_if.reset=1;
    #100ns bus_if.reset=0;
    ck.start();
    ck.sample();
end

翻转覆盖率

  • coverpoint也可以用来记录变量从A值到B值的跳转情况。
  • 还可以确定任何长度的翻转次数。
covergroup CoverPort;
    coverpoint port {
        bins t1 = (0=>1), (0=>2), (0=>3);
    }
endgroup

wildcard覆盖率

  • 可以使用关键字wildcard来创建多个状态或者翻转。
  • 在表达式中,任何x,z或者?都会被当成0或1的通配符。
bit [2:0] port;
covergroup CoverPort;
    coverpoint port{
        wildcard bins even={3'b??0};
        wildcard bins odd={3'b??1}
    }
endgroup

忽略bin

  • 在某些coverpoint可能始终无法得到全部的域值。
  • 对于那些不计算功能的域值可以使用ignore_bins来排除, 最终它们并不会计入coverpoint的覆盖率。
bit[2:0] low_ports_0_5; //只使用数值0-5
covergroup CoverPort;
    coverpoint low_ports_0_5 {
    ignore_bins hi={[6, 7]}; //忽略数值6-7
endgroup

非法的bin

  • 有些采样值不仅应该被忽略,而且如果出现还应该报错。
  • 这种情况可以在测试平台中监测, 也可以使用illegal_bins对特定的bin进行标示。
bit[2:0] low_ports_0_5; //只是用数值0-5
covergroup CoverPort;
    coverpoint low_ports_0_5{
        illegal_bins hi={[6, 7]}; //如果出现6-7便报错
    }
endgroup

交叉覆盖率

  • coverpoint是记录单个变量或者表达式的观测值。
  • 如果想记录在某一时刻,多个变量之间值的组合情况,需要使用交叉(cross) 覆盖率。
  • cross语句只允许带coverpoint或者简单的变量名。
class Transaction;
    rand bit[3:0] kind;
    rand bit[2:0] port;
endclass

Transaction tr;
covergroup CovPort;
    kind: coverpoint tr.kind; //kind是coverpoint名称
    port: coverpoint tr.port; //port是coverpoint名称
    cross kind, port;
endgroup

排除部分cross bin

  • 通过使用ignore bins、binsof和intersect分别指定coverpoint和值域, 这样可以清除很多不关心的cross bin。
covergroup Covport;
    port: coverpoint tr.port {
        bins port[] = {[O:$]};
    }

    kind: coverpoint tr.kind {
        bins zero = {0};
        bins lo   = {[1:3]};
        bins hi[] = {[8:$]};
        bins misc = default;
    }

    cross kind, port {
        ignore_bins hi = binsof(port) intersect {7};
        ignore_bins md = binsof(port) intersect {0} &&
                         binsof(kind) intersect {[9:11]};
        ignore_bins lo = binsof(kind.lo);
    }
endgroup
  • 原来port有8个bin,kind有11个bin,正常cross会产生88个bin,通过ignore_bins,hi排除了11个,md排除了3个,lo排除了24个。具体自行分析。

指定精细的交叉覆盖率

  • 随着cross覆盖率越来越精细, 可能需要花费不少的时间来指定哪些bin应该被使用或者被忽略。
  • 更适合的方式是不使用自动分配的cross bin, 而自己声明感兴趣的cross bin。
  • 假如有两个随机变量a和b,它们带着三种感兴趣的状态,(a0,b0)、(a1、b0)和(b==1)。
class Transaction;
    rand bit a, b;
endclass

covergroup CrossBinNames;
    a: coverpoint tr.a {
        bins a0 = {0};
        bins a1 = {1};
        option.weight=0; } //不计算覆盖率
    b: coverpoint tr.b {
        bins b0 = {0};
        bins b1 = {1};
        option.weight=0; } //不计算覆盖率
    ab: cross a, b {
        bins aOb0 = binsof(a.a0) && binsof(b.b0);
        bins a1b0 = binsof(a.a1) && binsof(b.b0);
        bins b1   = binsof(b.bl);}
endgroup
class Transaction;
    rand bit a, b;
endclass

covergroup CrossBinsofIntersect;
    a: coverpoint tr.a {
        option.weight=0; } //Do nOt count this cover point
    b: coverpoint tr.b {
        option.weight=0; } //Do nOt count this cover point
    ab: cross a, b {
        bins aOb0 = binsof(a) intersect{O} && binsof(b) intersect{O};
        bins alb0 = binsof(a) intersect{1} && binsof(b) intersect{O};
        bins b1 = binsof(b) intersect{1}; }
endgroup

覆盖选项

单个实例的覆盖率

  • 如果对一个covergroup例化多次, **那么默认情况下SV会将所有实例的覆盖率合并到一起。**如果需要单独列出每个covergroup实例的覆盖率,需要设置覆盖选项。
covergroup CoverLength;
    coverpoint tr.length;
    option.per_instance=l; //每个实例单独收集
endgroup

注释

  • 如果有多个covergroup实例, **可以通过参数来对每一个实例传入单独的注释。**这些注释最终会显示在覆盖率数据的总结报告中。
covergroup CoverPort(int lo, hi, string comment);
    option.comment = comment;
    option.per_instance = 1;
    coverpoint port {
        bins range= {[lo:hi]};
    }
endgroup

...

CoverPort cp_lo = new(0, 3, "Low port numbers");
CoverPort cp_hi = new(4, 7, "High port numbers" ;

覆盖次数限定

  • 默认情况下, 数值采样了1次就可以计入有效的bin。可以通过修改atleast来修改每个bin的数值最少的采样次数, 如果低于at_least数值, 则不会被计入bin中。
  • option.at_least可以在covergroup中声明来影响所有的coverpoint,也可以在coverpoint中声明来只影响该coverpoint下所有的bin。
  • 一般会使用默认的1,除非有特殊要求。

覆盖率目标

  • 一个covergroup或者一个coverpoint的目标是100%覆盖率。
  • 不过你也可以将其设置为低于100%的目标。这个选项只会影响覆盖率报告。
  • 一般会使用默认的100,除非有特殊要求。
covergroup CoverPort;
    coverpoint port;
    option.goal=90;
endgroup

covergroup方法

  • sample() : 采样。
  • get_coverage() /get_inst_coverage() : 获取覆盖率,返回0-100的real数值。
  • set_inst_name(string) : 设置cover group的名称。
  • start() /stop() : 使能或者关闭覆盖率的收集。

数据分析

  • 使用$get_coverage() 可以得到总体的覆盖率。
  • 也可以使用covergroup_inst.get_inst_coverage() 来获取单个covergroup实例的覆盖率。
  • 这些函数最实际的用处是在一个测试当中监测覆盖率的变化。
  • 如果覆盖率水平在一段时间之后没有提高,那么这个测试就应该停止。
  • 重启新的随机种子或者测试可能有望提高覆盖率。
  • 如果测试可以基于功能覆盖率采取一些深入的行动,例如重新限定随机的约束,那将是一件非常好的事情,但是这种测试很难编写。

参考资料

  • Wenhui’s Rotten Pen
  • SystemVerilog
  • chipverify

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

k8s svc流量转发

https://blog.csdn.net/qq_44930876/article/details/134813129 https://blog.csdn.net/weixin_43845924/article/details/136232099 默认使用iptables [rootlocalhost ~]# k logs kube-proxy-jcbcq I0405 10:37:28.610683 1 node.go:136] Successfully retrieved no…

NzN的数据结构--实现双向链表

上一章中&#xff0c;我们学习了链表中的单链表&#xff0c;那今天我们来学习另一种比较常见的链表--双向链表&#xff01;&#xff01; 目录 一、双向链表的结构 二、 双向链表的实现 1. 双向链表的初始化和销毁 2. 双向链表的打印 3. 双向链表的头插/尾插 4. 双向链表的…

[蓝桥杯 2019 国 C] 数正方形

[蓝桥杯 2019 国 C] 数正方形 题目描述 在一个 N N N \times N NN 的点阵上&#xff0c;取其中 4 4 4 个点恰好组成一个正方形的 4 4 4 个顶点&#xff0c;一共有多少种不同的取法&#xff1f; 由于结果可能非常大&#xff0c;你只需要输出模 1 0 9 7 10^9 7 1097 的…

八股面试速成—计算机网络部分

暑期实习面试在即&#xff0c;这几天八股和算法轮扁我>_ 八股部分打算先找学习视屏跟着画下思维导图&#xff0c;然后看详细的面试知识点&#xff0c;最后刷题 其中导图包含的是常考的题&#xff0c;按照思维导图形式整理&#xff0c;会在复盘后更新 细节研究侧重补全&a…

基于单片机钢琴电子节拍器系统设计

**单片机设计介绍&#xff0c;基于单片机钢琴电子节拍器系统设计 文章目录 一 概要二、功能设计三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机钢琴电子节拍器系统设计是一个综合性的项目&#xff0c;它结合了单片机编程、音频处理、用户界面设计等多个领域的…

SQL 中除了写 in 和 not in外,其他写法

一、WHY&#xff1f; IN 和 NOT IN 是比较常用的关键字&#xff0c;为什么要尽量避免呢&#xff1f; 1、效率低 项目中遇到这么个情况&#xff1a; t1表 和 t2表 都是150w条数据&#xff0c;600M的样子&#xff0c;都不算大。 但是这样一句查询 ↓ select * from t1 whe…

[leetcode] 25. K 个一组翻转链表

给你链表的头节点 head &#xff0c;每 k 个节点一组进行翻转&#xff0c;请你返回修改后的链表。 k 是一个正整数&#xff0c;它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍&#xff0c;那么请将最后剩余的节点保持原有顺序。 你不能只是单纯的改变节点内部的值…

SDKMAN多版本SDK并行管理工具

一、简介 SDKMAN是管理多个SDK并行版本的工具&#xff0c;它提供了方便的命令行界面&#xff08;CLI&#xff09;和API&#xff0c;用于列出&#xff0c;安装&#xff0c;切换和删除候选对象。此外&#xff0c;它还为我们设置了环境变量。 它还允许开发人员安装基于JVM的SDK&…

c++的学习之路:13、vector(2)

本章主要是模拟实现vector&#xff0c;文章末附上代码&#xff0c;和源码。 目录 一、STL源码 二、构造与析构 三、迭代器与【】、size、capacity、empty 四、reserve与resize 五、push_back与pop_back 六、insert与erase 七、测试 1 八、代码 九、思维导图 一、STL源…

【leetcode面试经典150题】16.接雨水(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

Web 前端性能优化之六:构建优化

5、渲染优化 如果把浏览器呈现页面的整个过程一分为二&#xff0c;前面章节所讨论的诸如图像资源优化、加载优化&#xff0c;以及构建中如何压缩资源大小等&#xff0c;都可视为浏览器为呈现页面请求所需资源的部分&#xff1b;本章将主要关注浏览器获取到资源后&#xff0c;进…

高等数学基础篇(数二)之二重积分

二重积分&#xff1a; 一、二重积分的概念及性质 1.二重积分的概念 2.二重积分的性质 二、二重积分的计算 1.利用直角坐标计算 2.利用极坐标计算 3.利用函数的奇偶性计算 4.利用变量的轮换对称性计算 目录 一、二重积分的概念及性质 1.二重积分的概念 2.二重积分的性…

Linux 常用指令及其理论知识

个人主页&#xff1a;仍有未知等待探索-CSDN博客 专题分栏&#xff1a;http://t.csdnimg.cn/Tvyou 欢迎各位指教&#xff01;&#xff01;&#xff01; 目录 一、理论知识 二、基础指令 1、ls指令&#xff08;列出该目录下的所有子目录和文件&#xff09; 语法&#xff1a; …

学习vue3第十四节 Teleport 内置组件介绍

<Teleport></Teleport> 作用目的&#xff1a; 用于将指定的组件或者元素传送到指定的位置&#xff1b; 通常是自定义的全局通用弹窗&#xff0c;绑定到 body 上&#xff0c;而不是在当前元素上面&#xff1b; 使用方法&#xff1a; 接收两个参数 to: 要将目标传…

刷题日记——机试(1)

1. 字母排序 分析——不排序解题 创建一个大小为128的数组sheet&#xff0c;序号表示ascii码强转为int表示的数值&#xff0c;对应的数组值表示该ascii码在输入字符串中出现的次数设置一个max变量和id变量&#xff0c;max初值为0&#xff0c;从下标为((int)‘A’)开始遍历shee…

考研数学|汤家凤《1800》题太多!怎么刷效果最好?

考研数学三的备考过程中&#xff0c;汤家凤1800题是很多考生选择的一本重要的习题集。它包含了大量的题目&#xff0c;难度覆盖了从基础到提高&#xff0c;甚至有一些题目的难度会超过实际考试的平均水平&#xff0c;目的是为了帮助考生全面提升解题能力&#xff0c;尤其是在应…

Golang | Leetcode Golang题解之第11题盛最多水的容器

题目&#xff1a; 题解&#xff1a; func maxArea(height []int) int {res : 0L : 0R : len(height) - 1for L < R {tmp : math.Min(float64(height[L]), float64(height[R]))res int(math.Max(float64(res), tmp * float64((R - L))))if height[L] < height[R] {L} el…

代码+视频,手动绘制logistic回归预测模型校准曲线(Calibration curve)(2)

校准曲线图表示的是预测值和实际值的差距&#xff0c;作为预测模型的重要部分&#xff0c;目前很多函数能绘制校准曲线。 一般分为两种&#xff0c;一种是通过Hosmer-Lemeshow检验&#xff0c;把P值分为10等分&#xff0c;求出每等分的预测值和实际值的差距 另外一种是calibrat…

扫描电镜如何能拍到样品的好的形貌?

扫描电镜是表征材料微观形貌的有力工具&#xff0c;它能够呈现样品的精细结构。然而&#xff0c;要拍摄出高质量的样品形貌并非易事&#xff0c;除了要熟悉扫描电镜的各种功能&#xff0c;还需要掌握一些技巧。本文将介绍如何利用景深、倾斜校正、动态聚焦等功能以及合轴和消像…

Day30 线程安全之窗口售票问题(含代码)

Day30 线程安全之窗口售票问题&#xff08;含代码&#xff09; 一、需求&#xff1a; 铁道部发布了一个售票任务&#xff0c;要求销售1000张票&#xff0c;要求有3个窗口来进行销售&#xff0c; 请编写多线程程序来模拟这个效果&#xff08; 注意&#xff1a;使用线程类的方式…