【IC验证面试常问问题-2】

IC验证面试常问问题

  • 1 SV基础语法类
    • 1.1 Task和Function的区别
    • 1.2 OOP的特性
    • 1.3 在TB中使用interface和clocking blocking的好处
    • 1.4 SV中ref参数传递--引用
    • 1.5 SV类中的this是什么?super是什么?

【博客首发与微信公众号《漫谈芯片与编程》,欢迎专注一下】
本篇博客继续介绍IC验证常问问题;

1 SV基础语法类

1.1 Task和Function的区别

task和function都是用来封装代码块,来定义可重用的代码块;
task:用于定义一个可重用一系列操作的代码块,可能需要耗费时间;
1.可以包含延迟、事件触发和其他复杂的控制结构;
2.可以有输入参数和输出参数,也可以没有参数;
3.可以调用其他task或function.
function:用于定义一个可以执行一系列操作并返回一个值的代码块。不耗时间;
1.通常用于执行一些计算或逻辑操作,并返回结果;
2.可以有输入参数,但不能有输出参数;
3.可以调用其他function,但不能调用task;

// 定义一个 function,返回两个整数的和
function int add(int a, int b);return a + b;
endfunction// 定义一个 task,打印两个整数的和,并等待一段时间
task print_sum_and_wait(int a, int b);#10;  // 等待 10 时间单位$display("The sum is: %0d", a + b);  // 打印结果
endtaskmodule tb;initial beginint result;result = add(5, ¾);  // 调用 function 并将结果赋值给 result$display("The sum is: %0d", result);  // 输出结果print_sum_and_wait(5, ¾);  // 调用 task$display("After the task");  // 这条语句会在 task 执行完毕后执行end
endmodule

1.2 OOP的特性

面向对象编程(Object-Oriented Programming, OOP)是一种编程范式,它通过“对象”来组织代码,这些对象是数据和对这些数据执行操作的封装。OOP 的核心思想是将现实世界中的实体抽象成程序中的对象,从而提高代码的复用性、模块化和可维护性。这些对象是类的实例,类定义了对象的属性(数据)和行为(方法)。
1.封装:将数据(属性)和操作这些数据的方法(行为)捆绑在一起,形成一个独立的实体(对象)。这样可以隐藏对象的内部实现细节,只通过对象提供的方法来访问和修改数据,提高了代码的安全性和可维护性。
实现机制支持:在SV中提供了class类的封装机制;类的属性和方法可以设置为 public、protected 或 local,从而控制其访问级别。

class Counter;local int count;  // 局部变量,外部不可访问function new(int init_value);count = init_value;endfunctionfunction void increment();count++;endfunctionfunction int get_count();return count;endfunction
endclass

2.继承:允许一个类(子类)继承另一个类(父类)的属性和方法。这样可以重用代码,减少重复,并且可以构建类的层次结构,使得代码更加清晰和易于理解。派生类可以添加新的属性和方法,或者重写基类的方法。
实现机制支持:使用 extends 关键字来实现继承;

class Animal;virtual function void make_sound();$display("Some generic sound");endfunction
endclassclass Dog extends Animal;function void make_sound();$display("Woof woof!");endfunction
endclassmodule tb;initial beginAnimal a = new();Dog d = new();a.make_sound();  // 输出 "Some generic sound"d.make_sound();  // 输出 "Woof woof!"end
endmodule

3.多态:同一个方法调用可以有不同的行为实现,允许不同类的对象通过相同的接口调用;这通常通过继承和接口实现来完成,具体是方法重载(overloading)和方法重写(overriding)来实现。多态使得代码更加灵活,可以根据对象的实际类型来执行不同的操作。
实现机制支持:在 SystemVerilog 中,多态通过虚方法(virtual method)和动态绑定(dynamic binding)来实现;

class Shape;virtual function real area();return 0.0;endfunction
endclassclass Circle extends Shape;real radius;function new(real r);radius = r;endfunctionfunction real area();return 3.14 * radius * radius;endfunction
endclassclass Rectangle extends Shape;real width, height;function new(real w, real h);width = w;height = h;endfunctionfunction real area();return width * height;endfunction
endclassmodule tb;initial beginShape s1 = new();Shape s2 = new Circle(5.0);Shape s3 = new Rectangle(4.0, 6.0);$display("Area of shape 1: %f", s1.area());  // 输出 0.0$display("Area of shape 2: %f", s2.area());  // 输出 78.500000$display("Area of shape 3: %f", s3.area());  // 输出 24.000000end
endmodule

4.抽象:忽略对象的复杂细节,只关注其基本特征和功能。抽象类和接口是实现抽象的两种方式,它们定义了一组方法的签名,但不提供具体实现,由子类或实现类来提供具体实现。
实现机制支持:在SV中,使用纯虚方法(pure virtual method)来实现抽象。

virtual class Shape;pure virtual function real area();
endclassclass Circle extends Shape;real radius;function new(real r);radius = r;endfunctionfunction real area();return 3.14 * radius * radius;endfunction
endclassclass Rectangle extends Shape;real width, height;function new(real w, real h);width = w;height = h;endfunctionfunction real area();return width * height;endfunction
endclassmodule tb;initial beginShape s1 = new Circle(5.0);Shape s2 = new Rectangle(4.0, 6.0);$display("Area of shape ¼: %f", s1.area());  // 输出 78.500000$display("Area of shape 2: %f", s2.area());  // 输出 24.000000end
endmodule

总结:
封装:将数据和操作数据的方法绑定在一起,隐藏内部实现细节。
继承:创建新类时继承现有类的属性和方法,提高代码复用性。
多态:不同类的对象通过相同的接口调用,表现出不同的行为,提高代码灵活性。
抽象:从具体实例中提取共同特征和行为,形成抽象概念,提高代码的可读性和可维护性。

1.3 在TB中使用interface和clocking blocking的好处

  • Interface提供了一种模块化的方式来定义信号和它们的行为。这使得TB的设计更加模块化,易于维护和重用;
  • Clocking blocking是interface的一个特性,它允许在时钟边沿同步地驱动和采样信号,这有助于确保信号的时序正确性。避免TB与 DUT的接口竞争,减少我们由于信号竞争导致的错误。采样提前,驱动落后,保证信号不会出现竞争。
    接口既可以在硬件世界(module)中使用,又可以在软件世界(class)中使用,interface作为SV中唯—的硬件和软件环境的媒介交互,解耦了硬件与软件;接口由于可以例化的特性, 使得对于多组相同的总线, 在例化和使用时变得更加灵活,不仅使得代码变得简洁, 也更易于验证环境的管理和维护。
interface my_interface(input logic clk, input logic rst_n);logic [7:0] data;logic valid;// 时钟块clocking cb @(posedge clk);output data, valid;endclocking// 时序断言property data_valid;@(posedge clk) disable iff (!rst_n) valid |-> data inside {8'h00, 8'hFF};endpropertyassert property (data_valid) else $error("Data valid assertion failed");endinterfacemodule tb;logic clk, rst_n;my_interface intf(clk, rst_n);// 时钟生成always #5 clk = ~clk;initial beginclk = 0;rst_n = 0;#10 rst_n = 1;// 使用时钟块驱动信号intf.cb.data <= ˜h55;intf.cb.valid <= 1;@(posedge clk);intf.cb.data <= ˜hAA;intf.cb.valid <= 0;@(posedge clk);$finish;end
endmodule

1.4 SV中ref参数传递–引用

ref参数传递:是一种将参数作为引用传递给函数或任务的方式。这意味着函数或任务内部对参数的修改会反映到函数或任务外部的原始变量上–操作同一块内存;
主要好处有:
1.修改原始数据:使用ref参数传递,函数或任务可以修改传入的参数值,如果不希望子程序改变数组的值,可以使用const ref类型。
2.减少内存使用:ref参数传递避免了复制大型数据结构的需要,因为参数是通过引用传递的,而不是通过值传递的。这可以减少内存使用和提高性能。
3.简化代码:避免返回值处理和额外的变量声明;

typedef struct {int id;string name;
} person;module tb;initial beginperson p;p.id = 1;p.name = "Alice";$display("Before: ID = %0d, Name = %s", p.id, p.name);modify_person(p);$display("After: ID = %0d, Name = %s", p.id, p.name);end// 使用 ref 参数修改结构体成员function void modify_person(ref person p);p.id = 2;p.name = "Bob";endfunction
endmodule

1.5 SV类中的this是什么?super是什么?

this:这个指针指向当前类的实例。它允许你在类的方法内部引用当前实例的成员,包括变量和方法。使用this可以避免在类的内部方法中对成员的引用产生歧义,特别是当方法的参数或局部变量与类的成员具有相同的名称时。

super:这个指针指向当前类的父类实例。它允许你在子类中调用父类的方法或访问父类的成员。使用super可以确保在子类中调用的是父类的方法,而不是子类中同名的方法。这在实现继承和方法重写时非常有用。

class Animal;string type;// 构造函数function new(string t);type = t;endfunction// 方法function void display();$display("Name: %s, Age: %0d", this.name, this.age);endfunction// 方法virtual function void make_sound();$display("Some generic sound");endfunction
endclassclass Dog extends Animal;// 构造函数function new(string t);super.new(t);  // 调用父类的构造函数endfunction// 重写父类的方法function void make_sound();super.make_sound();  // 调用父类的方法$display("Woof woof!");endfunction
endclassmodule tb;initial beginDog d = new("Canine");d.make_sound();  // 输出: Some generic sound//       Woof woof!end
endmodule

语法类除了文字介绍外,看示例代码帮助理解;
【REF】
1.https://blog.csdn.net/graymount/article/details/121391722
2.https://www.nowcoder.com/discuss/445245619951734784

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

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

相关文章

Linux系列-进程的属性

&#x1f308;个人主页&#xff1a;羽晨同学 &#x1f4ab;个人格言:“成为自己未来的主人~” 我们上一篇文章当中讲到了进程的概念&#xff0c;我们知道进程信息是放到一个tast_struct的结构体当中的&#xff0c;这个结构体也叫做PCB。 PCB是内存级的操作&#xff0c;我们…

PLC单键启停控制的多种写法

题目&#xff1a;编写程序&#xff0c;实现当按下SB1按钮奇数次&#xff0c;灯亮&#xff1b;当按下SB1按钮偶数次&#xff0c;灯灭&#xff0c;即单键启停控制&#xff0c;设计梯形图。 解法一&#xff1a;使用标志位进行自锁互锁 &#xff08;1&#xff09;刚上电&#xff0c…

PH热榜 | 2024-11-06

DevNow 是一个精简的开源技术博客项目模版&#xff0c;支持 Vercel 一键部署&#xff0c;支持评论、搜索等功能&#xff0c;欢迎大家体验。 Github&#xff1a;https://github.com/LaughingZhu/DevNow 1. MindOne Builder 标语&#xff1a;这是一个“设计优先”的应用构建工具…

11.6 校内模拟赛总结

打的很顺的一场 复盘 7:40 开题&#xff0c;看到题目名很interesting T1 看起来很典&#xff0c;中位数显然考虑二分&#xff0c;然后就是最大子段和&#xff1b;T2 构造&#xff1f;一看数据范围这么小&#xff0c;感觉不是很难做&#xff1b;T3 神秘数据结构&#xff1b;T…

SpringBoot健康监控

文章目录 1_监控-健康监控服务2_监控-Admin可视化3_使用介绍 1_监控-健康监控服务 目的&#xff1a;能够理解健康监控actuator的作用 讲解&#xff1a; 每一个微服务在云上部署以后&#xff0c;我们都需要对其进行监控、追踪、审计、控制等。SpringBoot就抽取了Actuator场景…

时间序列算法---ARIMA

时间序列其他相关参考文章&#xff1a; 时间序列分类任务—tsfresh库 时间序列预测—Prophet python时间序列处理 有季节效应的非平稳序列分析   现代时间序列分析方法主要有两个不同的方向&#xff1a;一个方向是由外向内的分析视角产生的方法是与确定性因素分解相关的方法&…

Java内存模型

Java内存模型 JMM即java memory model,它定义了主存、工作内存抽象概念,底层对应着CPU寄存器、缓存、硬件内存、CPU指令优化等。 JMM体现在以下几个方面 原子性 - 保证指令不受到线程上下文切换的影响(之前的synchornized原理文章有介绍过) 可见性 - 保证指令不会受CPU缓…

软考高级架构 - 8.2 - 系统架构评估 - 超详细讲解+精简总结

8.2-系统架构评估 系统架构评估就是对系统架构的质量进行分析&#xff0c;以便帮助设计者作出架构决策&#xff0c;确保系统能够符合需求。评估方法大致分为三种&#xff1a; 基于问卷或检查表&#xff1a;通过设计好的问卷或清单&#xff0c;收集开发人员和相关人员的…

【LLM】Generative Agents和代码实践

note Generative Agents是2023年斯坦福提出的agent小镇&#xff0c;通过memory->reflection->planning的框架提高NPC的行为目标性&#xff0c;给游戏NPC的灵活设计带来了可能。Generative Agents是一种多智能体交互的框架&#xff0c;它模拟现实中的人类行为。这些Agent…

K. Farm Management 【CCPC2024哈尔滨站】

K. Farm Management 思路: 很容易想到的策略&#xff1a; 给每个作物都安排最短的时长 l l l&#xff0c;剩下的时间作为可支配时间。选择删除收益最高的作物&#xff0c;然后将尽可能多的可支配时间用于这个作物。或者选择删除收益低时间还长的作物&#xff0c;然后将时间解…

智能 ODN 系统研究与设计

智能 ODN 系统研究与设计 摘 要&#xff1a;为了解决ODN面临的光纤错综复杂&#xff0c;故障定位低效等问题&#xff0c;引入电子标签&#xff0c;智能OTDR技术&#xff0c;提出了一种基于电子标签、光纤检测笔和智能OTDR故障监测的智能 ODN 解决方案,并重点讲述了智能ODN系统的…

Openlayers实现长度测量

概述 在 Openlayers 中,计算两点之间的距离,通常会用到ol/sphere模块。ol/sphere模块主要用于处理与球体(特别是地球球体)相关的数学和几何计算。而长度测量主要用到ol/sphere中的getDistance函数。 getDistance函数用于计算地球表面两点之间的距离,通常用于经纬度坐标。…

xftp连接中不成功 + sudo vim 修改sshd_config不成功的解决方法

我们使用sudo vim不成功&#xff0c;但是我们使用sudo su就可以 了&#xff01; root用户权利更大&#xff01; 喵的&#xff0c;终于成功了&#xff0c;一个xftp连接半天不成功。&#xff08;添加上面的内容就可以连接成功了↑&#xff09;

常用的c++特性-->day02

可调用对象 案例 #include <iostream> #include <string> #include <vector> using namespace std;using funcptr void(*)(int, string);int print(int a, double b) {cout << a << ", " << b << endl;return 0; } // …

应急车道占用检测算法的技术方案与应用

应急车道是高速公路上的生命通道&#xff0c;专门用于救护车、消防车、警车等紧急车辆通行&#xff0c;帮助应对突发状况。然而&#xff0c;一些驾驶员出于各种原因违规占用应急车道&#xff0c;阻碍救援车辆的正常通行&#xff0c;导致交通救援效率大幅下降&#xff0c;甚至加…

卡尔曼滤波算法Kalman filter algorithm

一、假如 状态向量服从高斯分布&#xff1a; 而且状态转移是线性的&#xff1a; 测量是状态的线性关系&#xff08;带噪声&#xff09; 初始状态的置信度也是正态分布 二、卡尔曼滤波的算法流程为 疑问&#xff1a;多测量融合&#xff0c;是不是用不同的传感器测量值去重复5…

java_继承

1.为啥用 继承? Pupil类 package com.hspedu.extend;// 小学生->模拟小学生考试的情况 public class Pupil {public String name;public int age;private double score;public void setScore(double score) {this.score score;}public void testing() {System.out.printl…

Redis 缓存击穿

目录 缓存击穿 什么是缓存击穿&#xff1f; 有哪些解决办法&#xff1f; 缓存穿透和缓存击穿有什么区别&#xff1f; 缓存雪崩 什么是缓存雪崩&#xff1f; 有哪些解决办法&#xff1f; 缓存预热如何实现&#xff1f; 缓存雪崩和缓存击穿有什么区别&#xff1f; 如何保…

【Redis的安装以及主从复制的搭建】配置Redis的哨兵模式

文章目录 一、安装Redis1、上传、解压、重命名2、安装GCC环境3、编译源码4、进行安装5、修改配置文件redis.conf 二、Redis主从复制搭建1、创建文件夹用来实现主从复制 三、配置Redis的哨兵模式1、创建文件夹2、修改sentinel.conf配置文件3、启动 一、安装Redis 1、上传、解压…

WPF中的转换器

单值转换器 1.创建项目后下载两个NuGet程序包 2.先定义一个转换器实现IValueConverter接口 using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; usin…