当前位置:首页 > 新闻资讯 > FPGA之家动态 >

FPGA 入门到精通系列2:verilog基础1-基础语法

时间:2024-07-29      来源:网络搜集 关于我们 0

    本文主要内容是对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;endmodule4、数据类型及其常量、变量(1)常用的数据类型有:reg型、wire型、integer型、parameter型.(2)常量

verilog中常用进制:二进制(b或B)、十进制(d或D)、八进制(o或O)、十六进制(h或H)。

A、数字表达式:

    <位宽><进制><数字> 如8d100。

       <进制><数字> 如d100,数字的位宽采用缺省位宽。        <数字> 如 0,默认为十进制。

B、x和z值:x代表不定值,z代表高阻值。

C、负数:只需在位宽表达式前加一个减号,减号必须写在数字定义表达式的最前面,如-8d5。

     注意减号不可以放在位宽和进制之间也不可以放在进制和具体的数之间,如8d-5。

D、下划线:可以用来分隔开数的表达以提高程序可读性。但不可以用在位宽和进制处,只能用在具体的数字之间,如8b1011_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的值。end8、条件语句(1)if_else语句,有优先级。A、if(表达式)语句if ( a > b ) out1 <= int1;B、if(表达式) 语句1    else 语句2if(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分支项> endcaseB、casez(表达式) <case分支项> endcaseC、casex(表达式) <case分支项> endcasecase(rega)16d0: result = 10 b0111111111;16d1: result = 10 b1011111111;16d2: result = 10 b1101111111;16d3: result = 10 b1110111111;16d4: result = 10 b1111011111;16d5: result = 10 b1111101111;16d6: result = 10 b1111110111;16d7: result = 10 b1111111011;16d8: result = 10 b1111111101;16 d9: result = 10 b1111111110;default:result = bx;endcase9、循环语句(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; endend(3)while语句   while(表达式) 语句  或:   while(表达式) begin 多条语句 endbegin: count1s reg[7:0] tempreg; count=0; tempreg = rega; while(tempreg) begin if(tempreg[0]) count = count + 1; tempreg = tempreg>>1; endend(4)for语句for(表达式1;表达式2;表达式3) 语句begin: init_mem reg[7:0] tempi; for(tempi=0;tempi<memsize;tempi=tempi+1) memory[tempi]=0;end10、结构说明语句(1) initial说明语句initialbegin areg=0; //初始化寄存器areg for(index=0;index<size;index=index+1) memory[index]=0; //初始化一个memoryend(2) always说明语句always @(posedge clock or posedge reset) //由两个沿触发的alwaysbegin……endalways @( a or b or c ) //由多个电平触发的alwaysbegin……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      endfunctionfunction [7:0] getbyte;input [15:0] address;begin <说明语句> //从地址字中提取低字节的程序 getbyte = result_expression; //把结果赋予函数的返回字节endendfunction11、系统函数和任务(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 标识符(宏名) 字符串(宏内容)  关于宏定义的八点说明:

宏名可以用大写字母表示,也可以用小写字母表示。建议使用大写字母,以与变量名相区别。

`define命令可以出现在模块定义里面,也可以出现在模块定义外面。

在引用已定义的宏名时,必须在宏名的前面加上符号“`”,表示该名字是一个经过宏定义的名字。

宏定义不是Verilog HDL语句,不必在行末加分号。

(2)“文件包含”处理`include  `include “文件名”(3)时间尺度 `timescale  `timescale 命令的格式如下:`timescale<时间单位>/<时间精度>(4)条件编译命令`ifdef、`else、`endif `ifdef 宏名 (标识符)    程序段1 `else    程序段2 `endif

—————————————————————————————

以上内容是verilog基础知识的总结,希望各位读者能有所收获,谢谢。

码字不易,如果大家觉得不错,请收藏点赞。

如果需要学习更多FPGA相关的知识,请大家关注《FPGA入门到精通》

公众号


注明:本内容来源网络,不用于商业使用,禁止转载,如有侵权,请来信到邮箱:429562386ⓐqq.com 或联系本站客服处理,感谢配合!

用户登陆

    未注册用户登录后会自动为您创建账号

提交留言