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