对verilog的初学者来说,线网和变量reg之间的不同点,也许是最难的。你有时得用reg而有时却得使用wire,使用来使用去,简直头晕。
而在SystemVerilog中,我们将会看到你可以在过去verilog中用reg型或是wire型的地方用logic型来代替。
实际上logic是对reg数据类型的改进,使得它除了作为一个变量之外,还可以被连续赋值、门单元和模块所驱动,显然,logic是一个更合适的名字。
举个RAM modelling的例子来说明上述问题,我们分别用Verilog和SystemVerilog来实现。
//RAM modelling in Verilog
1 module mema (r_wb,addr,d_q);
2 input r_wb;
3 input [7:0] addr;
4 inout [7:0] d_q;
5
6 wire r_wb;
7 wire [7:0] addr, d_q;
8 reg [7:0] mem [0:255];
9
10 assign d_q = (r_wb) ? mem[addr] : 8'hz ;
11
12 always @(r_wb or addr)
13 if (!r_wb)
14 mem[addr] = d_q;
15 endmodule
2 input r_wb;
3 input [7:0] addr;
4 inout [7:0] d_q;
5
6 wire r_wb;
7 wire [7:0] addr, d_q;
8 reg [7:0] mem [0:255];
9
10 assign d_q = (r_wb) ? mem[addr] : 8'hz ;
11
12 always @(r_wb or addr)
13 if (!r_wb)
14 mem[addr] = d_q;
15 endmodule
//RAM modelling in SystemVerilog
1 module mema (r_wb,addr,d_q);
2 input r_wb;
3 input [7:0] addr;
4 inout [7:0] d_q;
5
6 logic r_wb;
7 logic [7:0] addr
2 input r_wb;
3 input [7:0] addr;
4 inout [7:0] d_q;
5
6 logic r_wb;
7 logic [7:0] addr
logic [7:0] d_q; //Gotcha! should be declared: wire [7:0] d_q;
8 logic [7:0] mem [0:255];
9
10 always @(r_wb or addr)
11 if (!r_wb)
12 mem[addr] = d_q;
13 else
14 d_q = mem[addr];
15 endmodule
8 logic [7:0] mem [0:255];
9
10 always @(r_wb or addr)
11 if (!r_wb)
12 mem[addr] = d_q;
13 else
14 d_q = mem[addr];
15 endmodule
如上所看,抛去inout类型外,其余所有的变量都可以声明为logic类型,不用区分线网和变量reg之间的不同点,所以,SystemVerilog的优点是不是很明显?
SystemVerilog的其他优点,请大家参考:http://www.doulos.com/knowhow/sysverilog/tutorial
值得注意的是,logic不能有多个结构性的驱动,也就是说,logic不允许使用多于一次的持续赋值语句和输出端口连接的给同一变量赋值。这是因为没有类似于线网的多重驱动变量的定论。因此,假如你通过这些方式给一个变量赋过值,你将不能再用过程赋值语句给变量赋值。
如上面RAM modelling的代码,在对inout双向总线建模的时候,需要使用线网类型。(比起verilog-1995,新增加的许多systemverilog feature都要求变量只有一个驱动!)
如下代码的第3行和第4行,logic型的"exception"相继被两个实例化赋值,于是编译器便会报错。解决的办法是把exception定义成wire型。
//Multiple Driver Example
1 module multiple_drivers (output logic exception,
2 input logic [7:0] a, b);
3 is_zero inst0 (exception, b);
4 is_greater inst1 (exception, a, b);
5 endmodule
6
7 module is_zero (output logic zero,
8 input logic [7:0] x);
9 always @(x)
10 if (x ==0) zero =1;
11 else zero =0;
12 endmodule
13
14 module is_greater (output logic greater,
15 input logic [7:0] x, y);
16 always @(x, y)
17 if (x > y) greater =1;
18 else greater =0;
19 endmodule
2 input logic [7:0] a, b);
3 is_zero inst0 (exception, b);
4 is_greater inst1 (exception, a, b);
5 endmodule
6
7 module is_zero (output logic zero,
8 input logic [7:0] x);
9 always @(x)
10 if (x ==0) zero =1;
11 else zero =0;
12 endmodule
13
14 module is_greater (output logic greater,
15 input logic [7:0] x, y);
16 always @(x, y)
17 if (x > y) greater =1;
18 else greater =0;
19 endmodule