# 如何用Verilog Basics設計一個仲裁器
## 1. 仲裁器概述
### 1.1 什么是仲裁器
仲裁器(Arbiter)是數字系統中用于管理多個主設備(Master)共享同一資源(如總線、存儲器等)的電路模塊。其主要功能是:
- 接收來自多個主設備的請求信號
- 根據預設的優先級策略選擇一個主設備
- 授予選中的主設備訪問權限
### 1.2 典型應用場景
- 多處理器系統中的總線仲裁
- 存儲控制器中的訪問權限管理
- 網絡交換機的端口仲裁
- AXI總線中的事務調度
## 2. 仲裁器設計基礎
### 2.1 基本接口信號
```verilog
module arbiter (
input wire clk,
input wire rst_n,
input wire [N-1:0] req, // N個請求信號
output reg [N-1:0] grant // N個授權信號
);
| 策略類型 | 特點 | 適用場景 |
|---|---|---|
| 固定優先級 | 簡單但可能饑餓 | 實時性要求高的系統 |
| 輪詢(Round-Robin) | 公平性好 | 通用計算系統 |
| 時間片 | 保證帶寬分配 | 多媒體處理系統 |
| 混合策略 | 結合多種優點 | 復雜SoC系統 |
module fixed_priority_arbiter #(
parameter N = 4
)(
input wire [N-1:0] req,
output reg [N-1:0] grant
);
always @(*) begin
grant = 0;
for (int i = 0; i < N; i++) begin
if (req[i]) begin
grant[i] = 1;
break; // 固定優先級:低索引優先
end
end
end
endmodule
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
grant <= 0;
end else if (|req) begin
for (int i = 0; i < N; i++) begin
if (req[i] && !grant) begin
grant <= (1 << i);
break;
end
end
end else begin
grant <= 0;
end
end
module round_robin_arbiter #(
parameter N = 4
)(
input wire clk,
input wire rst_n,
input wire [N-1:0] req,
output reg [N-1:0] grant
);
reg [N-1:0] last_grant;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
grant <= 0;
last_grant <= 1; // 初始指向設備0
end else begin
grant <= 0;
for (int i = 0; i < N; i++) begin
int idx = (last_grant + i) % N;
if (req[idx]) begin
grant[idx] <= 1;
last_grant <= (1 << idx);
break;
end
end
end
end
endmodule
// 使用優先級編碼器優化
wire [N-1:0] masked_req = req & ~((last_grant - 1) | last_grant);
wire [N-1:0] unmasked_grant = masked_req ? masked_req : req;
always @(posedge clk) begin
if (|unmasked_grant) begin
last_grant <= unmasked_grant & -unmasked_grant;
end
grant <= unmasked_grant;
end
module weighted_arbiter #(
parameter N = 4,
parameter W = 8
)(
input wire clk,
input wire rst_n,
input wire [N-1:0] req,
input wire [N*W-1:0] weights,
output reg [N-1:0] grant
);
reg [W-1:0] counters[N];
reg [W-1:0] max_counter;
reg [N-1:0] max_idx;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
// 初始化代碼...
end else begin
// 更新計數器邏輯
for (int i = 0; i < N; i++) begin
if (req[i]) begin
counters[i] <= counters[i] + weights[i*W +: W];
end
end
// 選擇邏輯
max_counter = 0;
max_idx = 0;
for (int i = 0; i < N; i++) begin
if (req[i] && counters[i] > max_counter) begin
max_counter = counters[i];
max_idx = i;
end
end
grant <= (1 << max_idx);
counters[max_idx] <= counters[max_idx] - max_counter;
end
end
// 第一級仲裁
fixed_priority_arbiter #(.N(4)) fp_arb (
.req(high_priority_req),
.grant(high_priority_grant)
);
// 第二級仲裁
round_robin_arbiter #(.N(8)) rr_arb (
.clk(clk),
.rst_n(rst_n),
.req(low_priority_req),
.grant(low_priority_grant)
);
// 最終授權選擇
assign grant = |high_priority_grant ? high_priority_grant : low_priority_grant;
module arbiter_tb;
reg clk, rst_n;
reg [3:0] req;
wire [3:0] grant;
// 實例化DUT
round_robin_arbiter #(.N(4)) dut (
.clk(clk), .rst_n(rst_n),
.req(req), .grant(grant)
);
// 時鐘生成
always #5 clk = ~clk;
initial begin
// 測試用例...
end
endmodule
initial begin
// 初始化
clk = 0; rst_n = 0; req = 0;
#10 rst_n = 1;
// 測試1:單請求
req = 4'b0001;
#10 check_grant(4'b0001);
// 測試2:多請求輪詢
req = 4'b1101;
repeat(8) begin
#10;
$display("Grant: %b", grant);
req = req ^ grant; // 切換請求
end
// 其他測試...
$finish;
end
// 第二階段:仲裁決策 always @(posedge clk) grant <= next_grant;
2. **并行優先級編碼**:使用并行結構替代串行搜索
```verilog
wire [3:0] pri_enc = {
req[3],
!req[3] & req[2],
!req[3] & !req[2] & req[1],
!req[3] & !req[2] & !req[1] & req[0]
};
module arbiter #(
parameter N = 4,
parameter TYPE = "ROUND_ROBIN"
)(
// 接口...
);
generate
if (TYPE == "FIXED") begin
// 固定優先級實現
end else begin
// 輪詢實現
end
endgenerate
endmodule
對異步請求信號進行同步處理:
reg [N-1:0] req_sync0, req_sync1;
always @(posedge clk) begin
req_sync0 <= req_async;
req_sync1 <= req_sync0;
end
使用握手協議確保穩定傳輸
設置最大授權時間
reg [7:0] timeout;
always @(posedge clk) begin
if (|grant) begin
timeout <= timeout + 1;
if (timeout > 100) grant <= 0;
end else begin
timeout <= 0;
end
end
實現超時強制釋放機制
本文詳細介紹了使用Verilog設計仲裁器的基本方法和高級技巧。關鍵要點包括: 1. 根據系統需求選擇合適的仲裁策略 2. 使用參數化設計提高代碼復用性 3. 完善的驗證是確??煽啃缘年P鍵 4. 時序和面積的平衡需要根據應用場景權衡
通過靈活組合這些技術,可以設計出適應各種應用場景的高效仲裁器。
[GitHub倉庫鏈接] | [EDA Playground示例] “`
注:本文實際約2300字,保留了擴展空間。您可以通過以下方式進一步擴展: 1. 增加更多實現變體(如TDM仲裁器) 2. 添加更詳細的時序圖 3. 補充形式驗證方法 4. 添加FPGA實現結果 5. 擴展AXI仲裁器具體案例
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。