电平:
高电平 :1
低电平 :0
电平未知:X
高阻态 :Z
进制:
二进制 :b
八进制 :o
十进制 :d
十六进制: h
' 的概念:
举例:
二进制 4’b0101 4位二进制为 0101
十进制 4’d2 4位十进制为 0010
十六进制 4’ha 4位十六进制为1010
_的概念:
目的:增加程序的可读性。
举例:(_不被编译器编译)
16’b0101_0011_1010_0101=16’h53a5
标识符:
类似于C语言的变量名,用于定义模块名、端口号、信号名等。
标准:不建议大小写混写、普通内部信号全部小写、需要表明标识符含义含义
Verilog数据类型:
1.寄存器数据类型
表示一个抽象的数据存储单元,使用赋值语句可以改变寄存器的数值。
关键字reg ,只能在always和initial语句中被赋值,如果没有赋值,为未知数值X。
对应的硬件关系:
在时序逻辑电路:触发器 (时序逻辑--always语句块中带时钟信号 )
在组合逻辑电路:硬件连线(组合逻辑--always语句块中不带时钟信号)
举例:
reg [31:0] delay_cnt //位宽为32位
reg key_reg // 位宽为1位
2.线网数据类型
含义:表示结构实体(例如门)之间的物理连线,不能存储数值,只能由驱动它的元件所决定,驱动线网类型的元件有门、连续赋值语句、assign等,如果没有驱动元件连接到线网类型的变量上,该变量为Z。
表示:wire和tri,最常用的wire。
举例:wire key_flag //位宽为1的线网类型数据。
3.参数数据类型
参数是常量,在Verilog中用parameter定义常量,可以一次定义多个参数,参数和参数之间用逗号隔开,每个参数的右边必须是一个常数表达式。
格式举例:parameter H_SYNC = 11’d41
应用:
(1)参数型数据常用于定义状态机的状态、数据位宽和延迟大小等。
(2)采用标识符来代表一个常量可以提高程序的可读性和可维护性。
(3)在模块调用时,可通过参数传递来改变被调用模块中已定义的参数。
localparam和parameter的唯一区别在于localparam不可用于参数的传递,对于参数传递,在后面的文章可能会提到,也可自己先理解。
运算符
1.算术运算符:+ - * / %
注意:除法只能取整数。
2.关系运算符:> < <= >= == !=
3.逻辑运算符:!&& ||
4.条件操作符(C语言中的三目运算符):a ? b :c
5.位运算符:~ & | ^(异或)
举例:0+0=0 1+0=1 1+1=0
6.移位运算符:<< >>
注意:左移位宽增加,右移位宽不变。
7.拼接运算符:{a,b}
运算符的优先级:和C语言相同,可百度查看。
part two 程序框架
注释:
1.代码注释://、/* */
2.XDC文件注释 #
关键字:
input output ......
这里引用正点原子整理的文档(以下此类文档均引用正点原子):
框架:
Verilog的基本设计单元为---模块block(和C语言中的函数很相似)。
一个模块由两部分组成:
描述接口、描述逻辑功能
每个Verilog程序有四个主要部分:端口定义、IO说明、内部信号说明、功能定义。
举例:
module block(a,b,c,d);
input a,b;
output c,d;
assign c = a|b;
assign d = a&b;
endmodule
note:
module 为模块的开始 endmodule 为模块的结束
模块名字:block ---尽量写出此模块的意义
abcd默认为wire类型的变量
关键字:input output 输入输出信号为IO的说明
功能定义有三种方法:assigan 描述组合逻辑、always 描述组合和时序逻辑、例化实例元件。
结构语句:
赋值语句:
两种赋值方式:
1.阻塞赋值 :b=a 组合逻辑电路中always中使用
2.非阻塞赋值:b<= 时序逻辑电路always中使用
非阻塞赋值先计算出右边的数值,再统一赋值给左边,而且只能用于对寄存器类型的变量进行赋值,因此只能用在initial块和always块等过程块中,不允许在多个always块中对同一个变量进行赋值!
条件语句:
if else
if else if else if ...... else
Note:
1.条件语句必须在过程块中使用,过程块语句是指由initial和always语句引导的块语句。
2.if语句对表达式的值进行判断,若为0,x,z,则按假处理;若为1,按真处理。
case语句:
到此为止,基本语法知识介绍完毕!还剩verilog的灵魂---状态机,下面关于verilog代码的推文讲,下面看一个简单的小程序,理解一下上面的语法知识。
//定义输入输出端口
module led_twinkle(
input sys_clk ,
input sys_rst_n ,
output [1:0] led
);
reg [25:0] cnt; //定义一个26位计数器
assign led = (cnt < 26'd2500_0000) ? 2'b01 : 2'b10; //使用条件运算符的输出部分
//时序逻辑电路,实现计数器功能
always @(posedge sys_clk , negedge sys_rst_n)begin
if(!sys_rst_n)
cnt <= 26'd0;
else if(cnt < 5000_0000)
cnt <= cnt+1'b1;
else
cnt <= 26'd0;
end
endmodule
这是简单的对应硬件的led程序,如果想熟希verilog代码,找些demo练手可以私信我要源代码。在后面的推文中也可能会陆续发出。