这里主要记录一些我学到的用Verilog语言实现功能的编写思路(后续可能会不定时更新)。
一:生成随机电平
以第一句为例:
使用always语句每隔10ns不断执行:top_in1每隔10ns就会被赋值0或者1,即生成了随机电平。(使用random生成随机数后对2取模,则只能结果为0或者1)
二:定时打印仿真输出
常用于仿真文件中打印出一些信息方便查看。
使用方法如下:在initial语句中使用$timeformat设置打印出的时间的格式,使用monitor实时打印。
initial begin
$timeformat(-9,0,"ns",10);
$monitor("@time %t:,a=%b,b=%b,sum=%b,count=%b",$time,top_a,top_b,top_sum,top_count);
end
1. $timeformate用法
$timeformat(时间单位, 打印时间到小数点后几位, 与时间单位相对应单位名, 打印字符长度);
- 时间单位:取值为0~15之间,代表10的负几次方。即:0 表示秒,-3 表示毫秒,-6 表示微秒,-9 表示纳秒, -12 表示皮秒, -15 表示飞秒;中间值也可以使用:例如-10表示以100ps为单位。其默认值为`timescalse所设置的仿真时间单位。
- 打印时间到小数点后几位: 是在打印时间值时,小数点后要保留的位数。其默认值为0
- 与时间单位相对应单位名: 这里一般与前时间单位对应,如上述例子中,时间单位处填-9代表纳秒,这里就填“ns” 。其默认值为空字符串。
- 打印字符长度: 是指打印时间这部分的字符串的长度。表示时间值字符串的后面加上一个" ns"字符串的长度。
如下例子,上图为设置字符串长度为6,下图设置为10。
以上图为例子,时间值和" ns"合起来的字符串长度如果不足6个字符的话,就在这部分字符串的前面补空格,使得这部分字符串总长度为6个字符;如果这部分字符串长度超过了6个字符,那就不补空格了。
(2) 打印时间
使用$monitor等打印函数打印时间时用%t表示存放时间的位置,对应将$time存放进来。
PS:$monitor 的使用方法之前文章提到过,就不再说了
(3)该方法常用于仿真模块使用,故打印系统函数中应该用得是顶层模块定义的端口而不是子模块的端口。
三:生成理想时钟clk
alwasy #10 sys_clk = ~sys_clk;
(前提是sys_clk已经赋了一个初值)
理解:每隔10ns对sys_clk进行一次取反就可以得到一个理想的时钟信号,因此这个时钟信号的周期是20ns(如下图),即50MHz。
周期:一次重复所需的时间(单位s)。
频率:单位时间内重复的次数(单位Hz)。
根据他们的意义就可以得到 。这样想,假设一个周期是0.2s,一个周期即重复一次,1➗0.2 = 5,即一秒内重复5次,就是频率的意义。
1千赫 (kHz 103 Hz) =1 000 Hz;
1兆赫 (MHz 106 Hz) =1 000 000 Hz;
1吉赫 (GHz 109 Hz) =1 000 000 000 Hz;
1太赫 (THz 1012 Hz) =1 000 000 000 000 Hz;
1秒 (s) = 1000毫秒 (ms) = 1 000 000 纳秒(ns) = 1 000 000 000 微秒(μs)
= 1000 000 000 000 皮秒(ps)