verilog学习笔记
文章目录
前言
本次主要介绍Verilog的块语句概念,块语句对应到高级语言中其实就是多行指令的结构,在C语言等高级语言中由于代码的执行是逐行完成的,而硬件语言涉及到逻辑电路的控制,同步与异步指令的执行效果会有很大差异,因此块语句需要额外去介绍。
一、块语句的基本结构
块语句是将多条语句组合在一起的结构,一般有2种表示形式。
1.Begin end语句
用于顺序块语句的声明
进入后按顺序运行块内语句
每条语句的延迟是按照前一条语句的运行延迟时间决定
运行到最后才离开块结构
2.Fork join语句
用于并行块语句的声明
并行运行内部所有语句
每个语句的延迟是从进入块开始算的
延迟语句可以给赋值语句提供时序
在运行完最后一句或遇到disable结束
3.块名
可以在begin或fork后面给块命名
可以在块内定义局部变量
允许块结构被其他语句调用
Verilog里的所有变量都是静态的,只有一个存储地址
当把一个块嵌入另一个块中需要注意起始和结束时间,只有块运行结束后面的语句才会运行
4.条件语句
4.1 if语句
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语句允许简写
if(a)等于 if(a==1)
if (!a) 等于 if (a!=1)
If可以进行多层嵌套,注意if else的对应即可
可以用begin end块语句确定if else对应关系
4.2 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 |
相比if else语句,case可以对于存在不定值和高阻态的分支进行处理
注意:
如果使用if尽量用else闭合
如果使用case尽量用default
这样可以避免产生锁存器
4.3循环语句
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生成
4.1 循环生成
允许多次引用的实例:
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
只要能想象出展开后的形式,就能写出生成语句
4.2 条件生成语句
与循环生成语句的差别是,不能用生成变量
使用方法和循环生成类似
在生成语句的范围内
用条件语句调用不同的模块等
4.3 case生成语句
和条件语句类似
总结
本次主要介绍了有关块语句的内容,后续会进行一些仿真实践的学习。
本文详细介绍了Verilog中的块语句,包括Begin-end、Fork-join、条件语句(if、case)和循环语句的使用,以及块命名、禁用和生成块的概念,强调了在硬件编程中同步异步指令的执行差异和注意事项。
块语句&spm=1001.2101.3001.5002&articleId=115373461&d=1&t=3&u=59dc0466dfae442f8eafbb83612b4ddb)

被折叠的 条评论
为什么被折叠?



