在自己准备写一些简单的verilog教程之前,参考了许多资料----asic-world网站的这套verilog教程即是其一。这套教程写得极好,奈何没有中文,在下只好斗胆翻译过来(加了自己的理解)分享给大家。
这是网站原文:Verilog Tutorial
这是系列导航:Verilog教程系列文章导航
这是一些算术运算的示例:
module arithmetic_operators();
initial begin
$display (" 5 + 10 = %d", 5 + 10);
$display (" 5 - 10 = %d", 5 - 10);
$display (" 10 - 5 = %d", 10 - 5);
$display (" 10 * 5 = %d", 10 * 5);
$display (" 10 / 5 = %d", 10 / 5);
$display (" 10 / -5 = %d", 10 / -5);
$display (" 10 %s 3 = %d","%", 10 % 3);
$display (" +5 = %d", +5);
$display (" -5 = %d", -5);
#10 $finish;
end
endmodule
这是仿真结果:
5 + 10 = 15
5 - 10 = -5
10 - 5 = 5
10 * 5 = 50
10 / 5 = 2
10 / -5 = -2
10 % 3 = 1
+5 = 5
-5 = -5
运算符 |
描述 |
a < b |
a 小于 b |
a > b |
a 大于 b |
a <= b |
a 小于等于 b |
a >= b |
a 大于等于 b |
注:如果任何操作数是 x 或 z,则该测试的结果将被视为假 (0)
这是一些关系运算的示例:
module relational_operators();
initial begin
$display (" 5 <= 10 = %b", (5 <= 10));
$display (" 5 >= 10 = %b", (5 >= 10));
$display (" 1'bx <= 10 = %b", (1'bx <= 10));
$display (" 1'bz <= 10 = %b", (1'bz <= 10));
#10 $finish;
end
endmodule
这是仿真结果:
5 <= 10 = 1
5 >= 10 = 0
1'bx <= 10 = x
1'bz <= 10 = x
有两种类型的相等运算符。
运算符 |
描述 |
a === b |
a等于b, 包括 x 和 z |
a !== b |
a不等于b, 包括 x 和 z |
a == b |
a等于b, 结果可能是未知 |
a != b |
a不等于b, 结果可能是未知 |
注:结果始终为 0 或 1。
这是一些相等运算的示例:
module equality_operators();
initial begin
// Case Equality
$display (" 4'bx001 === 4'bx001 = %b", (4'bx001 === 4'bx001));
$display (" 4'bx0x1 === 4'bx001 = %b", (4'bx0x1 === 4'bx001));
$display (" 4'bz0x1 === 4'bz0x1 = %b", (4'bz0x1 === 4'bz0x1));
$display (" 4'bz0x1 === 4'bz001 = %b", (4'bz0x1 === 4'bz001));
// Case Inequality
$display (" 4'bx0x1 !== 4'bx001 = %b", (4'bx0x1 !== 4'bx001));
$display (" 4'bz0x1 !== 4'bz001 = %b", (4'bz0x1 !== 4'bz001));
// Logical Equality
$display (" 5 == 10 = %b", (5 == 10));
$display (" 5 == 5 = %b", (5 == 5));
// Logical Inequality
$display (" 5 != 5 = %b", (5 != 5));
$display (" 5 != 6 = %b", (5 != 6));
#10 $finish;
end
endmodule
这是仿真结果:
4'bx001 === 4'bx001 = 1
4'bx0x1 === 4'bx001 = 0
4'bz0x1 === 4'bz0x1 = 1
4'bz0x1 === 4'bz001 = 0
4'bx0x1 !== 4'bx001 = 1
4'bz0x1 !== 4'bz001 = 1
5 == 10 = 0
5 == 5 = 1
5 != 5 = 0
5 != 6 = 1
运算符 |
描述 |
! |
逻辑非 |
&& |
逻辑与 |
|| |
逻辑或 |
这是一些逻辑运算的示例:
module logical_operators();
initial begin
// Logical AND
$display ("1'b1 && 1'b1 = %b", (1'b1 && 1'b1));
$display ("1'b1 && 1'b0 = %b", (1'b1 && 1'b0));
$display ("1'b1 && 1'bx = %b", (1'b1 && 1'bx));
// Logical OR
$display ("1'b1 || 1'b0 = %b", (1'b1 || 1'b0));
$display ("1'b0 || 1'b0 = %b", (1'b0 || 1'b0));
$display ("1'b0 || 1'bx = %b", (1'b0 || 1'bx));
// Logical Negation
$display ("! 1'b1 = %b", (! 1'b1));
$display ("! 1'b0 = %b", (! 1'b0));
#10 $finish;
end
endmodule
这是仿真结果:
1'b1 && 1'b1 = 1
1'b1 && 1'b0 = 0
1'b1 && 1'bx = x
1'b1 || 1'b0 = 1
1'b0 || 1'b0 = 0
1'b0 || 1'bx = x
! 1'b1 = 0
! 1'b0 = 1
按位运算符对两个操作数执行按位运算。他们取一个操作数中的每一位,然后用另一个操作数中的相应位执行操作。如果一个操作数比另一个短,它将在左侧用零扩展以匹配较长操作数的长度。
运算符 |
描述 |
~ |
非 |
& |
与 |
| |
或 |
^ |
异或 |
^~ or ~^ |
同或 |
这是一些按位运算的示例:
module bitwise_operators();
initial begin
// Bit Wise Negation
$display (" ~4'b0001 = %b", (~4'b0001));
$display (" ~4'bx001 = %b", (~4'bx001));
$display (" ~4'bz001 = %b", (~4'bz001));
// Bit Wise AND
$display (" 4'b0001 & 4'b1001 = %b", (4'b0001 & 4'b1001));
$display (" 4'b1001 & 4'bx001 = %b", (4'b1001 & 4'bx001));
$display (" 4'b1001 & 4'bz001 = %b", (4'b1001 & 4'bz001));
// Bit Wise OR
$display (" 4'b0001 | 4'b1001 = %b", (4'b0001 | 4'b1001));
$display (" 4'b0001 | 4'bx001 = %b", (4'b0001 | 4'bx001));
$display (" 4'b0001 | 4'bz001 = %b", (4'b0001 | 4'bz001));
// Bit Wise XOR
$display (" 4'b0001 ^ 4'b1001 = %b", (4'b0001 ^ 4'b1001));
$display (" 4'b0001 ^ 4'bx001 = %b", (4'b0001 ^ 4'bx001));
$display (" 4'b0001 ^ 4'bz001 = %b", (4'b0001 ^ 4'bz001));
// Bit Wise XNOR
$display (" 4'b0001 ~^ 4'b1001 = %b", (4'b0001 ~^ 4'b1001));
$display (" 4'b0001 ~^ 4'bx001 = %b", (4'b0001 ~^ 4'bx001));
$display (" 4'b0001 ~^ 4'bz001 = %b", (4'b0001 ~^ 4'bz001));
#10 $finish;
end
endmodule
这是仿真结果:
~4'b0001 = 1110
~4'bx001 = x110
~4'bz001 = x110
4'b0001 & 4'b1001 = 0001
4'b1001 & 4'bx001 = x001
4'b1001 & 4'bz001 = x001
4'b0001 | 4'b1001 = 1001
4'b0001 | 4'bx001 = x001
4'b0001 | 4'bz001 = x001
4'b0001 ^ 4'b1001 = 1000
4'b0001 ^ 4'bx001 = x000
4'b0001 ^ 4'bz001 = x000
4'b0001 ~^ 4'b1001 = 0111
4'b0001 ~^ 4'bx001 = x111
4'b0001 ~^ 4'bz001 = x111
运算符 |
描述 |
& |
规约与 |
~& |
规约与非 |
| |
规约或 |
~| |
规约或非 |
^ |
规约异或 |
^~ or ~^ |
规约同或 |
这是一些规约运算的示例:
module reduction_operators();
initial begin
// Bit Wise AND reduction
$display (" & 4'b1001 = %b", (& 4'b1001));
$display (" & 4'bx111 = %b", (& 4'bx111));
$display (" & 4'bz111 = %b", (& 4'bz111));
// Bit Wise NAND reduction
$display (" ~& 4'b1001 = %b", (~& 4'b1001));
$display (" ~& 4'bx001 = %b", (~& 4'bx001));
$display (" ~& 4'bz001 = %b", (~& 4'bz001));
// Bit Wise OR reduction
$display (" | 4'b1001 = %b", (| 4'b1001));
$display (" | 4'bx000 = %b", (| 4'bx000));
$display (" | 4'bz000 = %b", (| 4'bz000));
// Bit Wise OR reduction
$display (" ~| 4'b1001 = %b", (~| 4'b1001));
$display (" ~| 4'bx001 = %b", (~| 4'bx001));
$display (" ~| 4'bz001 = %b", (~| 4'bz001));
// Bit Wise XOR reduction
$display (" ^ 4'b1001 = %b", (^ 4'b1001));
$display (" ^ 4'bx001 = %b", (^ 4'bx001));
$display (" ^ 4'bz001 = %b", (^ 4'bz001));
// Bit Wise XNOR
$display (" ~^ 4'b1001 = %b", (~^ 4'b1001));
$display (" ~^ 4'bx001 = %b", (~^ 4'bx001));
$display (" ~^ 4'bz001 = %b", (~^ 4'bz001));
#10 $finish;
end
endmodule
这是仿真结果:
& 4'b1001 = 0
& 4'bx111 = x
& 4'bz111 = x
~& 4'b1001 = 1
~& 4'bx001 = 1
~& 4'bz001 = 1
| 4'b1001 = 1
| 4'bx000 = x
| 4'bz000 = x
~| 4'b1001 = 0
~| 4'bx001 = 0
~| 4'bz001 = 0
^ 4'b1001 = 0
^ 4'bx001 = x
^ 4'bz001 = x
~^ 4'b1001 = 1
~^ 4'bx001 = x
~^ 4'bz001 = x
运算符 |
描述 |
<< |
左移 |
>> |
右移 |
这是一些移位运算的示例:
module shift_operators();
initial begin
// Left Shift
$display (" 4'b1001 << 1 = %b", (4'b1001 << 1));
$display (" 4'b10x1 << 1 = %b", (4'b10x1 << 1));
$display (" 4'b10z1 << 1 = %b", (4'b10z1 << 1));
// Right Shift
$display (" 4'b1001 >> 1 = %b", (4'b1001 >> 1));
$display (" 4'b10x1 >> 1 = %b", (4'b10x1 >> 1));
$display (" 4'b10z1 >> 1 = %b", (4'b10z1 >> 1));
#10 $finish;
end
endmodule
这是仿真结果:
4'b1001 << 1 = 0010
4'b10x1 << 1 = 0x10
4'b10z1 << 1 = 0z10
4'b1001 >> 1 = 0100
4'b10x1 >> 1 = 010x
4'b10z1 >> 1 = 010z
这是一些拼接运算的示例:
module concatenation_operator();
initial begin
// concatenation
$display (" {4'b1001,4'b10x1} = %b", {4'b1001,4'b10x1});
#10 $finish;
end
endmodule
这是仿真结果:
{4'b1001,4'b10x1} = 100110x1
复制运算符用于将一组位复制 n 次。假设你有一个 4 位变量,你想复制它 4 次以获得一个 16 位变量:那么我们可以使用复制运算符。
运算符 |
描述 |
{n{m}} |
复制m的值n次 |
这是一些复制运算的示例:
module replication_operator();
initial begin
// replication
$display (" {4{4'b1001}} = %b", {4{4'b1001}});
// replication and concatenation
$display (" {4{4'b1001,1'bz}} = %b", {4{4'b1001,1'bz}});
#10 $finish;
end
endmodule
这是仿真结果:
{4{4'b1001} = 1001100110011001
{4{4'b1001,1'bz} = 1001z1001z1001z1001z
这是一些条件运算的示例:
module conditional_operator();
wire out;
reg enable,data;
// Tri state buffer
assign out = (enable) ? data : 1'bz;
initial begin
$display ("time\t enable data out");
$monitor ("%g\t %b %b %b",$time,enable,data,out);
enable = 0;
data = 0;
#1 data = 1;
#1 data = 0;
#1 enable = 1;
#1 data = 1;
#1 data = 0;
#1 enable = 0;
#10 $finish;
end
endmodule
这是仿真结果:
time enable data out
0 0 0 z
1 0 1 z
2 0 0 z
3 1 0 0
4 1 1 1
5 1 0 0
6 0 0 z