在 Verilog 中,tri 是一种三态网络数据类型,用于模拟多驱动源的总线连接。
一、基本特性
-
tri表示一个三态信号,可以同时被多个源驱动 -
是
wire的别名,两者在功能上完全相同 -
主要用于提高代码可读性,表示多驱动场景
二、语法和用法
tri [msb:lsb] signal_name;
三、示例说明
1、基本用法
module tri_example;
tri data_bus; // 三态信号
reg drive_a, drive_b;
reg data_a, data_b;
// 多个驱动源
assign data_bus = drive_a ? data_a : 1'bz;
assign data_bus = drive_b ? data_b : 1'bz;
initial begin
$monitor("Time=%0t, drive_a=%b, data_a=%b, drive_b=%b, data_b=%b, data_bus=%b",
$time, drive_a, data_a, drive_b, data_b, data_bus);
// 初始状态:无驱动
drive_a = 0; drive_b = 0;
data_a = 0; data_b = 0;
#10;
// 只有 A 驱动
drive_a = 1; data_a = 1;
#10;
// 只有 B 驱动
drive_a = 0;
drive_b = 1; data_b = 0;
#10;
// 冲突:A 和 B 同时驱动
drive_a = 1; data_a = 1;
drive_b = 1; data_b = 0;
#10;
$finish;
end
endmodule
四、典型应用场景
1. 总线仲裁
module bus_controller;
tri [15:0] system_bus;
reg [15:0] cpu_data, mem_data, io_data;
reg cpu_sel, mem_sel, io_sel;
// 多个主设备共享总线
assign system_bus = cpu_sel ? cpu_data : 16'bz;
assign system_bus = mem_sel ? mem_data : 16'bz;
assign system_bus = io_sel ? io_data : 16'bz;
// 总线监控
always @(system_bus) begin
$display("Bus value changed to: %h", system_bus);
end
endmodule
2. 双向数据总线
module bidirectional_bus;
tri [7:0] data_bus;
reg [7:0] tx_data;
wire [7:0] rx_data;
reg direction; // 0:输入, 1:输出
// 双向驱动
assign data_bus = direction ? tx_data : 8'bz;
assign rx_data = data_bus;
initial begin
direction = 0; // 输入模式
#20;
direction = 1; // 输出模式
tx_data = 8'hA5;
end
endmodule
3. 多处理器系统
module multi_processor;
tri [31:0] shared_memory_bus;
reg [31:0] proc1_data, proc2_data, proc3_data;
reg [2:0] bus_grant;
// 处理器总线访问
assign shared_memory_bus = (bus_grant[0]) ? proc1_data : 32'bz;
assign shared_memory_bus = (bus_grant[1]) ? proc2_data : 32'bz;
assign shared_memory_bus = (bus_grant[2]) ? proc3_data : 32'bz;
// 总线仲裁逻辑
always @(*) begin
if (bus_grant > 1) begin
$display("Warning: Multiple bus drivers detected!");
end
end
endmodule
五、冲突处理规则
当多个驱动源同时有效时:
-
相同值:总线取该值
-
不同值:产生冲突,结果为
X(未知) -
高阻态:被忽略,不影响其他驱动
module conflict_example;
tri bus;
reg drive1, drive2;
assign bus = drive1 ? 1'b1 : 1'bz;
assign bus = drive2 ? 1'b0 : 1'bz;
initial begin
// 情况1: 无冲突
drive1 = 1; drive2 = 0; // bus = 1
#10;
// 情况2: 冲突
drive1 = 1; drive2 = 1; // bus = X (冲突)
#10;
// 情况3: 高阻态
drive1 = 0; drive2 = 0; // bus = Z
#10;
end
endmodule
六、与 wire 的区别
| 特性 | tri | wire |
|---|---|---|
| 语法功能 | 完全相同 | 完全相同 |
| 语义含义 | 强调多驱动 | 一般连线 |
| 可读性 | 总线场景更清晰 | 普通连接 |
// 这两种声明是等价的 tri bus_signal; wire bus_signal; // 与上一行完全相同
七、注意事项
-
仿真行为:冲突时会产生
X,需要设计仲裁逻辑 -
综合实现:会被映射到实际的三态缓冲器
-
代码规范:使用
tri可以提高总线相关代码的可读性 -
验证重点:需要测试多驱动场景下的行为
tri 类型在总线设计、双向接口和多模块通信中非常有用,能够清晰地表达设计意图。
8499

被折叠的 条评论
为什么被折叠?



