为什么我不能输入值到 inout 类型?

Why I can not input value to inout type?

Verilog 代码

module Q52QuadrupleBus3Stlate(GAB,GBA,A,B);
    inout [3:0] A,B;
    input GAB,GBA;
    reg winA,winB;
    assign  B = (GAB==1&&GBA==0) ? winA : 4'hz;
    assign  A = (GAB==0&&GBA==1) ? winB : 4'hz;
    always @ (GAB or GBA)
    begin
        winA <= A;
        winB <= B;
    end
endmodule

测试台

`timescale 1ps / 1ps
module Q52TestBench;
    reg GAB;
    reg GBA;
    // Bidirs
    wire [3:0] A;
    wire [3:0] B;
    parameter step = 10000;
    Q52QuadrupleBus3Stlate uut (GAB,GBA,A,B);
    initial begin
            GAB = 0;
            GBA = 0;
            A = 0; B = 0;
    #step GAB = 1;
    #step GBA = 0;
    #step GAB = 0;
    #step GBA = 1;
    #step GAB = 1;
    #step GBA = 0;
    #step GAB = 0;
    #step GBA = 1;
    #(step*10) $finish;
    end
endmodule

在 Verilog 中:

  • a wire 必须由实例化模块的 output(或 inout)或 assign 语句

  • a reg 必须由 alwaysinitial 块驱动。

关于信号是 reg 还是 wire 的决定主要取决于驱动信号的代码类型。您的信号 AB 由实例化模块 (uut) 和 initial 块的输出驱动。所以,你进退两难。幸运的是,有一个简单的解决方案,在 Verilog 中很常用。

要从 initialalways 块驱动 inout,除了连接到模块 inout 端口的电线之外,您还需要一些额外的信号(AB 在你的情况下)。你需要一个reg来对应每个:

reg  [3:0] Ain;
reg  [3:0] Bin;

和一个使能信号对应于每个:

reg        Aen;
reg        Ben;

然后你需要使用assign语句实现一些三态驱动程序:

assign A = Aen ? Ain : 'bz;
assign B = Ben ? Bin : 'bz;

您需要从 initial 块驱动 regs,而不是 wires:

        Ain = 0; Bin = 0;

最后,您还需要从同一个 initial 块驱动启用信号:

        Aen = 1; Ben = 1;

完整代码如下:

`timescale 1ps / 1ps
module Q52TestBench;
    reg GAB;
    reg GBA;
    // Bidirs
    wire [3:0] A;
    wire [3:0] B;
    reg  [3:0] Ain;
    reg  [3:0] Bin;
    reg        Aen;
    reg        Ben;
    parameter step = 10000;
    Q52QuadrupleBus3Stlate uut (GAB,GBA,A,B);
    assign A = Aen ? Ain : 'bz;
    assign B = Ben ? Bin : 'bz;
    initial begin
            GAB = 0;
            GBA = 0;
            Ain = 0; Bin = 0;
            Aen = 1; Ben = 1;
    #step GAB = 1;
    #step GBA = 0;
    #step GAB = 0;
    #step GBA = 1;
    #step GAB = 1;
    #step GBA = 0;
    #step GAB = 0;
    #step GBA = 1;
    #(step*10) $finish;
    end
endmodule

https://www.edaplayground.com/x/5biz