Files
risc-v-cpu/pipelined-cpu/srcs/rtl/cpu21_riscv_alu.v
T
Anccend cb0cb433ac 源文件收敛到 pipelined-cpu/ 一份:删除根目录 rtl/board/testbench/tools,补充回归脚本
- 现在只有一份源文件,就在 pipelined-cpu/ 下:
    srcs/rtl(13 个处理器 RTL)、srcs/board、srcs/constrs、srcs/tb、srcs/rom、
    tools/(rv_asm.py、hex2vh.py、run_regress.ps1)、programs/(汇编源码与期望值)。
  仓库根目录的 rtl/、board/、testbench/、tools/ 已删除(删除前逐个文件比对过 MD5,
  与工程目录里的副本完全一致),说明文档仍放在最外层
  cpu21_riscv_redirect_int_bpb说明.md。
- .gitignore 改为:忽略 pipelined-cpu/ 下的工程生成物(*.xpr、*.runs、*.sim、*.cache…),
  只跟踪 srcs/、tools/、programs/、create_project.tcl;_tmp/、_vivado/ 等本地临时目录
  继续忽略。
- 新增 tools/run_regress.ps1:一键回归脚本。编译 srcs/rtl/ → 跑 muldiv/isa/lui/mmio
  四个指令测试并与 programs/*.expected 逐值比对 → 跑两个流水基线 → 跑板级顶层
  (-d BOARD_ROM_FAST)检查跑马灯,最后汇总 PASS/FAIL 并返回失败数作为退出码。
  编译与仿真的中间文件写在 %TEMP%\cpu21_regress,不污染工程目录。实测全部通过。
- 新增 programs/board_demo_fast.asm:快速版演示程序(延时初值 64,约 2.6 µs/步),
  对应 srcs/board/cpu21_board_rom_fast.vh;仿真时用 -d BOARD_ROM_FAST 才会选到它。
- 两个测试平台增加 srcs/rom 探测路径,工程目录内直接 Run Simulation 即可加载镜像。
- 文档:目录结构一节按新布局重写;新增“回归测试”一节(脚本用法 + 期望基线数字);
  上板章节的生成/仿真命令改为相对工程目录(python tools/rv_asm.py programs/…、
  xvlog -d BOARD_ROM_FAST srcs/rtl/*.v …);tools 里的用法示例同步更新;
  “工程分享”一节去掉已不存在的副本同步说明。
- 清理:删除本地 _tmp/(约 57 MB)、_vivado/、.Xil/ 临时目录。
2026-09-13 19:09:36 +08:00

66 lines
2.3 KiB
Verilog

`timescale 1ns / 1ps
`default_nettype none
// -----------------------------------------------------------------------------
// ALU:组合运算单元(只做加减/移位/逻辑/比较等单拍运算)。
//
// 乘法与除法已移到 cpu21_riscv_muldiv.v(时序多周期单元),因为组合的 a*b / a%b
// 关键路径过长(综合后约 94 ns,100 MHz 下无法收敛)。因此本模块不再实现
// ALU_MUL / ALU_DIVU:这两个操作码只作为“这是乘除法指令”的标识,对应结果由
// 顶层从 muldiv 的输出选取(result2 的 wb_sel=3 约定保持不变)。
//
// result 为主结果;result2 为第二结果,由译码器用 wb_sel=3 选取。
// -----------------------------------------------------------------------------
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 使用)
always @* begin
result = 32'b0;
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)与除法(ALU_DIVU)在本模块内不产生结果:
// 它们由 cpu21_riscv_muldiv 多周期单元完成,顶层用 ex_muldiv 选择其输出。
ALU_MUL: ;
ALU_DIVU: ;
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_SLT: result = ($signed(a) < $signed(b)) ? 32'd1 : 32'd0;
ALU_SLTU: result = (a < b) ? 32'd1 : 32'd0;
ALU_MULH: ;
ALU_MULHSU: ;
ALU_PASSB: result = b;
default: result = 32'b0;
endcase
end
endmodule
`default_nettype wire