目录整理: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 文件仍然有效。
This commit is contained in:
2026-09-13 18:06:21 +08:00
parent 1ae6fe6ebe
commit 556fbe9530
29 changed files with 157 additions and 110 deletions
+71
View File
@@ -0,0 +1,71 @@
`timescale 1ns / 1ps
`default_nettype none
// -----------------------------------------------------------------------------
// ALU:纯组合运算单元。
//
// result 为主结果;result2 为第二结果(乘法的无符号高 32 位 / DIVU 的余数),
// 由译码器用 wb_sel=3 选取,用于无符号高位乘法 mulhu 与课程约定的 remu。
// 除法做了除零保护:b==0 时商为 32'hffff_ffff、余数为被除数。
// -----------------------------------------------------------------------------
module cpu21_riscv_alu (
input wire [ 3:0] op,
input wire [31:0] a,
input wire [31:0] b,
output reg [31:0] result,
output reg [31:0] result2
);
localparam ALU_SLL = 4'd0;
localparam ALU_SRA = 4'd1;
localparam ALU_SRL = 4'd2;
localparam ALU_MUL = 4'd3;
localparam ALU_DIVU = 4'd4;
localparam ALU_ADD = 4'd5;
localparam ALU_SUB = 4'd6;
localparam ALU_AND = 4'd7;
localparam ALU_OR = 4'd8;
localparam ALU_XOR = 4'd9;
localparam ALU_NOR = 4'd10;
localparam ALU_SLT = 4'd11;
localparam ALU_SLTU = 4'd12;
localparam ALU_MULH = 4'd13;
localparam ALU_MULHSU = 4'd14;
localparam ALU_PASSB = 4'd15; // 直接输出 B 端(供 LUI 使用)
reg [63:0] mult_result; // 无符号 32x32 乘积
reg signed [63:0] mult_ss; // 有符号 x 有符号
reg signed [63:0] mult_su; // 有符号 x 无符号
always @* begin
mult_result = a * b;
mult_ss = $signed(a) * $signed(b);
mult_su = $signed(a) * $signed({32'b0, b});
result2 = 32'b0;
case (op)
ALU_SLL: result = a << b[4:0];
ALU_SRA: result = $signed(a) >>> b[4:0];
ALU_SRL: result = a >> b[4:0];
ALU_MUL: begin
result = mult_result[31:0];
result2 = mult_result[63:32];
end
ALU_DIVU: begin
result = (b == 32'b0) ? 32'hffff_ffff : a / b;
result2 = (b == 32'b0) ? a : a % b;
end
ALU_ADD: result = a + b;
ALU_SUB: result = a - b;
ALU_AND: result = a & b;
ALU_OR: result = a | b;
ALU_XOR: result = a ^ b;
ALU_NOR: result = ~(a | b);
ALU_MULH: result = mult_ss[63:32];
ALU_MULHSU: result = mult_su[63:32];
ALU_SLT: result = ($signed(a) < $signed(b)) ? 32'd1 : 32'd0;
ALU_SLTU: result = (a < b) ? 32'd1 : 32'd0;
ALU_PASSB: result = b;
default: result = 32'b0;
endcase
end
endmodule
`default_nettype wire