input和output
module/endmodule :表征模块的开始与结束。
example :模块名可由用户指定,可包含字母、数字及下划线,需以字母开头,区分大小写
assign :赋值操作关键字,该关键字后可跟一个赋值表达式,该关键字是实现组合逻辑操作的一种主要描述方式。
input/output :表征该信号的方向,除输入、输出外还有一种inout(输入输出)型。
reg和wire
reg相当于存储单元,wire型相当于物理连线,即reg型变量保持最后一次的赋值,而wire型变量需要持续的驱动。
在always块中的变量,只能是reg型
使用wire型变量时,必须搭配assign
input、output、inout声明的变量,默认都是wire型
wire对应于连续赋值,如assign
reg对应于过程赋值,如always块、initial块
多bit逻辑门
对于下面5个逻辑表达式
y1 = a & b;
y2 = a | b;
y3 = a ^ b;
y4 = ~(a & b);
y5 = ~(a | b);
电路图:
语法说明:
[3:0]:表征该信号的位宽,实例中是推荐写法,[0:3]、[4:1]等写法也是合法的
对于逻辑表达式 y = a[7] & a[6] & a[5] & a[4] & a[3] & a[2] & a[1] & a[0];
其电路图为:
Verilog代码:
a[7]:可将一个多位宽信号中的一位或多位以此种方式进行单独处理
& :按位与、归并与操作,如该操作符只有一个操作数时,则将该操作数的所有位进行相与操作,可以实现与注释部分相同的功能,但写法更简洁
一位全加器
对于表达式 {cout,s} = a + b + cin;
Verilog代码
wire :线网型数据类型,verilog语法中的一种主要数据类型,用于表示线网型信号,与实际电路中的信号连线相对应。wire是verilog中的默认数据类型,此例中的输入输出信号没有指定数据类型,则默认为wire型。除wire外,另外一种主要数据类型为reg,表示寄存器类型数据。
内部信号 :此例中的p、g为内部信号,可以简化设计,增加代码可读性
触发器
语法说明:
时序逻辑 :电路具有记忆功能,电路状态不但与当前输入有关,还与前一时刻的状态有关。
同步逻辑 :在同一的时钟信号激励下工作,输出只在时钟的上升沿(或者下降沿)发生变化。
reg :除wire类型外,另外一种常用的数据类型,一般表示寄存器类型数据,不过并不绝对,记住一条原则:在always块内被赋值的信号应定义成reg型,用assign语句赋值的信号应定义成wire型。
always :除assign外,另外一种实现赋值操作的关键字,两者都不可嵌套,区别在于,assign语句只能实现组合逻辑赋值,且一个assign语句后面只能跟一条赋值表达式。而always即能实现组合逻辑赋值,又能实现时序逻辑赋值操作,且可以包含多条赋值表达式,多条赋值表达式,则应位于begin/end对中间。
过程语句
always
initial:
赋值语句
在一个过程块中,阻塞赋值与非阻塞赋值只能使用其中一种
在时序逻辑电路中,两种赋值方式可能或综合出不同的电路结构。如下所示
为避免出现一些稀奇古怪的电路,我们只需记住以下规则:
i:在组合逻辑电路中,使用阻塞式赋值方式"=";
ii: 在时序逻辑电路中,使用非阻塞式赋值方式"<="
iii:在同一个always块内,只能存在一种赋值方式。
iv:一个信号,只能在一个always或一个assign语句下赋值。
v:原则上来说,一个always块内只处理一个或一类信号,不同的信号可在不同的always块内处理。
vi: always块内只能对reg型信号进行处理,不能对wire型数据赋值,也不能实例化模块
过程赋值和连续赋值对比:
连续赋值:
1)语法上,有关键词“assign”来标识;
2)左侧被赋值的数据类型必须是线网型数据(wire);
3)连续赋值语句不能出现在过程快中(initial/always);
4)连续赋值语句主要用来对组合逻辑进行建模以及线网数据间进行描述;
5)连续赋值语句产生作用后,赋值表达式中信号的任何变化都将立即被反映到赋值线网型数据的取值上;
过程赋值:
1)语法上,没有关键词“assign”;
2)左侧被赋值的数据类型必须是寄存器类型的变量(reg);
3)过程性连续赋值语句只能出现在过程块中;
4)过程性连续赋值语句主要用来对时序逻辑电路进行行为描述;
5)在过程赋值语句的情况下,只有在过程赋值语句被执行时才执行赋值操作,语句执行完后被赋值变量的取值不再受到赋值表达式的影响;
循环语句
宏替换
电路设计举例