RISC-V CVA6 AXI适配器+DMA桥蜂鸟E203处理器的总线接口单元(BIU)仲裁器

复制代码
`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. **地址解码零延迟:** 阶段1必须用`wire`做纯组合逻辑,不能打拍。因为`req_valid`和`req_addr`是同时到达的,打拍会导致仲裁依据的是上一拍的旧地址,造成错误抢占。

  2. **1-entry FIFO防覆盖:** 阶段4不能只用单bit寄存器存"当前命令是谁的"。ICB总线命令和响应可以错开多拍,后续命令会覆盖单bit寄存器,导致早先命令的响应被错误路由。使用带有效位的FIFO,入队时锁存,出队时清空。

  3. **同周期Push/Pop处理:** 当新命令发射和旧响应返回发生在同一周期时,FIFO状态用`case({cmd_fire, rsp_fire})`精确控制------同时Push/Pop时FIFO保持满,新事务信息顶替旧事务。

  4. **零延迟从机旁路:** 如果总线上挂载了组合逻辑直连的从机(命令和响应同周期握手),此时FIFO为空,`route_is_ifu`直接取实时的`sel_ifu`,不依赖FIFO中的过期数据。

**接口兼容性:**

完全兼容蜂鸟E203原版ICB总线接口。上层模块(IFU/LSU)无需任何修改,直接替换原版BIU即可。地址窗口配置参数`addr_*base`和`addr*_mask`由SoC顶层在综合时静态配置。

**改动效果:**

消除IFU/LSU的总线结构冲突,LSU写外设延迟降低,整体取指吞吐提升。

相关推荐
風清掦11 小时前
【STM32学习笔记-14】WDG看门狗 - 14.2 WWDG窗口看门狗
笔记·stm32·单片机·嵌入式硬件·学习·fpga开发
夜听莺儿鸣14 小时前
201_002 Zynq7000 SoC PS资源介绍
嵌入式硬件·硬件架构
尤老师FPGA14 小时前
HDMI数据的接收发送实验(十二)
fpga开发
电气小僧18 小时前
OpenClaw部署教程
硬件工程·openclaw·龙虾
坏孩子的诺亚方舟18 小时前
FPGA神经网络数学基础0
人工智能·神经网络·线性代数·fpga开发
熠速19 小时前
PolarBox高性能实时仿真系统
arm开发·fpga开发·嵌入式实时数据库·硬件在环半实物仿真
南檐巷上学20 小时前
基于Zynq-7020的带有正弦波发生器的8051软核设计
单片机·嵌入式硬件·fpga开发·fpga
stars-he20 小时前
SPICE编程与仿真学习笔记:从网表到瞬态分析
笔记·学习·硬件工程
思尔芯S2C20 小时前
FPGA原型验证中的内存模型应用:基于DDR5的Linux系统启动与测试
fpga开发·内存模型·ddr4·ddr5·memory model·hbm3·prototyping
小此方21 小时前
Re:Linux系统篇(二十四)进程篇·九:进程从创建到退出的底层机制与写时拷贝全解
linux·运维·驱动开发