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

时间:2016-10-06 03:58:38

标签: overflow verilog hdl 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语句有关。

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

2 个答案:

答案 0 :(得分:2)

主要问题是你想要调用模块。模块不是您无法调用的功能或任务。您可以和应该对模块执行的操作是在另一个模块(在本例中为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

还有一件事,你的模块有参数,它定义了输入和输出的大小,但是它的名字表明它固定为3,这可能会造成混淆。

答案 1 :(得分:0)

您无法在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