什么才是优雅的代码
为简单起见,这里定义一个简单的数据结构:
当data作为master端口时,data0作为输入端口,data1作为输出端口。以下面的example为例:
那么现在问题来了,如果我们想让dataOut端口中的输出端口作为寄存器输出时,该如何去做呢?
刚学SpinalHDL时,我是这么来写的:
嗯,看起来没毛病,我只需要在例化的时候添加下就好了:
没毛病是没毛病,但就是看起来有点儿略显繁琐,写着有点儿费手。而真正优雅的代码应该像我们在将UInt那样的数据类型声明为Reg时那般优雅:
那么如何去实现这个目标?
只提出问题不解决那就是耍流氓
上面的代码你在写的时候其实是没有问题的,但运行的时候会出错。我们自定义的data类型确实也存在一个setAsReg方法。其继承关系如下:
不妨去看下multiData中的实现:
当我们继承了multiData,那么我们所有的电路元素均会记录在一个ArrayBuffer中。
ArrayBuffer中的每个元素为一个tuple,分别存放信号名及信号类型。我们在multiDataSetAsRegTest中添加一行打印信息:
执行时便可以看到
好了,搞清楚这一点,那么就可以看下出错的原因了。之所以出错,是因为multiData中setAsReg的实现并未考虑到当数据类型被例化时若带有方向其并做甄别处理。那么我们完全可以在data中重写该方法:
如此,上面的example便可以正常使用了
赋初值问题
有时候对于设置为寄存器的变量,我们需要进行赋初值,而像上面的example,直接调用data的init函数并不好用,当然你也可以显式直接对变量设置初始值,但当数据结构中的个数较多时则是一件繁琐的事情。
大多数情况下信号赋初值常为0,如果对于数据结构中所有被设为寄存器的变量都赋初值0,那么我们可以定义一个init方法(可能有点儿low):
如果只是想读部分信号赋初值,那么可以自行定义新的方法替换即可。
原作者:玉骐
|