数据类型及其常量及变量
1.数字
二进制整数(b或B);
十进制整数(d或D);
十六进制整数(h或H);
八进制整数(o或O);
表达方式:<位宽><进制><数字>
8‘d10(全面表达方式),’d10(位宽由机器决定,但至少32位),10(十进制整数10)
x和z值:x代表不定值,z代表高阻值(z也可以是‘?’)。
负数:-8’d10;
下划线:8‘d1111_0000;
2.参数型
parameter msb = 7; //定义参数msb为常量7
3.变量
wire型:线
reg型:寄存器
memory型:reg[127:0] sdata [15:0]
可以支持指定 bit 位后固定位宽的向量域选择访问。
[bit+: width] : 从起始 bit 位开始递增,位宽为 width。
[bit-: width] : 从起始 bit 位开始递减,位宽为 width。
运算符及表达式
(1). 算术运算符( +, -, *, /, %);
(2). 赋值运算符( =, <=);
(3). 关系运算符( >, <, >=, <=);
(4). 逻辑运算符( &&, ||, !);
(5). 条件运算符( ?: ); (a = b ? c : d)
(6). 位运算符( ~, |, &, ^, ^~);(取反,按位或,按位与,按位异或,按位同或(异或非))
(7). 移位运算符( <<, >>);
(8). 拼接运算符( {} );
(9). 等式运算符( = =, ! =, = = =, ! = =)
语句
条件语句
(1).if_else
(2).case
case (cnt)
4'd1: result <= 'd0;
4'd2: result <= 'd0;
4'd3: result <= 'd0;
4'd4: result <= 'd0;
default: result <= 'd0;
endcase
循环语句
(1).forever; (2).repeat; (3).while; (4).for
结构说明语句
(1).initial; (2).always; (3).task; (4).function
task和function的区别:
(1).function只能与主模块公用同一个仿真时间单位,而task可以定义自己的仿真时间单位
(2).function不能启动task,而task能启动其它task和function
(3).function至少要有一个输入变量,而task可以没有或有多个任何类型的变量
(4).function返回一个值,而task则不返回值
task <任务名>;
<端口及数据类型声明语句>;
<语句1>;
<语句2>;
调用:<任务名> (端口1,端口2,…,端口n);
例如:
task read_iv;
output [127:0] iv_out;
begin
apb_read(AES_IVR0, iv_out[ 31:0]);
apb_read(AES_IVR1, iv_out[ 63:32]);
apb_read(AES_IVR2, iv_out[ 95:64]);
apb_read(AES_IVR3, iv_out[127:96]);
end
endtask
read_iv(iv_rd);
function <返回值的类型和范围> (函数名)
<端口说明语句>
<变量类型说明语句>
begin
<语句>
.
.
end
调用:<函数名> ( <函数名> <表达式><, <表达式>>* )
例如:
function [31:0] factorial;
input [3:0] operand
reg [3:0] index,
begin
factorial = operand ? 1: 0;
for(index = 2; index <= operand; index = index + 1)
factorial = index * factorial
end
result <= n * factorial(n);
系统函数和任务
$bitstoreal, $rtoi, $setup, $skew, $hold, $setuphold, $itor, $strobe, $period, $time, $printtimescale, $timefoemat, $realtime, $width, $real tobits, $$recovery
$random: 返回一个32位的随机数
$finish, $stop
$display, $write
$readmemb, $readmemh
编译预处理
宏定义 `define
`define 标识符(宏名) 字符串(宏内容)
"文件包含"处理 `include
时间尺度 `timescale
`timescale <时间单位> / <时间精度>
条件编译命令
`ifdef、 程序段1
`else、 程序段2
`endif
状态机
Mealy型:时序逻辑的输出不仅取决于状态还取决于输入;
Moore型:时序逻辑的输出只取决于当前状态。
实际设计工作中,大部分状态机都属于Mealy状态机,因为状态机的输出中或多或少有几个属于Mealy类型的输出,输出不但与当前状态有关还与输入有关;还有几个输出属于Moore类型的,至于当前的状态有关。
阻塞赋值和非阻塞赋值
在描述组合逻辑的always块中用阻塞赋值,则综合成组合逻辑的电路结构;
在描述时序逻辑的always块中用非阻塞赋值,则综合成时序逻辑的电路结构。
可综合风格的Verilog模块编程的8个原则:
(1). 时序电路建模时,用非阻塞赋值。
(2). 锁存器电路建模时,用非阻塞赋值。
(3). 用always块建立组合逻辑模型时,用阻塞赋值。
(4). 在同一个always块中建立时序和组合逻辑电路时,用非阻塞赋值。
(5). 在同一个always块中不要既用非阻塞赋值又用阻塞赋值。
(6). 不要在一个以上的always块中为同一个变量赋值。
(7). 用$strobe系统任务来显示用非阻塞赋值的变量值。
(8). 在赋值时不要使用#0 延迟。
不要在一个以上always块中对同一个变量进行多次赋值可能会导致竞争冒险,即使使用非阻塞赋值也可能产生竞争冒险。因为不同always块执行的顺序时随机的。