Verilog HDL 自学笔记

这篇博客详细介绍了Verilog HDL中的数据类型,包括寄存器类型(register)、线网类型(wire)和参数类型(常量)。寄存器类型用于存储数据,线网类型表示元件间的物理连线,参数类型常用于定义常量。此外,还讨论了Verilog中的常量、数字表示方式和参数(Parameter)型。在运算符及表达式部分,涉及了算术、赋值、逻辑和位运算符。文章还深入讲解了阻塞赋值和非阻塞赋值的差异,以及顺序块和并行块的执行机制。

数据类型

寄存器类型(register)

寄存器表示一个抽象的数据存储单元,通过赋值语句可以改变寄存器存储的值

寄存器数据类型的关键字是reg,reg类型数据的默认初始值为不定值x

reg [31:0] delay_cnt;
reg        key_cnt;

reg类型的数据只能在always语句和initial语句中被赋值。

如果该过程语句描述的是时序逻辑,即always语句带有时钟信号,则该寄存器变量对应为触发器

如果该过程语句描述的是组合逻辑,即always语句不带有时钟信号,则该寄存器变量对应为硬件连线

线网类型(wire)

线网数据类型表示结构实体(例如门与门,模块与模块)之间的物理连线。

线网类型的变量不能储存值,它的值是有驱动它的元件所决定的

驱动线网类型变量的元件有门、连续赋值语句、assign等

如果没有驱动元件连接到线网类型的变量上,则该变量就是高阻的,其值为z。

线网数据类型包括wire型和tri型,其中最常用的是wire类型

wire   key_flag;

参数类型(常量)

参数其实就是一个常量,在Verilog HDL 中用parameter定义常量。

我们可以一次定义多个参数,参数与参数之间需要用逗号隔开。

每个参数定义的右边必须是一个常数表达式

 parameter H_SYNC = 11'd41;  //行同步
 parameter H_BACK = 11'd2;   //行显示后沿
 parameter H_DISP = 11'd480; //行有效数据

参数型数据常用于定义状态机的状态、数据位宽和延迟大小等。

采用标识符来代表一个常量可以提高程序的可读性和可维护性。

在模块调用时,可以同参数传递来改变被调用模块中已定义的参数。

常量

程序运行过程中,其值不能被改变的量成为常量。

数字

整数

  • 二进制整数(b)
  • 十进制整数(d)
  • 八进制整数(o)
  • 十六进制整数(h)

表达方式:

  • <位宽><进制><数字>
    1’b0; 4’d

参数(Parameter)型

运算符及表达式

  • 算术运算符(+,-,×,/,%)
  • 赋值运算符(=,<=)
  • 关系运算符(>,<,>=,<=,!=)
  • 逻辑运算符(&&与,||或,!非)
  • 条件运算符(?😃
  • 位运算符(,|,^,&,^) 按位分别运算
  • 移位运算符(<<,>>)
  • 拼接运算符({ })
  • 其它

单目运算符(unary operator):可以带一个操作数,操作数放在运算符的右边。

二目运算符(binary operator):可以带二个操作数,操作数放在运算符的两边。

三目运算符(ternary operator):可以带三个操作,这三个操作数用三目运算符分隔开。

赋值语句和语句块

阻塞赋值(Blocking)

在同一个always块中,一条阻塞赋值语句如果没有执行完,那么该语句后面的语句就不能继续执行,即被“阻塞”。

也就是说always块内的语句执行一种顺序关系,在begin和end之间的语句是顺序执行,属于串行语句

always@(posedge clk)
	begin 
	  b=a;
	  c=b;
	end

在时钟上升沿来的时候,a的值赋给b,执行完成后,b的值再赋给c,整个代码执行完时,a=c,整个过程在同一个时钟上升沿完成

  1. 赋值语句执行完后,块才结束。
  2. b的值在赋值语句执行完后立刻就改变的
  3. 可能会产生意想不到的结果。

非阻塞赋值(Non_Blocking)

非阻塞赋值是由时钟节拍决定,在时钟上升到来时,执行一次赋值语句右边的表达式,当所有赋值语句右边表达式执行完成时,将begin-end之间的所有赋值语句同时赋值到赋值符号的左边,属于并行执行语句。

always @(posedge clk )
	begin
	  b<=a;
	  c<=b;
	end
  1. 块结束后才完成赋值操作
  2. b的值并不是立刻就改变的
  3. 这是一种比较常用的赋值方法。(特别在编写可综合模块时)

顺序块

特点:

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

格式一

	begin
	  语句1;
	  语句2;
	  ……
	end

格式二

	begin:块名
	  块内声明语句
	  语句1;
	  语句2;
	  ……
	end
  • 块名即标识该块的一个名字,相当于一个标识符。
  • 块内声明语句可以使参数声明语句、reg型变量声明语句、integer型变量声明语句、real型变量声明语句。

并行块

特点:

  1. 块内语句是同时执行的,即程序流程控制一进入到该并行块,块内语句则开始同时并行地执行。
  2. 块内每条语句的延迟时间是相对于程序流程控制进入到块内时的仿真时间的。
  3. 延迟时间是用来给赋值语句提供执行时序的。
  4. 当按时间时序排序在最后的语句执行完后或一个disable语句执行时,程序流程控制跳出该程序块

格式一

	fork
	  语句1;
	  语句2;
	  ……
	join

格式二

	fork:块名
	  块内声明语句
	  语句1;
	  语句2;
	  ……
	join
  • 块名即标识该块的一个名字,相当于一个标识符。
  • 块内说明语句可以是参数说明语句、 reg型变量声明语句、 integer型变量声明语句、 real型变量声明语句、time型变量声明语句、事件(event)说明语句。

块名

在Verilog HDL语言中,可以给每个块取一个名字,块名提供了一个在任何仿真时刻确认变量值的方法,原因如下。

  1. 有了块名后,可以在块内定义局部变量,只在块内使用。
  2. 有了块名后,其他语句可以调用块,如被disable语句调用。
  3. 在Verilog语言里,所有的变量都是静态的,即所有的变量都只有一个唯一的存储地址,因此进入或跳出块并不影响存储在变量内的值。

起始时间和结束时间

在并行块和顺序块中都有一个起始时间和结束时间的概念。对于顺序块,起始时间就是第一条语句开始被执行的时间,结束时间就是最后一条语句执行完的时间。而对于并行块来说,起始时间对于块内所有的语句是相同的,即程序流程控制进入该块的时间,其结束时间是按时间排序在最后的语句执行
完的时间。

当一个块嵌入另一个块时,块的起始时间和结束时间是很重要的。至于跟在块后面的语句只有在该块的结束时间到了才能开始执行,也就是说,只有该块完全执行完后,后面的语句才可以执行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值