【FPGA篇章七】FPGA系统任务:详述常用的一些系统函数以及使用方法
欢迎大家关注我的微信公众账号,支持程序媛写出更多优秀的文章
系统任务和系统函数是Verilog标准的一部分,都以字符"$"为开头。系统任务可划分为六类,下面分别给出一些常用任务的用法。
1 显示任务
1.1 display和write任务
向终端或文件写入值时,系统会自动决定表达式参数值的位置大小。
比如一个16bit大小的数,用十六进制需要4个字符宽度(最大FFFF),用十进制需要5个字符宽度(最大65535)。
如果在%和radix间加一个0,可以取消这种自动决定的机制,看下面的示例:
reg [:] data = ;
initial $display("data: %d.", data); // data: 200. 数据占5个字符
initial $display("data: %0d.", data); // data: 200. 数据占3个字符
1.2 strobe监控
$strobe使用的参数(包括所有转义字符、格式控制)和$display完全相同。
这组系统任务$strobe、$strobeb、$strobeo、$strobeh可以在选择的时间点处显示仿真数据。
当前仿真时刻的其它所有语句、事件执行完后,$strobe系统任务才会执行,以确保显示的是正确的数据。示例如下:
reg [:] cnt = ;
always @ (posedge clk) cnt = $random; initial begin
forever @(posedge clk)
$strobe("At time %d, data is %d", $time, cnt);
end
终端打印的信息如下:
At time , data is
At time , data is
At time , data is
At time , data is
......
1.3 连续监控
$monitor使用的参数(包括所有转义字符、格式控制)和$display完全相同。
当$monitor任务的参数列表中有一个或多个参数的值发生变化时(不包括time、time、time、stime和$realtime),打印信息。这个连续地监控参数值的特性,称作连续监控。
$monitoron 和 $monitoroff用于启用或禁用监控过程,相当于打开或关闭监控标志。打开监控标志时,无论参数值是否发生变化,会立即打印一次信息;关闭监控标志后,监控任务处于待机状态,不会执行。默认情况下, 仿真开始的时候会自动打开监控标志。
2 文件I/O任务和函数
Verilog文件操作涉及到的函数也放在这里。
2.1 打开文件和关闭文件
打开文件任务 $fopen 和关闭文件任务 $fclose 的使用方法如下:
mcd = $fopen("file_name");
fd = $fopen("file_name", type);
fclose(mcd);
fclose(fd);
$fopen的输入参数都是字符串。如果没有指定type参数,返回值称作多通道描述符(MCD);如果设置了type参数,设定打开文件的方式,返回值称作文件描述符(FD)。
MCD和FD都是32bit的数,二者的区别大致如下:
MCD:32bit,最高位保留不用,剩下的每bit代表一个打开的文件(置1),因此同时最多只能打开31个文件。LSB被“标准输出”文件占用。
这种方法的优势是可以将多个MCD用按位或的方式组合在一起,从而同时向多个文件写入内容。这种打开方式相当于是FD的"w"方式,不支持读取文件内容。
FD:32bit,最高位保留不用,恒定为1。三个默认打开的文件会占用三个文件描述符:STDIN、STDOUT、STDERR。
这种方法的优势是可以指定打开文件的方式,不过不支持用按位或的方式组合FD,因此不能同时写入多个文件。
$fopen支持的文件打开方式如下表所示,支持的方式与在C语言种的含义相同:
type参数 | 功能 |
r / rb | 只读,文件指针指向文件头(不删除文件已有内容);文件不存在则返回0 |
r+ / r+b / rb+ | 可读可写,文件指针指向文件头(删除文件已有内容);文件不存在则返回0 |
w / wb | 只写,文件指针指向文件头(删除文件已有内容);文件不存在则尝试创建 |
w+ / w+b / wb+ | 可读可写,文件指针指向文件头(删除文件已有内容);文件不存在则尝试创建 |
a / ab | 只写,文件指针指向文件末尾(不删除文件已有内容);文件不存在则尝试创建 |
a+ / a+b/ ab+ | 读写方式打开,文件指针指向文件末尾(不删除文件已有内容);文件不存在则尝试创建 |
$fclose通过MCD或FD关闭了文件后,则不能再对此文件进行读、写操作,对此文件的fmonitor和fmonitor和fmonitor和fstrobe操作同时也会取消。相应的资源也会释放出来,用于打开其它文件。
2.2 文件输出
$fdisplay、$fwrite、$fstrobe、$fmonitor
显示任务的信息输出对象为“标准输出”,在Vivado中也就是Tcl控制台;加了"f"后,文件输出任务的信息输出对象为“文件”。
唯一区别在于:文件输出任务的第一个参数是要写入文件的MCD或FD。
此外也没有与monitoron和monitoron和monitoron和monitoroff对应的任务。
如果要关闭fmonitor或fmonitor或fmonitor或fstrobe任务的监控,需要用$fclose关闭文件来实现
下面给出一个示例代码,展示了MCD和FD的区别,以及如果通过按位或操作同时执行多个MCD的文件输出:
reg [:] fd1, fd2, fd3;
reg [:] mcd1, mcd2, mcd3;
reg [:] file_output;
initial begin
// MCD FILE OPEN
mcd1 = $fopen("test1.txt");
if (mcd1 == ) begin $display("mcd open1 failed!"); $finish; end
mcd2 = $fopen("test2.txt");
if (mcd2 == ) begin $display("mcd open2 failed!"); $finish; end
mcd3 = $fopen("test3.txt");
if (mcd3 == ) begin $display("mcd open3 failed!"); $finish; end
// 同时写入3个文件
file_output = mcd1 | mcd2 | mcd3 | ;
$fdisplay(file_output,"mcd1: %h, mcd2: %h, mcd3: %h", mcd1, mcd2, mcd3);
$fclose(mcd1); $fclose(mcd2); $fclose(mcd3); // FD FILE OPEN
fd1 = $fopen("test4.txt", "r+");
fd2 = $fopen("test5.txt", "r+");
fd3 = $fopen("test6.txt", "r+");
$display("fd1: %b, fd2: %b, fd3: %b", fd1, fd2, fd3);
$fclose(fd1); $fclose(fd2); $fclose(fd3);
end
使用按位或运算符将多个MCD合并在一起,1(即32bit中的LSB)表示标准输出,在Vivado中是Tcl控制台。执行$fdisplay会向三个文件和Tcl控制台同时输出信息。
终端打印信息如下,MCD和FD的值与前面所说的它们的特点相吻合:
mcd1: , mcd2: , mcd3:
fd1: ffffb1e0, fd2: ffffb1e1, fd3: ffffb1e2
2.3 数据转换为字符串
swrite 任务(包括swriteb、swriteo、swriteo、swriteo、swriteh)和 $sformat 任务可以将数据以格式化的形式转换为字符串,存储到reg型变量中。
它们的使用方法和 $fwrite 完全一样,只是第一个参数不是要输出的文件FD或MCD,而是要输出的reg型变量的名称。
这两个任务的功能和C语言stdio.h库中sprintf函数的功能类似。这两个的任务的区别在于:
$swrite:和其它任务一样,格式控制可以放在参数列表的不同参数中;
$sformat:格式控制只能放在第二个参数中,其余参数全部被视作输出项(和stdio库的sprintf函数用法完全相同)。
下面给出一个示例代码,试图将128和351两个数字拼接为字符串存放在reg变量中:
reg [*:] str_reg1, str_reg2;
reg [:] str1 = , str2 = ;
initial begin
// 格式控制放在不同的参数中
$swrite(str_reg1,"%0d","%0d",str1,str2);//"%0d",str2);
$display("The value of str_reg1 is : %s", str_reg1); // 格式控制只能放在第二个参数中
$sformat(str_reg2,"%0d","%0d",str1,str2);//"%0d",str2);
$display("The value of str_reg2 is : %s", str_reg2);
end
终端打印信息如下:
The value of str_reg1 is :
ERROR: No Format provided for this argument
ERROR: No Format provided for this argument
The value of str_reg2 is :
两个任务都采用将格式控制"%d"放在两个参数内的形式。swrite正确的得到了字符串"128351";sformat得到的结果错误,且提示了两次ERROR信息。这正是因为$format只将第二个参数"%d"视作格式控制,其余三个参数视作输出项,导致错误发生。
2.4 读取数据到内存中
$readmemb 和 $readmemh 可以批量地把文本文件中的数据读入到内存中,是一种快速的文件读取方法,无需打开文件、关闭文件等操作。
读取的文本文件只能包含以下内容:
空白区:空格、换行、TAB、跳页;
注释:支持所有类型的注释。使用注释和空白区的目的是为了分割不同的数字;
二进制或十六进制数字:readmemb用于读取二进制数据,readmemh用于读取十六进制数据。
两个任务的使用方法如下:
假设先定义一个有256个地址的字节存储器 memory_name
reg [7:0] memory_name[1:256];
$readmemb/h("file_name.data", memory_name);
$readmemb/h("file_name.data", memory_name, start_addr);
$readmemb/h("file_name.data", memory_name, start_addr, final_addr);
第一条语句在仿真时刻为0时,将装载数据到以地址是1的存储器单元为起始存放单元的存储器中去;
第二条语句将装载数据到以单元地址是 start_addr 的存储器单元为起始存放单元的存储器中去,一直到地址是256的单元为止;
第三条语句将从地址是 start_addr 的单元开始装载数据,一直到地址为 final_addr的单元。
内存地址也可以在文本文件中定义,使用" @hhhh ",即@符号+十六进制形式的地址数据。这样牵涉到的情况比较复杂,下面以示例的形式说明:
// test1:正常读取 调用任务:$readmemh("../test5.txt");
文本内容:A5A5 8BCD
内存内容:a5a5,,8bcd,,, // test2:调用任务时指定内存地址 => 按地址递增顺序存放在指定的地址范围内 调用任务:$readmemh("../test5.txt", data, , );
文本内容:A5A5 8BCD
内存内容:xxxx,xxxx,a5a5,,8bcd, // test3:调用任务时指定内存地址,起始地址小于结束地址 => 按地址递减顺序存放 调用任务:$readmemh("../test5.txt", data, , );
文本内容:A5A5 8BCD
内存内容:xxxx,xxxx,8bcd,,a5a5, // test4:文件内指定内存地址+注释 => 忽略注释的数据 调用任务:$readmemh("../test5.txt");
文本内容:@ A5A5 @ //8BCD 5869 2386
内存内容:xxxx,xxxx,a5a5,,xxxx, // test5:文件内指定内存地址,地址随机顺序 => 数据分别存放到指定位置 调用任务:$readmemh("../test5.txt");
文本内容:@ A5A5 @ @ 8BCD //5869 2386
内存内容:xxxx,,a5a5,xxxx,8bcd, // test6:调用任务和文件内都指定了地址 => 文件内的地址必须在任务参数地址的范围内 调用任务:$readmemh("../test5.txt");
文本内容:@ A5A5 @ @ 8BCD //5869 2386
内存内容:xxxx,xxxx,a5a5,xxxx,xxxx,
报错:ERROR: Out of bounds address specified in datafile. Read terminated.
2.5 随机数random
$random函数用于生成随机数,每次调用时返回一个新的32bit随机数(带符号整数)。该函数有一个可选的参数(reg、integer或time类型),表示随机种子。下面给出两个例子:
// example1: 产生(-b+1)到(b-1)之间的随机数
reg [:] rand;
rand = $random % b; // example2: 产生0到b-1之间的随机数
reg [:] rand;
rand = {$random} % b;
【FPGA篇章七】FPGA系统任务:详述常用的一些系统函数以及使用方法的更多相关文章
- Oracle SQL常用内置系统函数总结
Oracle数据库 内置系统函数主要分为以下类别:数学函数.字符串函数.日期函数.转换函数.聚合函数.分析聚合函数 一.数学函数 ------------返回数字 abs(n):返回数字 ...
- 一些常用的c++系统函数
数学<cmath><math.h>: 1 三角函数 double sin (double); double cos (double); double tan (double); ...
- Python基础学习笔记(七)常用元组内置函数
参考资料: 1. <Python基础教程> 2. http://www.runoob.com/python/python-tuples.html 3. http://www.liaoxue ...
- SQL Server 常用的系统函数
Ø 简介 本文主要列举 SQL Server 中常用的一些系统函数,帮助我们在编写 SQL 时忘了某个函数的用法方便查阅.主要分为以下几类函数,更多函数可参考官网. 1. 字符串函数 2. ...
- 使用Intel的FPGA电源设计FPGA 供电的常用反馈电阻阻值
使用Intel的FPGA电源设计FPGA 供电的常用反馈电阻阻值. 当前仅总结使用EN5339芯片的方案 Vout = Ra*0.6/Rb + 0.6 芯片手册推荐Ra取348K,则 3.3V时,取R ...
- FPGA开发流程1(详述每一环节的物理含义和实现目标)
要知道,要把一件事情做好,不管是做哪们技术还是办什么手续,明白这个事情的流程非常关键,它决定了这件事情的顺利进行与否.同样,我们学习FPGA开发数字系统这个技术,先撇开使用这个技术的基础编程语言的具体 ...
- 【FPGA篇章一】FPGA工作原理:详细介绍FPGA实现编程逻辑的机理
欢迎大家关注我的微信公众账号,支持程序媛写出更多优秀的文章 FPGA(Field Programmable Gate Array),即现场可编程逻辑门阵列,它是作为专用集成电路(ASIC)领域中一种半 ...
- 【FPGA篇章五】FPGA函数任务:对讲解函数与任务专题展开详解
欢迎大家关注我的微信公众账号,支持程序媛写出更多优秀的文章 任务和函数也属于过程块,多用于仿真文件设计中,使用两者的目的有所区别: 函数(function):对输入的值执行一些处理,返回一个新的值. ...
- FPGA+ARM or FPGA+DSP?
网上有人说.现在的FPGA,ARM功能已经强大到无需DSP协助处理了,未来DSP会不会消声灭迹?是DSP取代FPGA和ARM,还是ARM,FPGA取代DSP呢?担心好不容易学精了DSP,结果DSP变成 ...
随机推荐
- 官方解读:Salesforce线上考试新政与福利
随着疫情在世界范围内的迅速蔓延,Salesforce推出了一系列的线上认证考试改进方案,方便Salesforce从业者在疫情阶段也能够安全.便利地参与考试,今天让我们一起来捋一捋那些,和我们密切相关的 ...
- L26 使用卷积及循环神经网络进行文本分类
文本情感分类 文本分类是自然语言处理的一个常见任务,它把一段不定长的文本序列变换为文本的类别.本节关注它的一个子问题:使用文本情感分类来分析文本作者的情绪.这个问题也叫情感分析,并有着广泛的应用. 同 ...
- C - Ekka Dokka
Ekka and his friend Dokka decided to buy a cake. They both love cakes and that's why they want to sh ...
- sudo -s 命令 [oh-my-zsh] 提示检测到不安全目录
运行sudo -s 命令时,[oh-my-zsh] 冒出下面一大堆提示: [oh-my-zsh] Insecure completion-dependent directories detected: ...
- 详解 通道 (Channel 接口)
在本篇博文中,本人主要讲解NIO 的两个核心点 -- 缓冲区(Buffer) 和 通道 (Channel)之一的 缓冲区(Buffer), 有关NIO流的其他知识点请观看本人博文<详解 NIO流 ...
- v&n赛 ML 第一步(python解决)
题目链接 给了70组x,y,根据提示,是求拟合曲线,再通过x求y 知道MATLAB应该录入就能解决吧,但是没下这软件,试试用python解决 #coding:utf- from pwn import ...
- 【题解】P2831 愤怒的小鸟 - 状压dp
P2831愤怒的小鸟 题目描述 \(Kiana\) 最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于 \((0,0)\) 处,每次 \(Kiana\) 可以 ...
- MergeSort归并排序和利用归并排序计算出数组中的逆序对
首先先上LeetCode今天的每日一题(面试题51. 数组中的逆序对): 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. ...
- java Int类型转为double 类型;string转double
int a=12; double b=(double)a; or double c=Double.valueOf((double)a); string a_s="12"; doub ...
- EasyPoi 导入导出Excel时使用GroupName的踩坑解决过程
一.开发功能介绍: 简单的一个excel导入功能 二.Excel导入模板(大致模板没写全): 姓名 性别 生日 客户分类 联系人姓名 联系人部门 备注 材料 综合 采购 张三 男 1994/05/25 ...