1、时间尺度
`timescale时间刻度指令用来说明模块工作的时间单位和时间精度,基本语句如下
`timescale 时间单位/时间精度
时间单位和时间精度可以以秒、毫秒、纳秒、皮秒或飞秒作为度量,具体数值可以选择1、10或100,如:
`timescale 10ns/1ns //写法正确
`timescale 10ps/1ns //写法错误
2
该语句定义了当前模块中的仿真时间单位是10ns,仿真精度是1ns,语法上要求时间精度必须小于等于时间单位,即前面的数值要大于等于后面的数值。
仿真中使用 #数字
表示延时相应时间单位的时间。
`timescale 1ns/1ns
...
initial
begin
A = 0;B = 0; //初始值
#1 A = 1; //1个时间单位,1ns后才执行 A=1
#10 B = 1; //延时10ns后才执行 B=1
#20 A = 0; //延时20ns后才执行 A=0
end
2
3
4
5
6
7
8
9
例二:
`timescale 1ns/10ps //其精度 0.01,
#10.11; //延时 10110ps。
2
2、系统任务函数
2.1、display
用于输出、打印信息
$display(format_string, arguments);
- format_string:输出的格式字符串,可以包含文本和格式化占位符。
- arguments:要输出的变量或表达式,按照格式字符串中的占位符进行替换。
例如:
module text();
reg [3:0] a;
reg [3:0] b;
reg [4:0] sum;
initial begin
a = 4'b0101; // 5
b = 4'b0011; // 3
sum = a + b; // 8
// 输出信息
$display("a: %b, b: %b, sum: %b", a, b, sum);
end
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
其用法与 printf 差距不大。其格式有以下形式:
- %h 和 %H 表示十六进制形式输出
- %d 和 %D 表示十进制形式输出
- %o 和 %O 表示八进制形式输出
- %b 和 %B 表示二进制形式输出
- %s 和 %S 表示字符串的形式输出
- %f 和 %F 表示十进制数的形式输出实型数
- %e 和 %E 表示指数的形式输出实型数
- %t 和 %T 表示当前的时间格式形式输出
运行结果如下图所示:
2.2、random
用于生成伪随机数。它通常用于测试和验证中,帮助模拟随机事件或数据。可以生成范围在 -2,147,483,648 到 2,147,483,647 之间的整数。
正常试例:
module text();
reg [10:0] rand_value;
initial begin
rand_value = $random; // 生成一个随机数并赋值
$display("Random Value: %d", rand_value);
end
endmodule
2
3
4
5
6
7
8
9
10
运行结果如下图所示:
指定范围试例
module text();
parameter MAX_VALUE = 100; // 设置最大值
reg [10:0] rand_value;
initial begin
rand_value= $random % MAX_VALUE; // 生成范围在 0 到 99 之间的随机数
if (rand_value < 0) begin
rand_value = -rand_value; // 确保值为正
end
$display("Random Value in range [0, 99]: %d", rand_value);
end
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
运行结果如下图所示:
2.3、stop
$stop 用于在仿真过程中暂停仿真并进入交互模式。这通常用于调试目的。使用 $stop 时,仿真器会停止执行,并允许用户查看当前状态、信号值等,便于检查错误或分析仿真结果。
$finish 用于是退出仿真器,返回主操作系统,即结束整个仿真的过程。
`timescale 1ns/1ns
module text();
initial begin
$display("100ns Stop the simulation");
#100;
$stop;
$display("100ns Ends the simulation");
#100;
$finish
end
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
2.4、time
用于返回一个 64bit 的整数来表示的当前仿真时刻值。该时刻是以模块的仿真时间尺度为基准。返回值是一个整数,表示仿真时间单位,具体单位取决于仿真环境中设置的时间单位(如纳秒、微秒等)。
module text();
initial begin
#10; // 等待 10 时间单位
$display("It is time now: %0d", $time); // 输出当前时间
end
endmodule
2
3
4
5
6
运行结果如下图所示:
3、结构模块
- initial 用于定义在仿真开始时执行的代码。它通常用于初始化变量或设置特定的仿真条件。initial 块只在仿真开始时执行一次,以下是一个简单的结构示例:
`timescale 1ns/1ns
module text();
// 定义寄存器
reg [7:0] data;
// 使用 initial 块进行初始化
initial begin
// 初始化 data 的值
data = 8'b00000000;
// 打印初始值
$display("Initial data value: %b", data);
// 模拟过程
#10; // 延时10ns
data = 8'b10101010; // 在 10 时间单位后改变数据
$display("Updated data value: %b", data);
end
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
4、例化
仿真文件的例化指的是在测试平台(testbench)中例化设计模块,以便进行仿真。以下是示例,展示如何在测试平台中例化一个模块
设计模块
module adder(
input wire [3:0] a,
input wire [3:0] b,
output wire [4:0] sum
);
assign sum = a + b;
endmodule
2
3
4
5
6
7
仿真模块
module text;
// 定义输入信号
reg [3:0] a;
reg [3:0] b;
// 定义输出信号
wire [4:0] sum;
// initial 块用于驱动信号
initial begin
// 测试用例 1
a = 4'b0011; // 3
b = 4'b0001; // 1
#10; // 等待 10 时间单位
$display("Sum: %b", sum); // 打印结果
// 测试用例 2
a = 4'b0101; // 5
b = 4'b0010; // 2
#10;
$display("Sum: %b", sum); // 打印结果
// 结束仿真
$finish;
end
// 例化
adder u_adder (
.a(a), // 将 a 连接到 uut 的 a
.b(b), // 将 b 连接到 uut 的 b
.sum(sum) // 将 sum 连接到 uut 的 sum
);
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
在第 27 - 31 行是将仿真的信号和设计模块的信号进行一个连接绑定。
至此我们的语法介绍是不是感觉知识点太多了,记不完,这都是小事,只要能有个大概印象就足够了,接下来我将带你们慢慢都使用起来,一步步加深记忆。