System Verilog学习(一)

1、DUT(Device Under Test)
在这里插入图片描述
在这里插入图片描述

interface router_IO(input bit clock);
	logic 		 reset_n;
	logic [15:0] din;
	logic [15:0] frame_n;
	logic [15:0] valid_n;
	logic [15:0] dout;
	logic [15:0] busy_n;
	logic [15:0] valido_n;
	logic [15:0] frameo_n;
	clocking cb @ (posedge clock)
		default input #1 output #1;
		outpur reset_n;
		output din;
		output frame_n;
		output valid_n;
		input dout;
		input busy_n;
		input valido_n;
		input frameo_n;
	endclocking
	modport TB(clocking cb,output reset_n);
endinterface

在这里插入图片描述

program automatic router_test(router_IO.TB router);
//develop test code in initial block;
	initial begin
		$vcdpluson;  //Dumping waveform file control
		//$display("Hello world");
	end
	initial begin
		reset();
	end
	task reset();
		router.resetn <= 1'b0;
		router.cb.frame_n <= 16'hffff;
		router.cb.valid_n <= ~('b0);
		##2 router.cb.reset_n <= 1'b1;
		repeat(15) @(router.cb);
	endtask
endprogram

同步信号驱动时候用非阻塞赋值。
在这里插入图片描述在这里插入图片描述2、语法简介
program

endprogram
将initial中的begin…end放到其中,作为一个测试案例test case。
测试代码都是放在program block中,program例化在顶层的中top-level harness
结构如下:

//root global variables
//`include files
program [automatic] name(interface);
//`include files
//program global variables
initial begin
	//local variables
	//top-level tset code
end

task task_name();
	//local variable
	//code
endtask
endprogram

具体实例如下:

program automatic router_test(router_IO.TB router);
//develop test code in initial block;
	initial begin
		$vcdpluson;  //Dumping waveform file control
		//$display("Hello world");
	end
	initial begin
		reset();
	end
	task reset();
		router.resetn <= 1'b0;
		router.cb.frame_n <= 16'hffff;
		router.cb.valid_n <= ~('b0);
		##2 router.cb.reset_n <= 1'b1;
		repeat(15) @(router.cb);
	endtask
endprogram
module router_test_top;
	router_IO top_io(SystemClock);    //类似声明端口interface
	test t(top_io);					//将端口接到case中
	router dut(						//接到待测试模块
				.reset_n(top_io.reset_n),
				.clock(top_io.clock),
				. ...(top_io.  )
	);

endmodule
//做一个interface,再把dut连接到interface上,再把interface传到test program中,在test program中其实就是对interface做驱动

DUT连接到interface,首先dut传到testcase,testcase再去驱动interface,interface再去驱动dut。

数据类型
二值逻辑是“0”和“1”,四值逻辑多了“x”和“z”,二值逻辑的初始值是0,把“x”、“z”的四值逻辑赋值给二值逻辑,那就是“0”

bit是二值逻辑,无符号数
eg:bit flag;
bit [7:0] a = 8’b1;

二值逻辑的占用空间变成四值逻辑的一半,可以减少占用的内存,可以提高存取速度。

另一个二值逻辑是byte,8位有符号数
shortint是16位有符号数
int是32位有符号数
longint是64位有符号数

real是二值逻辑,类似double
shortreal 类似于float
eg:
real alpha = 100.0, coverage_result;
coverage_result = $get_coverage(); //取功能覆盖率的值
if(coverage_result==100.0)…;

四值逻辑,如果不赋初值,那么初值就是x
reg是四值逻辑
logic代替了reg和wire,可以用于连续赋值,灵活

integer是一个32位的有符号数
time是一个64位的无符号数,是做仿真时间用的
eg:

integer a = -100, b;
time current_time;
b = -a;
current_time = $time;  //返回仿真时间
if(current_time>=100ms) ...

string是一个字符串

数组
fixed- size arrays是固定数组
type array_name[size] [=initial_value];
eg:
integer numbers[5]; //array of 5 integers,indexed 0-4

int b[2] = `{3,7}; //bit[0]=3, bit[1]=7

int c[2][3] = `{{3,7,1},{5,1,9}};

byte d[7][2] = `{default:-1}; //all elements = -1

bit[31:0] a[2][3] = c; //array copy

dynamic arrays:动态数组
type array_name[] [=initial_value]; 只能使一维数组

Queues:队列
type array_name[$] [=initial_value];
不需要分配空间在这里插入图片描述Associative Array:联合数组
type array_name[index_type];
type array_name[*];

在这里插入图片描述数组的循环:foreach

program
	initial begin
		int data[];    //动态数组
		data = new[7];    //为数组分配7个空间
		foreach(data[i]) begin
			data[i] = 255>>i;
			$display("data[%0d]=%0d",i,data[i]);
		end
		$diplay("sum of array content = %0d",data.sum());
	end
endprogram

function array_type[$] array.find() with (expression)
将满足表达式的结果,压入到队列中

function int_or_index_type[$] array.find_index with (expression)
压缩索引号

item可以告诉队列中每个元素的值
eg:

program test;
	bit [7:0] SQ_array[$] = {2,1,8,3,5};
	bit [7:0] SQ[$];
	int idx[$];
	
	SQ = SQ_array.find() with (item > 3);
		//SQ[$] contains 5,8
	idx = SQ_array.find_index() with (item > 3);
		//idx[$] contains 2,4
endprogram

操作符
在这里插入图片描述在这里插入图片描述流程控制在这里插入图片描述task在运行的时候回消耗时间,function不消耗时间
function有输入没有输出,但是有返回值
在function里面不能调用task
在task里面可以调用function在这里插入图片描述program块一般是执行testcase,一般情况下initial begin end就结束了,但是也可以通过$finish去结束它。

subroutine一般是用task function,当endtask或者endfunction就结束,或者return也可以跳出

Loop循环,当end和break都可以跳出结束,continue,进入下一个循环。

system verilog调用C语言在这里插入图片描述在这里插入图片描述如何对DUT的信号进行采样和驱动?
使用Device Drive对DUT进行驱动
使用Monitor对DUT进行采样
怎么同步信号
在这里插入图片描述关于Driver在verilog里面用task进行编写做一些行为级的建模,在SV用面向对象编程

同步驱动:
(1)要使用非阻塞赋值
(2)不能驱动异步信号
(3)不能驱动输入信号在这里插入图片描述
在这里插入图片描述在这里插入图片描述同步信号:
在这里插入图片描述2、并发性
线性执行并行的任务
关键字是fork–join

int a,b,c;
fork
	statement0;
	begin
		statement1;
		statement2;
	end
join | join_any | join_none
statement3;

A;

fork
	begin
		recv();
	end
	begin
		send();
	end
join

这是两个线程

B:

fork
	recv();
	send();
join

两个线程
C:

fork
	begin
		recv();
		send();
	end
join

一个线程,顺序执行recv()和send()
D:

fork
	begin
		begin
			recv();
			send();
		end
		check();
	end
join

一个主线程,两个子线程,其中一个子线程里面还有顺序执行。

fork—join是指其中里面语句执行完了才能执行外面的

fork–join_any是指只有里面有一个语句执行完了就会执行外面的语句

fork—join_none里面和外面的语句同时执行在这里插入图片描述

3、封装OOP(Object Oriented Programming)面向对象编程
OOP就是复用
在这里插入图片描述在这里插入图片描述

class driver;
	string name;
	bit [3:0] sa,da;
	bit [7:0] payload [];
	task send();
		send_addrs();
		send_pad();
		send_payload();
	endtask
	
	task send_addrs();
	...
	endtask
	
	task send_pad();
	...
	endtask
	
	task send_payload();
	...
	endtask
endclass
class node;
	static int count=0;
	string str;
	node next;
	...
	extern task ping();
endclass

task node::ping();
	...
endtask

猜你喜欢

转载自blog.csdn.net/weixin_43727437/article/details/106001176