Verilog 中的模块:输出 reg 与将 reg 分配给线输出

Modules in Verilog: output reg vs assign reg to wire output

假设 module_a 中有 register_a,需要链接到 module_bregister_a 是否应该单独声明并分配给 module_a:

的输出
reg register_a;
assign output_a = register_a;

还是我们应该在模块声明中用 reg 内联声明 output_a 并在代码中使用它?

我假设您正在寻找这样的东西:

module module_b (...);
    ....
    module_a foo (.output_a(some_wire),
                  ...);
endmodule

如果是这样,那没关系——两个版本将产生相同的结果电路。

第一种方法确实有一些优点,即您可以根据需要对输出进行门控(类似于 assign output_a = valid ? register_a : 0;),并且如果定义了接口,则可以在内部使用您选择的名称适合您(例如预设引脚映射)。

如果您没有尝试执行上述操作,那么这可能不是真的。

我读到应该始终记录输出。也就是说 module_a 有一个名为 output_a 的输出。这是一种行为代码风格与顺序代码风格。的确,您可以通过任何一种方式创建相同的硬件,但我认为您的问题的答案是您应该将输出声明为 reg。

所以模块声明应该是这样的:

module module_a (output reg output_a);
....
output_a <= "some value"
endmodule

我想你问的是以下两者的区别:

module my_dff (output reg q, input clk, d); //None Blocking style
  always @(posedge clk) begin
    q <= d;
  end
endmodule

module my_dff (output q, input clk, d);
  reg reg_q;
  assign q = reg_q; // Blocking style
  always @(posedge clk) begin
    reg_q <= d;
  end
endmodule

两者之间在功能上没有区别。这主要是一种编码偏好。有很多模拟器不强制输入和输出的方向性,所以如果不小心有两个模块驱动同一个网络,这些模拟器 X 可以将 X 传播到 output reg 的寄存器。这种情况很少见,大多数模拟器(尤其是主流模拟器)都没有这个问题。

我个人更喜欢output reg,主要是代码行数少。

无论输出类型如何声明,当您实例化模块时,输出需要连接到网络类型(例如wire),而不是reg。输入可以是任何一种类型。

module fifo(output out, input clk, in);
  wire q0;
  reg q1;
  my_dff dff0 ( q0, clk, in );
  always @(posedge clk) begin
    q1 <= q0;
  end
  my_dff dff1 ( out, clk, q1 );
endmodule