*两种数据类型:线网类型(net type) 和寄存器类型(reg type)
(1)定义信号类型的同时,必须定义好信号的位宽。
-
默认信号的位宽是 1 位,当信号的位宽为 1 时可不表述,如定义位宽为 1 的 wire 型信号 a 可直接用“
wire a
;”来表示。 -
但信号的位宽大于 1 位时 就一定要表示出来,如用“
wire [7:0]
”来表示该 wire 型信号的位宽为 8 位 -
信号的位宽取决于要该信号要表示的最大值。(设计时必须考虑最大值)。该信号能表示的无符号数最大值是:2的n次方-1,其中 n表示该信号的位宽。例如,信号 a 的最大值为 1000,那么信号 a 的位宽必须大于或等于 10 位
在电脑上如何简便看,打开win搜索calc,选择程序员
显然,(1000)d=(11 1110 1000)2
二进制10位
(2)线网类型wire
线网类型用于对结构化器件之间的物理连线的建模,如器件的管脚,芯片内部器件如与门的输出等。由于线网类型代表的是物理连接线,因此其不存储逻辑值,必须由器件驱动。通常用 assign 进行赋值,如
assign A = B ^ C
wire 类型定义语法如下:
wire [msb: lsb] wire1, wire2, . . .,wireN;
- ,表示多个
- msb 和 lsb 定义了范围,表示了位宽。例如[7:0]是 8 位位宽,也就是可以表示成 8’b0 至 8’b1111_1111;
- msb 和 lsb 必须为常数值;
- 如果没有定义范围,缺省值为 1 位;
- 没有定义信号数据类型时,缺省为 wire 类型。
- 注意数组类型按照降序方式,如[7:0] ,不要写成[0:7]
举例:
wire [3:0] Sat; // Sat 为 4 位线型信号
wire Cnt; //1 位线型信号
wire [31:0] Kisp, Pisp, Lisp ;// Kisp, Pisp, Lisp 都是 32 位的线型信号
(3)寄存器类型 reg
reg 是最常用的寄存器类型,寄存器类型通常用于对存储单元的描述(reg不一定是寄存器),如 D 型触发器、ROM等。寄存器类型信号的特点是在某种触发机制下分配了一个值,在下一触发机制到来之前保留原值。
但必须注意的是:**reg 类型的变量不一定是存储单元,如在 always 语句中进行描述的必须是用 reg类型的变量。
reg 类型定义语法如下:
reg [msb: lsb] reg1, reg2, . . . reg N;
- msb 和 lsb 定义了范围,表示了位宽。例如[7:0]是 8 位位宽,也就是可以表示成 8’b0 至
8’b1111_1111
; - msb 和 lsb 必须为常数值;lsb一般为0;
- 如果没有定义范围,缺省值为 1 位;
- 没有定义信号数据类型时,缺省为 wire 类型,不是 reg 型。
- 对数组类型按照降序方式,如[7:0] ;不要写成[0:7]。
例如:
reg [3:0] Sat; // Sat 为 4 位寄存器型信号。
reg Cnt; //1 位寄存器。
reg [31:0] Kisp, Pisp, Lisp ; // Kisp, Pisp, Lisp 都是 32 位的寄存器型信号。
(4)线网型wire与寄存器型reg区别
(如果想不用寄存器就不用reg,用wire,此说法有误)
reg 型信号并不一定生成寄存器。针对什么时候使用 wire 类型,什么时候用 reg 类型这一问题,明德扬课程总结出一套解决方法:在本模块中使用 always 设计的信号都定义为 reg 型,其他信号都定义为 wire 型
举例:(选自明德扬)
always @(posedge clk or negedge rst_n) begin
if (rst_n==0) begin
cnt1 <= 0;
end
else if(add_cnt1) begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1+1 ;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1 == 8-1 ;
如:此案例中,cnt1在always模块中,所以cnt1应该为reg型。add_cnt1 和 end_cnt 不是由 always 产生的,所以定义为 wire 型。