Verilog 数据类型
Verilog data types
我正在学习 verilog 作为我大学课程的一部分,但是我的模块讲师离开了,所以我希望在这里得到一些帮助,
我们已经给出了一个参数化的n位灰度到二进制代码转换器的例子,如下:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
integer i;
always @ (*)
for(i = 0; i < n; i = i+1)
bin[i] = ^(gray >> i);
endmodule
我的问题:
由于 bin[i]
变量位于 @ always
块中赋值语句的左侧,难道不应该将此变量声明为 output reg [n-1 : 0] bin
吗?
正如我认为进程块赋值语句左侧的变量,即 always
/ initial
应该声明为 reg
数据类型?
As the bin[i] variable is on the left hand side of an assignment statement within an '@ always' block shouldn't this variable be declared as 'output reg [n-1 : 0] bin?
是的,如您所说,它应该需要 reg
,至少根据 Xilinx XST。使用该工具进行综合时,问题中给出的代码出错(并且缺少不相关的分号)。
首先让我们首先了解 Verilog 中的过程块到底是什么(假设我们使用 Verilog 开发硬件,例如 FPGA 设计)。程序块是 always
块(两种类型,组合和顺序)以及我们不会在此处介绍的其他几种类型的块。首先要知道的是 在程序块中,唯一允许的赋值是那些在左侧有 reg
的赋值。
这并不一定意味着会创建实体 register/flipflop。在这种情况下,一个不会。原因是块声明为 always @ (*)
。这个声明意味着这个过程是组合的(即不是顺序的,没有任何内部状态或时钟信号)。结果,没有创建物理触发器。
或者,您可以将程序块声明为 always @ (posedge some_clock_signal)
。这意味着创建了顺序逻辑,并且可以使用物理触发器(或其他存储方式,例如 FPGA 查找表中的分布式存储器)。要点是你仍然在那里声明 reg
,但现在你实际上是在创建寄存器。
有一种情况是用wire
(或者output
),就是连续赋值(比如assign a = b & c
), 它落在程序块之外。在此示例中,我使用 generate
来执行与原始代码中的循环相同的操作:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
genvar i;
generate
for (i=0; i < n; i=i+1)
begin: graydecoder // arbitrary label needed by generate syntax
assign bin[i] = ^(gray >> i);
end
endgenerate
endmodule
我正在学习 verilog 作为我大学课程的一部分,但是我的模块讲师离开了,所以我希望在这里得到一些帮助,
我们已经给出了一个参数化的n位灰度到二进制代码转换器的例子,如下:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
integer i;
always @ (*)
for(i = 0; i < n; i = i+1)
bin[i] = ^(gray >> i);
endmodule
我的问题:
由于 bin[i]
变量位于 @ always
块中赋值语句的左侧,难道不应该将此变量声明为 output reg [n-1 : 0] bin
吗?
正如我认为进程块赋值语句左侧的变量,即 always
/ initial
应该声明为 reg
数据类型?
As the bin[i] variable is on the left hand side of an assignment statement within an '@ always' block shouldn't this variable be declared as 'output reg [n-1 : 0] bin?
是的,如您所说,它应该需要 reg
,至少根据 Xilinx XST。使用该工具进行综合时,问题中给出的代码出错(并且缺少不相关的分号)。
首先让我们首先了解 Verilog 中的过程块到底是什么(假设我们使用 Verilog 开发硬件,例如 FPGA 设计)。程序块是 always
块(两种类型,组合和顺序)以及我们不会在此处介绍的其他几种类型的块。首先要知道的是 在程序块中,唯一允许的赋值是那些在左侧有 reg
的赋值。
这并不一定意味着会创建实体 register/flipflop。在这种情况下,一个不会。原因是块声明为 always @ (*)
。这个声明意味着这个过程是组合的(即不是顺序的,没有任何内部状态或时钟信号)。结果,没有创建物理触发器。
或者,您可以将程序块声明为 always @ (posedge some_clock_signal)
。这意味着创建了顺序逻辑,并且可以使用物理触发器(或其他存储方式,例如 FPGA 查找表中的分布式存储器)。要点是你仍然在那里声明 reg
,但现在你实际上是在创建寄存器。
有一种情况是用wire
(或者output
),就是连续赋值(比如assign a = b & c
), 它落在程序块之外。在此示例中,我使用 generate
来执行与原始代码中的循环相同的操作:
module bin_n_gray #(parameter n=4) (input [n-1 : 0] gray, output [n-1 : 0] bin);
genvar i;
generate
for (i=0; i < n; i=i+1)
begin: graydecoder // arbitrary label needed by generate syntax
assign bin[i] = ^(gray >> i);
end
endgenerate
endmodule