Verilog 中 wire 与 wor 的区别详解

在 Verilog 中,wirewor 都属于线网类型(net type) ,用于表示硬件中的连线。它们最大的区别在于:如何处理多个驱动源同时驱动同一根线的情况


一、核心区别一览

特性 wire wor
全称 wire(普通连线) wired-OR(线或)
多驱动时的行为 多驱动通常导致冲突(X 态) 多驱动按"或"逻辑合并
典型用途 普通信号连接 多源信号合并、open-drain 模拟
可综合性 完全可综合 部分综合工具支持有限,常用于仿真建模
默认值 高阻态 Z 高阻态 Z
属于的类别 普通 net 解决冲突的 net(resolved net)

二、wire 的行为详解

wire 是 Verilog 中最常用的线网类型,只能有一个驱动源 。如果有多个驱动源同时驱动 wire,结果是不确定的(X 态)。

示例 1:wire 单驱动(正常情况)

复制代码
module wire_demo (
    input  wire a,
    input  wire b,
    output wire y
);
    // wire 由 assign 单驱动,正常工作
    assign y = a & b;
endmodule

仿真行为: y 正确反映 a & b 的结果。


示例 2:wire 多驱动(冲突导致 X)

复制代码
module wire_conflict (
    input  wire a,
    input  wire b,
    output wire y
);
    // ⚠️ 两个 assign 同时驱动 y,发生冲突
    assign y = a;
    assign y = b;
endmodule

仿真行为:

  • a=1, b=0 时,y = X(冲突)
  • a=0, b=1 时,y = X(冲突)
  • a=b 时,y 才有确定值

这就是 wire 的限制:不能合并多个驱动源。


三、wor 的行为详解

wor 允许多个驱动源同时驱动一根线,多驱动的结果按**"或"逻辑**合并。这种特性来自早期硬件的"线或"总线(用 open-collector 输出 + 上拉电阻实现)。

wor 的真值表

驱动 1 驱动 2 wor 结果
0 0 0
0 1 1
1 0 1
1 1 1
0 Z 0
1 Z 1
Z Z Z
X 任意 X

示例 3:wor 多驱动(按 OR 合并)

复制代码
module wor_demo (
    input  wire a,
    input  wire b,
    input  wire c,
    output wor  y    // 注意:用 wor 而非 wire
);
    // 三个驱动源同时驱动 y,按 OR 合并
    assign y = a;
    assign y = b;
    assign y = c;

    // 等价于 assign y = a | b | c;
endmodule

仿真行为:

  • a=0, b=0, c=0y = 0
  • a=1, b=0, c=0y = 1
  • a=0, b=1, c=1y = 1
  • 任何一个为 1,y 都是 1

示例 4:wor 模拟多模块共享中断总线

这是 wor 最经典的应用场景------多个外设共享一根中断线。

复制代码
module interrupt_bus (
    input  wire irq_uart,    // UART 中断
    input  wire irq_timer,   // 定时器中断
    input  wire irq_gpio,    // GPIO 中断
    output wor  irq_to_cpu   // 合并后的中断信号到 CPU
);
    // 多个中断源通过 wor 合并:任意一个为 1,CPU 就收到中断
    assign irq_to_cpu = irq_uart;
    assign irq_to_cpu = irq_timer;
    assign irq_to_cpu = irq_gpio;
endmodule

硬件含义: 模拟早期处理器中"中断线或"的设计,任何一个外设拉高中断线,CPU 都能感知到。


示例 5:wor 在 testbench 中的对比测试

复制代码
`timescale 1ns/1ps
module tb_wire_vs_wor;
    reg a, b;
    wire y_wire;
    wor  y_wor;

    // 同样的多驱动场景,分别用 wire 和 wor
    assign y_wire = a;
    assign y_wire = b;

    assign y_wor = a;
    assign y_wor = b;

    initial begin
        $monitor("Time=%0t a=%b b=%b | y_wire=%b y_wor=%b",
                 $time, a, b, y_wire, y_wor);

        a = 0; b = 0; #10;   // y_wire=0   y_wor=0
        a = 1; b = 0; #10;   // y_wire=X   y_wor=1
        a = 0; b = 1; #10;   // y_wire=X   y_wor=1
        a = 1; b = 1; #10;   // y_wire=1   y_wor=1
        $finish;
    end
endmodule

仿真输出(关键差异):

复制代码
Time=0   a=0 b=0 | y_wire=0 y_wor=0
Time=10  a=1 b=0 | y_wire=x y_wor=1   ← wire 冲突变 X,wor 正确为 1
Time=20  a=0 b=1 | y_wire=x y_wor=1   ← wire 冲突变 X,wor 正确为 1
Time=30  a=1 b=1 | y_wire=1 y_wor=1

四、wor 的"近亲":其他 resolved net 类型

Verilog 还有几个类似的"解决冲突"线网类型,理解它们有助于全面把握:

类型 多驱动合并逻辑 典型应用
wor / trior OR(按位或) 中断总线、状态合并
wand / triand AND(按位与) open-drain I2C 总线、共享请求线
tri 同 wire,但强调三态 双向总线
tri0 无驱动时下拉为 0 模拟带下拉电阻的信号
tri1 无驱动时上拉为 1 模拟带上拉电阻的信号
trireg 保持上次驱动的值 模拟电容性总线

对比示例:wand 模拟 I2C 总线

复制代码
module i2c_bus_demo (
    input  wire master_sda,   // 主机 SDA
    input  wire slave1_sda,   // 从机 1 SDA
    input  wire slave2_sda,   // 从机 2 SDA
    output wand sda           // I2C 数据线(线与)
);
    // I2C 总线是 open-drain,任何一个拉低就为低
    assign sda = master_sda;
    assign sda = slave1_sda;
    assign sda = slave2_sda;
endmodule

真值表: 任何一个为 0,结果就是 0;全部为 1,结果才是 1。这就是 I2C "线与"的硬件本质。


五、实际使用建议

✅ 使用 wire 的场景(99% 的情况)

  • 普通信号连接、模块端口
  • 任何只有一个驱动源的信号
  • RTL 设计中默认就用 wire

⚠️ 使用 wor 的场景(特殊情况)

  • 行为级建模、抽象建模、TLM 模型
  • 仿真早期阶段模拟多源合并
  • 教学或特殊验证场景

❌ 不推荐使用 wor 的场景

  • 可综合 RTL 设计中尽量避免 wor

    • 大多数综合工具对 wor/wand 支持有限或会发出警告
    • 现代设计推荐显式写出 OR 逻辑,更清晰、更可移植
  • 推荐写法:

    // ❌ 不推荐:用 wor 隐式合并
    output wor irq;
    assign irq = irq_a;
    assign irq = irq_b;
    assign irq = irq_c;

    // ✅ 推荐:显式 OR 逻辑
    output wire irq;
    assign irq = irq_a | irq_b | irq_c;


六、一句话总结

类型 一句话概括
wire 普通连线,只能单驱动,多驱动会冲突变 X
wor "线或"连线,多个驱动按 OR 合并,仿真建模用,RTL 设计建议显式写 OR 替代

口诀: wire 单驱动,wor 多驱动按或合并,RTL 设计尽量用 wire + 显式逻辑。

相关推荐
GateWorld1 天前
LCD显示技术完全指南:原理·制造·驱动·FPGA实现之点屏五 miniLVDS
fpga开发·lcd显示·fpga点亮屏幕·minilvds
nuoxin1141 天前
WILX1200HC-5TG144I替代 LCMXO2-1200HC-5TG144I(富利威)
人工智能·嵌入式硬件·fpga开发·电脑·硬件工程·dsp开发
Bahair_2 天前
【FPGA】使用fdatool设计滤波器系数,使用FIR Compiler导入系数联合滤波
fpga开发
qq_411262422 天前
硬件是ESP32-P4连接LAN8720A,正常初始化之后,设备DHCP失败
stm32·单片机·fpga开发
第二层皮-合肥2 天前
【数据采集专栏】时钟同步(有时钟卡方案)
fpga开发
XINVRY-FPGA2 天前
XCKU035-2FBVA676I AMD Xilinx Kintex UltraScale FPGA
arm开发·嵌入式硬件·网络安全·fpga开发·硬件工程·信号处理·fpga
米琪脆脆屋2 天前
0-1学习FPGA之底层资源——LUT
fpga开发·fpga
TTGGGFF2 天前
ModelSim SE 10.1c 超详细安装与激活保姆级教程(图文详解 2026 仅供学习)
学习·fpga开发
Aaron15882 天前
无人机反制中AOA+TDOA联合定位技术与雷达探测定位技术的应用对比分析
arm开发·嵌入式硬件·fpga开发·硬件工程·无人机·信息与通信·信号处理