Files
risc-v-cpu/rtl/cpu21_riscv_forward_unit.v
T
Anccend 556fbe9530 目录整理:RTL/上板/仿真分开存放,测试 ROM 镜像归入 testbench/rom
- rtl/:12 个可综合的处理器源文件(顶层 cpu21_riscv_redirect_int_bpb.v,其余为各功能单元)。
- board/:板级顶层 cpu21_board_top.v、引脚约束 cpu21_board_top.xdc、片内 ROM 初始化
  cpu21_board_rom.vh 与短延时版本 cpu21_board_rom_fast.vh。
- testbench/:保留三个测试平台;ROM 镜像统一放到 testbench/rom/,测试程序源码与期望值
  仍在 testbench/programs/(其中的 .hex 是 RARS 原始输出,与 rom/ 里改过显示方式的版本
  内容不同,两者都保留)。
- 同步更新:两个测试平台的 ROM 探测路径改为 testbench/rom/(并在头注释里补充说明:
  PowerShell 会把 -generic_top/--testplusarg 参数里的 "=" 拆开、Verilog 字符串中的
  路径要用正斜杠);tools/hex2vh.py 的用法示例指向 board/cpu21_board_top.v;
  说明文档新增“目录结构”一节并同步所有路径引用;.gitignore 补充 .Xil/。
- 清理:删除 *.hex.lst 中间文件与空的 .Xil/ 目录。
- 验证:isa_test 24/24、lui_test 4/4、mmio_test 5/5 三项回归通过;两个基线(5560 / 6003
  周期)与整理前一致;板级仿真(默认 ROM 首次写入 LED=0001、快速 ROM 跑马灯循环)正常;
  Vivado 工程源文件路径同步到 rtl/ 与 board/ 后综合通过(LUT 5276、23 个引脚,与整理前
  完全一致),因此已有 bit 文件仍然有效。
2026-09-13 18:06:21 +08:00

48 lines
1.8 KiB
Verilog
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
`timescale 1ns / 1ps
`default_nettype none
// -----------------------------------------------------------------------------
// EX 级前递单元。
//
// 优先级:EX/MEM 级的结果最新 -> 其次 MEM/WB 级写回值 -> 最后是 ID 级
// 译码时读到的寄存器值。load 结果在 MEM 级之后才可用,因此 EX/MEM 的
// load(mem_to_reg)不参与前递,改由冒险单元插入一个气泡。
// -----------------------------------------------------------------------------
module cpu21_riscv_forward_unit (
input wire [31:0] rs1_value_i,
input wire [31:0] rs2_value_i,
input wire [ 4:0] rs1_idx_i,
input wire [ 4:0] rs2_idx_i,
// EX/MEM 级
input wire exmem_valid_i,
input wire exmem_reg_write_i,
input wire exmem_mem_to_reg_i,
input wire [ 4:0] exmem_rd_i,
input wire [31:0] exmem_value_i,
// MEM/WB 级
input wire memwb_valid_i,
input wire memwb_reg_write_i,
input wire [ 4:0] memwb_rd_i,
input wire [31:0] memwb_value_i,
// 前递后的操作数
output reg [31:0] src1_o,
output reg [31:0] src2_o
);
wire ex_mem_forward_valid = exmem_valid_i && exmem_reg_write_i &&
!exmem_mem_to_reg_i && (exmem_rd_i != 5'd0);
wire wb_forward_valid = memwb_valid_i && memwb_reg_write_i && (memwb_rd_i != 5'd0);
always @* begin
src1_o = rs1_value_i;
src2_o = rs2_value_i;
if (ex_mem_forward_valid && (exmem_rd_i == rs1_idx_i)) src1_o = exmem_value_i;
else if (wb_forward_valid && (memwb_rd_i == rs1_idx_i)) src1_o = memwb_value_i;
if (ex_mem_forward_valid && (exmem_rd_i == rs2_idx_i)) src2_o = exmem_value_i;
else if (wb_forward_valid && (memwb_rd_i == rs2_idx_i)) src2_o = memwb_value_i;
end
endmodule
`default_nettype wire