Verlog
定义的模块一般包括过程语句,其中过程语句分为两种:initial 和alwa
Initial用于仿真当中的初始化,always用于不断重复执行的。Always过程是可以用于综合的,initial是不可综合的。
Always过程语句:
Always@(<敏感信号表达式>)
Begin
//语句序列
End
其中触发条件写在敏感信号表达式当中。事件引发其中语句的执行。下面给出一个简单的示例:
Moduleadd32(input wire[31:0] in1,
Input wire[31:0] in2,
Output reg[31:0] out)
always@(in1or in2)
begin
out= in1+in2
end
endmodules
当然,敏感信号当中的多个信号也可以用逗号隔开,就像下面这样:
Moduleadd32(input wire[31:0] in1,
Input wire[31:0] in2,
Output reg[31:0] out)
always@(in1, in2)
begin
out= in1+in2
end
endmodules
如果使用通配符“*”,就表示改过程中的所有输入信号变量
组合电路与时序电路:
敏感信号有两种类型:一种为电平敏感类型,另一种为边沿敏感性,前一种一般对应组合电路,后一种一般对应时序电路。时序电路敏感信号一般是时钟信号,HDL 提供posedge negedge两个关键字描述时钟信号posedge表示时钟信号的上升沿作为触发条件,negedge表示时钟型号的下降沿作为触发条件。以32位加法器为例:
Module add32(inputwire clk,//增加了一个时钟信号
Input wire[31:0] in1
Inout wire[31:0] in2,
Output reg[31:0] out);
Always@(posedge clk)
Begin
Out= in1+in2;
End
Endmodule
这样就只会在时钟的上升沿才会进行加法的运算。
Initial 过程语句
Initial过程语句如下:
Initial
Begin
//语句序列
End
Initial过程语句不带触发条件,语句只执行一次。Initial过程语句通常用于仿真模块中队激励向量的描述,或者用于给寄存器赋初值,是面向模拟仿真的过程语句。通常不能被综合。下面是一个简单的例子:
Initial
Begin
For(addr= 0;addr< size; addr = addr+1)
Mem[addr]= 0;
End
赋值语句
赋值语句有两种:持续赋值语句,过程赋值语句。
1:持续赋值语句
Assign为持续赋值语句,主要用于对wire型变量的赋值。
2:过程赋值语句:
在always,initial过程中的赋值语句称为过程赋值语句,多用于对reg型变量经行赋值
其中又分为非阻塞式赋值和阻塞式赋值。
(1) 非阻塞式赋值(non-blocking)
赋值符号为哦“<=”,例如:
B<=a
非阻塞式赋值在整个过程语句结束时才会完成赋值操作,即b的值不是立刻改变的,
(2) 阻塞赋值(blocking)
赋值符号为“=”例如:
B=a
阻塞赋值在该语句结束时立即完成赋值操作,b的值在这条语句结束后立刻改变
在always9过程快当中,阻塞赋值语句可以理解为赋值语句是顺序执行的,二非阻塞语句是并发执行的。而阻塞语句与非阻塞语句只能使用一种。
条件语句
条件语句有if-else,case两种,应该放在always块内
1. if-else语句
语句有三种:
(1) if(表达式)
(2) if(表达式)
else
(3) if(表达式)
else if (表达式1)
else if (表达式2)
else if(表达式3)
……………
Else if(表达式n)
Else
上述的表达式一般为逻辑表达式或者关系表达式,系统对表达式经行判断,如果为0,x,z,则按假处理,如果为1,就按真处理。如果是多句时使用begin-end处理。
Moduleadd32(input wire rst,
Input wire[31:0] in1,
Input wire[31:0 in2,
Outout reg[31:0] out)
Always@(*)
Begin
If(rst ==1’b1)
Out<=32’h0
Else
Out <= in1+in2;
Endmodule
Case是一种分支语句,case语句多用于条件译码电路,如译码器,数据选择器,状态机以及微处理器的指令译码等 case的语句如下:
Case(敏感表达式)
值1:语句序列1;
值2:语句序列2;
………………………
值n:语句序列n;
Default:语句序列n+1;
Endcase
根据敏感表达式的值来执行相应的语句。否则执行相应的default语句。
Module ad_sub32(inputwire type,
input wire[31:0] in1,
Input wire[31:0] in2,
Output reg[31:0] out);
always@(*)
begin
case(type)
1’b1:out <= in1+in2;
1’b0:out <= in1-in2;
Default : out <=32’h0;
Endcase
End
Endmodule
除此之外还有casez和casex扩展。
在casez语句当中,如果比较双方的某些位值为Z,那么这些位的比较结果就不予以考虑。值。
在casex语句中,如果比较的双方的某些位的值为Z或者X,那么对于这些位的比较结果就不予考虑。只需要考虑其他位比较结果。
同样可以使用?来表示无关的值:
Case(a)
2‘b1?:out <= 1;
HDL之循环语句:
HDL存在四种类型的循环语句:for、forever、repeat、while。用来控制语句的执行次数,分别介绍如下。
1:for语句
For语句的格式如下。使用与C语音相似。
For(循环变量赋初值;循环结束条件;修改循环变量)
执行语句序列;
下面是使用for循环写的7人表决器:
Module vote(vote,pass);
Input wire[7:1] vote;
output reg pass;
reg[2:0] sum;
integer I;
always @(vote)
begin
sum = 0;
for(i=1;i<7;i++)
if(vote[i])
sum = sum+1;
if(sum[2] == 1’b1)
pass = 1;
else
pass =0;
end
endmodule
2、forever语句
Forever语句格式如下:
Foreverbegin
//语句序列
End
Forever循环语句连续不断地执行其中的语句序列,用来产生周期性的波形。
3、repeat 语句
Repeat(循环语句表达式)begin
//语句序列
End
4、while 语句
While(循环条件表达式)begin
//语句序列
End
编译只是语句:
HDL同样提供了编译指示的功能,编译时通常对指示语句进行预先的处理。
指示语句以“‘“开始,常用的编译指示语句有
‘define
‘include
‘ifdef
‘else
‘endif
分别介绍一下:
‘define用简单的有意义的标识符代替复杂的变量,用法如下:
‘define宏名 变量或者名字
//定义宏RstEnable 表示复位信号。
‘define RstEnable 1’b1
always@(clk)
begin
if(rst== ‘RstEnable)
//复位函数
Else
//复位无效
End
‘include语句
‘include是文件包含语句,它可将一个文件全部包含到另一个文件当中。
‘include“文件名”
条件编译语句’ifdef ‘else ‘endif
可以对指定的语句进行编译,其中有两种使用形式:
‘if 宏名
//语句序列1
‘endif
第二种
‘if 宏名
//语句序列1
‘else
//语句序列2
‘endif
行为语句的可综合性:
有些语句可以在仿真中使用,有些语句则不可以在仿真当中使用。也就是说综合器无法将这些语句转变为对应的硬件电路。
可综合的语句有:过程语句(always ),赋值语句(持续赋值assign、过程赋值语句=、<=)、条件语句(if-else、case)、循环语句当中的for语句,编译指示语句中,
‘define ‘ifdef ‘else ‘endif