概述
文章目录
- 一、Verilog基本语法
- Verilog语法概述
- 基本语法
- 数据类型及常量,变量
- 常量
- 变量
- 运算符
- 优先级
- 【重要】语句
- part0 概述
- part1 赋值条件语句详解
- part2 循环语句详解
- part3 结构语句详解
- 执行顺序
一、Verilog基本语法
Verilog语法概述
- 行为级描述、寄存器级描述(RTL)/系统级描述:把module当做黑盒,描述module的输入和输出的关系。门级实现由综合工具推断,常常可以做到最优。
- 结构级描述/门级描述:把module作为白盒,而描述组成module的门电路(部件)
module <module_name> (in1, in2, ..., out1, out2)
input in1, in2, ...;
output out1, out2, ...;
...
endmodule
// 注释1
/* 注释2 */
基本语法
- Verilog区分大小写
- Verilog的关键字都是小写
module,endmodule
定义一个基本模块,两个关键字之间的语句是对该模块的描述。定义模块方便复用parameter
关键字定义一个参数,增强模块的通用性output,input
关键字指定输入输出always @(posedge/negedge clk)
语句,每当clk出现上升沿/下降沿时,就执行接下来的语句块(begin,end
标志着一个语句块)。这种语句构成时序逻辑,当输入与上一个时刻的值有关的时候reg
类变量用<=
赋值,赋值左边是寄存器,右边是更新的值&q
语句输出q每一位相与的结果,即&q=q[1]&q[2]&q[3]&q[4]...q[N]
assign
关键字,描述组合逻辑,输出只与当前输入有关- input/output没有显示说明,默认为
wire
类型,如果需要reg
类型来储存值,需要显示声明 wire
只是一根导线,只能用来组合逻辑,assign
语句一旦等号右边发生变化,等号左侧立即得到结果;而always
的值的改变只能发生在下一个时刻(有@后面的语句所描述的时刻)initial begin,end
语句块指明初始化语句,这部分在上电后直接执行'timescale 1ns/1ps
制定测试的单位是1ns,精度是1ps#100
指令指明延迟,单位由之前的代码指定$stop
指令使仿真停止- 时序逻辑:
<=
赋值;组合逻辑:=
赋值
数据类型及常量,变量
常量
语法:<位宽>'<进制><数值>
变量
- nets type
- register type
- nets type
wire
- register type
以上后面三种数据不可以综合,主要用在算法级开发
reg
运算符
优先级
【重要】语句
part0 概述
- 赋值语句
- 连续赋值语句:
assign
语句 - 过程赋值语句:
always
开头,@
引导的一个铭感列表
- 条件语句
if-else
case
条件语句必须在顺序执行块中使用。所谓顺序执行是指由initial和always语句引导的执行语句集合。除了这两种语句引导的begin-end块中可以编写条件语句外,模块中的其他地方都不可以
- 循环语句
forever
repeat
while
for
- 结果说明语句
initial
always
task
function
- 编译预处理语句
define
include
timescale
part1 赋值条件语句详解
always过程块
always @(<敏感信号表达式>)
begin
...
end
always
语句块不能嵌套- 在敏感信号表达式之前加
posedge/negedge
关键字可以指定上升沿或下降沿触发。否则每当列表表达式的值发生变化,就会执行数据块
initial过程块
initial
过程块模拟上电后的行为,不可综合,常用与功能模拟初始化。写在测试文件(testbench)中- 同一模块的
initial
过程块,在上电时并行执行 initial
过程块不能嵌套
连续赋值语句assign
assign
语句用于对wire
类型变量进行赋值- 等式左边
wire
变量随右边的值进行变化
过程赋值语句
- 常用与对
reg
型变量赋值 - 阻塞赋值(
=
)与非阻塞赋值(<=
)
- 一个栗子
// For e.g.
...
always @(posedge clk)
begin
b <= a
c <= b
end
...
// 上升沿来前,假设b=1,a=2
// 则上升沿来时,b=2,c=1,即c获得b的旧值
// 原因是非阻塞赋值下,两个赋值语句并行执行
// 若将<=全部改为=,则c=2,因为阻塞赋值是顺序执行的
case语句
case (<敏感值表达式>)
value_1: ...;
value_2: ...;
...
default: ...; //可省略
endcase
- 敏感信号表达式的位置写*,综合器会推断表达式。推断的主要依据是赋值语句的右侧值
小结
语法要点
-
always
里面赋值左边必须声明为reg
-
assign
表达式左边必须声明为wire
-
阻塞赋值用=
-
非阻塞赋值用<=
-
边沿触发生成寄存器的时序逻辑
-
电平触发且条件完整,生成组合逻辑
-
电平触发但条件不完整(写了if没写else,或case不完整),生成锁存器的时序逻辑
结论:
- 如果是边沿触发逻辑,里面一律用<=
比如always @(posedge clk)
,里面一律用<=
赋值 - 如果是电平触发逻辑,一律用=
逻辑简单用assign
;逻辑复杂用always
语句
分支条件写完整,防止出现锁存器
part2 循环语句详解
for语句(可综合)
for (<变量赋初值语句>; <条件表达式>; <变量增值语句>)
循环体;
repeat语句
repeat语句用于仿真
语法:
repeat(<循环次数表达式>)
循环体;
part3 结构语句详解
主讲function和task
function(可综合)
function
常用语实现简单的函数,module
里可以调用function
,而function
在一定意义上相当于一个module
。
栗子
task(不可综合)
task常用与仿真验证,语句块里可以写各种高级语句
例子(例子中的task的作用是等待number_of_edges
个下降沿)
function和task的不同
task中可以使用的高级系统函数
执行顺序
- 顺序执行块:
begin - end
(例外:always
语句块中用begin - end
和非阻塞赋值<=
时,这时是并行执行) - 并行执行块:
fork - join
栗子
由于fork - join
语句块是并行执行的,上图中的两个语句块描述的是同一个过程:
上电(系统启动)后50ns,r='h35'
;再过50ns,r='hE2'
;再过50ns,r='h00'
;以此类推。
延伸该例子,将语句块改为
fork
begin
#50 r='h35';
#100 r='hE2';
end
#150 r='h00';
#200 r='hF7';
#250 r='h00';
end
则依据begin - end
语句块的顺序执行性,r
的值在150ns时是不确定的,因为同时有两个赋值发生。
简单总结,如果想要串行执行,需要满足两个条件:
begin - end
语句块- 阻塞赋值=
最后
以上就是谨慎路灯为你收集整理的Verilog HDL学习笔记一、Verilog基本语法的全部内容,希望文章能够帮你解决Verilog HDL学习笔记一、Verilog基本语法所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复