很久没有更这个系列了,因为最近也没啥出bug的机会,所以这次的案例是之前一个朋友在群里的问题,很有意思所以分享一下。原问题中不涉及到项目内容和代码,所以就放心大胆的在这里放一下:请教网友一个问题,定义了一个父类一个子类,除了一个function重名但内容不同,父类子类定义了完全相同的成员变量和其他的function,然后环境用了set type override type,最后仿真发现子类那个不同的function用到的成员变量并不是自己传进去的,好像来自父类,并且是随机值,这个bug怎么解释
虽然直觉问题应该出在“virtual,父类句柄调用,factory没生效,没初始化或者没加this”这几件事上,但没觉得这个操作有什么问题,直到群里有人说了遇到的类似问题:我也遇到过,总结就是子类中不要声明和父类里同名的变量
这才发现,他说的是“定义了完全相同的成员变量”不是有“完全相同的成员变量”。好,那很明显问题就出现在子类继承时声明了父类同名变量这件事上。来,请ds给我们讲一下:变量隐藏(Variable Hiding):如果子类声明了与父类 同名且同类型 的成员变量,父类的变量会被隐藏(但依然存在)。此时,子类的方法中直接使用变量名时,默认访问的是 子类自己的变量,但如果子类未正确初始化这些变量,或者父类变量被意外访问,可能导致数据不一致。
很清楚,也就是说子类中声明了一个父类中已经存在的成员变量AA,那么父类中的该变量依旧存在(近似处于隐藏状态),即当前子类空间中可以视为有两个AA,如果父类变量被意外访问那么可能会出意料之外的事。什么时候父类成员会被访问呢?关于这个事欢迎访问之前一个系列的文章《【system verilog】OOP属性下的构造函数new,虚方法virtual和cast方法》。不访问也没啥关系,反正有一个场景是很明确的(也就是问题中涉及到的):父类句柄指向子类空间时,访问不带virtual的成员,会返回父类的结果。关于function/task在上面那个系列里说很多了,那我们看成员变量。看这个代码:class father; int AA = 1000;endclassclass ext extends father; int AA = 2000;endclass...//env father fa; ext ex;... fa = ext::new(); ex = ext::new(); $display("fa.AA = %0d", fa.AA); $display("ex.AA = %0d", ex.AA);打印结果:
改成:
class father; int AA; function new(); AA = 1000; endfunctionendclassclass ext extends father; int AA; function new(); super.new(); //这个super写不写都行,避免争执还是写上吧 AA = 2000; endfunctionendclass...//env father fa; ext ex;... fa = ext::new(); ex = ext::new(); $display("fa.AA = %0d", fa.AA); $display("ex.AA = %0d", ex.AA);打印结果:
而如果注释掉子类中同名变量AA的重新声明,改成这样:
class father; int AA; function new(); AA = 1000; endfunctionendclassclass ext extends father; //int AA; function new(); super.new(); //这个super写不写都行,避免争执还是写上吧 AA = 2000; endfunctionendclass...//env father fa; ext ex;... fa = ext::new(); ex = ext::new(); $display("fa.AA = %0d", fa.AA); $display("ex.AA = %0d", ex.AA);就不存在问题了:
好,这个问题的复现和验证就完成了。我一直以为OOP这个系列已经可以终章了,没想到还能再补充一篇,过两天补过去吧,还是那句话,多交流多讨论总归是没有亏吃的。
系列文章入口
【芯片设计】SoC 101(一):绪论【芯片设计】FIFO漫谈(零)从无处不在的FIFO开始说起【芯片设计】计算机体系结构(一)虚拟内存【芯片设计】深入理解AMBA总线(零)绪论
【芯片设计】握手协议的介绍与时序说明【芯片设计】复位那些小事 —— 复位消抖【芯片设计】快速入门数字芯片设计(一)Introduction【芯片验证】UVM源码计划(零)下定决心读源码前的自测环节
【芯片设计】异步电路碎碎念(一) 到底什么是异步电路
【芯片设计】从RTL到GDS(一):Introduction
【芯片设计】系统中的可维可测状态记录寄存器设计
其他文章链接
【芯片验证】sva_assertion: 15道助力飞升的断言练习【芯片验证】可能是RTL定向验证的巅峰之作【芯片验证】RTL仿真中X态行为的传播 —— 从xprop说起【芯片验证】年轻人的第一个systemVerilog验证环境全工程与解析【芯片设计】verilog中有符号数和无符号数的本质探究
| 【芯片设计】论RTL中always语法的消失术 | 【芯片设计】代码即注释,注释即代码 | 【芯片设计】700行代码的risc处理器你确实不能要求太多了 |
入职芯片开发部门后,每天摸鱼之外的时间我们要做些什么呢 | 如何计算系统的outstanding 和 burst length? | 芯片搬砖日常·逼死强迫症的关键词不对齐事件 | 熟人社会里,一群没有社会价值的局外人 |
|