赞
踩
verilog的基本设计单元是“模块”(block)。一个模块由两部分组成:接口和逻辑功能,即定义输入是如何影响输出的。
verilog模块的结构位于module和endmodule之间,每个verilog程序包含4个主要部分:端口定义、I/O说明、内部信号声明和功能定义。
举例:
module block(a,b,c,d); //端口定义以及I/O说明
/*内部信号声明*/
input a,b;
output c,d;
/*功能定义(逻辑功能)*/
assign c = a|b;
assign d = a&b;
endmodule;
模块的端口声明了模块的输入输出口,格式为:
module 模块名(inport1,inport2,…,outport3,ouoput4,…);
模块的端口表示的是模块的输入和输出口名,即它与其他模块联系端口的标识。
在模块被引用时,在引用的模块中,有些信号要输入到被引用的模块中,有的信号需要从被引用的模块中取出来。在引用模块时其端口可以用以下两种方法连接:
I/O说明的格式为:
模块内部信号类型一般为wire和reg类型。
格式为:
reg [width-1] R1,R2,…;
wire [width-1] W1,W2,…;
例如:
reg [7:0] led;
reg [19:0] cnt;
wire [1:0] out;
模块中产生逻辑的方法有以下三种:
always @(posedge clk or negedge clr);
begin
if(clr) q <= 0;
else if(en) q <= d;
end
对于过程块(如initial块、always块)、连续赋值语句和实例引用三者而言:
(1)在verilog模块内部三者是并行的;
(2)三者是一种通过变量名互相连接的关系;
(3)在同一模块中,三者出现的先后顺序没有关系;
(4)只有连续赋值语句assign和实例引用语句可以独立于过程块而存在于模块的功能定义部分。
(1)整数
(2)x和z值
在数字电路中,x表示不定值,一个x可用来定义十六进制的4位二进制状态,八进制的3位,二进制的1位。
z表示高阻值,z的另外一种表示方式为“?”,其定义与x类似。
如:
4’b100x //位宽为4的二进制数,其中第0位为不定值
4’b111z //位宽为4的二进制数,其中第0为为高阻值
12’dz //位宽为12为的十进制数,其值为高阻值
8’h1? //为宽为8的十六进制数,其低四位值为高阻值
(3)负数
数字可以被定义为负数,表达方式为在位宽表达式前加“-”(减号),“-”位置固定,不能随意放置。
如:
-8’d10 //表示10的补码
(4)下划线_
“_”可用来分割数字的表达以提高程序可读性,用于数字之间(也可以不用直接用一串数字)
如:
16’b0110_1010_1110_0011 等同于 16’b0110101011100011
tips:
当常量不指明位数时,默认值为32位,每个字母用8位的ASCII值表示。
如:
10等同于32’d10等同于32’b1010
1等同于32’d1
-1等同于-32’d1等同于32’hFFFFFFFF
"AB"等同于16’B01000001_01000010//A的ASCII码值为65,B的ASCII码值为66
parameter用来定义一个标志符来代表一个常量,称为符号常量,即标识符形式的常量,来提高程序的可读性和可维护性。
参数型常量经常用于定义延迟时间和变量宽度。在模块或实例引用时,可通过参数传递改变在被引用模块或实例中已定义的参数。
格式如下:
parameter 参数名1=表达式,参数名2=表达式,…
如:
parameter len = 4;
parameter r = 6;
parameter msb = 7;
parameter byte_size = 8,byte_msb = byte_size-1;
paremeter average_delay = (len+r)/2;
verilog程序中,输入、输出信号类型默认时自动定义为wire型。wire型信号可以用作任何方程式的输入,也可以用作assign语句或实例元件的输出。
wire型信号格式与reg型信号格式类似,格式如下:
wire [n-1:0] data1,data2,…;//数据位宽为n
或者
wire [n:1] data1,data2,…;//数据位宽为n
如:
wire a;//定义了一个1位的wire型数据
wire [7:0] b;//定义了一个8位的wire型数据
wire [4:1] c,d;//定义了二个4位的wire型数据,多个变量中间用","隔开
reg是寄存器数据类型的关键字,通过赋值语句可以改变寄存器储存的值,其作用与改变触发器储存的值相当。
reg型数据的格式为:
reg [n-1:0] data1,data2,…;//数据位宽为n
或者
reg [n:1] data1,data2,…;//数据位宽为n
如:
reg rega; //定义一个1位reg型数据
reg [3:0] regb; //定义一个4位reg型数据
reg [4:1] regc,regd; //定义两个4位reg型数据
Verilog HDL通过对reg型变量建立数组来对存储器建模,可以描述RAM型寄存器、ROM型寄存器和reg文件。数组中的每一个单元通过一个数组索引进行寻址。在verilog语言中没有多维数组存在。memory型数据是通过扩展reg型数据的地址范围来生成的。
格式如下:
reg [n-1:0] memoryname[m-1:0]
或者
reg [n-1:0] memoryname[m:1]
其中,reg[n-1:0]定义了存储器中每一个存储单元的大小,即每个存储单元都是一个n位的寄存器,而[m:1]则定义了存储单元的数量。
如:
reg [7:0] mem1[255:0]; //定义了一个mem1存储器,其有256个8位的存储器,存储器的地址范围是0到255
always @(posedge clk)
begin
b <= a;
c <= b;
end
代码实现功能为:在clk上升沿到来时,b等于a,c等于b,用到了两个触发器(注:赋值操作是在always块结束后执行的,c应为原来的b值。)。所实现的电路功能如下:
(2)用阻塞赋值法确定reg型信号b和c
always @(posedge clk)
begin
b = a;
c = b;
end
代码实现功能为:在clk上升沿到来时,b马上取a的值,c马上取b的值,所实现的电路功能如下:
格式为:
begin
statement1;
statement2;
…
end
或者
begin:块名
块内声明语句;
statement1;
statement2;
…
end
其中,块名,为该块的名字,是一个标识名。
对于顺序快,起始时间为第一条语句开始被执行的事件,结束时间为最后一条语句执行完的时间。
如( 1):
begin
areg=breg;
#10 creg=areg;//两条赋值语句之间延迟10个时间单位
end
(2):
parameter d=50;//声明的是一个参数
reg[7:0] r;//声明r是一个8位寄存器变量
begin//由一系列延迟产生波形
#d r='h23;
#d r='hab;
#d r='h1f;
#d r='hd3;
#d ->end_wave;//->表示触发事件end_wave使其翻转
end
并行块的特点:
(1)块内语句同时进行;
(2)块内每条语句的延迟时间是相对于程序流程控制进入到块内的仿真时间而言的;
(3)延迟时间用来给赋值语句提供执行时序;
(4)当按时间顺序执行完最后的雨具,或一个disable语句执行时,程序流程控制跳出该程序块。
并行块格式如下:
fork
statement1;
statement2;
…
join
或者
fork:块名
块内声明语句;
statement1;
statement2;
…
join
如:
fork
#50 r='h23;
#100 r='hab;
#150 r='h1f;
#200 r='hd3;
#250 ->end_wave;//->表示触发事件end_wave使其翻转
join
此例子与顺序块中的例子(2),生成的波形是一样的。
对于并行块,起始时间对于块内所有的语句是相同的,程序流程控制进入该块的事件即为起始时间,结束时间为时间排序在最后的语句执行结束的时间。
如(3):
fork
#250 ->end_wave;//->表示触发事件end_wave使其翻转
#200 r='hd3;
#150 r='h1f;
#100 r='hab;
#50 r='h23;
join
此并行块生成的波形与并行块(2)生成的波形是一样的。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。