Verilog 硬件描述语言
参考
手册
华为质量管理手册 下载焊接手册下载团建手册下载团建手册下载ld手册下载
-------------------------------------------------------------------------------
1. 关于 IEEE 1364
标准
excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载
-------------------------------------------------------------------------------
本Verilog 硬件描述语言参考手册是根据IEEE 的标准“Verilog 硬件描述语言参考手册1364-1995”编写的。OVI (Open Verilog International) 根据Cadence 公司推出的Verilog LRM(1.6版)编写了Verilog 参考手册1.0和2.0版。OVI又根据以上这两个版本制定了IEEE1364-1995 Verilog标准。在推出Verilog标准前,由于Cadence公司的 Verilog-XL 仿真器广泛使用,它所提供的Verilog LRM成了事实上的语言标准。许多第三方厂商的仿真器都努力向这一已成事实的标准靠拢。
Verilog语言标准化的目的是将现存的通过Verilog-XL仿真器体现的Verilog语言标准化。IEEE的Verilog标准与事实上的标准有一些区别。因此,仿真器有可能不完全支持以下的一些功能:
· 在UDP(用户自定义原语)和模块实例中使用数组(见Instantiation说明)。
· 含参数的宏定义(见‘define)。
· ‘undef.
· IEEE标准不支持用数字表示的强度值(见编译预处理命令)。
· 有许多Verilog-XL支持的系统任务、系统函数和编译处理命令在IEEE标准中不支持。
· 若在模块中其Net或寄存类型变量只有一个驱动,IEEE标准允许在一个指定块中, 延迟路径的最终接点可以是一个寄存器或Net类型的变量。而在此标准推出之前,对最终接点的类型有着严格得多的要求(见Specify说明)。
· 指定路径的延迟表达式最多可以达到12个延迟表达式,表达式之间需用逗号隔开。而在此标准推出之前,最多只允许六个表达式(见Specify说明)。
· 在Net类型变量的定义中,标量保留字scalared与矢量保留字 vectored的位置也做了改动。原先,保留字位于矢量范围的前面。在IEEE标准中,它应位于Net类型的后面(见Net说明)。
· 在最小-典型-最大常量表达式中,对于最小、典型与最大值的相对大小并无限制。而原先最小值必须小于或等于典型值,典型值必须小于或等于最大值。
· 在IEEE标准中,表示延迟的最小-典型-最大表达式不必括在括号里。而原先,它必需括在括号里。
-----------------------------------------------------------------------------
二. Verilog简介
-----------------------------------------------------------------------------
在Verilog HDL 中,我们可通过高层模块调用低层和基本元件模块,再通过线路连接(即下文中的NET)把这些具体的模块连接在一起,来描述一个极其复杂的数字逻辑电路的结构。所谓基本元件模块就是各种逻辑门和用户定义的原语模块(即下文中的UDPs)。而所谓NET实质上就是表示电路连线或总线的网络。端口连接列表用来把外部NET连接到模块的端口(即引脚)上。寄存器可以作为输入信号连接到某个具体模块的输入口。NET和寄存器的值可取逻辑值0,1,x(不确定)和 z(高阻)。除了逻辑值外,NET还需要有一个强度(Strength)值。在开关级模型中,当NET的驱动器不止一个时,还需要使用强度值来表示。逻辑电路的行为可以用Initial和Always 的结构和连续赋值语句,并结合设计层次树上各种层次的模块直到最底层的模块(即UDP及门)来描述。
模块中每个Initial块、Always块、连续赋值、UDP 和各逻辑门结构块都是并行执行的。而 Initial及Always块内的语句与软件编程语言中的语句在许多方面非常类似,这些语句根据安排好的定时控制(如时延控制)和事件控制执行。在Begin-End块内的语句按顺序执行,而在Fork-Join块中的语句则并行执行。 连续赋值语句只可用于改变NET的值。寄存器类型变量的值只能在Initial及Always块中修改。Initial及Always块可以被分解为一些特定的任务和函数。PLI (即可编程语言接口的
英语
关于好奇心的名言警句英语高中英语词汇下载高中英语词汇 下载英语衡水体下载小学英语关于形容词和副词的题
缩写)是完整的Verilog语言体系的一个的组成部分,利用PLI便可如同调用系统任务和函数一样来调用C语言编写的各种函数。
编译
Verilog的原代码通常键入到计算机的一个或多个文本文件上。然后把这些文本文件交给Verilog编译器或解释器处理,编译器或解释器就会创建用于仿真和综合必需的数据文件。有时候,编译完了马上就能进行仿真,没有必要创建中间数据文件。
-----------------------------------------------------------------------------
三. 语法总结
-----------------------------------------------------------------------------
典型的Verilog模块的结构:
module M (P1, P2, P3, P4);
input P1, P2;
output [7:0] P3;
inout P4;
reg [7:0] R1, M1[1:1024];
wire W1, W2, W3, W4;
parameter C1 = “This is a string”;
initial
begin : 块名
// 声明语句
end
always @ (触发事件)
begin
// 声明语句
end
// 连续赋值语句..
assign W1 = Expression;
wire (Strong1, Weak0) [3:0] #(2,3) W2 = Expression;
// 模块实例引用
COMP U1 (W3, W4);
COMP U2 (.P1(W3), .P2(W4));
task T1; //任务定义
input A1;
inout A2;
output A3;
begin
// 声明语句
end
endtask
function [7:0] F1; //函数定义
input A1;
begin
// 声明语句
F1 = 表达式;
end
endfunction
endmodule //模块结束
------------------------------------------------------------------
声明语句:
#delay
wait (Expression)
@(A or B or C)
@(posedge Clk)
Reg= Expression;
Reg <= Expression;
VectorReg[Bit] = Expression;
VectorReg[MSB:LSB] = Expression;
Memory[Address] = Expression;
assign Reg = Expression
deassign Reg;
TaskEnable(...);
disable TaskOrBlock;
EventName;
if (Condition)
...
else if (Condition)
...
else
...
case (Selection)
Choice1 :
...
Choice2, Choice3 :
...
default :
...
endcase
for (I=0; I
方法
快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载
与本指南中其他地方不同。
-----------------------------------------------------------------------------
四. 编写Verilog HDL源代码的标准
-----------------------------------------------------------------------------
编写Verilog HDL源代码应按标准进行,其标准可分成两种类别。第一种是语汇代码的编写标准,标准规定了文本布局,命名和注释的约定,其目的是为了提高源代码的可读性和可维护性。第二种是综合代码的编写标准,标准规定了Verilog风格,其目的是为了避免常常碰到的不能综合和综合结果存在缺陷的问
题
快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题
,也为了在设计流程中及时发现综合中会发生的错误。
下面列出的代码编写标准可根据所选择的工具和个人的爱好自行作一些必要的改动。
语汇代码的编写标准:
· 每一个Verilog源文件中只准编写一个模块,也不要把一个模块分成几部分写在几个源文件中。
· 源文件的名字应与文件内容有关,最好一致(例ModuleName.v)。
· 每行只写一个声明语句或说明。
· 如上面的许多例子所示,用一层层缩进的格式来写。
· 用户定义变量名的大小写应自始至终一致(例如,变量名第一个字母大写)。
· 用户定义变量名应该是有意义的,而且含有一定的有关信息。而局部名(例如循环变量)可以是简单扼要。
· 通过注释对Verilog源代码作必要的说明,当然没有必要把Verilog源代码已能说明的再注释一遍,对接口(例如模块参数、端口、任务、函数变量)作必要的注释很重要。。
· 尽可能多地使用参数和宏定义,而不要在源代码的语句中直接使用字母、数字和字符串。
可综合代码的编写标准:
· 把设计分割成较小的功能块,每一块用行为风格去设计这些块。除了设计中对速度响应要求比较临界部分外,都应避免使用门级描述。
· 应建立一个定义得很好的时钟策略,并在Verilog源代码中清晰地体现该策略(例如采用单时钟、多相位时钟、经过门产生的时钟、多时钟域等)。保证在Verilog源代码中时钟和复位信号是干净的(即不是由组合逻辑或没有考虑到的门产生的)
· 要建立一个定义得很好的测试(制造)策略,并认真编写其Verilog代码,使所有的触发器都是可复位的,使测试能通过外部管脚进行,又没有冗余的功能等。
· 每个Verilog源代码都必须遵守并符合在Always声明语句中介绍过的某一种可综合标准模板。
· 描述组合和锁存逻辑的always块,必须在always块开头的控制事件列表中列出所有的输入信号。
· 描述组合逻辑的always块一定不能有不完全赋值,也就是说所有的输出变量必须被各输入值的组合值赋值,不能有例外。
· 描述组合和锁存逻辑的always块一定不能包含反馈,也就是说在always块中已被定义为输出的寄存器变量绝对不能再在该always块中读进来作为输入信号。
· 时钟沿触发的always块必须是单时钟的,并且任何异步控制输入(通常是复位或置位信号)必须在控制事件列表中列出。
· 避免生成不想要的锁存器。在无时钟的always块中,由于有的输出变量被赋了某个信号变量值,而该信号变量没在该always块的电平敏感控制事件中列出,这会在综合中生成不想要的锁存器。
· 避免不想要的触发器。在时钟沿触发的always 块中,用非阻塞的赋值语句对寄存器类型的变量赋值,综合后就会生成触发器;或者当寄存器类型的变量在时钟沿触发的always 块中经过多次循环它的值仍保持不变,综合后也会生成触发器。
· 所有内部状态寄存器必须是可复位的,这是为了使 RTL 级和门级描述能够被复位成同一个已知的状态以便进行门级逻辑验证。(这并不适用于流水线或同步寄存器)
· 对存在无效状态的有限状态机和其他时序电路(例如,四位十进制计数器有六个无效状态),如果想要在这些无效状态下,硬件的行为也能够完全被控制,那么必须用Verilog明确地描述所有的二的N次幂种状态下的行为,当然也包括无效状态。只有这样才能综合出安全可靠的状态机。
· 一般情况下,在赋值语句中不能使用延迟,使用延迟的赋值语句是不可综合的,除了在Verilog的RTL级描述中需要解决零延迟时钟的倾斜问题是个例外。
· 不要使用整型和time型寄存器,否则将分别综合成32位和64位的总线。
· 仔细检查Verilog代码中使用动态指针(例如用指针或地址变量检索的位选择或存储单元)、循环声明或算术运算部分,因为这类代码在综合后会生成大量的门,而且很难进行优化。
----------------------------------------------------------------------------
五. 设计流程
-----------------------------------------------------------------------------
用 Verilog 和综合工具设计 ASIC 或复杂 FPGA 的基本流程如下:
围绕着设计流程作多次反复是必要的,但下面的流程没有对此加以说明。而且设计流程必须根据所设计的器件的和特定的应用作必要的改动。
1系统分析和指标的确定
2系统划分
2.1顶级模块
2.2模块大小估计
2.3 预布局
3 模块级设计,对每一模块:
3.1写RTL级Verilog
3.2综合代码检查
3.3写Verilog测试文件
3.4 Verilog仿真
3.5写综合约束、边界条件、层次
3.6预综合以分析门的数量和延时
4芯片综合
4.1写Verilog测试文件
4.2 Verilog仿真
4.3综合
4.4门级仿真
5测试
5.1修改门级网表以便进行测试
5.2产生测试向量
5.3对可测试网表进行仿真
6布局布线以使设计的逻辑电路能放入芯片
7布局布线后仿真、故障覆盖仿真、定时分析
-----------------------------------------------------------------------------
Verilog 硬件描述语言参考手册(按字母顺序查找部分)
-----------------------------------------------------------------------------
Always 声明语句
包含一个或一个以上的声明语句(如:进程赋值语句、任务启动、条件语句、case语句和循环),在仿真运行的全过程中,在定时控制下被反复执行。
语法
always
声明语句
在程序中位于何处:
module- -endmodule
规则:
在always块中被赋值的只能是寄存器类型的变量,如 reg, integer, real, time, realtime。每个always在仿真一开始时便开始执行,在仿真的过程中不断地执行,当执行完always块中最后一个语句后,继续从always的开头执行。
注意!
如果always块中包含有一个以上的语句,则这些语句必须放在 begin_end或 fork_join块中。如果always中没有时间控制,将会无限循环。
可综合性问题:
always声明语句是用于综合过程的最有用的Verilog声明语句之一,然而always语句经常是不可综合的。为了得到最好的综合结果,always块的Verilog 程序应严格按以下的模板来编写。
always @ (Inputs) // 所有的输入信号都必须列出,在它们之间插入逻辑关系词or
begin
... ….. // 组合逻辑关系
end
always @(Inputs) // 所有的输入信号都必须列出,在它们之间插入逻辑关系词or
if (Enable)
begin
.……... //锁存动作
end
always @(posedge Clock) // Clock only
begin
……… // 同步动作
end
always @(posedge Clock or negedge Reset)
// Clock and Reset only
begin
if (!Reset) //测试异步复位电平是否有效
.…….. // 异步动作
else
.…… // 同步动作
end // 可产生触发器和组合逻辑
举例说明:
下面是一个寄存器级always的例子
always @(posedge Clock or negedge Reset)
begin
if (!Reset) // Asynchronous reset
Count <= 0;
else
if (!Load) // Synchronous load
Count <= Data;
else
Count <= Count + 1;
End
下面是一个描述组合逻辑电路的always块的例子:
always @(A or B or C or D)
begin
R = {A, B, C, D}
F = 0;
begin : Loop
integer I;
for (I = 0; I < 4; I = I + 1)
if (R[I])
begin
F = I;
disable Loop;
end
end // Loop
end
还请参阅:
Begin, Fork, Initial, Statement, Timing Control
------------------------------------------------------------------------------
Assign 连续赋值声明语句
每当表达式中NET(即连线)或寄存器类型变量的值发生变化时,使用连续赋值声明语句就可在一个或更多的电路连接中创建事件。
语法:{either}
assign [ Strength] [ Delay] NetLValue = Expression,
NetLValue = Expression,
...;
NetType [ Expansion] [ Strength] [ Range] [ Delay]
NetName = Expression,
NetName = Expression,
...; {See Net}
NetLValue = {either}
NetName
NetName[ ConstantExpression]
NetName[ ConstantExpression: ConstantExpression]
{ NetLValue,...}
在程序中位于何处:
module--endmodule
规则:
两种形式的连续赋值语句效果相同。
在连续赋值声明语句之前,赋值语句左边的NET(即连线类型的变量)必须明确声明。
注意!
连续赋值并不等同于进程连续赋值语句,虽然它们相似。确保把 assign 放在正确的地方。连续赋值语句必须放在任何initial和always块外。进程连续赋值语句可放在该语句被允许放的地方执行(在initial 、always、task、 function等块内部)。
可综合性问题:
· 综合工具不能处理连续赋值语句中的延迟和强度,在综合中被忽略。请用综合工具指定的定时约束来代替。
· 连续赋值语句将被综合成为组合逻辑电路。
提示:
用连续赋值语句去描述那些用简洁的表达式就能够很容易表达的组合逻辑电路。函数能够用来构建表示式。在描述较复杂的组合逻辑电路方面,用always块比用许多句分开的连续赋值语句更好,而且在仿真的速度更快一些。当Verilog需要电路连线时,可用连续赋值语句把寄存器的值传送到电路连线上(即NET上)。例如,把一个initial块中产生的测试激励信号加到一个实例模块的输入输出端口。
举例说明:
wire cout, cin;
wire [31:0] sum, a, b;
assign {cout, sum} = a + b + cin;
wire enable;
reg [7:0] data;
wire [7:0] #(3,4) f = enable ? data : 8’bz;
还请参照:
Net、Force、进程连续赋值语句
-----------------------------------------------------------------------------
Begin 声明语句
用于把多个声明语句组合起来成为一个语句,而其中每个声明语句的执行是按顺序。Verilog语法经常严格要求只有一个声明语句,例如always就是这样。如果always需要有多个声明语句,那么这些声明语句必须被包含在一个begin-end块中。
语法
begin [: Label
[ Declarations...]]
Statements...
End
Declaration = {either} Register Parameter Event
在程序中位于何处:
请参照 Statement 的说明
规则:
begin-end块必须包含至少一个声明语句。声明语句在begin-end块中被顺序执行。定时控制是相对于前一声明语句的。当最后的声明语句执行完毕后,begin-end块便结束。Begin-end 和fork-join块可以自我嵌套或互相嵌套。如果begin-end块包含局部声明,则它必须被命名(即必须有一个标识)。如果要禁止(disable)某个begin-end块,那么被禁止的begin-end块必须有名字。
注意!
Verilog LRM 允许begin-end块在仿真时被交替执行。这就是说如果begin-end块包含两个相邻且其间没有时间控制的声明语句时,仿真器仍有可能在同一时刻在这两个语句之间执行另一个进程的部分语句(例如另一个always块中的语句)。这就是Verilog 语言如果不加约束的话,便不能与硬件有确定对应关系的原因。
提示:
甚至在并不需要局部声明,也不想禁止Begin-end块时,也可以对该Begin-end块加标识命名,以提高其可读性。给不用在别处的寄存器作局部声明,能使声明的意图变得清楚。
举例说明:
initial
begin : GenerateInputs
integer I;
for (I = 0; I < 8; I = I + 1)
#Period {A, B, C} = I;
end
initial
begin
Load = 0; // Time 0
Enable = 0;
Reset = 0;
#10 Reset = 1; // Time 10
#25 Enable = 1; // Time 35
#100 Load = 1; // Time 135
end
还请参照:
Fork, Disable, Statement.
-------------------------------------------------------------------------------
Case 声明语句:
如果case控制表达式与标号分支表达式相等,则执行该分支的声明语句。
语法:
CaseKeyword ( Expression)
Expression,... : Statement {Expression may be variable}
Expression,... : Statement
... {Any number of cases}
[default [:] Statement] {Need not be at the end}
endcase
CaseKeyword = {either} case casex casez
在程序中位于何处:
请参照 Statement 的说明
规则:
· 不确定值(Xs)和高阻值(Zs)在casex声明语句中,以及(Zs )在casez声明语句的表达式匹配中都意味着“不必考虑”。
· 在case语句中最多只允许有一个default项。当没有一个分支标号表达式能与case表达式的值相等时,便执行default项。(标号是位于冒号左边的一个表达式或用逗号隔开的几个表达式,标号也可以是保留字default,在其后面可以跟冒号也可以不跟冒号。)
· 如果某标号是用逗号隔开的两个或两个以上表达式,只要其中任何一个表达式与case表达式的值相等时,就可执行该标号的操作。
· 如果没有一个标号表达式与case表达式的值相等,又没有default声明语句,该case声明语句没有任何作用。
注意:
· 如果在标号分支中有一个以上的声明语句,这些声明语句必须放在一个begin-end或fork-join块中。
· 只有第一个与case表达式的值相等的标号分支才被执行。Case语句的标号并不一定是互斥的,所以当错误地重复使用相同的标号时,Verilog编译器不会提示出错。
· Casex 或 casez 声明语句的语法是用保留字 endcase 作为结束,而不是用 endcasex 或 endcasez 来结束。
· 在 casex 声明语句的表达式中的 X (不定值)或Z(高阻值)可以和任何值相等,casez中的 Z 也是如此。这有可能会给仿真结果带来混乱。
可综合性问题:
Case声明语句中的赋值语句通常被综合成多路器。如果变量(如寄存器或Net类型)被用作Case语句的标号,它就会被综合成优先编码器(priority encoders)。
在一个无时钟触发的always块中,如有不完整的赋值(即对某些输入信号的变化其输出仍保持不变,未能及时赋值),它将被综合成透明锁存器。
在一个有时钟触发的always块中,如有不完整的赋值,它将被综合成循环移位寄存器。
提示:
· 为了使仿真能顺利进行,常常用 default 作为 case 声明的最后一个分支,以控制无法与标号匹配的 case 变量。
· 通常情况下用casez比用casex更好一些,因为X的存在可能会导致仿真出现令人误解和混乱的结果。
· 在casex 和 casez声明的标号中用“?”来代替“Z”比较好,因为这样做比较清楚,是一个无关项,而不是一个高阻项。
举例说明:
case (Address)
0 : A <= 1; // Select a single Address value
1 : begin // Execute more than one statement
A <= 1;
B <= 1;
end
2, 3, 4 : C <= 1; // Pick out several Address values
default : // Mop up the rest
$display(“Illegal Address value %h in %m at %t”, Address, $realtime);
endcase
casex (Instruction)
8’b000xxxxx : Valid <= 1;
8’b1xxxxxxx : Neg <= 1;
default
begin
Valid <= 0;
Neg <= 0;
end
endcase
casez ({A, B, C, D, E[3:0]})
8’b1??????? : Op <= 2’b00;
8’b010????? : Op <= 2’b01;
8’b001???00 : Op <= 2’b10;
default : Op <= 2’bxx;
endcase
还请参照:
If
-----------------------------------------------------------------------------
Comment 注释语句
注释应该位于Verillog源代码文件中。
语法
单行注释
//
多行注释
/* ... */
在程序中位于何处:
可以放在源代码的几乎任何地方,但是注意不能把运算符、数字、字符串、变量名和关键字分开。
规则:
单行注释以两个斜杠符开始,结束于该行的末尾 。
多行注释以“/*” 符开始,中间可能有多行,结束于“*/” 符。
多行注释不能嵌套,但是,在多行注释中可以有单行注释,但在这儿它没有别的特殊含义。
注意:
/* ... /* ... */ ... */- 这样的注释会出现语法错误,要注意注释符的匹配。
提示:
建议在源代码文件中自始至终用单行注释。只有在必需注释一大段的地方才用多行注释,例如在代码的开发和调试阶段,常需要详细地注释。
举例说明:
// This is a comment
/*
So is this - across three lines
*/
module ALU /* 8-bit ALU */ (A, B, Opcode, F);
请参照:
Coding Standard 编码标准
------------------------------------------------------------------------------
Defparam 定义参数声明语句
编译时可重新定义参数值。如果是分层次命名的参数,可以在该设计层次内或外的任何地方重新定义参数。
语法:
Defparam ParameterName = Constant Expression
ParameterName = ConstantExpression,
... ;
在程序中位于何处:
module--endmodule
可综合性问题:
一般情况下是不可综合的。
提示:
不要使用defparam 声明语句! 该声明语句过去常用于布线后的时延参数反标中,但现在时延参数反标一般用指定模块和编程语言接口(PLI)来做。在模块的实例引用时可用“#”号后跟参数的语法来重新定义参数。
举例说明:
‘timescale 1ns / 1ps
module LayoutDelays;
defparam Design.U1.T_f = 2.7;
defparam Design.U2.T_f = 3.1;
...
endmodule
module Design (...);
...
and_gate U1 (f, a, b);
and_gate U2 (f, a, b);
...
endmodule
module and_gate (f, a, b);
output f;
nput a, b;
parameter T_f = 2;
and #(T_f) (f,a,b);
endmodule
还请参照:
Name, Instantiation, Parameter
-----------------------------------------------------------------------------
Delay 时延
可以为UDP和门的实例指定时延,也可以为连续赋值语句和线路连接指定时延。时延是在网表中线路连接和元件传输时延的模型。
语法:
{either}
# DelayValue
#( DelayValue[, DelayValue[, DelayValue]]) {Rise,Fall,Turn-Off}
DelayValue = {either}
UnsignedNumber
ParameterName
ConstantMinTypMaxExpression
在程序中位于何处:
请参照:连续赋值语句、实例引用、线路连接。
规则:
· 如果只给出一个延迟,则它既表示上升延迟也表示下降延迟 (即从0转变到1或从1转变到0的时延),并且还表示关闭延迟(如果电路中有这样开关)。
· 如果给出两个延迟值,则第一个表示上升延迟,第二个表示下降延迟,除了tranif0, tranif1, rtranif0和rtranif1外,第一个值也可表示接通延迟,第二个表示关闭延迟。
· 如果给出三个延迟,第三个延迟表示关闭延迟(转变到高阻),除了三态电路外,第三个延迟表示电荷衰减时间。
· 延迟到X表示最小的指定延迟。
· 对于向量,从非零到零的转变被看作下降,转变到高阻被看作关闭,其余的变化被看作是上升。
注意!
许多工具要求MinTypMax延迟表达式必须用括号括起来。例如 #(1:2:3)是合法的,而 #1:2:3是非法的。
可综合性问题:
一般综合工具不考虑延迟。综合后网表中的延迟是由综合工具的命令项强制生成的,如在综合工具中可设置本次设计综合生成的门级电路所允许的最高时钟频率。
提示:
指定块的延迟(即线路路径延迟)通常是一种更加精确的延迟建模方法,可提供延迟计算机制和布线后反标信息。
还请参照:
线路连接, 实例引用, 连续赋值, Specify, 定时控制 等声明语句
-----------------------------------------------------------------------------
Disable 禁止
在运行激活的任务或命名的块时Disable能使在所在块执行完毕以前,终止该块的执行。
语法:
disable BlockOrTaskName;
在程序中位于何处:
请参照 Statement.
规则:
· 禁止(disable)命名块(即定义了名称的begin_end或fork_joink块)或任务便禁止了所有由该块或该任务激活的任务,直达该块或该任务层次树的底层。继续执行禁止(块或任务)语句后的声明语句。
· 命名块或任务可以通过其内部的禁止声明语句实现自我禁止
· 当一个任务被禁止时,以下内容未被指定:任何一个输出值或输入输出值;尚未起作用的非阻塞赋值语句、赋值和强制声明语句所预定的事件。
· 函数不能被禁止。
注意!
如果一个任务被自我禁止,这跟任务返回不一样,因为输出未定义。
可综合性问题:
只有当命名块或任务自我禁止时,禁止才是可综合的,一般情况下是不可综合的。
提示:
用禁止作为一种及早跳出任务的方法,用来跳出循环或继续下一步循环。
举例说明:
begin : Break //命名Break块
forever
begin : Continue //命名Continue块
...
disable Continue; // Continue with next iteration
...
disable Break; // Exit the forever loop
...
end // Continue
end // Break
-----------------------------------------------------------------------------
Errors 错误
下面列出的是编写Verilog源代码时最常犯的错误。前面的五个错误大约占所有错误的50%。
最容易犯的五大错误:
· 进程赋值语句的左侧变量没有声明为寄存器类型。
· Begin – end 声明语句忘了配套。
· 写二进制数时忘了标明数基(即‘b)。这样,在编译时会把它们当作十进制数来处理。
· 编译引导语句用了错误的撇号,应该用向后的撇号也就是用表示重音的撇号;而表示数基的撇号,应该是普通的撇号,也就是反向的逗号。
· 在声明语句的末尾忘了写上分号。
· 其他常犯的错误:
· 在定义任务或函数时,试图在任务或函数名后用括号来定义变量。
· 在调试时,忘了在测试文件中引用实例模块。
· 使用进程连续赋值语句而没有使用连续赋值语句(即赋值语句用错了地方)
· 把保留字作为标识符(例如用xor做标识符)。
· Always块忘了声明定时控制(导致无休止的循环)。
· 在事件控制列表中错误地使用了逻辑或操作符(即||)而没有使用或保留字or,例如把always @(a or b),写成了always @(a||b)。
· 用缺省定义的wire类型变量来做矢量端口的连线。
· 模块实例引用时端口的连接次序搞错。
· 在嵌套的 if-else 语句中 begin-end 配套错误。
· 错误地使用等号。“ = ”用于赋值,“ = = ”用于作数值比较,“ = = = ”用于需要对0、1、X、Z 这四种逻辑状态作准确比较的场合 。
-----------------------------------------------------------------------------
Event 事件
在行为模型中Events可以用来描述通信和同步。
语法:
event Name ,...; {Declare the event}
-> EventName; {Trigger the event}
语法
事件名,…;(事件声明)
->事件名 (触发事件)
在程序中位于何处:
请参照为 -> 所作的声明语句。
事件声明语句可以放在下面这些地方:
module--endmodule
begin : Label--end
fork : Label--join
task--endtask
function--endfunction
规则:
事件没有值,也没有延迟,它们仅被事件触发声明所触发,由沿敏感定时控制启动
检测。
可综合性问题:
通常是不可综合的。
提示:
在测试文件和系统级模块中,命名事件可用于同一个模块的不同always 块间或不同模块(用层次名)的always块间传递信息。
举例说明:
event StartClock, StopClock;
always
fork
begin : ClockGenerator
Clock = 0;
@StartClock
forever
#HalfPeriod Clock = !Clock;
end
@StopClock disable ClockGenerator;
join
initial
begin : stimulus
...
-> StartClock;
...
-> StopClock;
...
-> StartClock;
...
4-> StopClock;
end
还请参阅:
定时控制
PAGE
16