赞
踩
本文主要内容是对verilog基础语法的学习总结,主要学习书籍《verilog经典教程》。
FPGA主要使用的编程语言有VHDL和verilog,都是用于逻辑设计的硬件描述语言,并且都已成为IEEE标准。VHDL是在1987年成为IEEE标准,verilog HDL则在1995年才正式成为IEEE标准。verilog是目前应用最广泛的一种硬件描述语言。
一、Verilog与C语言
相比VHDL,Verilog是一种非常容易掌握的硬件描述语言,在语法上类似C语言,只要有C语言的编程基础,上手会很容易,接下来就以C语言对比来一起学习下。
1、常用的 C 与 Verilog 相对应的关键字与控制结构
2、C 与 Verilog 相对应的运算符
二、基本语法
1、输入输出信号
input 模块的输入信号,比如 input Clk。
output 模块的输出信号,比如 output[3:0]Led。
inout 模块的输入输出双向信号。
2、信号类型
wire 线信号,一般用于assign语句。
reg 寄存器,一般用于always块中。
3、模块结构
每个模块的内容都是嵌在module和endmodule两个语句之间,一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,如下示例。
- module block (
- //输入接口
- input wire a,
- input wire b,
- //输出接口
- output wire c,
- output wire d
- );
-
- //逻辑功能
- assign c= a | b ;
- assign d= a & b;
-
- endmodule
4、数据类型及其常量、变量
(1)常用的数据类型有:reg型、wire型、integer型、parameter型.
(2)常量
verilog中常用进制:二进制(b或B)、十进制(d或D)、八进制(o或O)、十六进制(h或H)。
A、数字表达式:
<位宽><进制><数字> 如8'd100。
<进制><数字> 如'd100,数字的位宽采用缺省位宽。
<数字> 如 0,默认为十进制。
B、x和z值:x代表不定值,z代表高阻值。
C、负数:只需在位宽表达式前加一个减号,减号必须写在数字定义表达式的最前面,如-8'd5。
注意减号不可以放在位宽和进制之间也不可以放在进制和具体的数之间,如8'd-5。
D、下划线:可以用来分隔开数的表达以提高程序可读性。但不可以用在位宽和进制处,只能用在具体的数字之间,如8'b1011_1101。
(3)参数(Parameter)型
主要用于定义常量,常见格式如下:
parameter 参数名1=表达式,参数名2=表达式, …, 参数名n=表达式;
localparam 参数名1=表达式,参数名2=表达式, …, 参数名n=表达式;
(4)变量
wire型定义为:wire [n-1:0] 数据名1,数据名2,…数据名i;其中n表示位宽。
reg型定义为:reg [n-1:0] 数据名1,数据名2,… 数据名i;
memory型定义:reg [n-1:0] 存储器名[m-1:0];表示建立m个n位宽大小的reg参数。
(5)运算符及表达式
1) 算术运算符(+,-,×,/,%)
2) 赋值运算符(=,<=)
3) 关系运算符(>,<,>=,<=)
4) 逻辑运算符(&&,||,!)
5) 条件运算符(?:)
6) 位运算符(~,|,^,&,^~)
7) 移位运算符(<<,>>)
8) 拼接运算符({ })
9) 其它
优先级关系如下图:
6、赋值语句
(1)非阻塞赋值,如b <= a;
(2)阻塞赋值,如 b = a;
7、块语句
常用begin表示开始,end表示结束,如:
- begin
- areg = breg;
- creg = areg; //creg的值为breg的值。
- end
8、条件语句
(1)if_else语句,有优先级。
A、if(表达式)语句
if ( a > b ) out1 <= int1;
B、if(表达式) 语句1
else 语句2
if(a>b) out1<=int1;else out1<=int2;
C、if(表达式1) 语句1;
else if(表达式2) 语句2;
else if(表达式3) 语句3;
........
else if(表达式m) 语句m;
else 语句n;
if(a>b) out1<=int1;else if(a==b) out1<=int2;else out1<=int3;
(2)case语句
A、case(表达式) <case分支项> endcase
B、casez(表达式) <case分支项> endcase
C、casex(表达式) <case分支项> endcase
- case(rega)
- 16'd0: result = 10 'b0111111111;
- 16'd1: result = 10 'b1011111111;
- 16'd2: result = 10 'b1101111111;
- 16'd3: result = 10 'b1110111111;
- 16'd4: result = 10 'b1111011111;
- 16'd5: result = 10 'b1111101111;
- 16'd6: result = 10 'b1111110111;
- 16'd7: result = 10 'b1111111011;
- 16'd8: result = 10 'b1111111101;
- 16 'd9: result = 10 'b1111111110;
- default: result = 'bx;
- endcase
9、循环语句
(1)forever语句
forever begin 多条语句 end
(2)repeat语句
repeat(表达式) begin 多条语句 end
实现的乘法器例子:
- parameter size=8,longsize=16;
- reg [size:1] opa, opb;
- reg [longsize:1] result;
- begin: mult
- reg [longsize:1] shift_opa, shift_opb;
- shift_opa = opa;
- shift_opb = opb;
- result = 0;
- repeat(size)
- begin
- if(shift_opb[1])
- result = result + shift_opa;
- shift_opa = shift_opa <<1;
- shift_opb = shift_opb >>1;
- end
- end
(3)while语句
while(表达式) 语句
或:
while(表达式) begin 多条语句 end
- begin: count1s
- reg[7:0] tempreg;
- count=0;
- tempreg = rega;
- while(tempreg)
- begin
- if(tempreg[0]) count = count + 1;
- tempreg = tempreg>>1;
- end
- end
(4)for语句
for(表达式1;表达式2;表达式3) 语句
- begin: init_mem
- reg[7:0] tempi;
- for(tempi=0;tempi<memsize;tempi=tempi+1)
- memory[tempi]=0;
- end
10、结构说明语句
(1) initial说明语句
- initial
- begin
- areg=0; //初始化寄存器areg
- for(index=0;index<size;index=index+1)
- memory[index]=0; //初始化一个memory
- end
(2) always说明语句
- always @(posedge clock or posedge reset) //由两个沿触发的always块
- begin
- ……
- end
-
- always @( a or b or c ) //由多个电平触发的always块
- begin
- ……
- end
(3)task和function说明语句
task和function说明语句分别用来定义任务和函数。利用任务和函数可以把一个很大的程序模块分解成许多较小的任务和函数便于理解和调试。
任务和函数有些不同,主要的不同有以下四点:
1) 函数只能与主模块共用同一个仿真时间单位,而任务可以定义自己的仿真时间单位。
2) 函数不能启动任务,而任务能启动其它任务和函数。
3) 函数至少要有一个输入变量,而任务可以没有或有多个任何类型的变量。
4) 函数返回一个值,而任务则不返回值。
task语句:
- 任务定义:
- task my_task;
- input a, b;
- inout c;
- output d, e;
- …
- <语句> //执行任务工作相应的语句
- …
- c = foo1; //赋初始值
- d = foo2; //对任务的输出变量赋值t
- e = foo3;
- endtask
- 任务调用:
- my_task(v,w,x,y,z);
function语句:
定义函数的语法:
function <返回值的类型或范围> (函数名);
<端口说明语句>
<变量类型说明语句>
begin
<语句>
........
end
endfunction
- function [7:0] getbyte;
- input [15:0] address;
- begin
- <说明语句> //从地址字中提取低字节的程序
- getbyte = result_expression; //把结果赋予函数的返回字节
- end
- endfunction
11、系统函数和任务
(1)$display和$write任务
$display("格式",p1,p2,....pn);
$write("格式",p1,p2,....pn);
(2)系统任务$monitor
任务$monitor提供了监控和输出参数列表中的表达式或变量值的功能。
$monitor;
$monitoron;
$monitoroff;
示例:
$monitor($time,"rxd=%b txd=%b",rxd,txd);
$monitoron和$monitoroff任务的作用是通过打开和关闭监控标志来控制监控任务
(3)时间度量系统函数$time
$time和$realtime。用这两个时间系统函数可以得到当前的仿真时刻。
(4)系统任务$finish
系统任务的作用是结束仿真过程
$finish;和$finish(n);
(5)系统任务$readmemb和$readmemh
读取文件。
1) $readmemb("<数据文件名>",<存贮器名>);
2) $readmemb("<数据文件名>",<存贮器名>,<起始地址>);
3) $readmemb("<数据文件名>",<存贮器名>,<起始地址>,<结束地址>);
4) $readmemh("<数据文件名>",<存贮器名>);
5) $readmemh("<数据文件名>",<存贮器名>,<起始地址>);
6) $readmemh("<数据文件名>",<存贮器名>,<起始地址>,<结束地址>);
(6)系统任务 $random
这个系统函数提供了一个产生随机数的手段。
$ramdom % b ,其中 b>0.它给出了一个范围在(-b+1):(b-1)中的随机数。
12、编译预处理
(1)宏定义 `define
`define 标识符(宏名) 字符串(宏内容)
关于宏定义的八点说明:
(2)“文件包含”处理`include
`include “文件名”
(3)时间尺度 `timescale
`timescale 命令的格式如下:`timescale<时间单位>/<时间精度>
(4)条件编译命令`ifdef、`else、`endif
`ifdef 宏名 (标识符)
程序段1
`else
程序段2
`endif
—————————————————————————————
以上内容是verilog基础知识的总结,希望各位读者能有所收获,谢谢。
码字不易,如果大家觉得不错,请收藏点赞。
如果需要学习更多FPGA相关的知识,请大家关注《FPGA入门到精通》公众号
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。