Verilog数据类型

Verilog数据类型,verilog,fpga,hdl,Verilog,Fpga,Hdl,我正在学习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) bi

我正在学习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_n_gray#(参数n=4)(输入[n-1:0]灰色,输出[n-1:0]bin);
整数i;
始终@(*)
对于(i=0;i>i);
端模
我的问题:

由于
bin[i]
变量位于
@always
块中赋值语句的左侧,该变量不应该声明为
output reg[n-1:0]bin

我认为进程块赋值语句左侧的变量,即
始终
/
初始
应声明为
reg
数据类型

由于bin[i]变量位于“@always”块内赋值语句的左侧,该变量不应该声明为“output reg[n-1:0]bin”吗

是的,至少根据Xilinx XST,它应该需要您所说的
reg
。问题中给出的代码在使用该工具进行合成时出错(并且缺少不相关的分号)

首先,让我们从理解Verilog中的过程块开始(假设我们使用Verilog开发硬件,例如FPGA设计)。程序块是
始终
块(有两种类型,组合块和顺序块),以及我们在此不介绍的其他几种类型的块。首先要知道的是,在程序块中,唯一允许的赋值是那些在左侧有
reg
的赋值

这并不一定意味着将创建一个物理寄存器/触发器。在这种情况下,一个将不会。原因是块声明为
始终@(*)
。该声明意味着该过程是组合的(即非顺序的,没有任何内部状态或时钟信号)。因此,不会创建物理触发器

或者,您可以将程序块声明为
始终@(posedge some_clock_signal)
。这意味着创建了顺序逻辑,可以使用物理触发器(或其他存储方式,如FPGA查找表中的分布式内存)。需要注意的是,您仍然在那里声明为
reg
,但现在您实际上正在创建寄存器

在一种情况下,您可以使用
wire
(或
output
),这是通过连续赋值(例如
assigna=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
模块bin_n_gray#(参数n=4)(输入[n-1:0]灰色,输出[n-1:0]bin);
genvar i;
生成
对于(i=0;i>i);
结束
最终生成
端模
由于bin[i]变量位于“@always”块内赋值语句的左侧,该变量不应该声明为“output reg[n-1:0]bin”吗

是的,至少根据Xilinx XST,它应该需要您所说的
reg
。问题中给出的代码在使用该工具进行合成时出错(并且缺少不相关的分号)

首先,让我们从理解Verilog中的过程块开始(假设我们使用Verilog开发硬件,例如FPGA设计)。程序块是
始终
块(有两种类型,组合块和顺序块),以及我们在此不介绍的其他几种类型的块。首先要知道的是,在程序块中,唯一允许的赋值是那些在左侧有
reg
的赋值

这并不一定意味着将创建一个物理寄存器/触发器。在这种情况下,一个将不会。原因是块声明为
始终@(*)
。该声明意味着该过程是组合的(即非顺序的,没有任何内部状态或时钟信号)。因此,不会创建物理触发器

或者,您可以将程序块声明为
始终@(posedge some_clock_signal)
。这意味着创建了顺序逻辑,可以使用物理触发器(或其他存储方式,如FPGA查找表中的分布式内存)。需要注意的是,您仍然在那里声明为
reg
,但现在您实际上正在创建寄存器

在一种情况下,您可以使用
wire
(或
output
),这是通过连续赋值(例如
assigna=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
模块bin_n_gray#(参数n=4)(输入[n-1:0]灰色,输出[n-1:0]bin);
genvar i;
生成
对于(i=0;i>i);
结束
最终生成
端模

我糊涂了!你能不能简单地解释一下,因为我只是在学这些东西@我很乐意,但不幸的是我现在不能。“如果我在半小时到一小时左右的时间内更新我的答案会有问题吗?你的答案的第一部分似乎是肯定的,应该声明为reg,但第二部分似乎你的说辞很好,”AndyWest说,“一旦我有机会,我会澄清这个措辞。@AndyWest你是对的(我没有注意到)。至少根据我的FPGA工具(Xilinx ISE/XST),它需要是一个
reg
。我现在就在答案编辑中写一个解释