1.时间尺度
`timescale
`timescale 时间单位 /时间精度
时间精度不能大于时间单位,时间单位表示一个单位时间的时间长度,时间精度决定了在哪一位进行四舍五入
`timescale 1ns/100ps
module tb_adder4b;
reg [8:0] sti;
wire [3:0] t_sum;
wire t_c_out;
adder4b xadder4b( // instance DUV
.a (sti[8:5] ),
.b (sti[4:1] ),
.c_in (sti[0] ),
.sum (t_sum ),
.c_out (t_c_out )
);
initial //stimulus generation
begin
sti[9:0]=9'b0000_0000_0;// @ 0ns
#10 sti[9:0]=9'b1111_0000_1;// @ 10ns
#10 sti[9:0]=9'b0000_1111_1;// @ 20ns
#10 sti[9:0]=9'b1111_0001_1;// @ 30ns
#10 sti[9:0]=9'b0001_1111_0;// @ 40ns
#10 $finish;
end
endmodule
2.块语句
块内赋值语句,被赋值信号均为reg类型,块内不可能出现assign语句
顺序块
begin-end
块内语句按顺序执行
`timescale 1ns /1ns
initial
begin
#5 ... //@ 5ns
#10 ... //@ 15ns
#15 ... //@ 30ns
end
并行块
fork-join
块内语句并发执行
`timescale 1ns /1ns
initial
fork
#5 ... //@ 5ns
#10 ... //@ 10ns
#15 ... //@ 15ns
join
3.结构说明语句
always语句
- 不断重复,直至仿真结束
- 满足出发条件时,运行过程块一次
- 需和一定的时序控制结合: @,#
initial语句
- 只执行一次,仿真必有
- 多个initial begin-end等效于一个initial fork-join
always // deadclock
haha = !haha;
always #half_period
haha = !haha
`timescale 1ns /1ns
initial
begin
#5 ... //@ 5ns
end
initial
begin
#10 ... //@ 10ns
end
initial
begin
#15 ... //@ 15ns
end
//=======等效于========//
`timescale 1ns /1ns
initial
fork
#5 ... //@ 5ns
#10 ... //@ 10ns
#15 ... //@ 15ns
join
task语句
格式:
task 任务名称
输出、输出声明:
语句:
endtask
例如一个CPU读写的任务
task Read;
output [7:0] Rtask_data; //data read out
input [5:0] Rtask_Addr;
begin
uP_rw = 0;
# SLOW_PERIOD;
uP_addr = Rtask_Addr;
uP_rw = 1;
# SLOW_PEROID;
end
endtask
调用task时的代码如下
Read (Data, Addr);
function语句
格式:
function [BITWIDTH -1 : 0] 函数名称;
输入声明;
语句;
endfunction
与task不同的是,函数将返回一个值。以上代码会返回一个BITWIDTH宽度的值,例如
function [7:0] Product;
input [3:0] Sig_A;
input [3:0] Sig_B;
begin
Product = Sig_A * Sig_B;
end
endfunction
调用function的格式如下:
ProductResult = Product (A,B); //将A和B的乘积的值赋给ProductResult变量
4.循环语句
forever
必须写在initial块中,常用于监控和生成时钟,可以替代always块
always @(posedge req) begin
...
end
//=========等效于===========//
initial begin
forever begin
@(posedge req);
...
end
end
//=====生成时钟=====//
initial begin
clk = 1'b0;
#5 clk = 1'b1;
#5 clk = 1'b0;
#5 clk = 1'b1;
...
//================//
initial begin
clk = 1'b0;
forever #HALF_PERIOD
clk = !clk;
end
//==================//
initial
clk = 1'b0;
always #HALF_PERIOD
clk = !clk;
repeat
连续执行一条语句N次,常用来做延迟若干时钟周期
repeat (次数) (限定条件)
repeat (N) @(posedge clk)
//wait for 20 clock cycles
repeat (20) @(posedge clk)
while
循环变量赋初值;
while(循环条件) begin
执行语句;
循环变量变化;
end
for
for(循环变量赋值;循环条件;循环变量变化)
执行语句;
跳转操作
- continue: 跳至下一次循环
- break: 跳出循环
- disable: 结束某个块(已被命名)或任务
initial begin
...
for(i=0;i<64;i=i+1) begin: loop1
for(j=0;j<64;j=j+1) begin: loop2
if(a[i][j]==0)
continue;
if(b[i][j]==0)
//break;
disable loop2
...
end
end
end
5.事件语句
wait(signal)
等待电平事件
initial begin
wait(intr);
clear_intr = 1'b1;
...
end
@(event)
等待边沿事件,@(posedge clk)常用于延迟一个时钟周期,或于时钟边沿对齐
initial begin
@(poseedge rst_n);
@(posedge clk);
start = 1'b1;
...
end
6.后门操作
上帝视角
通过层次结构,直接访问某一信号,用.分割例化名
initial
@(posedge tb.rst_n);
U_itcm.U_sram.mem[0] = 32'b0;
...
begin
force-release语句
强迫赋值语句,对变量实行强制赋值,用于制造激励难以达到的情况,只能在结构说明语句中使用
initial
@(posedge start);
force din = 32'hdeadbeef;
@(posedge finish);
release din;
begin
7.常用系统任务与系统函数
系统任务
$time: 当前仿真时刻
$random: 生成随机数
- $random(): 生成一个32位有符号整数,可以指定范围和符号
- $random % a: 给出[-a+1,a-1]范围内的随机整数
- {$random} % a: 给出[0,a-1]范围内的随机整数,这里{}相当于绝对值
系统函数
打印到屏幕
$display和$write: 功能上相同,但$display可以自动换行
$monitor(参数1,参数2,...,参数n); 监控、输出参数列表中的表达式或变量的值,有一个发生变化就输出
$monitor($time,"p1=%x p2=%b",p1,p2);
输出到文件
$fopen
功能: 打开文件,文件句柄一般为integer类型的变量
格式: 文件句柄=$fopen("文件名");
$fmonitor,$fdisplay,$fwrite
功能: 写入已打开的文件
格式: $fdisplay(文件句柄,正常的$display语句);
$fclose
功能: 关闭文件
格式: $fclose(文件句柄);
in_handler = $fopen("golden_input.txt");
for(i=0;i<=`SRAM_DEPTH-1;i++)
begin
wdata[i] = {$random} % (2**(`SRAM_DEPTH)); //256
`SRAM_PATH.array[i] = wdata[i];
$fdisplay(in_handler, "@%h\n%h",i,wdata[i]);
end
$fclose(in_handler);
从文件获取数据
$readmemb,$readmemh
功能: 从文件读取数据到存储器中
格式:
- readmemh("<文件名>",<存储器名>);
- readmemh("<文件名>",<存储器名>,<起始地址>);
- readmemh("<文件名>",<存储器名>,<起始地址>,<结束地址>); 注意,如果有地址,要以@<十六进制数>的形式表示
module dir_exchange();
reg [`SRAM_DATAW-1:0] ori_data [`SRAM_DEPTH-1:0];
reg [`SRAM_DATAW-1:0] final_data [`SRAM_DEPTH-1:0];
integer i;
integer j;
integer in_handler;
integer out_handler;
intial
begin
$readmemh("../golden_input.txt",ori_data);
$readmemh("../golden_output.txt",final_data);
Comments | NOTHING