目录
摘要:Verilog中除全局的系统任务和函数外,所有的数据、函数和任务都在模块中。Verilog模块也可以包含其他模块的实例,并且任何未实例化的模块都位于顶层,另外模块的层次结构通常是任意的,在维护端口列表上无疑会花费大量的精力。
SV对verilog的一个重要增强是可以通过模块端口(包括网络)来传递任何数据类型,以及所有的变量类型(包括实数、数组和结构)。
1 packages
- 在verilog中如果不使用“include compiler directive”,就没有办法跨模块共享公共代码(任务和 函数);
- package 提供了在 多个模块之间 共享公共代码的方法;
- 可以共享的内容:
- parameter
- data
- type
- task
- function
- sequence
- property
- package所遵循的规则:
- package 不能包含任何赋值语句;
- package的变量声明赋值应该出现在任何initial、always、always_comb、always_latch或者always_ff块 之前;
- package 中的项不能有层次引用;
- 访问 package 的数据、函数和类型的两种方法:
- 通过类范围解析算子 ::
- 通过import语句:该语句提供了package内标识符的直接可见性;
- package是用来定义一个通用的实用程序的,通常具有持久性和不可重写性;
一个完整的例子:
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Package Declaration
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 package msgPkg;
5 integer errCnt = 0;
6 integer warnCnt = 0;
7 bit terminate_on_error = 0;
8 string msgName = "NULL";
9 //=================================================
10 // Initilizes the messaging
11 //=================================================
12 task initMsgPkg (string mName, bit term);
13 terminate_on_error = term;
14 msgName = mName;
15 endtask
16 //=================================================
17 // Prints the INFO message
18 //=================================================
19 task msg_info (string msg);
20 $display ("@%0dns %s INFO : %s",$time,msgName,msg);
21 endtask
22 //=================================================
23 // Prints the warning message
24 //=================================================
25 task msg_warn (string msg);
26 $display ("@%0dns %s WARN : %s",$time,msgName,msg);
27 warnCnt ++;
28 endtask
29 //=================================================
30 // Prints error message
31 //=================================================
32 task msg_error (string msg);
33 $display ("@%0dns %s ERROR : %s",$time,msgName,msg);
34 errCnt ++;
35 if (terminate_on_error) $finish;
36 endtask
37 //=================================================
38 // Prints fatal message and terminates simulation
39 //=================================================
40 task msg_fatal (string msg);
41 $display ("@%0dns %s FATAL : %s",$time,msgName,msg);
42 $finish;
43 endtask
44 //=================================================
45 // Returns the error count
46 //=================================================
47 function integer getErrCnt();
48 getErrCnt = errCnt;
49 endfunction
50 //=================================================
51 // Returns the warning count
52 //=================================================
53 function integer getWarnCnt();
54 getWarnCnt = warnCnt;
55 endfunction
56
57 endpackage
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Package Declaration
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 package definesPkg;
5 //=================================================
6 // TypeDefs declaration
7 //=================================================
8 typedef enum {FALSE, TRUE} bool;
9 typedef struct {
10 bit [7:0] addr;
11 bit [7:0] data;
12 bit wr;
13 } mem_s;
14
15 endpackage
1 //=================================================
2 // Include all the files
3 //=================================================
4 `include "msgPkg.sv"
5 `include "definesPkg.sv"
6 //=================================================
7 // Import the Packages
8 //=================================================
9 import msgPkg::*;
10 import definesPkg::bool;
11
12 //+++++++++++++++++++++++++++++++++++++++++++++++++
13 // DUT Using the package
14 //+++++++++++++++++++++++++++++++++++++++++++++++++
15 module simple_package();
16
17 bool value = definesPkg::FALSE;
18
19 initial begin
20 msgPkg::initMsgPkg("PACKAGES",0);
21 msgPkg::msg_info("Testing Packages");
22 #10 msgPkg::msg_warn("Testing Packages");
23 #10 msgPkg::msg_error("Testing Packages");
24 msgPkg::msg_info($psprintf("Warning Count %0d, Error Count %0d",
25 msgPkg::getWarnCnt(), msgPkg::getErrCnt()));
26 if (value != definesPkg::TRUE)
27 #10 msgPkg::msg_fatal("Value is FALSE");
28 end
29
30 endmodule
1
2 @0ns PACKAGES INFO : Testing Packages
3 @10ns PACKAGES WARN : Testing Packages
4 @20ns PACKAGES ERROR : Testing Packages
5 @20ns PACKAGES INFO : Warning Count 1, Error Count 1
6 @30ns PACKAGES FATAL : Value is FALSE
2. Top level module
$root:作用时明确指向顶层实例,或者表明实例化的根(在打印时会有明确显示);
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Child Module
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 module child();
5
6 //=================================================
7 // Method inside child
8 //=================================================
9 task print();
10 $display("%m : Inside Module child");
11 endtask
12
13 initial begin
14 $root.top.U.U.print();
15 end
16
17 endmodule
18
19
20 //+++++++++++++++++++++++++++++++++++++++++++++++++
21 // Parent Module
22 //+++++++++++++++++++++++++++++++++++++++++++++++++
23 module parent();
24
25 //=================================================
26 // Method inside parent
27 //=================================================
28 task print();
29 $display("%m : Inside Module praent");
30 endtask
31
32 child U ();
33
34 initial begin
35 $root.top.U2.print();
36 $root.top.U.print();
37 end
38
39 endmodule
40
41 //+++++++++++++++++++++++++++++++++++++++++++++++++
42 // Top Module
43 //+++++++++++++++++++++++++++++++++++++++++++++++++
44 module top();
45
46 parent U();
47 child U2();
48
49 //=================================================
50 // Method inside top
51 //=================================================
52 task print();
53 $display("%m : Inside Module top");
54 endtask
55
56 endmodule
57
58 //compile result
59
60 top.U.U.print : Inside Module child
61 top.U2.print : Inside Module child
62 top.U.print : Inside Module praent
63 top.U.U.print : Inside Module child
3. Nested module
- 在verilog中,不允许模块内部嵌套声明另一个模块;
- 在SV中,允许模块声明嵌套;
- 外部名称空间对内部模块是可见的,因此任何声明的名称都可以使用,除非被local隐藏 ;
- 嵌套模块的一个目的是在不使用端口的情况下显示模块的逻辑分区;
1 //+++++++++++++++++++++++++++++++++++++++++++++++++
2 // Nested Module
3 //+++++++++++++++++++++++++++++++++++++++++++++++++
4 module nested_module();
5
6 //=================================================
7 // Module declration inside the module
8 //=================================================
9 module counter(input clk,enable,reset,
10 output logic [3:0] data);
11
12 always @ (posedge clk)
13 if (reset) data <= 0;
14 else if (enable) data ++;
15 endmodule
16
17 logic clk = 0;
18 always #1 clk++;
19 logic enable, reset;
20 wire [3:0] data;
21
22 counter U(clk,enable,reset,data);
23
24 initial begin
25 $monitor("@%0dns reset %b enable %b data %b",
26 $time,reset,enable,data);
27 reset <= 1;
28 #10 reset <= 0;
29 #1 enable <= 1;
30 #10 enable <= 0;
31 #4 $finish;
32 end
33
34 endmodule
35
36 //compile result
37 @0ns reset 1 enable x data xxxx
38 @1ns reset 1 enable x data 0000
39 @10ns reset 0 enable x data 0000
40 @11ns reset 0 enable 1 data 0000
41 @13ns reset 0 enable 1 data 0001
42 @15ns reset 0 enable 1 data 0010
43 @17ns reset 0 enable 1 data 0011
44 @19ns reset 0 enable 1 data 0100
45 @21ns reset 0 enable 0 data 0101
4. Extern module
- 为了支持单独编译,可以使用模块的extern声明来声明模块上的端口,而不需要定义模块本身;
- extern模块声明由关键字extern后跟模块名称和模块的端口列表组成;
1 extern module counter (input clk,enable,reset,
2 output logic [3:0] data);
3
4 //+++++++++++++++++++++++++++++++++++++++++++++++++
5 // Extern Module
6 //+++++++++++++++++++++++++++++++++++++++++++++++++
7 module extern_module();
8
9 logic clk = 0;
10 always #1 clk++;
11 logic enable, reset;
12 wire [3:0] data;
13
14 counter U(clk,enable,reset,data);
15
16 initial begin
17 $monitor("@%0dns reset %b enable %b data %b",
18 $time,reset,enable,data);
19 reset <= 1;
20 #10 reset <= 0;
21 #1 enable <= 1;
22 #10 enable <= 0;
23 #4 $finish;
24 end
25
26 endmodule
1 //=================================================
2 // Module declration
3 //=================================================
4 module counter(input clk,enable,reset,
5 output logic [3:0] data);
6
7 always @ (posedge clk)
8 if (reset) data <= 0;
9 else if (enable) data ++;
10
11 endmodule
12
13 //compile result
14 @0ns reset 1 enable x data xxxx
15 @1ns reset 1 enable x data 0000
16 @10ns reset 0 enable x data 0000
17 @11ns reset 0 enable 1 data 0000
18 @13ns reset 0 enable 1 data 0001
19 @15ns reset 0 enable 1 data 0010
20 @17ns reset 0 enable 1 data 0011
21 @19ns reset 0 enable 1 data 0100
22 @21ns reset 0 enable 0 data 0101