不同抽象级别的Verilog HDL模型

写在最前面(记录下自己):

7月初,毕业离校就开始自学IC验证,某乎上面建议学习verilog、systemverilog、UVM。

花了三天时间看完了一本verilog语法,知道一些规则,就结合FPGA实战项目(状态机、交通灯等),学习了数字电路、Verilog,熟悉语法点、看的懂部分代码,通过quartus II进行了仿真(功能仿真、后仿真);

后来又去某乎,别人建议参考绿皮书、红宝书、白皮书学习systemverilog、UVM,这有颜色的书是什么呀?于是乎,就去各大辅导机构招生群里咨询,最终确认:

  1. 绿皮书SystemVerilog验证+测试平台编写指南
  2. 白皮书:张强的 UVM实战
  3. 红宝书:刘斌的 芯片验证漫游指南

接下来就去啃这三本书,看路桑的V2视频,学完SystemVerilog、UVM,会简单使用Questasim,只做了几个简单的练习,但是抛过课程,自己连个interface都不会写,别说自己写出testbench,发现这和FPGA的项目完全不一样。后来就去练习Synopsys公司的一个的SV实验,但实验教程上面使用的VCS逻辑仿真工具,我用Questasim会出错,于是就去找VCS。结果呢?

好吧,结果电脑BIOS进不去,虚拟化没办法打开,虚拟机没办法安装,申请了免费的服务器,被迫学习linux、shell、gvim。然后发现服务器上安装不了图形化界面。好吧,人生中真正属于自己的电脑该有了,把去年攒的奖学金全部拿出来,刚好入手战神Z7-CT7NA(i7-9750H、GTX1660Ti)。

既然有了战神,那速度还可以吧,虚拟机就位,cenos7、Redhat就位,vcs就位。既然环境有了,就去学习VCS,结果又附加学习Makefile、DC、verilog。
 
 
这四十天,看的书有:《快速阅读:一年轻松读完1000本书》、《变态心理学》、《verilog编程艺术》、《细说linux基础知识》、《芯片验证漫游指南》、《太极拳》、《坏小孩》、《非暴力沟通》、《自卑与超越》、《戴老师魔性诗词课》、《共情式沟通》
这四十天,干的农活有:晒小麦,栽ren,拔草,碾胡麻,到兔场清粪
这四十天,进过城,办过贷款,打过斯诺克,开过奥迪A6L
 
 
突然就想去找夏老师的verilog实战去看看,这篇文章就来了。
 

第九章 不同抽象级别的Verilog HDL模型

Verilog模型可以是实际电路不同级别的抽象。这些抽象的级别和它们对应的模型类型共有以下五种:
1) 系统级(system)
2) 算法级(algorithmic)
3) RTL级(RegisterTransferLevel):
4) 门级(gate-level):
5) 开关级(switch-level)
 
一个复杂电路的完整Verilog HDL模型是由若干个Verilog HDL模块构成的,每一个模块又可以由若干个子模块构成。这些模块可以分别用不同抽象级别的Verilog HDL描述,在一个模块中也可以有多种级别的描述。利用Verilog HDL语言结构所提供的这种功能就可以构造一个模块间的清晰层次结构来描述极其复杂的大型设计。

门级结构描述

and 与门
nand 与非门
nor 或非门
or 或门
xor 异或门
xnor 异或非门
buf 缓冲器
not 非门
nand #10 nd1(a,data,clock,clear);
表示在模块中引用了一个名为nd1的与非门(nand),输入为data、clock和clear,输出为a,输出与输入的延时为10个单位时间。
 

1.如何用Verilog HDL语言描述D型主从触发器模块?

门级结构描述D触发器
不同抽象级别的Verilog HDL模型_第1张图片
 
门级结构描述D型主从触发器模块的Verilog 代码如下:
//flop.v
module flop(data,clock,clear,q,qb);
		input data,clock,clear;
		output q,qb;

        nand  #10   nd1(a,data,clock,clear),    //  注意结束时用逗号,最后才用分号
                    nd2(b,ndata,clock),         // 表示nd1 到nd8 都是nand(与非门)
                    nd4(d,c,b,clear),
                    nd5(e,c,nclock),
                    nd6(f,d,nclock),
                    nd8(qb,q,f,clear);
        nand  #9    nd3(c,a,d),
                    nd7(q,e,qb);
        not #10     iv1(ndata,data),
                    iv2(nclock,clock);
endmodule
上面module和endmodule之间构成的模块,命名为flop.v
 
当在其他模块中引用这个模块时,有两种方法(顺序法、端口名对应法)
 
顺序法1) flop flop_d( d1, clk, clrb, q, qn);
端口名2) flop flop_d (.clock(clk),.q(q),.clear(clrb),.qb(qn),.data(d1));
 
它们都表示实例f1op_d 引用已编模块 flop。只是如果采取顺序法实例的端口信号必须按照被引用模块的端口信号传入;采用端口名法,实例的端口信号和被引用模块的端口信号必需一一列出
 

2.如何引用上面的模块flop,构成一个四位寄存器?

由已经设计成的模块来构成更高一层的模块

不同抽象级别的Verilog HDL模型_第2张图片

引用上面的模块flop,构成一个四位寄存器,代码如下:

//hardreg.v
//` include  " flop.v"
module	hardreg(d,clk,clrb,q);
input		clk,clrb;
input[3:0]	d;
output[3:0]	q;

flop	  f1(d[0],clk,clrb,q[0],),   // 注意结束时用逗号,最后才用分号
          f2(d[1],clk,clrb,q[1],),   // 表示f1 到f4 都是flop
          f3(d[2],clk,clrb,q[2],),
f4(d[3],clk,clrb,q[3],);

endmodule

既然四位寄存器的verilog已经出炉了,我最关心的部分已经来了。

3.如何对于上面的四位寄存器进行验证?

testbench代码如下。

//hardreg_top.v
//`include "flop.v"
//`include " hardreg.v"      //仿真时需要包含文件"hardreg.v" 和 "flop.v" 
/***如果仿真环境可以把有关的文件安排在一个项目中,只要底层模块经过编译,并记录在编译的库中,可以不用包含文件。**/
module  hardreg_top;         //顶层模块,没有输入和输出的端口
reg clock, clearb;           //为产生测试用的时钟和清零信号需要寄存器 
reg [3:0] data;           //为产生测试用数据需要用寄存器
wire [3:0] qout;            //为观察输出信号需要从模块实例端口中引出线

 `define  stim  #100 data=4'b	        //宏定义 stim,可使源程序简洁
  event  end_first_pass;		        //定义事件end_first_pass

hardreg  reg_4bit (.d(data), .clk(clock), .clrb(clearb), .q(qout));
/************************************************************************
把本模块中产生的测试信号data、clock、clearb输入实例reg_4bit以观察输出信号qout。
实例reg_4bit实际上是已经设计好的模块hardreg。
实例引用的hardreg模块,根据包含文件的不同, 可以是表示行为的模块也可以是表示结构的模块。
***********************************************************************/

initial
	begin
	 clock = 0;
	 clearb = 1;
	end	
	
	always #50 clock = ~clock;

	always @(end_first_pass)
	clearb = ~clearb;

	always @(posedge clock)
           $display("at time %0d clearb= %b data= %d qout= %d",
                      $time, clearb, data, qout);
/*****************************************************
    类似于C语言的 printf 语句,可打印不同时刻的信号值
******************************************************/
initial
	begin
	repeat(4)		//重复四次产生下面的data变化
		begin
			data=4'b0000;
			`stim 0001;
/***************************************************************
			  宏定义stim引用,等同于 #100 data=4'b0001;。注意引用时要用 `符号。
******************************************************/
			`stim 0010;
			`stim 0011;
			`stim 0100;
			`stim 0101;
			`stim 0110;
			`stim 0111;
			`stim 1000;
			`stim 1001;
			`stim 1010;
			`stim 1011;
			`stim 1100;
			`stim 1101;
			`stim 1110;
			`stim 1111;
			#200 -> end_first_pass;
		 end
/***********************************************
延迟200个单位时间,触发事件end_first_pass
************************************************/
		$finish;		//结束仿真
	end
endmodule

4.既然有了所有的代码,就进入linux开始VCS编译仿真

编译

 
运行上面的命令,产生的效果如下(多了四个文件):
 
不同抽象级别的Verilog HDL模型_第3张图片
 

仿真

运行上面的命令,产生的效果如下(是不是多了两个文件):

不同抽象级别的Verilog HDL模型_第4张图片

运行./simv -gui打开DVE图形化界面不同抽象级别的Verilog HDL模型_第5张图片

不同抽象级别的Verilog HDL模型_第6张图片

好吧,我暂且认为是自己的testbench中没有加$vcdpluson()造成的。

5.重新盘一下第四步为什么没有波形文件

1、编译

要想有波形文件,必须在testbench中加入$vcdpluson类似的的语句,最简单的格式如下:

initial begin
    $vcdpluson;
end

编译的时候,必须加上“+vcd+vcdpluson”开关,在仿真时才能产生波形文件,使用如下命令编译:

vcs *.v -l readme.log +v2k  -debug_all +vcd+vcdpluson

vcs  *.v                  就是编译的主要命令

-l readme.log         就是把编译过程记录在文件readme.log中,以备后面查看

+v2k                       好像是遵守verilog 2005 标准编译吧

-debug_all              就是打开所有的debug开关,还有-debug_pp、-debug

+vcd+vcdpluson     在仿真时才能产生波形文件

不同抽象级别的Verilog HDL模型_第7张图片

2.仿真

命令如下:

./simv -l run.log

./simv         就可以生成波形文件vcdpluson.vpd

-l run.log   把仿真的过程记录在文件run.log中,以备后面查看

不同抽象级别的Verilog HDL模型_第8张图片

3.看波形

dve –vpd vcdpluson.vpd

结果又报错了,尽管打开了dve,但是打不开波形文件

不同抽象级别的Verilog HDL模型_第9张图片

修改文件名,继续!结果不知道为什么是这样!就这样吧

不同抽象级别的Verilog HDL模型_第10张图片

写在最后

我现在真的不知道该怎么学习验证了。昨天问学长,他怎么学的verilog,他说就简单看了一下verilog语法,也没练习。我该怎么做呀!有点难搞,炸裂,裂开。

你可能感兴趣的:(VCS,verilog,verilog)