先独立作答,再展开参考答案。八股原题沿用原笔记编号;扩展练习为本站根据对应考点编写。
Q7 · task 和 function 有什么区别?
八股原题 · Q7 · 题型:问答
考点
- 是否允许消耗仿真时间
- 返回值与参数
- 调用方向限制
展开参考答案 · Q7
题目来源(原笔记记录)
- 小鹏汽车 · SOC验证 · 校招(function 和 task 的区别)
- 某TPU公司 · 数字IC验证 · 校招(function 与 task 的区别)
- 豪威科技 · 数字IC验证 · 校招 · 一面(task vs function:区别 + 参数输入类型)
- 通用 · 数字IC验证 · 实习 · 基础面经(function 与 task 的区别)
- ArmChina · 数字IC设计验证 · 校招 · 三面(task 和 function 区别)
- 泰凌微 · 数字IC验证 · 实习(task 与 function 的区别、常用数据类型转换函数)
- 汇顶科技 · 数字IC验证 · 校招 · 一面(function 和 task 的区别)
- 芯动科技 · 数字IC验证 · 校招 · 笔试(task 和 function 的关系)
- 面试书《Cracking Digital VLSI Verification Interview》· 第4章 Q17(对应题目:task 与 function 的区别)
function 做零仿真时间的计算,task 做可能等待的行为,分水岭就是能不能耗仿真时间。
第一,function 不能耗时。 不能有 #、@、wait 这些耗时语句,也不能调用可能耗时的 task;它可以返回一个值,或者声明成 void。
第二,task 可以耗时。 可以有多个 output、inout、ref 参数,但没有函数式返回值。
| 对比项 | function | task |
|---|---|---|
| 是否可耗时 | 不可以 | 可以 |
| 返回值 | 一个,或 void | 无函数返回值,可用输出参数 |
| 调用关系 | 可调用 function | 可调用 task 和 function |
| 适合场景 | 计算、转换、查询 | 驱动、等待、协议操作 |
易错点:“function 零时间”指不推进仿真时间,不等于它不消耗 CPU 运行时间。
一句话:function 做零仿真时间计算,task 做可能等待的行为;function 不能调用耗时 task。
E7 · 等待时钟的 function
扩展练习 · E7 · 题型:代码改错 · 对应原题:Q7
考点
- 是否允许消耗仿真时间
- 返回值与参数
- 调用方向限制
function void send();
@(posedge clk);
valid = 1;
endfunction指出问题并修改;如果调用方也是 function 怎么办?
展开参考答案 · E7
带事件等待的子程序应改成 task send(); ... endtask。调用方如果是 function,也不能通过直接调用该 task 来等待时钟;应把调用链中需要等待的行为改为 task,纯计算部分仍可保留为 function。
Q8 · SystemVerilog 支持函数重载吗?如何实现相近需求?
八股原题 · Q8 · 题型:问答
考点
- 用户自定义函数重载的限制
- 默认参数、按名传参和参数化类
展开参考答案 · Q8
题目来源(原笔记记录)
- 合见工软 · 数字IC验证 · 校招 · 一面(函数重载 function overloading 的实现方式)
- 泰凌微 · 数字IC验证 · 校招 · 一面(重载 overload 的条件)
- 昆仑芯 · 数字IC验证 · 校招 · 二面(SV 中重载的实现方式)
- 面试书《Cracking Digital VLSI Verification Interview》· 第3章 Q44(对应题目:方法重载 Overloading 与方法重写 Overriding)
SystemVerilog 不支持 C++ 那种”同名函数、不同参数列表”的重载——面试先把这个限制说出来,别直接写两个同名函数。
第一,限制。 同一作用域不能定义多个同名、不同参数的用户函数。
第二,相近需求怎么做。 用不同函数名、默认参数、按名传参,或者参数化类来泛化。
function int calc(int a, int b = 1); // 默认参数
return a + b;
endfunction
int result = calc(.b(4), .a(3)); // 按名传参第三,细节。 按名传参能避免参数顺序写错,默认值适合稳定的可选配置;这里讨论普通用户函数的同名重载;不要与方法重写混淆。SV 另有受限制的 bind 运算符重载机制,不等同于 C++ 的普遍用法。
一句话:SV 没有 C++ 式同名函数重载;用不同名字、默认参数、按名传参实现相近需求。
E8 · 用默认参数代替同名重载
扩展练习 · E8 · 题型:代码改错 · 对应原题:Q8
考点
- 用户自定义函数重载的限制
- 默认参数、按名传参和参数化类
同一作用域声明 calc(int a) 和 calc(int a, int b) 两个用户函数是否可行?合并为一个函数,使 calc(3) 返回 4、calc(.b(4), .a(3)) 返回 7。
展开参考答案 · E8
不支持用参数列表区分这两个同名用户函数。
function automatic int calc(int a, int b = 1);
return a + b;
endfunction默认参数实现单参数调用,按名传参允许交换书写顺序。