`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