前言
不务正业的我又开始整活啦,先祝福各位帅哥美女:
这次整个什么活呢~之前不是已经能在波形里写字了嘛,那么咱们进一步的在波形里画个粽子吧!
这次还是要用到之前的环境:
|献上祝福语波形生成器|
当然了,其实这个环境不是必须的,只有你有一个可以仿真出波形的sv环境,那么就ok啦!
分步实操
找到粽子
要想在波形里画粽子,你总得有个粽子的图,鉴于波形的表达能力太有限了,所以建议找个简笔画粽子来~比如说这个粽子.jpg:
于是呢,我们就有了原始的素材:一个甜粽!
转换01点阵
在转换01点阵图之前呢,要先把图像压缩一下,要把高度压缩到32个像素(原因后面聊),宽度可以大一些,但是也别太大。所以压缩后的粽子大概是这样的:
针对这个小粽子转点阵。由于波形里1bit信号只有时钟状态:0/1/x/z,其中xz又不是特别好传递,因此我们最好使用只有01的点阵图。把jpg图像转换为01点阵图,通过python非常容易实现,大概30行代码:
#-*-coding:gb2312-*- import sys import os import re import matplotlib.pyplot as plt import cv2 import numpy as np def main(): img_path = r"D:\MyWork\python\zongzi1.jpg" img_data = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) #只读取灰度,不读取色彩 img_data = np.transpose(img_data) #转置一下 tmp_list = [] for row in img_data: for i in row: if int(i) >= 240: #0~255,纯白色为255,设置一个阈值归一化为0/1 tmp_list.append("0") else: tmp_list.append("1") tmp_list.append("\n") with open("gogogo.txt", "w") as f: for tr in tmp_list: f.write(tr) pass if __name__ == '__main__': main()
最后得到的点阵图长这样:
注意,这个粽子必须得是躺下的才行,因为后面环境里是一行一行的吃数据,然后转成32bit的信号,展开后就又称竖着的了~~
环境处理点阵图
接下来就是用前面提到的那个环境啦,当然不用也没关系,只要知道如何吃点阵图进仿真环境就可以了。把生成的点阵图命名为gogogo.cfg,放在了script/目录下,然后在环境里这样写:
integer file; file = $fopen("../script/gogogo.cfg","r"); while(!$feof(file))begin bit[32-1:0] value; $fscanf(file, "%b\n", value); `uvm_do_with(my_tr, {my_tr.gogogo == local::value;}) end
这样就成功的把01点阵数据复制到my_tr.gogogo这个信号上去了。如果想话两个粽子怎么办呢?简单的很,就是把这段话复制一下,再生成一次就可以啦。
回过头看前面的一个问题,为啥高度(也就是后面环境处理时一个value的位宽)不能超过32bit呢?这个是我实践出真知,不知道是否和integer file指针有关或者和工具系统什么有关,如果超过32bit数据就吃的有问题,而且不止我这里出过这个问题,别人也反馈过类似的情况。所以我们就老老实实的画高度为32个像素点的粽子吧!
但是呢这样生成的粽子不够红火,怎么办呢?只要应用波形中x是红色的,z是黄色的这个特性,在driver中做这么一步操作:
this.vif.drv.gogogo<= 32'hxxxx_xxxx & pkt.gogogo;
在xprop = vmerge情况下,x & 1 = x,x & 0 = 0,所以最后我们就得到了两个红红火火的甜粽子!