第六章 Verilog的数据类型及逻辑系统
学习 Verilog逻辑值系统
学习 Verilog中不同类的数据类型
理解每种数据类型的用途及用法
数据类型说明的语法学习内容:
Verilog采用的四值逻辑系统
0?,Low,False,Logic Low,Ground,VSS,
Negative Assertion
1?,High,True,Logic High,Power,
VDD,VCC,Positive Assertion
X? Unknown,Occurs at Logical Which Cannot
be Resolved Conflict
HiZ,High Impedance,Tri- Stated,
Disabled Driver (Unknown)
主要数据类型
Verilog主要有三类 (class)数据类型:
net (线网),表示器件之间的物理连接
register (寄存器),表示抽象存储元件
parameters(参数 ),运行时的常数 (run-time constants)
net(线网)
net需要被持续的驱动,驱动它的可以是门和模块。
当 net驱动器的值发生变化时,Verilog自动的将新值传送到 net上。在例子中,线网 out由 or门驱动。当 or门的输入信号置位时将传输到线网 net上。
net类的类型(线网)
有多种 net类型用于设计 (design-specific)建模和工艺
(technology-specific)建模
没有声明的 net的缺省类型为 1 位 (标量 )wire类型。但这个缺省类型可由下面的编译指导改变:
`default_nettype <nettype>
net类型 功 能
wire,tri
supply1,supply0
wor,trior
wand,triand
trireg
tri1,tri0
标准内部连接线 (缺省 )
电源和地多驱动源线或多驱动源线与能保存电荷的 net
无驱动时上拉 /下拉综合编译器不支持的 net类型
net类的类型(线网)
wire类型是最常用的类型,只有连接功能。
wire和 tri类型有相同的功能。用户可根据需要将线网定义为 wire或 tri以提高可读性。例如,可以用 tri类型表示一个 net有多个驱动源。或者将一个 net声明为
tri以指示这个 net可以是高阻态 Z(hign-impedance)。可推广至 wand和 triand、
wor和 trior
wand,wor有线逻辑功能;与 wire的区别见下页的表。
trireg类型很象 wire类型,但 trireg类型在没有驱动时保持以前的值。这个值的强度随时间减弱。
修改 net缺省类型的编译指导:
`default_nettype <nettype>
nettype不能是 supply1和 supply0。
net类在发生逻辑冲突时的决断
Verilog有预定义的决断函数
支持与工艺无关的逻辑冲突决断
– wire-and用于集电极开路电路
– wire-or用于射极耦合电路寄存器类 ( register)
寄存器类型在赋新值以前保持原值
寄存器类型大量应用于行为模型描述及激励描述。在下面的例子中,
reg_a,reg_b,reg_sel用于施加激励给 2:1多路器。
用行为描述结构给寄存器类型赋值。给 reg类型赋值是在过程块中。
寄存器类的类型
寄存器类有四种数据类型寄存器类型 功能
reg 可定义的无符号整数变量,可以是标量 (1位 )或矢量,是最常用的寄存器类型
integer 32位有符号整数变量,算术操作产生二进制补码形式的结果。通常用作不会由硬件实现的的数据处理。
real 双精度的带符号浮点变量,用法与 integer相同。
time 64位无符号整数变量,用于仿真时间的保存与处理
realtime 与 real内容一致,但可以用作实数仿真时间的保存与处理
不要混淆寄存器数据类型与结构级存储元件,如 udp_dff
Verilog中 net和 register声明语法
net声明
<net_type> [range] [delay] <net_name>[,net_name];
net_type,net类型
range,矢量范围,以 [MSB,LSB]格式
delay,定义与 net相关的延时
net_name,net名称,一次可定义多个 net,用逗号分开。
寄存器声明
<reg_type> [range] <reg_name>[,reg_name];
reg_type:寄存器类型
range,矢量范围,以 [MSB,LSB]格式。只对 reg类型有效
reg_name,寄存器名称,一次可定义多个寄存器,用逗号分开
Verilog中 net和 register声明语法
举例:
reg a; //一个标量寄存器
wand w; // 一个标量 wand类型 net
reg [3,0] v; // 从 MSB到 LSB的 4位寄存器向量
reg [7,0] m,n; // 两个 8位寄存器
tri [15,0] busa; // 16位三态总线
wire [0,31] w1,w2; // 两个 32位 wire,MSB为 bit0
选择正确的数据类型
module top;
wire y;
reg a,b;
DUT u1 (y,a,b) ;
initial begin
a = 0; b = 0;
#5 a = 1;
end
endmodule
module DUT (Y,A,B);
output Y;
input A,B;
wire Y,A,B;
and (Y,A,B) ;
endmodule
输入端口可以由
net/register驱动,但输入端口只能是 net
输出端口可以是
net/register类型,输出端口只能驱动 net
在过程块中只能给
register类型赋值若 Y,A,B说明为
reg则会产生错误。
in1
in2
O
A
B
Y
双向端口输入 /输出只能是 net类型选择数据类型时常犯的错误
用过程语句给一个 net类型的或忘记声明类型的信号赋值。
信息,illegal …… assignment.
将实例的输出连接到声明为 register类型的信号上。
信息,<name> has illegal output port specification.
将模块的输入信号声明为 register类型。
信息,incompatible declaration,<signal name> ……
下面所列是常出的错误及相应的错误信息 (error message)
信号可以分为端口信号和内部信号。出现在端口列表中的信号是端口信号,其它的信号为内部信号。
对于端口信号,输入端口只能是 net类型。输出端口可以是 net类型,也可以是 register类型。若输出端口在过程块中赋值则为 register类型;若在过程块外赋值 (包括实例化语句),则为 net类型。
内部信号类型与输出端口相同,可以是 net或 register类型。判断方法也与输出端口相同。若在过程块中赋值,则为 register类型;若在过程块外赋值,则为 net类型。
若信号既需要在过程块中赋值,又需要在过程块外赋值。这种情况是有可能出现的,如决断信号。这时需要一个中间信号转换。
信号类型确定方法总结如下:
选择数据类型时常犯的错误举例修改前:
module example(o1,o2,a,b,c,d);
input a,b,c,d;
output o1,o2;
reg c,d;
reg o2
and u1(o2,c,d);
always @(a or b)
if (a) o1 = b; else o1 = 0;
endmodule
修改后:
module example(o1,o2,a,b,c,d);
input a,b,c,d;
output o1,o2;
// reg c,d;
// reg o2
reg o1;
and u1(o2,c,d);
always @(a or b)
if (a) o1 = b; else o1 = 0;
endmodule
example.v
选择数据类型时常犯的错误举例
Compiling source file "example.v"
Error! Illegal left-hand-side assignment [Verilog-ILHSA]
"example.v",11,o1 = b;
Error! Illegal left-hand-side assignment [Verilog-ILHSA]
"example.v",12,o1 = 0;
2 errors
第一次编译信息
verilog –c example.v
第二次编译信息
Compiling source file "example.v"
Error! Incompatible declaration,(c) defined as input
at line 2 [Verilog-IDDIL]
"example.v",5,
Error! Incompatible declaration,(d) defined as input
at line 2 [Verilog-IDDIL]
"example.v",5,
Error! Gate (u1) has illegal output specification [Verilog-GHIOS]
"example.v",8,
3 errors
参数( parameters)
用参数声明一个可变常量,常用于定义延时及宽度变量。
参数定义的语法,parameter <list_of_assignment>;
可一次定义多个参数,用逗号隔开。
在使用文字 (literal)的地方都可以使用参数。
参数的定义是局部的,只在当前模块中有效。
参数定义可使用以前定义的整数和实数参数。
module mod1( out,in1,in2);
.,,
parameter cycle = 20,prop_ del = 3,
setup = cycle/2 - prop_del,
p1 = 8,
x_ word = 16?bx,
file = "/ usr1/ jdough/ design/ mem_ file,dat";
.,,
wire [p1,0] w1; // A wire declaration using parameter
.,,
endmodule
注意,参数 file不是 string,
而是一个整数,其值是所有字母的扩展 ASCII值。若
file=―AB‖,则 file值为
8?h4142。用法:
$fopen(file);
$display(―%s‖,file);
参数重载( overriding)
可用 defparam语句在编译时重载参数值。
defparam语句引用参数的层次化名称
使用 defparam语句可单独重载任何参数值。
Defparam语句 (现在综合工具还不支持)
module mod1( out,in1,in2);
.,,
parameter p1 = 8,
real_constant = 2.039,
x_word = 16?bx,
file =
"/usr1/jdough/design/mem_file.dat";
.,,
endmodule
module test;
.,,
mod1 I1( out,in1,in2);
defparam
I1,p1 = 6,
I1,file = "../ my_mem.dat";
.,,
endmodule
参数重载( overriding)
module mod1( out,in1,in2);
.,,
parameter p1 = 8,
real_constant = 2.039,
x_word = 16?bx,
file = "/usr1/jdough/design/mem_file.dat";
.,,
endmodule
module top;
.,,
mod1 #( 5,3.0,16?bx,"../ my_mem,dat") I1( out,in1,in2);
.,,
endmodule
模块实例化时参数重载使用 #
次序与原说明相同不需要给所有参数赋新值,但不能跳跃赋值,假设模块 MOD顺序定义三个参数 a,b,c,则:
MOD u1 #( a,b) (...);
MOD u2 #(a) (...);
MOD u3 #(a,,c) (...);
MOD u4 #(,b,c) (...);
为什么编译器认为这是参数而不是延时呢?
因为 #说明延时的时候只能用于 gate或过程语句,不能用于模块实例。
gate( primitives)在实例化时只能有延时,不能有模块参数。
寄存器数组 (Register Arrays)
在 Verilog中可以说明一个寄存器数组。
integer NUMS [7,0]; // 包含 8个整数数组变量
time t_vals [3,0]; // 4个时间数组变量
reg类型的数组通常用于描述存储器其语法为,reg [MSB:LSB] <memory_name> [first_addr:last_addr];
[MSB:LSB]定义存储器字的位数
[first_addr:last_addr]定义存储器的深度例如:
reg [15,0] MEM [0:1023]; // 1K x 16存储器
reg [7,0] PREP [?hFFFE,?hFFFF]; // 2 x 8存储器
描述存储器时可以使用参数或任何合法表达式
parameter wordsize = 16;
parameter memsize = 1024;
reg [wordsize-1,0] MEM3 [memsize-1,0];
存储器寻址 (Memory addressing)
存储器元素可以通过存储器索引( index)寻址,也就是给出元素在存储器的位置来寻址。
mem_name [addr_expr]
Verilog不支持多维数组。也就是说只能对存储器字进行寻址,而不能对存储器中一个字的位寻址。
module mems;
reg [8,1] mema [0,255]; // declare memory called mema
reg [8,1] mem_word; // temp register called mem_ word
.,,
initial
begin
$displayb( mema[5]); //显示存储器中第 6个字的内容
mem_word = mema[5];
$displayb( mem_word[8]); // //显示第 6个字的最高有效位
end
endmodule
若要对存储器字的某些位存取,
只能通过暂存器传递复习 (review)
问题:
1,在 Verilog中,什么情况下输出端会输出 X值?
2,net和 register类型的主要区别是什么?
3,在 Verilog中如何定义一个常数?
解答:
1,若输出端输出 X值,一种可能是输出 net上发生驱动冲突,二是由一个未知值传递到 net上引起。
2,register有存储功能,而 net必须持续驱动。
3,在 Verilog中使用 parameter定义一个常数。文本宏也是常数的一种形式。
第 7章 结构描述 (structural modeling)
如何使用 Verilog的基本单元 (primitives)
如何构造层次化设计
了解 Verilog的逻辑强度系统学习内容:
术语及定义 (terms and definations)
结构描述,用门来描述器件的功能
primitives(基本单元 ),Verilog语言已定义的具有简单逻辑功能的功能模型 (models)
结构描述
Verilog结构描述表示一个逻辑图
结构描述用已有的元件构造。 module MUX4x1( Z,D0,D1,D2,D3,S0,S1);
output Z;
input D0,D1,D2,D3,S0,S1;
and (T0,D0,S0_,S1_),
(T1,D1,S0_,S1),
(T2,D2,S0,S1_),
(T3,D3,S0,S1);
not (S0_,S0),(S1_,S1);
or (Z,T0,T1,T2,T3);
endmodule
module rs_latch (y,yb,r,s);
output y,yb;
input r,s;
nor n1( y,r,yb);
nor n2( yb,s,y);
endmodule
结构描述等价于逻辑图,
都是连接简单元件构成更复杂元件通过门的实例使用门忽略了门的实例名。
同一种门可以通过一个语句实例化
Latch
结构描述(续)
结构描述等价于逻辑图。它们都是连接简单元件来构成更为复杂的元件。 Verilog使用其连接特性完成简单元件的连接。
在描述中使用元件时,通过建立这些元件的实例来完成。
上面的例子中 MUX是没有反馈的组合电路,使用中间或内部信号将门连接起来。描述中忽略了门的实例名,并且同一种门的所有实例可以在一个语句中实例化。
上面的锁存器 (latch)是一个时序元件,其输出反馈到输入上。它没有使用任何内部信号。它使用了实例名并且对两个 nor门使用了分开的实例化语句。
Verilog基本单元( primitives)
Verilog基本单元提供基本的逻辑功能,也就是说这些逻辑功能是预定义的,用户不需要再定义这些基本功能。
基本单元是 Verilog开发库的一部分。大多数 ASIC和 FPGA元件库是用这些基本单元开发的。基本单元库是自下而上的设计方法的一部分。
基本单元名称 功能
and
or
not
buf
xor
nand
nor
xnor
Logical And
Logical Or
Inverter
Buffer
Logical Exclusive Or
Logical And Inverted
Logical Or Inverted
Logical Exclusive Or Inverted
基本单元的引脚 (pin)的可扩展性
基本单元引脚的数目由连接到门上的 net的数量决定。因此当基本单元输入或输出的数量变化时用户不需要重定义一个新的逻辑功能。
所有门(除了 not和 buf)可以有多个输入,但只能有一个输出。
not和 buf门可以有多个输出,但只能有一个输入。
带条件的基本单元
Verilog有四种不同类型的条件 基本单元
这四种基本单元只能有三个引脚,output,input,enable
这些单元由 enable引脚使能。
– 当条件基本单元使能信号无效时,输出高阻态。
基本单元名称 功能
bufif1 条件缓冲器,逻辑 1 使能
bufif0 条件缓冲器,逻辑 0 使能
notif1 条件反相器,逻辑 1 使能
notif0 条件反相器,逻辑 1 使能带条件的基本单元(续)
条件 基本单元有三个端口:输出、数据输入、使能输入三种未知状态:
值 强度
x 1,0,z 未知
L 0,z 未知
H 1,z 未知基本单元实例化
在端口列表中,先说明输出端口,然后是输入端口
实例化时实例的名字是可选项
and (out,in1,in2,in3,in4); // unnamed instance
buf b1 (out1,out2,in); // named instance
延时说明是可选项。所说明的延时是固有延时。输出信号经过所说明的延时才变化。没有说明时延时为 0。
notif0 #3.1 n1 (out,in,cntrl); // delay specified
信号强度说明是可选项
not (strong1,weak0) n1 (inv,bit); // strength specified
module intr_sample;
reg A; wire Y;
not #10 intrinsic (Y,A);
initial begin
A = 0;
#15 A = 1; #15 A = 0; #8 A = 1;
#8 A = 0; #11 A = 1; #10 $finish;
end
endmodule
仿真波形固有延时模块实例化 (module instantiation)
模块实例化时实例必须有一个名字。
使用位置映射时,端口次序与模块的说明相同。
使用名称映射时,端口次序与位置无关
没有连接的输入端口初始化值为 x。
module comp (o1,o2,i1,i2);
output o1,o2;
input i1,i2;
.,,
endmodule
module test;
comp c1 (Q,R,J,K); // Positional mapping
comp c2 (.i2(K),.o1(Q),.o2(R),.i1(J)); // Named mapping
comp c3 (Q,,J,K); // One port left unconnected
comp c4 (.i1(J),.o1(Q)); // Named,two unconnected ports
endmodule
名称映射的语法:
.内部信号(外部信号)
没有连接时通常会产生警告
module driver (in,out,en);
input [2,0] in;
output [2,0] out;
input en;
bufif0 u[2:0] (out,in,en); // array of buffers
endmodule
实例数组 (Array of Instances)
实例名字后有范围说明时会创建一个实例数组。在说明实例数组时,
实例必须有一个名字 (包括基本单元实例 )。其说明语法为:
<模块名字 > <实例名字 > <范围 > (<端口 >);
两个模块功能完全等价范围说明语法:
[MSB,LSB]
module driver_equiv (in,out,en);
input [2,0] in;
output [2,0] out;
input en;
// Each primitive instantiation is done separately
bufif0 u2 (out[2],in[2],en);
bufif0 u1 (out[1],in[1],en);
bufif0 u0 (out[0],in[0],en);
endmodule
实例数组 (Array of Instances)(续 )
如果范围中 MSB与 LSB相同,则只产生一个实例。
一个实例名字只能有一个范围。
下面以模块 comp为例说明这些情况
module oops;
wire y1,a1,b1;
wire [3,0] a2,b2,y2,a3,b3,y3;
comp u1 [5,5] (y1,a1,b1); // 只产生一个 comp实例
comp m1 [0,3] (y2,a2,b2);
comp m1 [4,7] (y3,a3,b3); // 非法
endmodule
ml作为实例阵列名字使用了两次现有综合工具还不支持实例数组逻辑强度 (strength)模型
Verilog提供多级逻辑强度。
逻辑强度模型决定信号组合值是可知还是未知的,以更精确的描述硬件的行为。
下面这些情况是常见的需要信号强度才能精确建模的例子。
– 开极输出 (Open collector output)(需要上拉)
– 多个三态驱动器驱动一个信号
– MOS充电存储
– ECL门( emitter dotting)
逻辑强度是 Verilog模型的一个重要部分。通常用于元件建模,如 ASIC和
FPGA库开发工程师才使用这么详细的强度级。但电路设计工程师使用这些精细的模型仿真也应该对此了解。
逻辑强度 (strength)模型(续)
用户可以给基本单元实例或 net定义强度。
基本单元强度说明语法:
<基本单元名 > <强度 > <延时 > <实例名 > ( <端口 >);
例,nand (strong1,pull0) #( 2,3,4) n1 (o,a,b); // strength and
delay
or (supply0,highz1) (out,in1,in2,in3); // no instance name
用户可以用 %v格式符显示 net的强度值
$monitor ($ time,," output = %v",f);
电容强度 (large,medium,small)只能用于 net类型 trireg和基本单元 tran
例如,trireg (small) tl;
信号强度值系统
Level Type %v formats Specification
Supply 7 Drive Su0 Su1 supply0,supply1
Strong 6 Drive(default) St0 St1 strong0,strong1
Pull 5 Drive Pu0 Pu1 pull0,pull1
Large 4 Capacitive La0 La1 large
Weak 3 Drive We0 We1 weak0,weak1
Medium 2 Capacitive Me0 Me1 medium
Small 1 Capacitive Sm0 Sm1 small
High Z 0 Impedance Hi0 Hi1 highz0,highz1
Verilog多种强度决断
在 Verilog中,级别高的强度覆盖级别低的强度复习问题:
1,什么是 Verilog中的结构化描述?
2,连接模块端口有哪两种方法?哪一种更通用一些?
3,什么是实例数组?
4,什么时候实例名字是可选的?
解答:
1,结构化描述是使用 Verilog基本单元或单元 (cell)级元件对设计进行描述,与逻辑图很相似。
2,可以根据次序(位置映射)或名字(名称映射)来映射端口。虽然在这个教程中大多使用位置映射,这主要是为了节省空间。在实际设计中,名称映射可能更通用一些。
3,实例数组用一条语句创建模型 (模块或基本单元)的多个实例。
4,基本单元实例化时实例名是可选的,说明基本单元数组时除外。当实例化模块时,实例名是必须的。
第 8章 延时模型学习内容,
1,如何说明块延时
2,如何说明分布延时
3,如何说明路径延时
4,怎样在模块中说明时序检查
5,标准延时格式 SDF( Standard Delay Format)
术语及定义
模块路径 (module path),穿过模块,连接模块输入 (input端口或 inout端口)到模块输出 (output端口或 inout端口)的路径。
路径延时 (path delay),与特定路径相关的延时
PLI,编程语言接口,提供 Verilog数据结构的过程访问。
时序检查 (timing check),监视两个输入信号的关系并检查的系统任务,
以保证电路能正确工作。
时序驱动设计 (timing driven design),从前端到后端的完整设计流程中,
用时序信息连接不同的设计阶段延时模型类型 (Delay Modeling Types)
延时有三种描述模型:
将全部延时集中到最后一个门延时分布在每一个门上用专用块说明每一个路径 pin-to-
pin延时典型的延时说明:
Delay from A to O = 2
Delay from B to O = 3
Delay from C to O = 1
分布延时块延时路径延时块延时 (Lumped Delay)
块延时方法是将全部延时集中到最后一个门上。这种模型简单但不够精确,只适用于简单电路。因为当到输出端有多个路径时不能描述不同路径的不同延时。
可以用这种方法描述器件的传输延时,并且使用最坏情况下的延时
(最大延时)。
`timescale 1ns/ 1ns
module noror( Out,A,B,C);
output Out;
input A,B,C;
nor n1 (net1,A,B);
or #3 o1 (Out,C,net1);
endmodule
用块延时描述时,不同路径的延时完全相同,左边例中各路径延时为:
A -> Out is 3 ns
B -> Out is 3 ns
C -> Out is 3 ns
分布延时 (Distributed Delays)
分布延时方法是将延时分散到每一个门。在相同的输出端上,不同的路径有不同的延时。分布延时有两个缺点:
– 在结构描述中随规模的增大而变得异常复杂。
– 仍然不能描述基本单元 (primitive)中不同引脚上的不同延时。
`timescale 1ns/ 1ns
module noror( Out,A,B,C);
output Out;
input A,B,C;
nor #2 n1 (net1,A,B);
or #1 o1 (Out,C,net1);
endmodule
这种描述方法描述的不同路径的延时。例中各路径延时为:
A -> Out is 3 ns
B -> Out is 3 ns
C -> Out is 1 ns
模块路径延时 (Module Path Delays)
module noror( O,A,B,C);
output O;
input A,B,C;
nor n1 (net1,A,B);
or o1 (O,C,net1);
specify
(A => O) = 2;
(B => O) = 3;
(C => O) = 1
endspecify
endmodule
例中各路径延时为:
A -> Out is 2 ns
B -> Out is 3 ns
C -> Out is 1 ns
在专用的 specify块描述模块从输入端到输出端的路径延时。
– 精确性:所有路径延时都能精确说明。
– 模块性:时序与功能分开说明路径必须括在圆括号内结构描述的零延时反馈 (Loop)
当事件队列中所有事件结束时仿真前进一个时片。在某种零延时反馈情况下,
新事件在同一时片不断的加入,致使仿真停滞在那个时片。
若在结构描述中出现从输出到输入的零反馈情况,多数仿真器会检测到这个反馈并产生错误信息。 Verilog的 lint checker对这种情况会提出警告。
解决这个问题的方法是在电路中加入分布延时。路径延时不能解决零延时振荡问题,因为输出信号在反馈前不会离开模块。
精确延时控制在 Verilog中,可以:
说明门和模块路径的上升 (rise)、下降 (fall)和关断 (turn-off)延时
and #(2,3) (out,in1,in2,in3); // rise,fall
bufif0 #( 3,3,7) (out,in,ctrl); // rise,fall,turn- off
(in => out) = (1,2); // rise,fall
(a => b) = (5,4,7); // rise,fall,turn- off
在路径延时中可以说明六个延时值 (0?1,1?0,0?Z,Z?1,1?Z,Z?0)
(C => Q) = (5,12,17,10,6,22);
在路径延时中说明所有 12个延时值 (0?1,1?0,0?Z,Z?1,1?Z,Z?0,
0?X,X?1,1?X,X?0,X?Z,Z?X)
(C => Q) = (5,12,17,10,6,22,11,8,9,17,12,16);
上面所说明的每一个延时还可细分为最好、典型、最坏延时。
or #( 3.2:4.0:6.3) o1( out,in1,in2); // min,typ,max
not #( 1:2:3,2:3:5) (o,in); // min,typ,max for rise,fall
user_module #(1:2:3,2:3:4) ( …… ) ;在 Cadence Verilog中还不支持
(b => y) = (2,3,4,3,4,6,4,5,8); // min,typ,max for rise,fall,and
turnoff
精确延时控制(续)
上升延时是输出转换为 1时的延时
下降延时是输出转换为 0时的延时
关断延时输出转换为三态时的延时
到 X的转换延时是最小延时,而从 X到其它值的转换使用最坏延时
– 如果说明了上升、下降和关断延时,则 1->X的转换延时使用上升和关断延时的最小值。 X->0的延时为下降延时; X->Z的转换为关断延时。
– 如果只说明了上升和下降延时,则 1->X和 X->0使用下降延时,X->Z使用上升和下降延时的最小延时
– 如果只说明了一个延时,则所有转换使用这个延时。
– 如果说明了六个延时,则 1->X使用 1->X和 1->Z中最小延时; X->0使用 1->0
和 X->0的最大延时; X->Z使用 1->Z和 0->Z中的最大延时。
延时说明定义的是门或模块的 固有延时 。输入上的任何变化要经过说明的延时才能在输出端反映出来。如果没有延时说明,则 基本单元 的延时为 0。分布 关断延时 只对三态基本单元有效。
Specify块
specify块定义了模块的时序部分
– 时序信息和功能在不同的块中描述,这样功能验证独立于时序验证。 specify块在不同的抽象级中保持不变。
– 设计的功能描述中的延时,如 #delay在综合时不起作用
specify块由 specify开始,到 endspecify结束,并且在模块内部
使用关键字 specparam在 specify中进行参数声明。不要同模块参数 (由
parameter说明 )混淆。 specparam只能在 specify块内声明参数并使用;而
parameter也只能在 specify外声明参数并使用。
specify块可以:
– 描述穿过模块的路径及其延时
– 描述时序检查以保证器件的时序约束能够得到满足
– 定义特定模块或特定模块路径的时钟过滤限制模块路径的并行连接和全连接( specify续)
*>表示全连接,也就是所有输入连接到所有输出
=>表示并行连接,也就是信号对之间的连接
(a,b => q,qb) = 15;
等价于:
(a => q) = 15;
(b => qb) = 15;
(a,b *> q,qb) = 15;
等价于:
(a => q) = 15;
(b => q) = 15;
(a => qb) = 15;
(b => qb) = 15;
模块路径的并行连接和全连接( specify续)
这里有一些路径延时说明的例子:
// 从 a 到 out 和从 b 到 out的路径延时说明
(a,b => out) = 2.2;
// 从 r 到 o1 和 o2 的上升、下降延时说明
(r *> o1,o2) = (1,2);
// 从 a[1] 到 b[1] 和 从 a[0] 到 b[0] 的路径延时说明
(a[ 1,0] => b[ 1,0]) = 3; // 并行连接
// 从 a 到 o 的全路径延时说明
(a[7,0] *> o[7,0]) = 6.3; // full connection
specify块参数
specify块中的参数由关键字 specparam说明。 specparam参数和模块中
parameter定义的参数作用范围不同,并且 specparam定义的参数不能重载。
下面总结了两种参数的差别:
specify参数
– 关键字为 specparam声明
– 必须在 specify块内声明
– 只能在 specify块内使用
– 不能使用 defparam重载
模块参数
– 使用关键字 parameter声明
– 必须在 specify块外声明
– 只能在 specify块外使用
– 可以用 defparam重载
– 占用存储器,因为在每个模块实例中复制
module noror (O,A,B,C);
output O;
input A,B,C;
nor n1 (net1,A,B);
or o1 (O,C,net1);
specify
specparam ao = 2,bo = 3,co = 1;
(A => O) = ao;
(B => O) = bo;
(C => O) = co;
endspecify
endmodule
使用 specparam定义参数的例子:
状态依赖路径延时 SDPD
状态依赖路径延时在说明的条件成立时赋予路径一个延时。
module XOR2 (x,a,b);
input a,b;
output x;
xor (x,a,b);
specify
if (a) (b=> x) = (5,6,7);
if (!a) (b=> x) = (5,7,8);
if (b) (a=> x) = (4,5,7);
if (!b) (a=> x) = (5,7,9);
endspecify
endmodule
有时路径延时可能依赖于其它输入的逻辑值。 SDPD就是用于说明这种情况。在例子中,a到 out的延时依赖于
b的状态。
SDPD说明语法:
if <condition> 路径延时说明 ;
SDPD说明不使用 else子句。条件值为 X或 Z则认为条件成立。当一个路径中有多个条件成立时使用最小值。
所有输入状态都应说明。若没有说明则使用分布延时 (若说明了分布延时 ),
否则使用零延时。
条件有一些限制,但许多仿真器并不遵循 IEEE标准的限制。
惯性 (inertial)和传输 (transport)延时模型对于惯性延迟,若路径延时小于门的固有延时,信号会被淹没。
对于传输延迟,输入上每个变化都会反映到输出上。
惯性延迟与传输延时的比较固有延时 2ns
小于 2ns固有延时的脉冲在输出上没有反映输入的任何变化反映到输出
1ns宽度的脉冲仿真器使用缺省的延迟模型,有的可以用命令行选项,有的用仿真器专用的编译指导指定延迟模型。
路径脉冲控制使用 specparam参数 PATHPULSE$控制模块路径对脉冲的处理。
语法:
PATHPULSE$ = (< reject_value>,<error_value>?)
PATHPULSE$< path_source>$< path_destination> =
(< reject_value>,<error_value>?)
specify
(en => q) = 12;
(data => q) = 10;
(clr,pre *> q) = 4;
specparam
PATHPULSE$ = 3,
PATHPULSE$en$q = ( 2,9 ),
PATHPULSE$clr$q = 1 ;
endspecify
en输入波形输出 q带倾斜波形硬件可能产生的波形例子路径脉冲控制
可以用 PATHPULSE$声明的 specparam参数覆盖全局脉冲控制
PATHPULSE$声明的 specparam参数缩小了指定模块或模块内特定路径的模块路径延时的范围。
只声明一个值时,error_value和 reject_value相同,如
PATHPULSE$ = 3; 等价于 PATHPULSE$ = (3,3);
脉冲宽度小于 reject_value的信号将被滤掉,而小于 error_value的值会使输出产生不定状态。
由上面带斜率的波形可以看出,模块中 en信号在时间 t发生变化并开始影响 q;
若 en脉冲在时间 t+2结束,则 q没有被完全驱动,q将恢复原值,如点波形所示。若 en脉冲在时间 t+9结束,q则可能完成驱动,也可能没有,处于未知状态。如果 en到 t+9一直有效,q将输出新值。
Verilog时序检查
使用时序检查以验证设计的时序
时序检查完成下列工作:
– 确定两个指定事件之间的时差
– 比较时差与指定的时限
– 如果时差超过指定时限则产生时序不能满足的报告。这个报告只是一个警告信息,不影响模块的输出
Verilog支持的时序检查有:
– setup(建立时间)
– hold(保持时间)
– pulse width(脉冲宽度)
– clock period(时钟周期)
– skew(倾斜)
– recovery(覆盖)
Verilog时序检查(续)
系统任务 $setup在数据变化到时钟沿的时差小于时限则报告一个
violation,如
$setup( data,posedge clk,4);
系统任务 $hold在时钟沿到数据变化的时差小于时限则报告一个
violation,如
$hold( posedge clk,data,3);
$setuphold是 $setup和 $hold的联合。
$setuphold( posedge clk,data,4,3);
Verilog时序检查(续)
建立时间,$setup( data_event,clk_event,limit,notifier);
保持时间,$hold( clk_event,data_event,limit,notifier);
建立 /保持时间,$setuphold( clk_event,data_event,s_limit,h_limit,notifier);
覆盖,$recovery(reference_event,data_event,limit,notifier);
$removal( ctrl_event1,ctrl_event2,limit,notifier);
$recrem( reference_event,data_event,rec_limit,rem_limit,notifier);
$width( ctrl_event,limit,threshold,notifier);
$period( ctrl_event,limit,notifier);
$skew( ctrl_event1,ctrl_event2,limit,notifier);
时序检查中的通知 (notifier)(续)
可以说明并使用一个 notifier来显示时序不满足 (violation)
$setuphold( ref_event,data_event,s_limit,h_limit,NOTIFY);
notifier是可选的
notifier是一个 1位的寄存器
时序检查产生 violation时,Verilog报告信息并使 notifier翻转
当时序 violation产生时,可以用 notifier使输出变为未定义值。
有两种方法使 notifier影响输出值
将 notifier作为 UDP的一个输入端口
在高级行为模块中,不需要为 notifier声明一个端口也可以对其进行操作。
notifier举例
`timescale 1ns/ 1ns
module dff_notifier (q,ck,d,rst);
input ck,d,rst;
output q;
reg FLAG; // 1-bit notifier
// dff netlist goes here
specify
(ck => q) = (2,3,4);
$setup( d,posedge ck,2,FLAG);
endspecify
endmodule
module test;
reg ck,d,rst;
dff_notifier (q,ck,d,rst);
// stimulus and response checking goes
here
always @( notifier) begin
rst = 1; #10 rst = 0;
end
endmodule
notifier初始值为 X;第一个产生时序 violation时,其值变为
1。其后每次产生时序
violation,其值翻转。
时序检查 —条件时序检查
module dff (data,clk,rst,q,qb);
input data,clk,rst;
output q,qb;
// instantiate the primitives for the basic flip-flop
udp_dff( q_int,data,clk,rst);
buf b1( q,q_int);
not n1( qb,q_int);
// create timing checks
specify
$setup( data,posedge clk &&& rst,12);
$hold( posedge clk,data &&& rst,5);
$width( posedge clk,25);
endspecify
endmodule
在条件时序检查中,是否进行时序检查取决于条件表达式的计算值专用操作符 &&&在时序检查中设置条件。
只当条件表达式为真时才进行时序检查当 rst为高时进行
setup和 hold检查
width检查与 rst无关时序检查 —条件时序检查条件表达式中条件只能是一个标量信号,这个信号可以:
用位反操作符( ~)取反。
用等于操作符( = =或! =)与一个标量常量进行比较
用相同操作符 (===或! ==)与一个标量常量进行比较
若条件表达式计算值为 1,x或 z则认为条件成立。
由于条件时序检查的条件表达式中只能有一个信号,因此需要多个信号产生条件时必须使用哑逻辑使将它们表达为一个内部信号表示才能用于条件时序检查。
SDF(Stand Delay Format)文件
增量或绝对延时,如模块路径,器件、内部连接和端口 (包括输入端口延时)
时序检查,如 setup,hold,recovery,skew,width period
时序约束,如 path
条件或无条件模块路径延时
设计、实例、类型或库的专用数据
比例、环境、工艺及用户定义基本单元标准延时格式( SDF)是一种标准的,与工具无关的表示时序数据的文本格式。 SDF文件通常用于 Verilog仿真。教程不对 SDF做详细介绍。
应注意的是,Verilog仿真器必须能够将 SDF文件中的数据标注用于仿真。
这些数据包括:
SDF允许不同工具共享延时数据。可以将关键路径信息由综合器传递给布局布线工具,也可将内部连接线延时信息由布局布线工具反传给仿真器。
内部连接延时内部连接延时是对器件之间连接线延时的估算。例如:
(INSTANCE )
(DELAY
(ABSOLUTE
(INTERCONNECT u1,u2,u3,o1 u1,u4,i3 (5,6,7) (5.5,6,6.5) )
)
)
内部连接延时上面的例子中的内部连接延时说明了一个 input到 output连接的线延时。
延时分上升、下降和关断延时,每种延时又有最好、典型和最坏值。
限定于敏感边沿的 iopath,时钟到输出;用上升、下降的最好、典型、最坏值说明。
条件 iopath,input到 output;用上升、下降和关断的最好、典型、最坏值说明
IOPATH延时
IOPATH延时是器件从输入端口到输出端口的一个合法路径上的延时。
例如:
(INSTANCE test.u1.u2)
(DELAY (ABSOLUTE
( IOPATH in o1 (1:2:3) (1:3:4))
( IOPATH(posedge ck) o1 (2:3:4) (4:5:6))
( COND en (IOPATH in o2(2:4:5) (4:5:6) (4:5:7) )
)
)
IOPATH延时
端口 IOPATH,从输入到输出;用最好、典型和最坏值说明上升和下降延时。
限定敏感边沿的 IOPATH,从时钟到输出,用最好、典型和最坏值描述其上升和下降延时。
条件 IOPATH,从输入到输出;用最好、典型和最坏值描述其上升、下降和关断延时。
在上面 IOPATH延时的例子中包括:
在上面 IOPATH延时的例子中,实例 test.u1.u2 需要一个如下面所示的
specify块用于反标注。
specify
( in => o1) = (1,2,3,1,3,4);
( ck => o1) = (2,3,4,4,5,6);
if ( en ) ( in => o2) = (2,4,5,4,5,6,4,5,7);
endspecify
SDF文件中的时序信息覆盖
specify块中的时序信息注意:
复习问题:
哪一种延时说明是最精确的?
怎样防止一个结构化零延时反馈?
为什么不能在 specify块中使用模块参数 (parameter)?
Verilog仿真时在哪里说明一个线延时?
Verilog仿真时在哪里说明时序检查?
解答:
在 specify块中说明的延时信息是最精确的。因为可以说明 pin-to-pin的路径延时
在门加上一个 #延时来防止零延时组合逻辑反馈。
模块延时在每次实例化时都复制一份。而低层元件必须大量应用参数,并且其实例化次数也非常多。因此使用 specparam节省了大量存储器。
在 SDF文件中。在编译或仿真时标注这些延时
在 specify块中描述,可以由 SDF文件中的时序检修改或代替。
第九章 编译控制的使用学习目标:
开发商提供的 Verilog库
用 Verilog库仿真
Verilog源代码加密
其它仿真器相关的问题术语及定义
PLI:编程语言接口,基于 C的过程访问 Verilog数据结构
UDP:用户定义的基本单元,用户定义的门级组合的及时序 的 Verilog基本单元。
VHDL,VHSIC HDL,类似 Ada的高级 VLSI设计语言
Verilog模型库
ASIC和 FPGA开发商开发并提供工艺专用库
设计人员以库中的元件建立网表
仿真器在编译时扫描模型库寻找实例化模块合成库可以支持多种工具,例如它可以包含下列工具所需要的信息
仿真器(如 Verilog-XL和 NC Verilog)
综合器(如 Ambit)
时序分析器(如 Pearl)
故障仿真( Verifault-XL)
开发商提供了大量的 Verilog库。这些库并不是 Verilog仿真器专用的,但其库管理格式都基于 Verilog-XL风格。
库中每个元件都包括功能及工具专用的时序及工艺信息。
元件库建模建立 Verilog模型库,需要:
每个元件(或单元)用一个 module描述
将相关的 module放在同一个文件或 同一个目录中当把 module放到同一个目录时,文件名应与 module名相同。 文件名的扩展名是可选的可以用两种抽象级描述库单元
结构级
– 用 Verilog基本单元或 UDP
– 用于描述组合逻辑或简单的时序逻辑
行为级
– 用过程块或赋值语句
– 用于描述大的或复杂的元件,如 RAM或 ROM
元件库建模(续)
库单元的特点:
每个库单元的描述在编译指导 `celldefine和 `endcelldefine之间
每个库单元的描述有两部分:
– 功能描述
– 时序描述
`celldefine
`timescale 1ns / 100ps
module full_adder( cout,sum,a_in,b_in,c_in);
input a_in,b_in,c_in;
output cout,sum;
// 功能描述
.,,
// 时序描述
...
endmodule
`endcelldefine
在模块定义之前插入 `timescale定义单元所使用的时间单位和精度
Verilog库的使用在 Cadence Verilog仿真器中使用 Verilog库:
使用库文件
– 在命令行中使用选项,-v file_name
使用库目录
– 在命令行中使用选项 –y directory_name
– 在命令行中使用选项 +libext+file_extension
在使用库目录时,如果每个文件都有一个扩展名,则在 Cadence Verilog
仿真器 必须用 +libext选项指定其扩展名。 仿真器中没有缺省地使用,v作扩展名使用 -v或 -y选项指定库时,只编译那些设计中用到的模块。如果在命令行中直接输入库文件名而没有使用 -v选项 (或在文件中使用编译指导
`include),则库中所有模块都被编译。使用选项大大压缩编译时间及内存空间。在 NC Verilog中也压缩了使用的磁盘空间。
库文件扫描每一个 -v选项指定一个库文件
verilog test,v design,v -v library_file,v
module and2(...);
.,,
endmodule
module mux(...);
.,,
endmodule
module dff(...);
.,,
endmodule
library_file.v
库目录扫描每一个 -y选项指定一个库目录。
+libext+选项指定有效的文件扩展名。
verilog test,v design,v -y library_ directory +libext+,v
Verilog模型库目录编译指导 `uselib
定义设计中使用的库元件(包括 UDP)的位置
一直有效,直到遇到另一个 `uselib或 `resetall
覆盖任何命令行选项中库的设置。也就是说如果不能在 `uselib指定的位置找到元件,仿真器不会再按命令行中 -v或 -y选项去寻找。
`uselib语法
`uselib library_reference library_reference
其中,library_reference可以是:
file = file_name_path
dir = directory_name_path libext =,file_extension
注意,`uselib使用,v作为缺省扩展名,如 -y命令选项不同使用空 `uselib或
`resetall会产生什么效果?
在 `uselib中可以使用,\‖进行多行说明
`uselib file=/usr1/chrisz/libs/foo.lib \
dir=/usr1/chrisz/libs/goo/libext=.v
恢复命令行
-v和 -y设置编译指导 `uselib使用举例
module adder (c_out,sum,a,b,c_in);
output c_out,sum;
input a,b,c_in;
`uselib dir=/libs/FAST_LIB/
SN7486 u1 (half_sum,a,b);
`uselib dir=/libs/TTL/ libext=,v file=/libs/TTL_U/udp.lib
SN7408 u2 (half_c,a,b);
SN7408 u3 (tmp,c_in,half_sum);
SN7486 u4 (sum,c_in,half_sum);
SN7432 u5 (c_out,tmp,half_c);
endmodule
`uselib
目录库 TTL中的单元可以使用文件库 udp.lib中定义的单元指定目录库 FAST_LIB中寻找实例 u1的定义指定目录库 TTL及文件库
udp.lib寻找其它实例的定义编译指导 `uselib
`define TTL_LIB dir=/libs/TTL/libext=,v
`define TTL_UDP file=/ libs/ TTL_U/udp.lib
`uselib `TTL_LIB `TTL_UDP
在 `uselib中库的指定可以使用由 `define定义的宏进行文本替换。
在命令行中用 +define+选项给宏一个值。设计易于管理,可移植性高。
编写与大小无关的源代码
Verilog是对大小写敏感的语言,如 sel和 SEL是不同的标识符
Verilog 关键字均使用小写,如 input,output
标识符中大小写都可以使用,但 Sel和 sel是不同的标识符
仿真时使用 -u选项进入大小写不敏感模式。仿真器将所有标识符转换为大写形式,而关键字仍保持为小写。
module MUX2_1 (out,a,b,sel);
output out;
input a,b,sel;
not not1( SEL,sel);
and and1( a1,a,SEL);
and and2( b1,b,sel);
or or1( out,a1,b1);
endmodule
在正常情况下,左边例子中 sel和
SEL是不同的信号。若使用 -u选项,
sel和 SEL变为相同的信号。
将产生错误的仿真结果。
如果在大小写不敏感的工具中使用这个模型,则用 -u选项可以找出错误。
可以用 -d选项输出 -u选项产生的大小写不敏感的描述编译指导尽管编译指导是 Verilog语言的一部分,但其作用取决于编译器,因此不同的仿真器中其作用可能不同。
`resetall将编译指导变为缺省值。
Cadence Verilog仿真器在遇到 `resetall时,文本宏定义不变。要清除文本宏定义,使用
`undef macro_name
在使用 `include编译指导时,使用 +incdir命令行选项指定所包含文件的查找路径。
+incdir+directory1+ directory2+..,directoryN
仿真器首先查找当前目录,若没有找到再沿指定路径顺序查找。
编译指导编译指导从出现时开始有效,直到被覆盖或使其失效。因此编译指导是全局的。
下列编译指导是 Verilog IEEE标准中的:
库单元分界
`celldefine
`endcelldefine
复合编译指导
`default_nettype
`include
`unconnected_drive
`nounconnected_drive
`resetall
`timescale
定义文本宏其和基于文本宏的转换
`define
`undef
`ifdef
`else
`endif
定义文本宏用 +define+命令行参数定义文本宏语法,+define+MACRO_NAME=“MACRO_TEXT”
注意,文本宏的覆盖可能影响设计的结构,可能强制 NC Verilog重新编译全部或部分设计
例子
verilog test,v +define+gate="or"
`define gate and
module test;
reg a,b;
`gate (c,a,b);
initial
begin
a= 0; b= 1;
$monitor ($time,,c,a,b);
#1 $finish;
end
endmodule
文本宏中字符串长度没有限制。
清除文本宏定义,使用:
`undef macro_name
清除所有文本宏定义,使用
`undefall
选择仿真延迟模型选择延时值
用下列命令行选项选择延时模型
+mindelays
+typdelays
+maxdelays
用下列命令行选项或编译指导指定单位延时、零延时、分布延时或路径延时
+delay_mode_unit `delay_mode_unit
+delay_mode_zero `delay_mode_zero
+delay_mode_path `delay_mode_path
+delay_mode_distributed `delay_mode_distributed
– 在单位和零延时模型中,仿真器忽略所有 specify块,门延时为单位或零
– 分布延时忽略所有 specify块,只保留门延时
– 路径延时忽略门延时,只保留 spcify块中延时
– 零延时和路径延时可造成结构零延时反馈,因此使用编译指导影响设计中的指定块。
单位指的是时间精度 precision
在设定单位延时和零延时模型时不影响过程中时序控制固有延时和传输延时模型仿真时可以用固时延时模型或传输延时模型
固有延时模型 (缺省模型 )不传送脉冲宽度小于电路延时的信号。这是开关电路的行为特性
在传输延时模型中,输入上的所有变化在路径延时之后反映到输出上。这是传输线的行为特性。
采用命令行选项 +transport_path_delays设置传输延时模型注意:记住使用 +pathpulse用于路径延时控制小于 2ns的脉冲没有响应任何脉冲都有响应输入固有延时输出传输延时输出
Verilog-XL路径延时的限制模块路径延时由 specify块说明。 Verilog-XL中路径输出端必须是一个可以加速的基本单元。 NC Verilog没有这个限制。
1,路径输出端口必须由一个可加速的门驱动。
合法 合法
2,输出端口在模块内部只能有一个驱动。
非法非法不是可加速基本单元或是行为描述时:
Error! Path delay output is not
accelerated due to.,,
.,,[ Verilog- PDOMBA< number>]
Error! Multiple path delays defined to node
<path_ destination>;
Path delay outputs must have only one driver
within the module
[Verilog- PDOMOD]
解决方法:
在输出加基本单元 buf
Verilog-XL可加速的对象
Verilog-XL可加速 net和基本单元,但也有例外情况:
不能加速的 net:
– 矢量 net
– 具有非零延时的 net
– 被 force语句驱动或驱动过的 net
– net被连续赋值(除非使用 +caxl)
不能加速的基本单元
– 双向基本单元 tran tranif0 tranif1 rtran rtranif0 itranif1
– buf和 not门有多个输出
– 基本单元的输入连接到寄存器数组的一位或一部分
– 基本 单元的延时有非常数表达式
– 基本单元的一个输入是表达式(除非使用 +caxl)
– 基本单元的不同延时超过 65535
系统任务 $shownonxl( )寻找非 XL结构。其参数设定一个模块的实例时查找该实例。若没有参数则在整个设计层次中查找。
不能由 XL算法加速,但可以由 Switch-XL加速延时必须真正的不同。延时
#(3,4)和 #(3,2)是不同的,而
#3和 #(3,3)是相同的系统任务可以显示所有 forced net
用 Verilog-XL加密源代码用户可以保护设计中的所有权信息
有两种方法保护 Verilog源描述:
– 用 +autoprotect命令行选项保护所有模块
– 结合编译指导 `protect和 `endprotect,使用 +protect选项保护所选模块或区域。
仿真器对源文件的加密是将 `protect和 `endprotect之间的源代码封装起来。
保护机制建立一个加密文件。仿真加密模块时,这些编译指导指示仿真器将源代码解密并仿真,但用户不能访问加密的数据结构。
可以用 Affirma Model Packager保护私有模块用于 NC Verilog和 NC
VHDL仿真。但对其它 Verilog仿真器不会很理想。
保护所有 Verilog源代码用 +autoprotect命令行选项进行编译可以保护所有 Verilog源代码。编译后建建立一个新的只有模块名字可读的源文件。
verilog design.v +autoprotect
加密
module AND2 `protected
8Q@ RMSQH5DT^< oAXO3N^ VVhaD89ldTiYhe
@n== 0Pi@ Q\ JifJ[ Z< ai766? ReA0RPaQ94H
GHN60= Y[ KQgBdW4dO3662XYUXK=; CM= EVc
cZo2@ 65`Lm< XL,0VR[ CAUbShNPHne2
IVFe3ZFa; pB5fO6kpT_< h$
`endprotected endmodule
模块名不保护
design.vpmodule AND2( a,b,c);
output a;
input b,c;
and a1( a,b,c);
specify
(b => a) = (1.2,2.0);
(c => a) = (1.4,1.8);
endspecify
endmodule design.v
Verilog-XL缺省的输出文件名为原文件名后加,p‖
可以用 +autoprotect选项指定输出文件扩展名
verilog design.v +autoprotect.port
输出的保护文件名为,design.v.prot
保护选择的源描述为了保护源描述的某一部分,用编译指导 `protect和 `endprotect将这部分包含起来。在编译源文件时使用命令行选项 +protect。
verilog design.v +protect
module AND2( a,b,c);
output a;
input b,c;
`protect
and a1( a,b,c);
specify
(b => a) = (1.2,2.0);
(c => a) = (1.4,1.8);
endspecify
`endprotect
endmodule
保护区域
module AND2( a,b,c);
output a;
input b,c;
`protected
RFdelSQV5DT^< ilbl= Yl2AiTMmV
mKD^ Bg23WoqMlQbbREfQ`hfXF9S
G,M94J5E6SC079qZAZVgd$
`endprotected
endmodule
不保护模块名及端口列表
design.vp
提高了可移植性可以用 +protect选项指定输出文件扩展名
verilog design.v +protect.prot
输出的保护文件名为,design.v.prot
加密不变在 Verilog-XL中输入 (import)VHDL模型在 Verilog设计中可以包含 VHDL模型,并用 Cadence VHDL仿真器 (leapfrog)
进行协同仿真。这称为 VHDL import。
module MULTIPLIER (IN1,IN2,OUT1,CLK)
(* integer simulator = "Leapfrog";
integer model = "WORKLIB,
MULTIPLIER";*);
input [15,0] IN1,IN2;
input CLK;
output [31,0] OUT1;
endmodule
verilog包装的一个 shell例子
(* ……*) 中的命令是属性,是 Verilog语言的一部分,还没有标准化。
将 VHDL模型进行预编译并放在
Leapfrog的 work库中。
执行 vhdlshell产生每个 VHDL模型的 verilog包装 (shell)。
确保 从 Leapfrog的 license有效
执行 Verilog仿真。它自动启动
Leapfrog仿真器。
在 Verilog-XL中引入 VHDL模型从 Leapfrog仿真器与常规的 Leapfrog仿真器使用不同的 license。如果从 Leapfrog仿真器的 license有效,并且设计中有 VHDL模型,Verilog-XL自动启动、连接到从 Leapfrog仿真器。 Verilog-XL仿真器控制从仿真器何时启动,何时停止,并与之同步。
使用 Leapfrog协同仿真时要注意以下几点:
对于 Verilog-XL,VHDL模型是黑盒子。除能观察其端口外,不能观测其内部信号。为了能够观察其内部结构,需要在 VHDL模型中设置附加的端口。这将影响仿真性能。
shell模块中不能实例化其它模块
shell中端口次序、大小、类型及指针方向必须与 VHDL模型匹配。
VHDL模块中不能实例化 Verilog模块。
不能在引入的 VHD模块之间传输双向信号
不能向 VHDL inout端口传送 Verilog的 tran门信号。
所有 Verilog模块必须有 `timescale
使用 Leapfrog协同仿真器时不能使用 $save和 $restart
使用 INCA协同执行 Verilog和 VHDL
在 Verilog设计中可以包含 VHDL模型,使用 NC仿真器协同执行。协同执行
(co-execute)使用单一过程,比协同仿真 (co-simulation)更有有效。
用 ncvhdl预编译 VHDL模型
可以执行 ncshell产生 VHDL模型的 Verilog封装。也可以直接实例化 VHDL对象
(不通过 shell),通过使用 VHDL定义的端口名称及次序,而不需要转换端口类型。
确保一个 NC CoEx仿真器的 license有效。
执行 NC仿真,使用 ncxlmode。
module MULTIPLIER (IN1,IN2,OUT1,CLK)
(* integer foreign = "VHDL( event) WORKLIB.MULTIPLIER"; *);
input [15,0] IN1,IN2;
input CLK;
output [31,0] OUT1;
endmodule
VHDL模型的 Verilog封装的一个例子使用 INCA协同执行 Verilog和 VHDL(续 )
CoEx选项的 license不同于 NC Verilog和 NC VHDL仿真器。如果 license有效,并且设计中有 VHDL模型,仿真器自动协同执行。由于使用同一个过程,
同步是非常有效的。
在协同执行时要注意下列几点:
当进入并观测实例模型内部时,必须遵循协同执行及 VHDL的访问规则。
shell端口次序、大小、类型及指针方向必须与 VHDL模块匹配。
不能向 VHDL inout端口传送 Verilog的 tran门信号。
所有 Verilog模块必须有 `timescale
协同执行时不能使用 $save,$restart和 $reset。
可以在 Verilog设计层次中引用层次名(使用 Verilog模块外引用或 OOMR)。
这些引用可以穿过 VHDL对象(但不能作为目标)。如果任何路径中的 VHDL
对象名称使用大写或非法字符,或 Verilog关键字,必须使用 nmp工具确定其
Verilog名称。同样,必须注意将 VHDL实例中指针 (n)改变为 Verilog指针 [n]。
注意:可以使用 ncshell工具产生 shell以引入 (import)LMSFI,FMI或 Swift模型到 VHDL设计中。产生的 shell也可用于 Verilog-XL或 Leapfrog仿真。
小结在本章我们学习了:
生产商提供的 Verilog库
使用 Verilog库仿真
Verilog源代码加密
其它与仿真相关的话题复习问题:
当仿真器遇到编译指导 `resetall时将所有编译指导置为缺省值吗?
使用什么选项指定库的名字?
如果仿真器没有在编译指导 `uselib指定的库中找到实例的定义,它会去哪里寻找?
解答:
不是。当使用编译指导 `resetall时,IEEE规范没有说明如何处理文本宏。
Cadence Verilog仿真器对文本宏不作处理。要重文本宏,使用编译指导 `undef。
使用 -v选项和 /或 -y及 +libext+选项。
不会再去别的位置查找。