verilog学习笔记(四)赋值语句与块语句
继续整理完操作符内容
关键词
Verilog语言事先定义的一些确认符,都是小写字母定义,在使用关键词时要注意,另外注意定义变量时不要与关键词重复。
常见的关键词有:initial always begin end.....
赋值语句
verilog中的常见赋值方式有2种分别是非阻塞赋值和阻塞赋值。
非阻塞赋值
该赋值方法的特点是:语句块中上一个语句赋值的变量在下面的语句中的值不会马上变化,而是在语句块结束后才变化。
非阻塞赋值没有运行顺序,属于并行处理。
用<=表示
阻塞式赋值
在赋值结束后,语句块才结束。
赋值语句结束后立刻改变变量的值。
用=表示
块语句
将多条语句组合在一起的结构,一般有2种表示形式。
1.Begin end语句
顺序块
进入后按顺序运行块内语句
每条语句的延迟是按照前一条的仿真时间决定
运行到最后才离开块
2.Fork join语句
并行块
并行运行内部所有语句
每个语句的延迟是从进入块开始算的
延迟语句可以给赋值语句提供时序
在运行完最后一句或遇到disable结束
块名
可以在begin或fork后面给块命名
可以在块内定义局部变量
允许块被其他语句调用
Verilog里的所有变量都是静态的,只有一个存储地址
当把一个块嵌入另一个块中需要注意起始和结束时间,只有块运行结束后面的语句才运行
条件语句
If有3种使用的形式分别是
1单独使用if
2if else一起使用
3多个条件的if else语句
if(a>b) out=in; #1 if (a>b) out1=in1; else out2=in2; #2 if () else if() else
#3
条件语句必须在过程块中使用,过程块指always和initial引导的语句,且是begin end块
注意:
0,x,z都作为假进行处理
只有1是真
If else可以有begin end作为复合块
允许简写
If(a)等于 if(a==1)
If (!a) 等于 if (a!=1)
If可以进行多层嵌套,注意if else的对应即可
可以用begin end块语句确定if else对应关系
Case语句
多分支选择语句
Case<分支项>endcase
Casex<分支项>endcase
Casez<分支项>endcase
分支项的一般格式
分支表达式:语句;
默认项: 语句;
Case括号内的表达式称为控制表达式,分支表达式通常为常数
当控制表达式与某个分支表达式相等,则执行对应语句,当所有的分支都不匹配则执行默认语句
每个分支必须不相同
执行完分支后则跳出case语句
分支表达式的值必须明确才能比较
Case语句所有表达式的位宽必须一致
Case,casez,casex真值
Case等同为与
|
0 |
1 |
x |
z |
0 |
1 |
|
|
|
1 |
|
1 |
|
|
x |
|
|
1 |
|
z |
|
|
|
1 |
Casez处理不考虑高阻值的情况
|
0 |
1 |
x |
z |
0 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
0 |
1 |
x |
0 |
0 |
1 |
1 |
z |
1 |
1 |
1 |
1 |
Casex处理不考虑高阻值和不定值的情况
|
0 |
1 |
x |
z |
0 |
1 |
0 |
1 |
1 |
1 |
0 |
1 |
1 |
1 |
x |
1 |
1 |
1 |
1 |
z |
1 |
1 |
1 |
1 |
相比ifelse语句,case可以对于存在不定值和高阻态的分支进行处理
如果使用if尽量用else
如果使用case尽量用default
这样可以避免产生锁存器
循环语句
Forever 循环语句用于initial块中,常用于产生时钟信号
Repeat(表达式)语句,表达式通常为常数
While(表达式)语句
For(循环变量;循环结束条件;循环变量增值)
并行块注意:
若两条语句在同一时刻对一个变量产生影响,可能出现竞争风险,这样的语句要避免出现。
块命名
module top initial begin:block1 integer i1; end initial begin:block2 reg r1; end
块其中的变量可以用
Top.block1.i1来引用
块禁用
Disable语句可以终止块的运行,类似break
生成块
生成语句可以动态生成verilog代码,该声明方便参数化模块的生成
对矢量的多个位进行重复操作,多个模块的实例重复操作,根据参数定义确定程序是否包含某段代码等,可以提高编写效率
Generate
Endgenerate
生成的实例范围有:模块,用户定义原语,门级原语,连续赋值语句,initial和always
允许在生成范围内声明的类型:net,reg,integer,real,time,realtime,event
生成的数据类型具有唯一标识符名,可以逐层引用
生成的任务和函数同样具有唯一的标识符名
不能出现在生成范围的模块声明有:参数,局部参数,输入输出声明,指定块。
有3中生成块方法:
1循环生成
2条件生产
3Case生成
循环生成
允许多次引用的实例:
1变量声明
2模块
3用户定义原语,门级原语
4连续赋值
5Initial always块
下面是2个N位总线变量进行按位亦或,使用生成块进行编程
module bit_xor(out,i0,i1); parameter N=32; output [N-1:0] out; input [N-1,:0] i0,i1; genvar j; generate for (j=0;j<N;j=j+1) begin:xor_loop xor g1(out([j],i0[j],i1[j]); end endgenerate
genvar生成变量
在仿真时,生成块的代码会被展开,生成变量的值只能由循环生成语句赋值
Xor_loop是赋予循环生成语句的名字,循环语句中的各个亦或门的相对层次为
Xor_loop[0].g1, Xor_loop[1].g1…. Xor_loop[31].g1
只要能想象出展开后的形式,就能写出生成语句
条件生成语句
与循环生成语句的差别是,不能用生成变量
使用方法和循环生成类似
在生成语句的范围内
用条件语句调用不同的模块等
case生成语句
和条件语句类似