Verilog学习一


由于马上要开始读研了,故需要重温Verilog知识~


一、Verilog语法基本概念

  1. Verilog HDL是一种用于数字系统设计的语言。用Verilog HDL描述电路设计就是该电路的Verilog HDL模型,也可称之为模块
  2. Verilog可以对应五种模型类型,分别是:系统级、算法级、RTL级、门级、开关级电路。
  3. Verilog较VHDL语言更加宽容,但在高要求场合也会采用VHDL语言。
  4. 夏宇闻先生书中在这一部分介绍了多种Verilog HDL语言模块代码。值得注意一下几句:
	assign equal = (a==b)? 1:0; 
	/*表示如果a、b相等,输出为1,否则为0*/
	bufif1 mybuf(out,in,enable);
	/*bufif1是一种三态驱动器,*/
	and #1 u2(sela,a,nsl)
	/*#1 表示延时1个单位时间*/
  1. Verilog语言的语法与C语言类似,但其逻辑思想却截然不同。
  2. Verilog也可用来描述变化的测试信号,实现此功能的模块叫做testbench。
`include "muxtwo.v"
   	module t;
   	reg	ain,bin,select;
   	reg	clock;
   	wire outw;
   initial
   begin
   	ain = 0;
   	bin = 0;
   	select = 0;
   	clock = 0;
   end
   	always #50 clock = ~clock; // T = 100;
   	always @(posedge clock)
   		begin
   			#1 ain = {$random}%2;
   			#3 bin = {$rabdom}%2;
   		end
   		always #10000	select=!select //选通信号周期为10000
   		//……
   		muxtwo m(.out(outw),.a(ain), .bin(bin), .sl(select));
   endmodule

二、模块的结构、数据类型、变量和基本运算符号

1.模块的结构

Verilog的基本设计的单元是block模块。一个模块由两部分构成,一部分描述端口,另一部分描述逻辑功能。

module block(a,b,c,d);
input a,b;
output c,d;

assign c = a|b;
assign d = a&b;
endmodule

上面代码即实现了端口和逻辑功能的描述。
在引用端口时,有两种方法:
1.严格按照模块定义的端口顺序来连接,此时不用注明定义时的端口名;
2.在引用时用“.”符号,标明原模块时定义时规定的端口名。这样做可以不按照顺序,提高了可移植性和可读性。

模块内容 包括 I/O说明,内部信号声明和功能定义。

  1. I/O说明格式如下:
输入口: 	input[信号位宽-1:0]端口名1...
			input[信号位宽-1:0]端口名i;//i个输入口
输出口: 	output[信号位宽-1:0]端口名1...
			output[信号位宽-1:0]端口名j;//j个输出口
输入/输出口	inout[信号位宽-1:0]端口名1...
			inout[信号位宽-1:0]端口名k;//k个双相总线端口

当然I/O说明也可写在端口声明语句中。

  1. 内部信号说明 正常定义即可。
    例如:reg[width-1 : 0] R1,R2…;

  2. 功能定义:assign、实例元件、always块

  3. 这里要着重理解哪些功能是同时发生的,哪些是顺序发生的。 always语句内通常是顺序发生的。

  4. 只有连续赋值语句assign和实例引用语句可以独立于过程块而存在于模块的功能定义部分。

2.数据类型及其常量和变量。

四种最基本的数据类型:reg、wire、interger、parameter。
数字
1.整数<位宽><进制><数字> 不说明位宽时,依据机器默认决定。
2.x和z值 x表示不定值,用“x”表示。z值表示高阻值,用“?”表示。一个x可以表示对应进制的一位,?同理。
3.负数 负数的“-”号要放在位宽之前。
4.小数 定点和浮点两种,这个有点复杂。
参数
parameter可以用来定义常量,即用parameter来定义一个标识符以代表一个常量,称之为符号常量。

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

parameter通常用来定义延迟时间和变量宽度
在层次调用时,可以通过参数传递改变在被引用模块或者实例中已经定义的参数。例如:

module Decode(A,F);
	parameter	width = 1, polarity = 1;
	...
endmodule
module Top;
	wire[3:0] A4;
	wire[4:0] A5;
	wire[15:0] F16;
	wire[31:0] F32;
	Decode #(4,0)	D1(A4,F16); //引用width=4 polarity=0
	Decode #(5)		D2(A5,F32);//width = 5, polarity=1(unchanged);
endmodule

而在一个模块中改变另一个模块的参数时,需要用defparam命令
变量 包括:网络数据类型(wire/tri)、寄存器数据类型(reg)、存储器(mem)等。
1.wire表示单个门或者连续赋值语句驱动的网络型数据、tri表示多驱动器驱动的网络型数据。无驱动器连接时,默认为z高阻态;若未定义逻辑强度,则在多驱动情况下容易产生不确定值。
2.reg类型指寄存器类型,默认初始值为x(不定值),通常用来表示always模块内的指定信号,常代表触发器。 这里特别注意,当reg型数据是操作数时,默认是无符号值,比如开始寄存器被赋值为-1,则运算时认其为15。
3.mem类型 reg[n-1:0] 存储器名[m-1:0];

3.运算符及表达式

运算符 算术运算符+ , - , × , / , %
赋值运算符 =(阻塞) , <=(非阻塞)
关系运算符 > , < , >= , <=
逻辑运算符 && , || !
条件运算符 ? :
位运算符 ~ , | , ^(异或), & , ^~ (长度不同的数据进行位运算时,系统会自动将其按右端对齐,位数少的操作数会在相应高位用0填满。)
移位运算符 <<,>>
拼接运算符 { }

三、小结

1.verilog所有过程快、连续赋值语句、实例引用都是并行的。
2.只有连续赋值(assign)语句和实例引用语句可以独立于工程块而存在于模块的功能定义部分。
3.“always”模块内被赋值的每一个信号都必须定义为reg型。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值