在使用后门访问方式将文件中的数据写入到eram中时,首先使用UVM_FILE声明文件句柄,句柄一共有27个。然后使用$fopen打开文件将句柄赋值到声明的句柄中。使用$urandom_range产生随机化数据,使用$fdisplay将数据输入到文件中,使用$fclose关闭文件,很重要。
在实际运行时,发现当j=27时,产生的eram_read_16k_128_27.dat文件产生的数据为0,其原因为在使用UVM_FILE宏声明句柄时,27个只能包括0-26,不能包括2-28,第27和28个的文件数据为0。这点和数据的声明是一致的,在声明时,必须给出数组的上下界,几乎所有数组都使用0作为索引下界,因此允许简便的声明,但此时默认下界为0。
1 UVM_FILE eram_16K_128[27];
2 for (int j=2; j<29; j++)
3 begin
4 eram_16k_128[j] = $fopen($psprintf("eram_read_16k_128_%d.dat,j),"wb");
5 for(int i=0, i<16384;i++)
6 begin
7 data128 = $urandom_range(0,{128{1'b1}});
8 $fdisplay(eram_16k128[j],"@%x\n%x",i,data128);
9 end
10 $fclose(eram_16k_128[j]);
5 end
$readmem(数据文件名、存储器名):用来将文件里存放的数据读取到存储器中。
$readmemb要求每个数字为二进制,h为十六进制。。。
$fopen(const char*filename, const char*mode):使用参数mode指定的方式打开参数filename指定的文件。文件顺利打开,指向该流的文件指针返回,打开失败返回null。
mode类型有:
r:只读,w:只写,+:在原有类型上增添可读或可写,b:二进制文件,t:txt文档,a:只写,附加,文件不存在创建,文件存在新数据加到文件尾后。使用w/a时,若文件不存在可以创建文件,但指定的路径要存在,w/a不能创建路径。
字符串 | 说明 |
r | 以只读方式打开文件,该文件必须存在。 |
r+ | 以读/写方式打开文件,该文件必须存在。 |
rb+ | 以读/写方式打开一个二进制文件,只允许读/写数据。 |
rt+ | 以读/写方式打开一个文本文件,允许读和写。 |
w | 打开只写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。 |
w+ | 打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。 |
a | append,以附加的方式打开只写文件。若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF 符保留)。 |
a+ | 以附加方式打开可读/写的文件。若文件不存在,则会创建该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF符不保留)。 |
wb | 以只写方式打开或新建一个二进制文件,只允许写数据。 |
wb+ | 以读/写方式打开或新建一个二进制文件,允许读和写。 |
wt+ | 以读/写方式打开或新建一个文本文件,允许读和写。 |
at+ | 以读/写方式打开一个文本文件,允许读或在文本末追加数据。 |
ab+ | 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。 |
$fdisplay(<file_desc>, "<string>", variables):$fdisplay 的使用方法和$display系统函数的使用方法很类似,$display是将格式化的结果输出到控制台上,而$fdisplay 是将格式化的输出结果写入到文件中。file_desc为文件句柄,表示对哪个文件进行写操作,<string>表示写入文件的格式,variable为写入的数值。
$fwrite(<file_desc>, "<string>", variables): 函数的使用方法与$fdisplay 类似, 只是$fwrite 信号没有缺省的换行操作。
$fclose:用于关闭文件。
$sformat:比$sformatf多一个参数,该参数用于存放最终整理好的字符串。
string jerry_string;
string jerry_string_r;
$sformat(jerry_string,"jerry_face_score=%0d",100);
$sformatf:$sformatf()返回的值就是整理好的字符串,可以直接把它整体拿去使用;
jerry_string_r=$sformatf("jerry_cool_score=%0d",100);
$psprintf是由VCS添加的sv扩展,暂未被system verilog标准收录;$psprintf()返回一个格式化的临时字符串,并且可以传递给其他子程序。这样可以不用定义新的临时字符串并在格式化语句与函数调用过程中传递这个字符串。
defparam tb_top.duv.xxx_wrapper.u_mem.PreloadFilename = "./ram_data/xxx.dat";
a = $fopen($psprintf("./ram_data/xxx.dat","w");
data = $urandom_range(0,128);
$fdisplay(a,"%h",data);
$fclose(a);
tb_top.duv.xxx_wrapper.u_mem.uut.load_mem;
在asic分支,mem ip库里有后门赋值的方法,load_mem,可以调用这个task对mem初始化,前提是PreloadFilename文件存在。在define文件里defparam xxx_wrapper.u_mem.PreloadFilename = "./ram_data/xxx.dat";使用a = $fopen($psprintf("./ram_data/xxx.dat"),"w");打开文件产生文件句柄,再使用$fdisplay(a,"%h",data)将产生的data文件输入到句柄,使用$fclose(a)关闭文件。这样就产生了文件。之前定义过mem里的PreloadFilename文件指向产生的文件,PreloadFile文件就存在了,再使用load_mem,赋值完成。
$sformat & $sformatf是system verilog标准中的系统函数,用于整理字符串的格式;
find with(item>5):返回调用对象中的值大于5的元素。
find_index(item>5):返回调用对象中的值大于5的元素的索引。
find_first_index with(item ==5):返回调用对象中的值等于5的第一个元素的索引。
同理 find_last with()和find_last_index with()返回括号中满足条件的最后一个元素和最后一个元素的索引。
sort:对象中的元素从小到大排序。
rsort:从大到小排序。
reserve:倒序排列
shuffle:随机排列
事件同步:@event和wait event.triggered。@为边沿敏感,wait event.triggered为电平敏感。二者阻塞都必须在触发时间前,否则先发生触发后阻塞,阻塞感知不到事件的触发动作,会一直卡死。
The basic mechanism to wait for an event to be triggered is via the event control operator @, the @ operator blocks the calling process until the given event is triggered. For a trigger to unblock a process waiting on an event, the waiting process shall execute execute the @ statement before the triggering process executes the trigger operator, ->. If the trigger executes first, then the waiting process remains blocked.
通过控制事件操作符@等待事件触发,@操作符会一直阻塞直到此事件被触发。使用触发操作符->触发事件后后,被@阻塞的进程会解锁继续进行。如果先触发事件后用@操作符阻塞,则@操作符后的进程仍然会被阻塞。如果->event和@event发生在同一个time step,就会造成竞争冒险,因为无法确认他们哪一个先执行。
SV can distinguish the event trigger itself, which is instantaneous, from the event's triggered state, which persists throught the time step. The triggered event property allows users to examine this state.
event的triggered属性的持续时间是一个time step, 因此它解决了触发事件和等待事件在同一个time step时的竞争冒险问题。只要wait(event.triggered)在->event之前执行,或者在同一个time step执行,都能正确地等到事件。
平台中经常会用到随机数据进行拼接,$urandom_range(0,128'b1)返回的数据是32位的,不是128位,因此期望对128bit数据全随机,这样的高96位肯定是0