Ⅰ Verilog语言基础
一、数据基础
-
电平:0,1,Z/?(高阻态),X(未知态或未初始化)
-
数值表示: < 位宽>’<进制><数字>
-
数据对象:reg:可以存储数据 wire:连接两个引脚,不能存储数据
-
操作符:位运算(每个对应比特进行运算,结果和输入长度相同)/逻辑运算(结果为单个比特,只有0或1)
-
算术运算:相比C/C++ 无自加自减
-
关系运算:Verilog 有全等“=”:比较‘X’和‘Z’的值;逻辑等“”:遇到X/Z,则结果为X
阻塞式赋值:类似C,执行完赋值再继续
非阻塞式赋值:先建立传递关系,稍后一起更新,类似并行计算。
-
特殊符号: C中使用 {} 包含代码块;
Verilog中使用begin…end;
Also:
begin y <== a && b //非阻塞赋值 end //复合语句 a[7:5] //选取数组的一段数 {s,a,b} //并置运算 #5 //延迟5个单位时间 @ //信号更改时刻出发条件 //这是单行注释 /* 这是多行注释 */
二、语句
-
赋值再C语言中是值的传递,而在Verilog中是信号的连接,Verilog赋值语句主要出现在assign、always、initial语句块中。
-
分支语句可以嵌套,但是嵌套层数多时硬件速度会下滑。
分支语句相当于一个MUX
-
Case的用法与C不同,等效于一个多路选择器。
always@(a,b,c,sel) begin case(sel) 2'b00 : out = a; 2'b01 : out = b; 2'b10 : out = c; default : out = 0; endcase end
-
循环:Verilog无 i++ ;循环函数必须要有明确的循环次数才可综合。
integer i; always@(posedge clk) begin for(i=0;i<13;i=i+1) if(data[i]) num = num + 1; end while(cnt>0) begin q = q + 1'b0; end
-
函数:function<位宽><函数名>返回一个用于表达式的值
function[3:0]mul_end input[3:0]a; input[3:0]b; begin mul_end = a & b; end endfunction
** Verilog function只能用于组合逻辑,函数定义不能包含时间控制语句,即任何用#,@,wait 来标识的语句。
** 函数不能调用“task”
** 定义函数时至少要有一个输入参数
** 返回值只能是1个,不可多个
-
initial / always语句 都是在0时刻开始执行,都可以有一条 或多条语句
initial 可综合,不需要敏感信号;
always不可综合,一般有敏感信号控制
initial //注意无分号 begin //注意无分号 控制语句…… end //注意无分号 initial // 一个将军发令一次,小兵不断执行 begin sel = 2'b0; #5 sel = 2'b01; #5 sel = 2'b10; #5 $finish; end
always //循环执行 begin #5 clk = ~clk end always@(posedge clk) begin if(reset) q <= 1'b0; else q <= d; end
-
Task语句 任务就是一段封装在task和endtask之间的程序
task task_demo; // 任务命名为task_demo input [7:0]x,y; // 输入端口说明 output [7,0]tmp; // 输出端口说明 if(x>y) //给出任务定义的描述语句 tmp = x; else tmp = y; endtask task_demo(x1,y1,res); // 调用
** 第一行“task” 语句中无端口名称;
** task的输入、输出、双向端口数量不受限制
** task定义的描述语句中,可以使用出现不可综合操作符合语
** 在task中可以调用其他task或function,也可以调用自身
** 在task定义结构内不能出现initial和always模块
** task定义中可以出现“disable 中止语句”,中断正在执行的任务,但其不可综合