Verilog 调用其他模块的最佳方式是什么?

Verilog 调用其他模块的最佳方式是什么?,verilog,Verilog,我对连接感到困惑,我想使用ALU调用RippleCarry模块,我需要执行分支,而不总是执行块和过程分配 我不知道什么方法最好。我看到其他人在TestBench.v或ALU.v中编写过 这是我的密码 铝钒 涟漪阵 module RippleCarry( input [31:0] a, b, input Cin, output Cout, output [31:0] Sum ); 在verilog中,不调用模块,而是实例化模块。与传统编程不同,verilog是一种硬件描述

我对连接感到困惑,我想使用
ALU
调用
RippleCarry
模块,我需要执行分支,而不总是执行块和过程分配

我不知道什么方法最好。我看到其他人在
TestBench.v
ALU.v
中编写过

这是我的密码

铝钒

涟漪阵

module RippleCarry(
  input  [31:0] a, b,
  input Cin,
  output Cout,
  output [31:0] Sum
);
  

在verilog中,不调用模块,而是实例化模块。与传统编程不同,verilog是一种硬件描述语言;这意味着它是描述硬件的代码,而不是像在典型编程语言中那样指定由cpu运行的指令。当信号具有不同的值时,硬件不会具体化和非具体化;控制信号仅定义输入和输出之间连接的许多不同数据路径中的哪一条

在你的情况下,你不会写这样的东西:

module ALU(...)
  if (Signal == 6'd35) begin
    RippleCarry RC(...);
  end
endmodule
由于
信号
是一条随着硬件运行而改变值的控制线,这意味着当
信号
为35时,纹波进位加法器存在,而当它不存在时,纹波进位加法器消失

相反,加法器应该被实例化,它存在于设计中并且总是存在。现在的问题是,仅当
信号
为35时,才将其输出定向到ALU的输出

module ALU(input [5:0] Signal,
  input [31:0] a, b,
  output reg [31:0] Output); // Note, I made Output a reg so I can use always, it doesn't mean it's actually a register

  wire [31:0] rcOutput;

  // Instantiate the RC adder so it exists in the hardware
  RippleCarry RC(.a(a), .b(b), .Sum(rcOutput));

  // Direct the output of the RippleCarry adder to the output only when signal is 35, otherwise just leave it at 0.
  // Use switch here to make it easy to add more operations later
  always @(*) begin
    Output = 32'd0; // default

    case (Signal)
      6'd35: Output = rcOutput; // rc add
    endcase
  end
endmodule
编辑:我知道你现在不想使用
始终
分配
,这不会改变基本设计,但会使其更加模糊和不可扩展,这就是为什么我将以上内容作为参考。在信号只有一个操作码的情况下,我们可以简单地实现将信号与35进行比较的逻辑,如果门不相等,则屏蔽输出:

// Replace the always block with the below, though it's certainly not as nice, it's a possible implementation of that always block in gates
wire [5:0] SignalN;
wire SignalIs35;
not g1[5:0](SignalN, Signal);
// 35 is 100011 in binary, so see if Signal is that value
and g2(SignalIs35, Signal[5], SignalN[4], SignalN[3], SignalN[2], Signal[1], Signal[0]);
and g3[31:0](Output, rcOutput, {32{SignalIs35}});

为什么需要在ALU中添加
wire[31:0]rcOuput
?我认为它可以使用
RippleCarry RC(.a(a),.b(b),.Sum(输出))
。如果使用
.Sum(Output)
,则纹波进位加法器的输出直接连接到ALU的输出,并且当
信号
不是35时,无法屏蔽其输出。在编写Verilog时,您需要设想您正在描述的硬件;它不是顺序执行的代码,而是定义的“物理”结构。为了完整性,我确实想提到,如果您将
Output
声明为
wand
而不是
wire
,那么您可以只使用
RippleCarry RC(.a(a),.b(b),.Sum(Output))只要当
信号
为35时,您也将
输出
分配给所有的1,当它不为35时,也将其分配给所有的0(
分配输出={32{Signal=='d35}
也在ALU中)。然而,我不会说这是一个好的方法,也不记得大多数合成工具是否能处理它(特别是对于FPGA,它可能只是做了我在上述解决方案中所做的事情)Ok。非常感谢你!
// Replace the always block with the below, though it's certainly not as nice, it's a possible implementation of that always block in gates
wire [5:0] SignalN;
wire SignalIs35;
not g1[5:0](SignalN, Signal);
// 35 is 100011 in binary, so see if Signal is that value
and g2(SignalIs35, Signal[5], SignalN[4], SignalN[3], SignalN[2], Signal[1], Signal[0]);
and g3[31:0](Output, rcOutput, {32{SignalIs35}});