`include "e203_defines.v"
module e203_biu_5stage_arbiter (
input logic clk, rst_n,
// IFU
input logic ifu_req_valid, output logic ifu_req_ready,
input logic [`E203_PC_SIZE-1:0] ifu_req_addr,
output logic [31:0] ifu_rsp_data, output logic ifu_rsp_valid, input logic ifu_rsp_ready,
// LSU
input logic lsu_req_valid, output logic lsu_req_ready,
input logic [`E203_PC_SIZE-1:0] lsu_req_addr,
input logic lsu_req_rw, input logic [31:0] lsu_req_wdata, input logic [3:0] lsu_req_wmask,
output logic [31:0] lsu_rsp_rdata, output logic lsu_rsp_valid, input logic lsu_rsp_ready,
// ICB
output logic icb_cmd_valid, input logic icb_cmd_ready,
output logic [`E203_PC_SIZE-1:0] icb_cmd_addr, output logic icb_cmd_read,
output logic [31:0] icb_cmd_wdata, output logic [3:0] icb_cmd_wmask,
input logic icb_rsp_valid, output logic icb_rsp_ready,
input logic [31:0] icb_rsp_rdata, input logic icb_rsp_err,
// 地址窗口
input logic [31:0] addr_itcm_base, addr_itcm_mask,
input logic [31:0] addr_dtcm_base, addr_dtcm_mask,
input logic [31:0] addr_sys_base, addr_sys_mask
);
// 阶段1:组合地址解码
wire ifu_hit_itcm = (ifu_req_addr & ~addr_itcm_mask) == (addr_itcm_base & ~addr_itcm_mask);
wire ifu_hit_sys = (ifu_req_addr & ~addr_sys_mask) == (addr_sys_base & ~addr_sys_mask);
wire ifu_hit_ext = ~ifu_hit_itcm & ~ifu_hit_sys;
wire lsu_hit_dtcm = (lsu_req_addr & ~addr_dtcm_mask) == (addr_dtcm_base & ~addr_dtcm_mask);
wire lsu_hit_sys = (lsu_req_addr & ~addr_sys_mask) == (addr_sys_base & ~addr_sys_mask);
wire lsu_hit_ext = ~lsu_hit_dtcm & ~lsu_hit_sys;
// 阶段2:仲裁
wire lsu_urgent = lsu_req_valid & lsu_req_rw & lsu_hit_ext;
wire sel_ifu = ifu_req_valid & ~lsu_urgent;
wire sel_lsu = lsu_req_valid & ~sel_ifu;
// 阶段3:命令发射
assign icb_cmd_valid = sel_ifu | sel_lsu;
assign icb_cmd_addr = sel_ifu ? ifu_req_addr : lsu_req_addr;
assign icb_cmd_read = sel_ifu | ~lsu_req_rw;
assign icb_cmd_wdata = lsu_req_wdata;
assign icb_cmd_wmask = sel_ifu ? 4'b0000 : lsu_req_wmask;
assign ifu_req_ready = sel_ifu & icb_cmd_ready;
assign lsu_req_ready = sel_lsu & icb_cmd_ready;
// 阶段4:1-entry FIFO 追踪(防碰撞 + 零延迟旁路)
reg rsp_vld_q, rsp_is_ifu_q;
reg [31:0] rsp_addr_q;
wire cmd_fire = icb_cmd_valid & icb_cmd_ready;
wire rsp_fire = icb_rsp_valid & icb_rsp_ready;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) rsp_vld_q <= 1'b0;
else case ({cmd_fire, rsp_fire})
2'b00: ;
2'b01: rsp_vld_q <= 1'b0;
2'b10: rsp_vld_q <= 1'b1;
2'b11: rsp_vld_q <= 1'b1; // 新事务顶替旧事务,FIFO保持满
endcase
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
rsp_is_ifu_q <= 1'b0;
rsp_addr_q <= 32'b0;
end else if (cmd_fire) begin
rsp_is_ifu_q <= sel_ifu;
rsp_addr_q <= icb_cmd_addr;
end
end
// 旁路逻辑:FIFO空时走直连,支持0周期延迟从机
wire route_is_ifu = rsp_vld_q ? rsp_is_ifu_q : sel_ifu;
wire [31:0] route_addr = rsp_vld_q ? rsp_addr_q : icb_cmd_addr;
// 阶段5:响应路由与错误锁定
assign icb_rsp_ready = route_is_ifu ? ifu_rsp_ready : lsu_rsp_ready;
assign ifu_rsp_data = icb_rsp_rdata;
assign ifu_rsp_valid = icb_rsp_valid & route_is_ifu;
assign lsu_rsp_rdata = icb_rsp_rdata;
assign lsu_rsp_valid = icb_rsp_valid & ~route_is_ifu;
reg err; reg [31:0] err_addr;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) {err, err_addr} <= '0;
else begin
err <= rsp_fire & icb_rsp_err;
if (rsp_fire & icb_rsp_err) err_addr <= route_addr;
end
end
endmodule
**模块名称:** `e203_biu_5stage_arbiter`
**功能:** 蜂鸟E203处理器的总线接口单元(BIU)仲裁器。负责在取指单元(IFU)和访存单元(LSU)之间分配ICB总线使用权,并将总线响应正确路由回请求发起方。
**原始问题:**
蜂鸟E203原版BIU采用固定优先级仲裁(IFU > LSU),且依赖分散的组合逻辑进行地址判断和响应路由。当LSU需要连续写入外部设备时,IFU会持续占用总线导致写阻塞;同时响应路由缺乏流水线追踪,在多事务并发时可能错乱。
**五阶段改造:**
| 阶段 | 功能 | 说明 |
|:---|:---|:---|
| 阶段1 | 地址区间预判 | 纯组合逻辑,零延迟判定当前请求目标属于ITCM、DTCM、系统总线还是外部设备 |
| 阶段2 | IFU/LSU优先级仲裁 | IFU默认优先,但LSU写外部设备时拉高`lsu_urgent`紧急抢占总线,保证IO写时序 |
| 阶段3 | ICB命令统一生成 | 根据仲裁结果选择地址、读写方向、写数据和写掩码,驱动ICB总线命令通道 |
| 阶段4 | 1-entry FIFO追踪 | 记录已发出但尚未收到响应的在飞事务的归属和地址;防同周期Push/Pop碰撞;支持0周期延迟从机的旁路直连 |
| 阶段5 | 响应路由与错误锁定 | 根据FIFO锁存的归属信息将响应数据路由至正确的发起方;总线错误时锁定肇事地址 |
**关键微架构修复:**
-
**地址解码零延迟:** 阶段1必须用`wire`做纯组合逻辑,不能打拍。因为`req_valid`和`req_addr`是同时到达的,打拍会导致仲裁依据的是上一拍的旧地址,造成错误抢占。
-
**1-entry FIFO防覆盖:** 阶段4不能只用单bit寄存器存"当前命令是谁的"。ICB总线命令和响应可以错开多拍,后续命令会覆盖单bit寄存器,导致早先命令的响应被错误路由。使用带有效位的FIFO,入队时锁存,出队时清空。
-
**同周期Push/Pop处理:** 当新命令发射和旧响应返回发生在同一周期时,FIFO状态用`case({cmd_fire, rsp_fire})`精确控制------同时Push/Pop时FIFO保持满,新事务信息顶替旧事务。
-
**零延迟从机旁路:** 如果总线上挂载了组合逻辑直连的从机(命令和响应同周期握手),此时FIFO为空,`route_is_ifu`直接取实时的`sel_ifu`,不依赖FIFO中的过期数据。
**接口兼容性:**
完全兼容蜂鸟E203原版ICB总线接口。上层模块(IFU/LSU)无需任何修改,直接替换原版BIU即可。地址窗口配置参数`addr_*base`和`addr*_mask`由SoC顶层在综合时静态配置。
**改动效果:**
消除IFU/LSU的总线结构冲突,LSU写外设延迟降低,整体取指吞吐提升。