原创 Verilog中各种语句含义及用法简述

2009-7-18 11:36 6424 5 5 分类: FPGA/CPLD

Verilog中各种语句含义及用法简述
















一般认为
Verilog HDL在系统级抽象方面比VHDL略差一些,而在门级开关电路描述方面比VHDL要强的多


写了第一个verilog程序,是一个加法器内容如下
module adder(count,sum,a,b,cin);
input[2:0] a,b;
input cin;
output count;
output [2:0] sum;
assign{count,sum}=a+b+cin;
endmodule


开始编译出现了几次错误,后来发现给实体的命名和程序中实体要一致而且大小写要一样,整个程序是嵌套再module和endmodule当中的


而其中的注释和C/C++类似,用//和/*…*/来标明


module compare(equal,a,b);
output equal;
input [1:0] a,b;
assign equal=(a==b)?1:0;//和C语言中的相同
endmodule



verilog的基本设计单元是“模块(BLOCK)”。一个模块由两个部分组成,一部分描述端口,一部分描述逻辑功能,即定义输入是如何影响输出的。如下
module block(a,b,c,d);
input a,b;
output c,d;


assign c="a|b";
assign d="a"&b;
endmodule


模块中最重要的部分是逻辑功能定义。有三种方法可以再模块中产生逻辑。
1、用“assign”声明语句
如:assign a="b"&c;
2、用实例元件,如同调入库元件一样
如:and and_inst(q,a,b);
3、用“always”块
如:always @(posedge clk or posedge clr)  //always块生成了一个带有异步清除端的D触发器。
               begin
                             if(clr) q<=0;
                   else if(en)  q<=d;
     end
采用assign语句是最常用的方法之一。“always”块可以用于产生各种逻辑,常用于描述时序逻辑。


Verilog HDL中总共有19种数据类型
4 个最基本的数据类型:integer型、parameter型、reg型和wire型。其他的类型有large型、medium型、scalared型、 time型、small型、tri型、trio型、tril型、triand型、trior型、trireg型、vectored型、wand型和wor 型,以后会有介绍。


一、数字
整数
有二、八、十、十六进制
<位宽>’<进制><数字>,这是一种全面的描述方式
缺省的位宽由具体的机器系统决定,至少是32位
缺省的进制为十进制
x表示不定值,z代表高阻值,z还可以用?代替
4'b10x0 //位宽为4的二进制数从低位数起第二位为不定值
4'b101z //位宽为4的二进制数从低位数起第一位为高阻值
12'dz    //位宽为12的十进制数,其值为高阻值
12'd?    //同上
8'h4x    //位宽为8的十六进制数,其低4位值为不定值
要表示负数的话只需在位宽表达式前加一个减号


4、下划线(underscore_)
可以用在数字之间提高数字的可读性如16'b1010_1011_1111_1010


二、参数(parameter)型
即用parameter来定义一个标识符代表一个常量,称为符号常量,类似于const和define pi一样。


网络数据类型表示结构实体(例如门)之间的物理连接,不能储存值,而且必须收到驱动器的驱动,如果没有驱动则该变量就是高阻的,值为z,常用的网络数据类型包括wire和tri型,wire型变量通常是用来表示单个门驱动或连续赋值语句驱动的网络型数据,tri型变量则用来表示多驱动器驱动的网络型数据
wire[7:0] b;//定义了一个8位的wire型数据


reg型
寄存器是数据存储单元的抽象,缺省初始值为不定值x


memory型
Verilog HDL通过对reg型变量建立数组来对存储器建模,可以描述RAM,ROM和reg文件。
如reg[7:0] mema[255:0];
定义了一个名为mema的存储器,有256个8位的寄存器,地址范围从0到255。
如果想对memory中的存储单元进行读写操作。必须指定该单元在存储器中的地址。·


2.3  运算符及表达式
(1)算数运算符(+,-,*,/,%);%为模运算,求余运算符
(2)赋值运算符(=,<=);
(3)关系运算符(>,<,>=,<=);
(4)逻辑运算符(&&,||,!);逻辑与,逻辑或,逻辑非
(5)条件运算符(?:);r=s?t:u;如果s为真,则r=t,否则r=u
(6)位运算符(~,|,^,&,^~);~取反,|位或,^按位异或,&按位与,^~按位同或(异或非)
(7)移位运算符(<<左移,>>右移);a>>n,n代表移几位,都用0来填补移出的空位
(8)拼接运算符({});把多个信号的某些位拼接起来
(9)其他。
单目运算缩减运算,如&b,是将b的每一位相与得出一位的结果


赋值语句和块语句
信号有两种赋值方式
1、非阻塞(non_blocking)赋值方式(如b<=a;)b的值不是立刻改变的,等到块结束后才完成赋值操作
2、阻塞(blocking)赋值方式(如b=a;)b的值立刻改变


顺序块
语句是顺序执行的
parameter d="50";
reg[7:0] r;
begin
#d r='h35;
#d r='hE2;
#d r='h00;
#d r='hF7;
#d ->end_wave;
end


用顺序块和延时控制组合来产生一个时序波形


并行块是语句同时执行的
在并行块和顺序块中都有一个起始时间和结束时间的概念。对于顺序块,起始时间就是第一条语句开始被执行的时间,结束时间就是最后一条语句执行结束的时间。而对于并行块来说,起始时间对于块内所有的语句是相同的,即程序植程控制进入该块的时间,其结束时间是按时间排序在最后的语句执行结束的时间。


if_else语句
case_endcase 语句
(1)case(表达式)<case分支项> endcase
(2)casez(表达式)<case分支项> endcase
(3)casex(表达式)<case分支项> endcase
Verilog HDL 针对电路的持性提供了case语句的其他两种形式,用来处理caee语句比较过程中的不必考虑的情况(don't care condition)。其中,casez语句用来处理不考虑高阻值z的比较过程,casex语句则将高阻值z和不定值x都视为不必关心的情况。所谓不必关心的情况,即在表达式进行比较时,不将该位的状态考虑在内。这样,在case语句表达式进行比较时,就可以灵活地设置以对信号的某些位进行比较。见下面的两个例子。


2.6  循环语句
有4种类型的循环语句
(1)forever--连续执行的语句,常用于产生周期性的波形,作为仿真测试信号。
(2)repeat--连续执行一条语句n次
(3)while--执行一条语句直到某个条件不满足
(4)for循环语句,和C/C++中的循环语句类似


2.7  结构说明语句
(1)initial;和always在仿真一开始即开始执行,initial语句只执行一次
(2)always;而always语句则不断重复执行
(3)task;和function语句可以在程序模块的一处或多处调用
(4)function;


always #half_period areg=~areg;//这条语句生成了一个周期为2*half_period的无限延续的信号波形。


reg

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
5
关闭 站长推荐上一条 /3 下一条