- 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 文件仍然有效。
48 lines
1.8 KiB
Verilog
48 lines
1.8 KiB
Verilog
`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
|