ALU 的 Verilog HDL 行为编码调用模块

Verilog HDL behavioral coding calling modules for ALU

这是我第一次在 verilog hdl 中编程,我无法弄清楚我的代码有什么问题。我需要在行为代码中设计一个简单的 ALU。

到目前为止,我已经创建了一个减法器和加法器模块。(我需要添加更多模块,但我希望在添加其他模块之前让它们在 ALU 模块中工作)。

我在同一个项目的单独 .v 文件中有以下模块(很确定这是行为?):

module adder3bit( sum, co, a, b);
parameter n = 2;
output reg [n:0] sum;
output reg co;
input [n:0] a;
input [n:0] b;

always @(a, b)
{co, sum} = a + b;

endmodule


module subtract3bit(diff, bo, a, b);
parameter n = 2;
output reg [n:0] diff;
output reg bo;
input [n:0] a;
input [n:0] b;

always @(a, b)
{bo, diff} = a - b;

endmodule

我测试了这些,发现它们在工作。

现在我试图在主 ALU 模块中调用它们:

module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
    adder3bit A1(out,overflow,a,b);
if(sel=='b1)
    subtract3bit S1( out, overflow, a, b);
end
endmodule

我的语法可能有误,但显示错误。我只是非常不熟悉verilog。我感觉我第一次学习 C 的感觉。非常感谢帮助。

我知道它正在正确调用模块,但我认为这与 if 语句有关。

谢谢,希望能学到新东西!

您不能在 verilog 中的 always 块内实例化模块。相反,您可以将模块 adder3bit 和 substract3bit 更改为任务,您可以使用您现在编写的代码。 解决方案将是这样的

task adder3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] sum;
output reg co;
begin
always @(*) {co, sum} = a + b;
endtask


task subtract3bit;
parameter n = 2;
input [n:0] a;
input [n:0] b;
output reg [n:0] diff;
output reg bo;
begin
always @(*) {bo, diff} = a - b;
endtask

module alu( out, overflow, a, b,sel);
input [2:0] a, b;
input sel;
output [2:0] out;
output overflow;
always @(a,b,sel)
begin
if(sel=='b0)
    adder3bit (a,b,out,overflow);
if(sel=='b1)
    subtract3bit ( a,b,out,overflow);
end
endmodule

主要问题是你要调用模块。模块不是您不能调用它们的函数或任务。您可以并且应该对模块做的是在另一个模块(在本例中为 ALU 模块)中实例化它。模块不能在程序块内实例化(e.x。总是在你的代码中)。加法器和减法器都会在其输入的每次更改时产生新结果,因此您只需要正确驱动该模块的输入并读取其输出即可。

我建议您以更具可读性的方式声明模块的端口:

module adder3bit #(
    parameter N = 2
) ( 
   output reg [N:0] sum, 
   output reg co,
   input [N:0] a,
   input [N:0] b
);
    always @(a, b)
        {co, sum} = a + b;

endmodule

在 ALU 中,您可以像这样实例化 adder3bit:

module alu (
    input [2:0] a,
    input [2:0] b,
    input sel,
    output [2:0] out,
    output overflow
)
    localparam SIZE = 3;
    wire [SIZE - 1 : 0] diff;
    wire [SIZE - 1 : 0] sum;
    wire co;
    wire bo;

    adder3bit #( 
       .N(SIZE) 
    ) adder (
       .a(a),
       .b(b),
       .sum(sum),
       .co(co)
    );

    subtract3bit #( 
       .N(SIZE) 
    ) subtractor (
       .a(a),
       .b(b),
       .diff(diff),
       .bo(bo)
    );

    always @(*)
    begin
         if(sel=='b0)
             {out,overflow) = {sum, co};
         if(sel=='b1)
             {out,overflow) = {diff, bo};
    end
endmodule

还有一件事,您的模块具有定义其输入和输出大小的参数,但它的名称表明它固定为三个,这可能会造成混淆。