大创_FPGA图像处理_Verilog HDL基本语法+简单的程序

大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第1张图片
大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第2张图片

1.1.简单的Verilog HDL模块

1.1.1.简单的Verilog HDL程序介绍

下面先介绍几个简单的Verilog HDL程序,然后从中分析Verilog HDL程序的特性。

//例1.1.1
module adder(count,sum,a,b,cin);
	input [2:0] a,b;
	input cin;
	output count;
	output [2:0] sum;
	assign {count,sum} = a + b + cin;
endmodule

这个例子通过连续赋值语句描述了一个名为adder的三位加法器可以根据两个三比特数a、b和进位(cin)计算出和(sum)和进位(count)。 从例子中可以看出整个Verilog HDL程序是嵌套在module和 endmodule 声明语句里的。

//例1.1.2
module compare (equal,a,b);
	output equal;
	input [1:0] a,b;
	assign equal = (a==b) ? 1 : 0;
endmodule

上面这个程序通过连续赋值语句描述了一个名为compare的比较器。对两比特数 a、b 进行比较,如a与b相等,则输出equal为高电平,否则为低电平。

//例1.1.3
module trist2(out,in,enable);
	output out;
	input in,enable;
	bufifl mybuf(out,in,enable);
endmodule

这个程序描述了一个名为trist2的三态驱动器。程序通过调用一个在Verilog语言库中现存的三态驱动器实例元件bufif1来实现其功能。

//例1.1.4
module trist1(out,in,enable);
	output out;
	input in,enable;
		mytri tri_inst(out,in,enable);//调用由mytri模块定义的实例元件tri_inst
endmodule

module mytri(out,in,enable);
	output out;
	input in.enable;
		assign out = enable ? in : 'bz;
endmodule

这个程序例子通过另一种方法描述了一个三态门。在这个例子中存在着两个模块。模块trist1调用由模块mytri定义的实例元件tri_inst。模块trist1是顶层模块。模块mytri则被称为子模块。

通过以上几个例子可以看出:
大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第3张图片

1.1.2.模块的结构

Verilog的基本设计单元是“模块”(block)。一个模块是由两部分组成的,一部分描述接口,另一部分描述逻辑功能,即定义输入是如何影响输出的。
例:

module block(a,b,c,d);
	input a,b;
	output c,d;
	
	assign c = a | b;
	assign d = a & b;
endmodule

Verilog结构完全嵌在module和endmodule声明语句之间,每个Verilog程序包括四个主要部分:端口定义、I/O说明、内部信号声明、功能定义。

1.1.3.模块的端口定义

module 模块名(1,口2,口3,口4,……);

1.1.4.模块的内容

模块的内容包括I/O说明、内部信号声明、功能定义

用Verilog模块实现一定的功能,首先应该清楚哪些是同时发生的,哪些是顺序发生的。
(两个或更多的“always”模块也是同时执行的,但是模块内部的语句是顺序执行的。)

1.2.数据类型

Verilog HDL中总共有19种数据类型,用来表示数字电路硬件中的数据储存和传送元素,首先了解reg、wire、integer、parameter四种。
其他类型还有:large型、medium型、scalared型、time型、small型、tri型、trio型、tri1型、triand型、trior型、trireg型、vectored型、wand型、wor型。

1.2.1.常量

数字
大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第4张图片
大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第5张图片
负数
大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第6张图片
在这里插入图片描述
参数(parameter)
在Verilog HDL种使用parameter来定义一个标识符代表一个常量

parameter 参数名1=表达式,参数名2=表达式,……;

例:

parameter a = 5;
parameter b = 6,c = 7;
parameter d = 8.9;
parameter e = (a - b)/c;

参数型常数经常用于定义延迟时间和变量宽度。在模块或实例引用时可通过参数传递改变在被引用模块或实例中已定义的参数。

1.2.2.变量

wire型

wire型信号可以用作任何方程式的输入,也可以用作assign语句或实例元件的输出,格式与reg型信号类似。

wire [n-1:0] 数据名1,数据名2,……数据名i;//共i条总线,每条总线内有n条线路

或者

wire [n:1] 数据名1,数据名2,……数据名i;

reg型

寄存器是数据储存单元的抽象,在“always”块内被赋值的每一个信号都必须定义成reg型

格式:

reg [n-1:0] 数据名1,数据名2,……数据名i;

或者

reg [n:1] 数据名1,数据名2,……数据名i;

reg型数据的缺省初始值是不定值。reg型数据可以赋正值,也可以赋负值。但当一个reg型数据是一个表达式中的操作数时,它的值被当作是无符号值,即正值。

注意:reg型只表示被定义的信号将用在“always”块内,理解这一点很重要。并不是说reg型信号一定是寄存器或触发器的输出。虽然reg型信号常常是寄存器或触发器的输出,但并不一定总是这样。

memory型

在Verilog语言中没有多维数组存在,memory型数据是通过扩展reg型数据的地址范围来生成的。

格式:

reg [n-1:0] 存储器名[m-1:0];
reg [n-1:0] 存储器名[m:1];

例:

reg [7:0] mema[255:0];

定义了一个名为mema的存储器,有256个8位的存储器。该存储器的地址范围是0到255.注意:对存储器进行地址索引的表达式必须是常数表达式。

注意区别memory型、reg型数据,如一个由n个1位寄存器构成的存储器是不同于一个n位寄存器的。

reg [n-1:0] rega;	//一个n位的寄存器
reg mema [n-1:0];	//一个由n个1位寄存器构成的存储器组

一个n位寄存器可以在一条赋值语句下进行赋值,而一个完整的存储器则不行。
例:

rega = 0//合法
mema = 0;	//非法

正确的写法是:

mema[3] = 0;	//地址索址可以是表达式

1.3.运算符及表达式

大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第7张图片
根据所带操作数个数可分为以下三种:

在这里插入图片描述

1.3.1.基本的算术运算符

大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第8张图片
在进行整数除法运算时,结果值要略去小数部分,只取整数部分。而进行取模运算时,结果值的符号位采用模运算式里第一个操作数的符号位。
在进行算术运算操作时,如果某一个操作数有不确定的值x,则整个结果也为不定值x。

1.3.2.位运算符

在这里插入图片描述

1.3.3.逻辑运算符

&& 逻辑与
|| 逻辑或
! 逻辑非	//优先级高于算数运算符

1.3.4.关系运算符

<	>	<=	>=

1.3.5.等式运算符

===		=====
//后两个对操作数进行比较时对某些位的不定值x和高阻值z也进行比较,两个操作数必须完全一致,结果才是1

1.3.6.移位运算符

左移位:<<		右移位:>>

例:

module shift;
	reg [3:0] start,result;
	initial
	begin
		start = 1;//初始值设置为0001
		result = (start << 2);//移位后,result的值为0100,移过两位后,用0来补
	end
endmodule

1.3.7.位拼接运算符

{}

这个符号可以将两个或多个信号的某些位拼接起来

用法:{信号1的某几位,信号2的某几位,……,信号n的某几位}

在位拼接表达式中不允许存在没有指明位数的信号,因为计算时必须知道每个信号的位宽。

其他用法:

{4{w}}		//使用重复法来简化表达式,等同于{w,w,w,w}
{b,{3{a,b}}}	//嵌套,等同于{b,a,b,a,b,a,b}
//需要注意的是表示倍数的必须是常数表达式

1.3.8.缩减运算符

reg [3:0] B;
reg C;
	C = &B;
	//相当于:
	C = ( (B[0] & B[1]) & B[2] ) & B[3];

1.3.9.优先级别

大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第9张图片

1.3.10.关键词

always, and, assign,begin,buf,bufif0,bufif1,case,casex,casez,cmos,deassign,
default,defparam,disable,edge,else,end,endcase,endmodule,endfunction,endprimitive, 
endspecify, endtable, endtask, event, for, force, forever, fork, function,highz0,
highz1, if,initial, inout, input,integer,join,large,macromodule,medium,module,
nand,negedge,nmos,nor,not,notif0,notifl, or, output, parameter, pmos, posedge, 
primitive, pull0, pull1, pullup, pulldown, rcmos, reg, releses, repeat, mmos, rpmos, 
rtran, rtranif0,rtranif1,scalared,small,specify,specparam,strength,strong0, strong1, 
supply0, supply1, table, task, time, tran, tranif0, tranif1, tri, tri0, tri1, triand, 
trior, trireg,vectored,wait,wand,weak0,weak1,while, wire,wor, xnor, xor

1.4.赋值语句和块语句

1.4.1.赋值语句

阻塞赋值与非阻塞赋值

1.4.2.块语句

1、顺序块

顺序块特点:

  1. 块内语句按顺序执行
  2. 每条语句的延迟时间是相对于前一条语句的仿真时间而言的
  3. 直到最后一条语句执行完,程序流程控制才跳出该语句块

2、并行块

并行块特点:

  1. 块内语句同时执行
  2. 块内每条语句的延迟时间是相对于程序流程控制进入到块内时的仿真时间的
  3. 延迟时间是用来给赋值语句提供时序的

3、块名

只需将名字加在关键词begin或fork后面即可

4、起始时间和结束时间

1.5.条件语句

1.5.1.if_else

1.5.2.case语句

1.6.循环语句

1.6.1.forever语句

1.6.2.repeat语句

1.6.3.while语句

1.6.4.for语句

1.7.结构说明语句

initial和always说明语句在仿真的一开始即开始执行。initial语句只执行一次。相反,always语句则是不断地重复执行,直到仿真过程结束。在一个模块中,使用initial和always语句的次数是不受限制的。task和function语句可以在程序模块中的一处或多处调用。

1.7.1.initial语句

initial
	begin
		……
		……
		……
	end

1.7.2.always语句

声明格式:

always <时序控制> <语句>

1.7.3.task和function语句

任务和函数的不同点:

  • 函数只能与主模块共用一个仿真时间单位,而任务可以定义自己的仿真时间单位
  • 函数不能启动任务,而任务能启动其他的任务和函数
  • 函数至少要有一个输入变量,而任务可以没有或有多个任何类型的变量
  • 函数返回一个值,而任务则不返回值

1.8.系统函数和任务

每个系统函数和任务前面都用一个标识符$来加以确认,它们提供了非常强大的功能。

$bitstoreal, $rtoi, $display, $setup, $finish, $skew, $hold,
$setuphold, $itor, $strobe, $period, $time, $printtimescale,
$timefoemat, $realtime, $width, $real tobits, $write, $recovery

1.8.1.$display和 $write任务

格式:

$display(p1,p2,……pn);
$write(p1,p2,……pn);

大创_FPGA图像处理_Verilog HDL基本语法+简单的程序_第10张图片

1.8.2.系统任务$monitor

格式:

$monitor(p1,p2,……pn);
$monitor;
$monitoron;
$monitoroff;

1.8.3.时间度量系统函数$time

$time可以返回一个64比特的整数来表示当前仿真时刻值

`timescale 10ns/1ns
module test;
	reg set;
	parameter p=1.6;
	initial
		begin
			$monitor($time,"set=",set);
			#p set=0;
			#p set=1;
		end
endmodule

1.8.4.系统任务 $finish

1.8.5.系统任务 $stop

$stop的任务是将仿真器置成暂停模式,在仿真环境下给出一个交互式的命令提示符,将控制权交给用户。

1.8.6.系统任务 $readmemb 和 $readmemh

用来从文件中读取数据到储存器中,可以在仿真的任何时刻执行使用。、

1.8.7.系统任务 $random

1.9.编译预处理

`accelerate,`autoexpand_vectornets,`celldefine,`default_nettype,`define,`else,
`endcelldefine,`endif,`endprotect,`endprotected,`expand_vectornets,`ifdef,`include,
`noaccelerate,`noexpand_vectornets , `noremove_gatenames , `noremove_netnames ,
`nounconnected_drive , `protect , `protecte , `remove_gatenames , `remove_netnames ,
`reset,`timescale,`unconnected_drive

你可能感兴趣的:(FPGA,现代信号处理电路设计,fpga开发,verilog)