ImageVerifierCode 换一换
格式:DOCX , 页数:38 ,大小:32.79KB ,
资源ID:1468727      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bingdoc.com/d-1468727.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(牛人的Systemverilog总结Word格式文档下载.docx)为本站会员(b****1)主动上传,冰点文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰点文库(发送邮件至service@bingdoc.com或直接QQ联系客服),我们立即给予删除!

牛人的Systemverilog总结Word格式文档下载.docx

1、 /释放空间l 队列在队列中增加或删除元素比较方便。l 关联数组当你需要建立一个超大容量的数组。关联数组,存放稀疏矩阵中的值。采用在方括号中放置数据类型的形式声明:Bit63:0 assocbit63:0;l 常量:1)Verilog 推荐使用文本宏。好处:全局作用范围,且可以用于位段或类型定义缺点:当需要局部常量时,可能引起冲突。2)Parameter 作用范围仅限于单个module3)Systemverilog: 参数可以在多个模块里共同使用,可以用typedef 代替单调乏味的宏。过程语句l 可以在for循环中定义变量,作用范围仅在循环内部for(int i=0;i10;i+)array

2、i =i;l 任务、函数及void函数1) 区别:Verilog中task 和function最重要的区别是:task可以消耗时间而函数不能。函数中不能使用#100的延时或的阻塞语句,也不能调用任务;Systemverilog中函数可以调用任务,但只能在fork joinnone生成的线程中。2)使用: 如果有一个不消耗时间的systemverilog任务,应该把它定义成void函数;这样它可以被任何函数或任务调用。 从最大灵活性角度考虑,所有用于调用的子程序都应该被定义成函数而非任务,以便被任何其它任务或函数调用。(因为定义成任务,函数调用任务很有限制)l 类静态变量作用:1)类的静态变量,

3、可以被这个类的对象实例所共享。当你想使用全局变量的时候,应该先想到创建一个类的静态变量静态变量在声明的时候初始化。2)类的每一个实例都需要从同一个对象获取信息。l 静态方法当静态变量很多的时候,操作它们的代码是一个很大的程序,可以用在类中创建一个静态方法读写静态变量,但是静态方法不能读写非静态变量。l ref高级的参数类型Ref 参数传递为引用而不是复制。Ref比 input 、output、inout更好用。Function void print_checksum(const ref bit 31:0 a );1) 也可以不用ref进行数组参数传递,这时数组会被复制到堆栈区,代价很高。2)

4、用带ref 进行数组参数传递,仅仅是引用,不需要复制;向子程序传递数组时,应尽量使用ref以获得最佳性能,如果不希望子程序改变数组的值,可以使用const ref。3) Ref参数,用ref 传递变量;可以在任务里修改变量而且,修改结果对调用它的函数可见,相对于指针的功能。l Return语句增加了return语句。Task任务由于发现了错误而需要提前返回,如果不这样,那么任务中剩下的语句就必须被放到一个else条件语句中。体会下Task load_array(int len. Ref int array );If(len0) begin $display(“Bad len”); Returu

5、n;/任务中其它代码 endtaskl 局部数据存储 automatic作用Verilog中由于任务中局部变量会使静态存储区,当在多个地方调用同一个任务时,不同线程之间会窜用这些局部变量。Systemverilog中,module和program块中,缺省使用静态存储;如果想使用自动存储,需加入automatic关键词。测试平台l Interface背景 :一个信号可能连接几个设计层次,如果增加一个信号,必须在多个文件中定义和连接。接口可以解决这些问题。如果希望在接口中增加一个信号,不需要改变其他模块,如TOP模块。(1)接口中去掉信号的方向类型;(2)DUT 和测试平台中,信号列表中采用接口

6、名,例化一个名字注意:因为去掉了方向类型,接口中不需要考虑方向信号,简单的接口,可以看做是一组双向信号的集合。这些信号使用logic类型d1 。双向信号为何可以使用logic呢?这里的双向,只是概念上的双向,不想verilog中databus多驱动的双向。双向信号如何做接口?(1)仲裁器的简单接口Interface arb_if( input bit clk); Logic 1:0 grant,request; Logic rst;EndinterfaceDUT 使用接口:Module arb(arb_if arbif);Always (posedge arbif.clk or negedge

7、 arbif.rst) endmodule(2)DUT 不采用接口,测试平台中使用接口(推荐) DUT 中源代码不需要修改,只需要再top中,将接口连接到端口上。 Module top; Bit clk; Always #2 clk =clk; Arb_if arbif(clk); Arb_port al(.grant(arbif.grant), .request(arbif.grant), .rst(arbif.rst), .clk(arbif.clk) ); Test t1(arbif); Endmodulel Modport背景:端口的连接方式包含了方向信息,编译器依次来检查连续错误;接

8、口使用无信号的连接方式。Modport将接口中信号分组并指定方向。例子:l 在总线设计中使用modport并非接口中每个信号都必须连接。Data总线接口中就解决不了,个人觉得?因为data是一个双驱动l 时钟块一旦定义了时钟块,测试平台就可以采用arbif.cb等待时钟,而不需要描述确切的时钟信号和边沿,即使改变了时钟块中的时钟或边沿,也不需要修改测试代码应用:将测试平台中的信号,都放在clocking 中,并指定方向(以测试平台为参考的方向)。并且在modprot test(clocking cb,最完整的接口:Interface arb_if(input bit clk);Logic1:L

9、ogic rst;Clocking cb (posedge clk); Output request; Input grant;EndclockingModport test (clocking cb, Output rst);Modport dut (input clk, request,rst, Output grant); endinterface变化:将request 和grant移动到时钟块中去了,test中没有使用了。l 接口中的双向信号Interface master_if(input bit clk); /在类中为了,不使用有符号数,常用bit定义变量 Wire 7:0 dat

10、a; Clocking cb(posedge clk); Inout data; Endclocking Modport TEST(clocking cb);endinterfaceprogram test(master_if mif);initial begin mif.cb.data = z;mif.cb;$display(mif.cb.data); /总线中读数据Mif.cb.data = 8h5a; /驱动总线 /释放总线注:(1)interface 列表中clk 采用的是input bit clk;为什么要用bit?(2)时钟块 clocking cb 中,一般将testbench中

11、需要的信号,方向指定在这里; 而在modprot 指定test信号方向的时候,采用clocking cb。(3)interface中信号,不一定都用logic,也可采用wire(双驱动);systemverilog中如果采用C代码的风格(参数列表中方向和类型写一起),必须采用logic类型(4)现在的风格,DUT 没才用clocking cb ,测试平台和DUT的时钟如何统一?l 激励时序DUT和测试平台之间时序必须密切配合。l 测试平台和设计间的竞争状态好的风格:使用非阻塞赋值可以减少竞争。systemverilog验证中initial 中都采用= 赋值,而等待延迟采用arbif.cb等待一

12、个周期来实现。而verilog中采用的风格时,initial 中采用 =阻塞赋值,沿时可以采用#2,等实现。因此时钟发生器,只能放在module 中,而不能放在program中l Program中不能使用always块测试平台可以使用initial 但不能使用always,使用always 模块不能正常工作。原因:测试平台的执行过程是进过初始化、驱动和响应等步骤后结束仿真。如果确实需要一个always块,可以使用initial forever 来完成。比如:在产生时钟时。类l 类中static变量如果一个变量需要被其他对象所共享,如果没有OPP,就需要创建全局变量,这样会污染全局名字空间,导致

13、你想定义局部变量,但变量对每个人都是可见的。1)作用:类中static变量,将被这个类的所有实例(对象)所共享,使用范围仅限于这个类。例:class transaction; Static int count=0; Int id;EndclassTrasaction tr1,tr2;Id不是静态变量,所以每个trasaction对象都有自己的id;count 是静态变量,所有对象只有一个count变量。如何用?当你打算创建一个全局变量的时候,首先考虑创建一个类的静态变量。2)static变量的引用句柄或类名加:4) static 变量的初始化static变量通常在声明时初始化。不能在构造函数中

14、初始化,因为每一个新的对象都会调用构造函数。l 静态句柄:当类的每一个对象,都需要从同一个对象(另一个类)中获取信息的时候。如果定义成非静态句柄,则每个对象都会有一份copy,造成内存浪费。当使用更多静态变量的时候,操作他们的代码会很长。可以在类中创建一个静态方法用于读写静态变量。systemverilog不允许,静态方法读写非静态变量。l 类之外的方法解决类太长的问题。类最好控制在一页内,如果方法很都很长。l This如果在类很深的底层作用域,却想引用类一级的对象。在构造函数中最常见。this指向类一级变量l 如何做类,类做多大?上限:类不能太大当类中存在多处相同的代码,你需要将这段代码做成

15、当前类的一个成员函数或父类的成员函数。下限:类不能太小类太小,增加了层次。方法:如果一个小类只被例化了一次,可以将它合并到父类中去。l 动态对象概念区分:方法中修改对象 和修改句柄修改对象将对象的变量重新赋值。修改句柄在任务中new()对象。1) 当你将对象传递给方法句柄,new()后变成对象,在将其作为参数传递给方法。实质和作用:传递的是句柄。这个方法可以读取对象中的值;也以改变对象中的值2) 修改标量变量的值在方法的参数中,前面加ref;(用ref传递,ref传递的是变量的地址)。 方法可以修改变量的值,并将修改的值,传递给主程序。引申:方法可以改变对象,即使没有使用ref 修饰句柄。 因

16、为传递的是句柄,句柄是地址。不要将句柄和对象混为一谈,如果传递的是对象,对象是单向的,那方法以外也不能传递回来。可以这样理解吧。 读写对象中的值:Task transmit(Transcation t); Cbbus.rx_data 和ifelse可产生和case效果类似的语句块,可以用于枚举类型的表达式。l 双向约束l 控制多个约束块可以打开或关闭某个约束可以使用内建的Handle.constraint.constraint_mode()打开或关闭。l 内嵌约束很多测试只会在代码的一个地方随机化对象,但是约束越来越复杂时,Systemverilog可以使用randomized with 来增

17、加额外的约束,这和在类里增加的约束是等效的。l Pre_randomize 和post_randomize函数有时候需要再调用randomize()之前或之后立即执行一些操作。随机化前:设置类里的一些非随机变量(如上下限、权重),随机化后:计算数据的误差矫正值。l 约束的技巧1) 约束中使用变量2) 使用非随机值如果一套约束在已产生了几乎所有想要的激励向量,但还缺少几种。可以使用rand_mode把这些变量设置为非随机变量。l 数组约束Systemverilog可以用foreach对数组中的每一个元素进行约束。线程及线程间的通信l 测试平台使用许多并发执行的线程。测试平台隶属于程序块。Syst

18、emverilog引入两种新的创建线程的方法forkjoin_none和forkjoin_any1) 使用forkjoin_none来产生线程在调度其内部语句时,父线程继续执行。2) 使用forkjoin_any实现线程同步在调度块内语句,当第一个语句执行完,父线程才继续执行。l 动态线程Systemverilog中可以动态创建线程。用法:forkjoin_none放在了任务中,而不是包含两个线程。主程序中有连个线程:发送和检测线程。但是不能同时启动,发送事物后,才能检测,否则还未产生数据,就开始检测;但是检测又不能阻塞下一次发送事物的线程。所以forkjoin_none 放在了检测task

19、任务(后作用的线程中)中,测试平台产生随机事物并发送到DUT中,DUT把事物返回到测试平台。测试平台必须等到事物完成,但同时不希望停止随机事物的发送。Program automatic test(bus_ifc.Tbbus);Task check_trans(Transaction tr);Fork Begin Wait(bus.cb.addr = tr.addr); EndJoin_noeEndtask Repreat(10) begin Tr= new(); Assert.(tr.randomize(); /把事物发送到DUT中 Transmit(tr); /等待DUT的回复 Check_

20、trans(tr);#100;endprograml 并发线程中务必使用自动变量来保持数值。l #0 延迟,使得当前线程必须等到forkjoin_none语句中产生的线程执行完后,才得以运行。l 停止线程1) 停止单个线程使用fork .join_any 后加disable。3) 停止多个线程Disable fork 能停止从当前线程中衍生出来得所有子线程。应该使用fork .join 把目标代码包含起来,以限制Disable fork的作用范围。l 事件Verilog中当一个线程在一个事件上发生阻塞的同时,正好另一个线程触发了这个事件,则竞争就出现了。如果触发线程先于阻塞线程,则触发无效(触

21、发是一个零宽度的脉冲)。解决方法:Systemverilog 引入了triggered()函数,用于检测某个事件是否已被触发过,包括正在触发。线程可以等待这个结果,而不用在操作符上阻塞。Event e1,e2; -e1; e2;e2; e1;上面的代码,假设先执行第一个块,再执行第二个块。第一个块会阻塞在e2(阻塞先执行),直到e2触发,再运行(触发后执行);在执行第二个块时,会阻塞在e1,但是e1已经触发(触发先执行,阻塞后执行,触发是个零宽度的脉冲,会错过第一个事件而锁住)用wait(e1.triggered()来代替阻塞el,如果先触发,也可以执行。l 等待多个事件最好的办法是:采用线程计数器来等待多个线程。l 旗语Get()可以获取一个或多个钥匙,put()可以返回一个或多个钥匙。Try_get()获取一个旗语而不被阻塞。l 信箱

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2