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}});