`timescale 1ns / 1ps `default_nettype none // ----------------------------------------------------------------------------- // ALU:纯组合运算单元。 // // result 为主结果;result2 为第二结果,用于 MUL 的高 32 位与 DIVU 的余数。 // 除法做了除零保护: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; reg [63:0] mult_result; always @* begin mult_result = a * 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_SLT: result = ($signed(a) < $signed(b)) ? 32'd1 : 32'd0; ALU_SLTU: result = (a < b) ? 32'd1 : 32'd0; default: result = 32'b0; endcase end endmodule `default_nettype wire