FPGA快速入门— Verilog快速入门

Verilog HDL(Hardware Description Language)是在用途最广泛的C语言的基础上发展起来的一种硬件描述语言,具有灵活性高、易学易用等特点。 Verilog HDL可以在较短的时间内学习和掌握,目前已经在FPGA开发/IC设计领域占据绝对的领导地位。

简单的编程案例

为快速入门Verilog语言,先从简单的编程案例开始。以LED流水灯程序为例来给大家展示Verilog的程序框架,代码如下所示。

module led(
input sys_clk , //系统时钟
input sys_rst_n, //系统复位,低电平有效
output reg [3:0] led //4位LED灯
);

//parameter define
parameter WIDTH = 25 ;
parameter COUNT_MAX = 25_000_000; //板载50M时钟=20ns,0.5s/20ns=25000000,需要25bit
//位宽
//reg define
reg [WIDTH-1:0] counter ;
reg [1:0] led_ctrl_cnt;
//wire define
wire counter_en ;
//***********************************************************************************
//** main code
//***********************************************************************************
//计数到最大值时产生高电平使能信号
assign counter_en = (counter == (COUNT_MAX - 1'b1)) ? 1'b1 : 1'b0; 
//用于产生0.5秒使能信号的计数器
always @(posedge sys_clk) 
begin
if (sys_rst_n == 1'b0)
counter <= 1'b0;
else if (counter_en)
counter <= 1'b0;
else
counter <= counter + 1'b1;
end
//led流水控制计数器
always @(posedge sys_clk) 
begin
if (sys_rst_n == 1'b0)
led_ctrl_cnt <= 2'b0;
else if (counter_en)
led_ctrl_cnt <= led_ctrl_cnt + 2'b1;
end
//通过控制IO口的高低电平实现发光二极管的亮灭
always @(posedge sys_clk) 
begin
if (sys_rst_n == 1'b0)
led <= 4'b0;
else begin
case (led_ctrl_cnt) 
2'd0 : led <= 4'b0001;
2'd1 : led <= 4'b0010;
2'd2 : led <= 4'b0100;
2'd3 : led <= 4'b1000;
default : led <= 4'b1111;
endcase
end
end
endmodule 

需要注意的几个点:

  • 注释:两种方式,一种是以“/*”符号开始,“*/”结束,在两个符号之间的语句都是注释语句,因此可扩展到多行。另一种是以//开头的语句,它表示以//开始到本行结束都属于注释语句。
  • 模块定义:以module开始,endmodule结束;
  • 端口定义:input  output
  • 数据类型的定义:reg 、wire、parameter
  • assign语句:条件成立选择1,否则选择0
  • always语句:语句中的posedge代表在时钟上升沿进行信号触发。begin/end代表语句的开始和结束。
  • If-else语句:和C语言是比较类似的。
  • Case语句:需要一个case关键字开始,endcase关键字结束,default作为默认分支,和C语言也是类似的。
  • 问号语句:与if-else类似。

 

Verilog的常用语法

Verilog的数字进制格式 

Verilog数字进制格式包括二进制、八进制、十进制和十六进制,一般常用的为二进制、十进制和十六进制。

二进制表示如下:4’b0101表示4位二进制数字0101;

十进制表示如下:4’d2表示4位十进制数字2(二进制0010);

十六进制表示如下:4’ha表示4位十六进制数字a(二进制1010),十六进制的计数方式为0,1,2,…,9,a,b,c,d,e,f,最大计数为f(f:十进制表示为15)。

当代码中没有指定数字的位宽与进制时,默认为32位的十进制,比如100,实际上表示的值为32’d100

 

Verilog的数据类型 

在Verilog语法中,主要有三大类数据类型,即寄存器类型、线网类型和参数类型。从名称中,我们可以看出,真正在数字电路中起作用的数据类型应该是寄存器类型和线网类型。

寄存器类型

寄存器类型表示一个抽象的数据存储单元,它只能在always语句和initial语句中被赋值,并且它的值从一个赋值到另一个赋值过程中被保存下来。如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应为寄存器;如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变量对应为硬件连线;

寄存器类型的缺省值是x(未知状态)。

寄存器数据类型有很多种,如reg、integer、real等,其中最常用的就是reg类型,它的使用方法如下:

            //reg define

            reg [31:0] delay_cnt;   //延时计数器

            reg key_flag ;         //按键标志

线网类型

线网表示Verilog结构化元件间的物理连线。它的值由驱动元件的值决定,例如连续赋值或门的输出。如果没有驱动元件连接到线网,线网的缺省值为z(高阻态)。线网类型同寄存器类型一样也是有很多种,如tri和wire等,其中最常用的就是wire类型,它的使用方法如下:

        //wire define

        wire data_en;       //数据使能信号

        wire [7:0] data ;   //数据

 

参数类型

参数类型其实就是一个常量,常被用于定义状态机的状态、数据位宽和延迟大小等,由于它可以在编译时修改参数的值,因此它又常被用于一些参数可调的模块中,使用户在实例化模块时,可以根据需要配置参数。在定义参数时,我们可以一次定义多个参数,参数与参数之间需要用逗号隔开。这里我们需要注意的是参数的定义是局部的,只在当前模块中有效。它的使用方法如下:

            //parameter define

            parameter DATA_WIDTH = 8; //数据位宽为8位

 

Verilog的运算符

大家看完了Verilog的数据类型,我们再来介绍下Verilog的运算符。Verilog中的运算符按照功能可以分为下述类型:1、算术运算符、 2、关系运算符、3、逻辑运算符、 4、条件运算符、 5、位运算符、 6、移位运算符、 7、拼接运算符。下面我们分别对这些运算符进行介绍。

算术运算符

算术运算符,简单来说,就是数学运算里面的加减乘除,数字逻辑处理有时候也需要进行数字运算,所以需要算术运算符。常用的算术运算符主要包括加减乘除和模除(模除运算也叫取余运算)如表 所示:

符号

使用方法

说明

+

a + b

a 加上 b

-

  • 12
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值