assign语句
用于对wire型变量赋值,是描述组合逻辑最常用的方法之一。
例如assign c=a&b; //a、b可以是wire型变量或寄存器变量,c必须是wire型变量或其他线网型变量。
用于对reg型变量赋值
在过程块中使用过程赋值语句。
always块包含一个或一个以上的语句(如:过程赋值语句、条件语句和循环语句等),在运行的全过程中,在时钟控制下被反复执行。
时钟有效边沿来了就执行。
在always块中被赋值的只能是寄存器reg型变量。
always块的写法是:always @ (敏感信号表达式)
例如:
always @ (clk) //只要clk发生变化就触发
always @ (posedge clk) //clk上升沿触发
always @ (negedge clk) //clk下降沿触发
always @ (negedge clk1 or posedge clk2) // clk1下降沿触发,clk2上升
沿也触发
always @ (*)该语句所在模块的任何输入信号变化了都触发。
阻塞的概念:
在一个块语句中,如果有多条阻塞赋值语句,在前面的赋值语句没有完成之前,后面的语句就不能被执行,就像被阻塞了一样,因此称为阻塞赋值方式。
阻塞(blocking)赋值方式:
赋值符号为=,如 b = a ;
非阻塞的概念:
多条非阻塞赋值在过程块内同时完成赋值操作,多条语句相当于同时执行!
非阻塞(non-blocking)赋值方式:
赋值符号为<=,如 b <= a ;
更多可以见:小梅哥Xilinx FPGA学习笔记9——语法(阻塞与非阻塞赋值)
条件语句用于always或Initial过程块内部,主要包含if-else语句和case语句。
if-else语句用于判定所给条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一。if-else语句有3种形式。
如果语句有多条组成,必须包含在begin和end之内。
3种形式的if语句后面都有表达式,一般为逻辑表达式为关系表达式。当表达式的值为1,按真处理,若为0、x、z,按假处理。
else语句不能单独使用,它是if语句的一部分
case语句是一种多分支选择语句,if只有两个分支可以选择,但是case可以直接处理多分支语句,这样程序看起来更直观简洁。
case(表达式)
分支表达式: 语句;
分支表达式: 语句;
… …
默认项(default) 语句;
endcase
case语句的所有表达式的值的位宽必须相等。
在case语句中,分支表达式每一位的值都是确定的(或者为0,或者为1);
在casez语句中,若分支表达式某些位的值为高阻值z,则不考虑对这些位的比较;
在casex语句中,若分支表达式某些位的值为z或不定值x,则不考虑对这些位的比较。
在Verilog中存在着多种循环语句,用来控制执行语句的执行次数。
在FPGA设计中,循环语句不一定能被综合,多用于在仿真代码生成仿真激励信号
forever语句: 连续执行的语句。
格式:forever begin语句块end
forever常用于仿真代码中。
仿真的时间单位,可以在系统中设置,也可以在仿真文件的开始加上:`timescale 1ns / 1ps //时间单位1ns, 精度1ps
仿真程序代码【1】和【2】是等价的,都是产生20个时间单位的方波,占空比50%。
repeat语句: 连续执行n次的语句。
格式:repeat(表达式) begin语句块end
其中 **“表达式”**用于指定循环次数,可以是一个整数、变量或者数值表达式。如果是变量或者数值表达式,其数值只在第一次循环时得到计算,从而得到确定循环次数。
repeat语句也常用于仿真。例如:
repeat (10)
begin
#10 clk=0;
#10 clk=1;
end
while语句: 执行语句,直至某个条件不满足。
格式:while(表达式) begin语句块end
表达式是循环执行条件表达式,代表了循环体得到继续重复执行时必须满足的条件,通常是一个逻辑表达式。
在每一次执行循环体之前,都需要对这个表达式是否成立进行判断。while 语句在执行时,首先判断循环执行条件表达式是否为真,如果真,执行后面的语句块, 然后再重新判断循环执行条件表达式是否为真,直到条件表达式不为真为止退出循环。
在执行语句中,如果没有改变循环执行条件表达式的值的语句,循环就成为死循环。
for 语句: 三个部分
for(表达式1;表达式2;表达式3)
for(循环变量赋初值;循环执行条件;循环变量增值)。
例如 for(i=0;i<=7;i=i+1)。
如果要让系统能够综合,那么循环的次数一定是固定的。
程序实例实现了统计输入的8位数据in中1的个数,每个时钟上升沿统计一次。