使用case语句有条件地调用模块



我想在sel=0时实现模块加法器,在sel=1时实现模块减法器。我了解到generate可以用于有条件地调用另一个模块中的模块。

3.         module checker(o,a,b,sel);
4.         output reg o;
5.         input a,b,sel;
6.         always@(*)
7.         begin
8.         generate
9.         case (sel)                               
10.        1'b0 : adder a1(.sum(o),.a(a),.b(b));
11.        1'b1 : subtractor s1(.diff(o),.a(a),b(b));
12.        endcase
13.        endgenerate
14.        end
15.        endmodule
        //errors shown are:
    D:/FILES/verilog files/Neha/checker.v" Line 8: Syntax error near "generate".
    D:/FILES/verilog files/Neha/checker.v" Line 11: Port connections cannot be mixed ordered and named.
    D:/FILES/verilog files/Neha/checker.v" Line 13: Syntax error near "endgenerate".
    D:/FILES/verilog files/Neha/checker.v" Line 10: Instantiation is not allowed in sequential area except checker instantiation.
    D:/FILES/verilog files/Neha/checker.v" Line 11: Instantiation is not allowed in sequential area except checker instantiation

提前感谢!

我们在这里设计硬件,而不是编写软件。Verilog module是一块硬件。您不能"调用"Verilog module,就像您可以"调用"PCB上的芯片一样。

您的addersubtractor模块是硬件块。你不能"打电话"给他们。您需要一些硬件(可能是多路复用器)来选择两个输出并驱动o输出:

module checker(o,a,b,sel);
  output /* is this really 1 bit wide?   */ o;
  input  /* are these really 1 bit wide? */ a,b;
  input sel;
  wire   /* are these really 1 bit wide? */ sum, diff;;
  adder      a1(.sum(sum),   .a(a), .b(b));
  subtractor s1(.diff(diff), .a(a), .b(b));
  assign o = sel ? diff : sum;
endmodule

顺便说一句,你的输入和输出肯定超过1位宽吗?

你不能这样做。由于generate块在模拟之前被省略,因此generate中的case需要一个参数或宏。

您可以将sel作为两个模块的输入,并进行相应的操作。

以下是您的模块的外观:

module add_sub(input a,b,sel,output wire [1:0] s);
assign s = (sel) ? (a + b) : (a - b);
endmodule

根据sel,必须执行该操作。

顶部模块简单地实例化了add_sub模块。

module checker(o,a,b,sel);
add_sub a1(.a(a), .b(b), .sel(sel), .s(o));
endmodule

通电时无法动态生成硬件。因此,逻辑必须存在。

如果您想节省门,可以使用单个加法器,而不是一个加法器和一个减法器。根据选择将b值或-b(2的赞美)值传递给它。通过这种方式,您可以节省减法逻辑。请使用以下示例并正确编码。

assign b_final = sel ? b : -b;
assign s = a+ b_final;

最新更新