2008年11月13日

Verilog HDL语法备忘

1。符号常量(Parameter)
parameter 参数1=表达式,..., 参数n=表达式;
在每个赋值语句的右边必须是一个常数表达式。
改变参数型常数的方法:
1)创建实例时用 #(参数, ..., 参数n) 改变实例的参数值
module Decode(A,B);
Parameter p1=1, p2=1;
....
endmodule
module Top;
wire A1;
wire B1;
wire A2;
wire B2;
Decode #(2,0) D1(A1, B1);
Decode #(3) D2(A2, B2);
endmodule
在上例中#(3)改变了p1值,p2保持不变。
2)在一个模块中改变另一个模块参数值使用defparam命令
module Test;
wire w;
Top T();
endmodule
module Top;
Block B1();
Block B2();
endmodule
module Block;
Parameter p=0;
endmodule
module Annotate;
defparam
Test.T.B1.p=2,
Test.T.B2.p=3;
endmodule

2。变量类型
Verilog模块中输入输出信号类型缺省默认类型是wire型。
reg型数据常用于表示"always"模块内的指定信号,常代表触发器。
"always"模块内被赋值的每一个信号都必须定义成reg型。reg型只
表示被定义的信号将用在"always"模块内。
reg类型数据的缺省值为不定值x。
assign A=B;
always #1 Count=C+1;
以上类型: A(wire) B(wire/reg) Count(reg) C(wire/reg)

3。阻塞和非阻塞赋值方式
1)Nonblocking b<=a;
2)Blocking b=a;

4。块语句
1)顺序块 begin 语句;语句;end 或 begin:块名 语句;语句;end
2)并行块 fork 语句;语句;join 或 fork:块名 语句;语句;join
在Verilog语言里,所有的变量都是静态的,即所有的变量都只有一个唯
一的存储地址,因此进入和跳出块不影响存储在变量内的值。

5== !==== !==的区别
===比较两个操作数必需完全一致,其结果才是1,否则为0
真值表:
===
0)0->1
1)1->1
X)X->1
Z)Z->1
other->0
==
0)0->1; 1->0;
1)0->0; 1->1;
X)any->X
Z)any->X

6case casez casex的真值表
case采用===比较方式
casez中0,1,x采用===比较方式, z和any比较为1
casex中0,1采用===比较方式, x,z和any比较为1
注意以上语句的所有表达式的值位宽必须相等。
例如:
A=0;
B=0;
ADDRESS=5'b0X000;
casex(ADDRESS)
5'b00???: A=1;
5'b01???: B=1;
.....
endcase

结果:A=1 B=0

7。避免生成多余的锁存器
例如
always @(al or d)
begin
if(al) q<= d;
end
当al为0时q没有赋值即默认保持原值,这就会自动生成锁存器。
避免生成多余的锁存器的原则:
a)如果用到if语句,最好写上else项。
b)如果用到case语句,最好写上default项。

8。避免X阻塞事件
reg[7:0] Count;
initial
begin
Count=1;
B=x;
end
always
begin
@(A) Count=Count+1;
@(B) Count=Count+1;
end

结果:Count=1,因为@(B)阻塞了进程。

9。注意变量位宽
例如:
reg[2:0] A;
reg[7:0] B;
A=-1; //3'b111
B=A; //8'b00000111 B!=-1

没有评论: