SV学习笔记(六)

news2024/11/20 23:24:48

覆盖率类型

写在前面

  • 覆盖率是 衡量设计验证完备性 的一个通用词。
  • 随着测试逐步覆盖各种合理的场景,仿真过程会慢慢勾画出你的设计情况。
  • 覆盖率工具会 在仿真过程中收集信息 ,然后进行后续处理并且得到覆盖率报告。
  • 通过这个报告找出覆盖之外的盲区,然后修改现有的测试或者创建新的测试来填补这些盲区。
  • 这个过程可以一直迭代进行,直到你对覆盖率满意为止。
    • 可以使用一个反馈回路来分析覆盖率的结果,并决定采取哪种行动来达到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

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

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

相关文章

设计模式——原型模式05

原型模式核心复制&#xff0c;每次new出来的对象完全不一样&#xff0c;实现对象之间的隔离。 学习前最好先掌握jAVA值传递和深浅拷贝 设计模式&#xff0c;一定要敲代码理解 浅拷贝 克隆出对象&#xff0c;其中两者的引用类型属性是同一个对象。 对象信息 /*** author ggb…

C++:逻辑运算符-非与或(19)

!非!a如果a为假&#xff0c;那么当前他就是真&#xff0c;如果a是真&#xff0c;那么他直接就是假&&与a&&ba与b都为真&#xff0c;那么就是真&#xff0c;如果两个里面有一个为假那么就是假||或a||ba或b有一个为真&#xff0c;那么就是真 非&#xff08;!&…

怎样把学浪购买的课程下载下来

如何把学浪已购买的课程下载下来?这里就教大家一个方法,利用一个工具轻轻松松把视频下载下来 这个工具我打包成压缩包了,有需要的自己取一下 链接&#xff1a;https://pan.baidu.com/s/1y7vcqILToULrYApxfEzj_Q?pwdkqvj 提取码&#xff1a;kqvj --来自百度网盘超级会员V1…

基于springboot+vue+Mysql的在线考试系统

开发语言&#xff1a;Java框架&#xff1a;springbootJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包&#xff1a;…

redis集合Set

set是一种无序集合。它和列表的区别在于列表中的元素都是可以重复的&#xff0c;而set中的元素是不能重复的。而且set中的元素&#xff0c;并不像列表那样是具有顺序的。 SADD是添加一个元素。course是集合。 SMEMBERS SISMEMBER判断Redis在不在集合course里 SREM是用来删除Re…

Jupyter Notebook安装使用(一)

1. 简介 Jupyter Notebook 是一个非常强大的工具&#xff0c;它允许用户创建和共享包含实时代码、方程式、可视化和叙事文本的文档。这种工具特别适合数据清理和转换、数值模拟、统计建模、数据可视化、机器学习等多种应用领域。 2. 安装Jupyter Notebook 2.1. 使用 Anaconda…

校招说明书

3400字的详细说明&#xff0c;介绍了程序员类岗位校招的整体时间节点和招聘流程。还对一些常见的问题进行讨论&#xff0c;例如内推、offer和三方、实习等。 第一章介绍基本的术语&#xff0c;第二章介绍整个校招的重要流程及时间点&#xff0c;然后第三章介绍每次招聘要经过的…

golang 和java对比的优劣势

Golang&#xff08;或称Go&#xff09;和Java都是非常流行的编程语言&#xff0c;被广泛应用于各种领域的软件开发。尽管它们都是高级编程语言&#xff0c;但它们具有许多不同的特性和适用场景。本文将重点比较Golang和Java&#xff0c;探讨它们的优势和劣势。 性能方面&#…

JSP

文章目录 JSP1. 快速入门2. page 指令3. 三种常用脚本声明脚本表达式脚本代码脚本 4. 注释5. 内置对象6. 域对象7. 请求转发标签8. EL 表达式快速入门EL运算操作EL的11个隐含对象四个特定域变量 9. JSTL快速入门<c:set /><c:if />\<c:choose> \<c:when>…

【微服务】------核心组件架构选型

1.微服务简介 微服务架构&#xff08;Microservice Architecture&#xff09;是一种架构概念&#xff0c;旨在通过将功能分解到各个离散的服务中以实现对解决方案的解耦&#xff0c;从而降低系统的耦合性&#xff0c;并提供更加灵活的服务支持。 2.微服务技术选型 区域内容…

爬虫学习第一天

爬虫-1 爬虫学习第一天1、什么是爬虫2、爬虫的工作原理3、爬虫核心4、爬虫的合法性5、爬虫框架6、爬虫的挑战7、难点8、反爬手段8.1、Robots协议8.2、检查 User-Agent8.3、ip限制8.4、SESSION访问限制8.5、验证码8.6、数据动态加载8.7、数据加密-使用加密算法 9、用python学习爬…

汽车疲劳测试试验平台技术要求(北重厂家)

汽车疲劳测试试验平台技术要求通常包括以下几个方面&#xff1a; 车辆加载能力&#xff1a;测试平台需要具备足够的承载能力&#xff0c;能够同时测试多种车型和不同重量的车辆。 动力系统&#xff1a;测试平台需要具备稳定可靠的动力系统&#xff0c;能够提供足够的力和速度来…

C++ 指针与数组

指针与数组名都是地址&#xff0c;可以混合使用访问数组元素。 用指针访问数组&#xff0c;计算数组元素之和。 总结 如图所示&#xff0c;获取数组起始地址的方法有两种&#xff0c; 其一为数组名&#xff0c; 其二为通过数组的首元素地址。指针变量p是通过数组名获得指向…

通用开发技能系列:SQL基础学习

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 通用开发技能系列 文章&#xff0c;主要对编程通用技能 SQL基础 进行学习 1.数据库简介 1.1.数据库中的一些名称 DataBase&#xff1a;数据库 程序员只负责怎么维护存取数据&#xff0c;不管数据库是什么 DBA…

Deep Unsupervised Learning using Nonequilibrium Thermodynamics

就直接从算法部分开始了&#xff1a; 2 算法 我们的目标是定义一个前向&#xff08;或者推理&#xff09;扩散过程&#xff0c;这个过程能够转换任意的复杂数据分部到一个简单、tractable、分布&#xff0c;并且学习有限时间扩散过程的反转 从而 定义我们的生成模型分布。我们…

“人性化设计”技术概要

本文是由《埃森哲技术愿景 2024&#xff1a;“人性化设计”技术将通过提高生产力和创造力来重塑行业并重新定义领导者》这个文章来翻译解读的。原文地址如下&#xff0c;大家可以自行下载&#xff1a; 下载地址 其实看到这篇文章的时候&#xff0c;联想到这些年机器人的市场发展…

使用 HTMX 和 Bun 进行全栈 Web 开发

将 HTMX 放在前端&#xff0c;Bun 放在后端&#xff0c;然后将它们与 Elysia 和 MongoDB 连接起来&#xff0c;形成快速便捷的技术栈&#xff0c;使开发 Web 应用程序变得轻而易举。 Bun 和 HTMX 是目前软件领域最有趣的两个事情。 Bun 是一个速度极快的一体化服务器端 JavaSc…

SpringBoot快速入门笔记(3)

文章目录 一、MybatisPlus1、ORM2、添加依赖3、全局配置4、Navicat5、UserController6、CRUD操作7、BaseMapper8、两个注解 二、多表查询1、模拟用户订单2、通过用户查相关订单3、UserMapperNew4、查询订单和所属用户5、OrderMapper6、OrderController 三、条件查询四、分页查询…

爬虫 新闻网站 并存储到CSV文件 以红网为例 V2.0 (控制台版)升级自定义查询关键词、时间段,详细注释

爬虫&#xff1a;红网网站&#xff0c; 获取指定关键词与指定时间范围内的新闻&#xff0c;并存储到CSV文件 V2.0&#xff08;控制台版&#xff09; 爬取目的&#xff1a;为了获取某一地区更全面的在红网已发布的宣传新闻稿&#xff0c;同时也让自己的工作更便捷 对比V1.0升级的…

瑞吉外卖实战学习--14、菜品上传

添加菜品接口 前言效果图1、菜品分类查询接口2、上传图片和下载图片3、创建接收数据的Dto4、创建提交的方法 前言 本项目gitee位置&#xff1a;gitee网址 本篇文章是学习了添加菜品的总结&#xff0c;其中包括菜品分类的接口&#xff0c;图片上传接口&#xff0c;数据整体上传…