硬件设计及建模—第12.pptx
SYSTEM VERILOG HARDWARE DESIGN AND MODLEING Wang JinxiangMicroelectronics Center of HIT第1页/共40页参考书:1.Sauart Sutherland,Simon Davidmann.SystemVerilog 硬件设计及建模.科学出版社,2007年2.IEEE Std 1800-2005,SystemVerilog Language Reference Manual LRM第2页/共40页主要内容:1.简介2.声明的位置3.文本值和数据类型4.用户自定义和枚举数据类型5.数组、结构体和联合体6.过程块、任务和函数7.过程语句8.层次化设计9.接口10.设计实例:状态机、ATM开关11.行为级和交易级建模第3页/共40页 为什么要学习SystemVerilog?SystemVerilog起源 SystemVerilog针对硬件设计关键增强第1章 SystemVerilog 简介第4页/共40页1.1 为什么要学?Verilog,VHDL,SystemC SystemVerilog优点 EDA公司的支持!第5页/共40页1.2 SystemVerilog起源 IEEE 1364-2005 Verilog标准的扩展 整合了SUPERLOG、VERA、C、C+及 VHDL特性,同时包括了OVA和PSL断言 SystemVerilog是设计与验证的统一的语言 SystemVerilog与Verilog向下兼容 SystemVerilog是由Accellera标准机构制定第6页/共40页1.2.1 SystemVerilog标准历程2002年6月:SystemVerilog 3.0(综合)2003年5月:SystemVerilog 3.1(验证)2004年5月:SystemVerilog 3.1a2004年6月:Accellera捐赠给IEEE2005年11月:IEEE 18002005 IEEE13642005(Verilog)第7页/共40页1.2.2 SystemVerilog获得的捐赠 SUPERLOG扩展可综合子集CoDesign Automation Open VERA验证语言Synopsys PSL断言IBM Open VERA断言Synopsys DirectC和适用的应用程序设计接口Synopsys 单独编辑和$readmem扩展Mentor Graphics 标签联合体和高层次语言特征BlueSpec第8页/共40页1.3 SystemVerilog关键增强 设计内部的封装通信和协议检查的接口 类似C语言中的数据类型,如int 用户自定义类型(typedef)枚举类型、结构体和联合体 类型转换 package 外部编译单元区域+、-、+=等赋值操作 显式过程块 priority和unique修饰符 通过引用传送到任务、函数和模块第9页/共40页 package定义及从package中导入定义$unit编译声明空间未命名块中的声明增强的时间单位定义第2章 SystemVerilog 声明的位置 logic、enum、typedef、struct第10页/共40页2.1 package在Verilog中,变量、线网、任务和函数的声明必须在module和endmodule关键字之间,如果一个任务在多个模块中被引用,如何处理?Verilog采用include编译指令和其它编码技巧来解决问题,但同时引入了其它的问题,如设计维护等。SystemVerilog借鉴了VHDL中package的概念,很好地解决了这个问题!第11页/共40页2.1.1 package内容 package中的内容在package和endpackage之间定义,可以包含的可综合结构有:1.parameter和localparam常量定义2.const变量定义3.typedef用户自定义类型4.全自动task和function定义5.import语句6.操作符重载定义第12页/共40页2.1.1 package内容 package definitions;parameter VERSION=“1.1”;typedef enum ADD,SUB,MUL opcodes_t;typedef struct logic 31:0 a,b;opcodes_t opcode;instruction_t;function automatic 31:0 multiplier(input 31:0 a,b);return a*b;endfunction endpackage第13页/共40页2.1.2 package内容的引用 四种引用方式:1.用范围解释操作符直接引用2.将package中特定子项导入到模块或接口中3.用通配符导入package中的子项到模块或接口中4.将package中子项导入到$unit中第14页/共40页2.1.2 package内容的引用方法1:module ALU(input definitions:instruction_t IW,input logic clock,output logic 31:0 result);always_ff(posedge clock)begin case(IW.opcode)definitions:ADD:result=IW.a+IW.b;definitions:SUB:result=IW.a IW.b;definitions:MUL:result=definitions:multiplier(IW.a,IW.b);endcase end endmodule第15页/共40页2.1.2 package内容的引用方法2:module ALU(input definitions:instruction_t IW,input logic clock,output logic 31:0 result);import definitions:ADD;import definitions:SUB;import definitions:MUL;import definitions:multiplier;always_ff(posedge clock)begin case(IW.opcode)ADD:result=IW.a+IW.b;SUB:result=IW.a IW.b;MUL:result=multiplier(IW.a,IW.b);endcase end /import definitions:opcodes_t;?endmodule第16页/共40页2.1.2 package内容的引用方法3:module ALU(input definitions:instruction_t IW,input logic clock,output logic 31:0 result);import definitions:*;always_comb begin case(IW.opcode)ADD:result=IW.a+IW.b;SUB:result=IW.a IW.b;MUL:result=multiplier(IW.a,IW.b);endcase end endmodule通配符导入并不自动导入整个package,只是相当于添加了一条搜索路径!第17页/共40页2.1.3 package综合指导package中的的任务和函数必须说明为自动的才能被综合,并且不能包括静态变量。自动任务或函数的存储区在每次调用时才会分配,引用自动package中的自动任务或函数的每个模块看到的是不被其它模块共享的唯一副本,保证了综合前后行为相同。package中的变量声明是不可综合的!第18页/共40页2.2$unit编译单元声明 内容:1.时间单位和精度声明2.变量、常量声明声明4.用户定义数据类型,使用typedef、enum和class5.任务和函数编译单元是同时编译的所有源文件。编译单元为软件工具提供了一种对整个设计的各个子块单独编译的方法。SystemVerilog可以在package,模块、接口和程序块的外部进行声明,这些外部声明在“编译单元域”中,对所有同时编译的模块都是可见的。(与后面的例子似乎有些矛盾!)第19页/共40页2.2$unit编译单元声明 parameter VERSION=“1.2a”;reg resetN=1;typedef struct packed reg 31:0 address;reg 31:0 data;reg 31:0 opcode;instruction_word_t;function automatic int log2(input int n);if(n 1)begin n=n/2;log2+;end return(log2);endfunction第20页/共40页2.2$unit编译单元声明module register(output instruction_word_t q;input instruction_word_t d;input wire clock);always(posedge clock,negedge resetN)if(!resetN)q=0;else q=d;endmodule第21页/共40页2.2$unit编译单元声明编译单元域只作用于同时编译的源文件。每次编译源文件就创建一个唯一仅针对此次编译的编译单元域!假定模块CPU和模块controller都引用外部声明的变量reset,考虑以下两种情况:(1)如果两个模块同时编译(2)如果每个模块分别编译第(2)种情况第二次编译时看不到第一次编译中的reset声明,可能编译失败,也可能使reset成为隐式的net,如果是后一种情况,那么就有了两个叫reset的不同信号!第22页/共40页2.2.1 编码指导(1)不要在$unit空间进行任何声明,所有共享的声明都要在package中进行(2)需要时可以将package导入到$unit中(3)如果声明分散在多个文件中,会使代码结构混乱、逻辑性差、难于调试、产生错误!第23页/共40页2.2.2 标识符搜索规则(1)搜索按IEEE1364 Verilog标准定义的局部声明(2)搜索通配导入到当前作用域的package中的声明(3)搜索编译单元域中的声明(4)搜索设计层次中的声明,遵循IEEE Verilog搜索规则SystemVerilog搜索规则保证了与Verilog完全向后兼容第24页/共40页2.2.3 源代码顺序 module parity_gen(input wire 63:0 data);parity=data;endmodule reg parity;module parity_check(input wire63:0 data,output logic err);assign err=(data!=parity);endmodule一个好习惯:先声明,后引用!编译不会有错,但两个模块中的parity其实并不相同,第一个是隐式的线网,第二个是$unit变量!第25页/共40页 module ALU(input definitions:instruction_t iw,input logic clock;output logic 31:0 result);import definitions:instruction_t;module ALU(input instruction_t iw,input logic clock;output logic 31:0 result);2.2.4 将package导入$unit原则 package也可以通过通配符导入到$unit域中。通配符导入只是将package加到SystemVerilog源路径中!第26页/共40页2.2.4 将package导入$unit原则(1)文件编译顺序信赖性(2)多文件编译与单文件编译(3)每个文件使用导入语句(同时编译时非法!)(4)条件编译将package导入到$unit同样会遇到在$unit中进行声明和定义时的问题!第27页/共40页 ifndef DFFS_DONE define DFFS_DONE package definitions;parameter VERSION=“1.1”;typedef enum ADD,SUB,MUL opcode_t;typedef struct logic 31:0 a,b;opcode_t opcode;instruction_t;function automatic 31:0 multiplier(input 31:0 a,b);return a*b;endfunction endpackage import definitions:*;endif2.2.4 将package导入$unit原则第28页/共40页 include“definitions.pkg”/编译package文件 module alu(input instruction_t IW,input logic clock,output logic 31:0 result);always_comb begin case(IW.opcode)ADD:result=IW.a+IW.b;SUB:result=IW.a-IW.b;MUL:result=multiplier(IW.a,IW.b);endcase end endmodule2.2.4 将package导入$unit原则第29页/共40页 include“definitions.pkg”/编译package文件 module alu_test;instruction_t test_word;logic 31:0 alu_out;logic clock=0;ALU dut(.IW(test_word),.result(alu_out),.clock(clock);always#10 clock=clock;initial begin (negedge clock)test_word.a=5;test_word.b=7;test_word.opcode=ADD;/endmodule2.2.4 将package导入$unit原则如果definitions.pkg单独编译如何?第30页/共40页2.2.5 综合指导在编译单元域声明的可综合结构有:(1)typedef用户定义类型(2)自动函数(3)自动任务(4)parameter和localparam常量(5)package导入 package中定义的变量是共享变量,不可综合 package中定义的静态任务和函数也是不可综合的!第31页/共40页2.3 未命名语句块中的声明 Verilog允许在命名的beginend或forkjoin块中声明局部变量,局部变量避免了对同名但用途不同的模块级变量的无意义访问。module chip(input clock);integer i;always(posedge clock)begin:loop integer i;for(i=0;i=127;i=i+1)begin end end endmodule 第32页/共40页2.3 未命名语句块中的声明 在命名块中声明的变量可以用包含块名的层次路径引用,层次化引用不可综合,通常在验证程序使用。module test;reg clock;chip chip(.clock(clock);always#5 clock=clock;initial begin clock=0;repeat(5)(negedge clock);$display(“chip.i=%0d”,chip.i);$display(“chip.loop.i=%0d”,chip.loop.i);end endmodule 第33页/共40页2.3 未命名语句块中的声明 SystemVerilog扩展了Verilog,允许在未命名块中声明变量,语法与在命名块中声明相同。module chip(input clock);integer i;always(posedge clock)begin integer i;for(i=0;i=127;i=i+1)begin end end endmodule 未命名块中声明的变量不能被层次化引用!第34页/共40页2.4 仿真时间单位和精度 Verilog语言不能在时间值后指定时间单位,时间值之间有简单的关系如1时间单位延时3个时间单位延时,可是 always#5 clock=clock;时钟周期是多长?10ps?10ns?10ms?单从这条语句本身不能得到答案,那么Verilog中又是如何解决的呢?第35页/共40页2.4.1 编译指令timescale 编译指令timescale包括两部分:时间单位和时间精度,时间精度表明仿真时时间的最小取值。timescale对文件编译顺序有依赖性。timescale 1ns/1ns module A();nand#3();endmodule module B();nand#5();endmodule timescale 1ms/1ms module C();nand#2();endmodule timescale 1ns/1ns module A();nand#3();endmodule module B();nand#5();endmodule timescale 1ms/1ms module C();nand#2();endmoduleFile AFile BFile CFile AFile CFile B第36页/共40页2.4.2 SystemVerilog时间单位和精度1.包含时间单位的时间值:module adder(input wire63:0 a,b,output reg 63:0 sum,output reg carry);timeunit 1ns;timeprecision 10ps;/是模块的一部分,/而不是作为软件工具的指令 endmodule2.使用关键字timeunit和timeprecision:forever#5ns clock=clock;/时间值与单位之间不能有空格!timeunit和timeprecision使模块、接口或程序块与时间单位和精度信息直接绑定,解决了timescale存在的不确定性和对文件顺序的依赖性。它必须在其它声明或语句之前,紧随模块、接口或程序的声明之后第37页/共40页2.4.3 编译单元的时间单位和精度 timeunit和timeprecision的声明可以在编译单元域中,但必须在其它声明的前面1.如果时间值带时间单位,使用指定的单位2.使用在模块、接口和程序块内部指定的时间单位和精度3.使用父模块或接口指定的时间单位和精度4.使用有效的timescale时间单位和精度5.使用在编译单元域中定义的时间单位和精度6.使用仿真器默认的时间单位和精度时间单位和精度搜索次序:该搜索顺序保证了SystemVerilog模型与Verilog模型兼容!第38页/共40页 timeunit 1ns;/外部声明的时间单位和精度 timeprecision;module my_chip();timeprecision 1ps;/局部精度 always(posedge data_request)begin#2.5 send_packet;/使用外部单位和局部精度#3.75ns check_crc;/使用指定的单位 end endmodule timescale 1ps/1ps /优先于外部声明 module FSM();timeunit 1ns;/优先于timescale的指定 always(state)begin#1.2 case(state)/使用局部单位和timescale的精度 WAIT#20ps;/使用此处指定的单位 end endmodule2.4.3 编译单元的时间单位和精度第39页/共40页感谢您的观看!第40页/共40页