diff --git a/lacpu/rtl/cpu/alu.v b/lacpu/rtl/cpu/alu.v index 7b8bf27..9c9fa20 100755 --- a/lacpu/rtl/cpu/alu.v +++ b/lacpu/rtl/cpu/alu.v @@ -1,5 +1,5 @@ module alu( - input [11:0] alu_op , + input [14:0] alu_op , input [31:0] alu_src1 , input [31:0] alu_src2 , output [31:0] alu_result , @@ -22,20 +22,26 @@ module alu( wire op_sll; wire op_srl; wire op_sra; + wire op_mul; + wire op_mulh; + wire op_mulhu; - assign op_add = alu_op[ 0]; - assign op_sub = alu_op[ 1]; - assign op_slt = alu_op[ 2]; - assign op_sltu = alu_op[ 3]; - assign op_and = alu_op[ 4]; - assign op_nor = alu_op[ 5]; - assign op_or = alu_op[ 6]; - assign op_xor = alu_op[ 7]; - assign op_sll = alu_op[ 8]; - assign op_srl = alu_op[ 9]; - assign op_sra = alu_op[10]; - assign op_lui = alu_op[11]; + assign op_add = alu_op[ 0]; + assign op_sub = alu_op[ 1]; + assign op_slt = alu_op[ 2]; + assign op_sltu = alu_op[ 3]; + assign op_and = alu_op[ 4]; + assign op_nor = alu_op[ 5]; + assign op_or = alu_op[ 6]; + assign op_xor = alu_op[ 7]; + assign op_sll = alu_op[ 8]; + assign op_srl = alu_op[ 9]; + assign op_sra = alu_op[10]; + assign op_lui = alu_op[11]; + assign op_mul = alu_op[12]; + assign op_mulh = alu_op[13]; + assign op_mulhu = alu_op[14]; wire [31:0] add_sub_result; wire [31:0] slt_result; @@ -48,6 +54,9 @@ module alu( wire [31:0] sll_result; wire [63:0] sr64_result; wire [31:0] sr_result; + wire [63:0] mul64_result; + wire [63:0] mulu64_result; + wire [31:0] mul_result; // 32-bit adder wire [31:0] adder_a; @@ -88,17 +97,26 @@ module alu( assign sr_result = sr64_result[31:0]; + // MUL MULH result + assign mul64_result = $signed(alu_src1) * $signed(alu_src2); + assign mulu64_result = alu_src1 * alu_src2; + + assign mul_result = op_mul ? mul64_result[31: 0] : + op_mulh ? mul64_result[63:32] : + /*op_mulhu*/ mulu64_result[63:32]; + // final result mux - assign alu_result = ({32{op_add|op_sub}} & add_sub_result) - | ({32{op_slt }} & slt_result) - | ({32{op_sltu }} & sltu_result) - | ({32{op_and }} & and_result) - | ({32{op_nor }} & nor_result) - | ({32{op_or }} & or_result) - | ({32{op_xor }} & xor_result) - | ({32{op_lui }} & lui_result) - | ({32{op_sll }} & sll_result) - | ({32{op_srl|op_sra}} & sr_result); + assign alu_result = ({32{op_add|op_sub }} & add_sub_result) + | ({32{op_slt }} & slt_result) + | ({32{op_sltu }} & sltu_result) + | ({32{op_and }} & and_result) + | ({32{op_nor }} & nor_result) + | ({32{op_or }} & or_result) + | ({32{op_xor }} & xor_result) + | ({32{op_lui }} & lui_result) + | ({32{op_sll }} & sll_result) + | ({32{op_srl|op_sra }} & sr_result) + | ({32{op_mul|op_mulh|op_mulhu}} & mul_result); assign Carry = op_sub ^ adder_cout; assign Sign = alu_result[31]; assign Overflow = (op_add|op_sub) ? ( adder_a[31] & adder_b[31] & adder_cout) diff --git a/lacpu/rtl/cpu/exe_stage.v b/lacpu/rtl/cpu/exe_stage.v index a80c55d..f777956 100755 --- a/lacpu/rtl/cpu/exe_stage.v +++ b/lacpu/rtl/cpu/exe_stage.v @@ -57,7 +57,7 @@ module exe_stage( wire es_data_is_rf_wdata; - assign {es_alu_op , //166:155 + assign {es_alu_op , //169:155 es_src1_is_pc , //154:154 es_src2_is_imm , //153:153 es_src2_is_4 , //152:152 diff --git a/lacpu/rtl/cpu/id_stage.v b/lacpu/rtl/cpu/id_stage.v index 6c0bc62..7c0e398 100755 --- a/lacpu/rtl/cpu/id_stage.v +++ b/lacpu/rtl/cpu/id_stage.v @@ -40,7 +40,7 @@ module id_stage( rf_wdata //31:0 } = ws_to_rf_bus; - wire [11:0] alu_op; + wire [14:0] alu_op; wire src1_is_pc; wire src2_is_imm; wire src2_is_4; @@ -113,7 +113,7 @@ module id_stage( wire rj_lt_rd; wire rj_ltu_rd; - assign ds_to_es_bus = {alu_op , //166:155 + assign ds_to_es_bus = {alu_op , //169:155 src1_is_pc , //154:154 src2_is_imm , //153:153 src2_is_4 , //152:152 @@ -174,6 +174,9 @@ module id_stage( assign inst_slliw = (op[21: 5] == 12'b0000_0000_0100) & op17_d[5'b00001]; assign inst_srliw = (op[21: 5] == 12'b0000_0000_0100) & op17_d[5'b01001]; assign inst_sraiw = (op[21: 5] == 12'b0000_0000_0100) & op17_d[5'b10001]; + assign inst_mulw = (op[21: 5] == 12'b0000_0000_0001) & op17_d[5'b11000]; + assign inst_mulhw = (op[21: 5] == 12'b0000_0000_0001) & op17_d[5'b11001]; + assign inst_mulhwu = (op[21: 5] == 12'b0000_0000_0001) & op17_d[5'b11010]; assign inst_slti = (op[21:11] == 7'b0000_001 ) & op10_d[3'b000]; assign inst_sltui = (op[21:11] == 7'b0000_001 ) & op10_d[3'b001]; assign inst_addiw = (op[21:11] == 7'b0000_001 ) & op10_d[3'b010]; @@ -200,6 +203,9 @@ module id_stage( assign inst_bltu = (op[21:15] == 3'b011 ) & op6_d[3'b010]; assign inst_bgeu = (op[21:15] == 3'b011 ) & op6_d[3'b011]; + + + assign alu_op[ 0] = inst_addw | inst_addiw | inst_pcaddu12i | inst_ldb | inst_ldh | inst_ldbu | inst_ldhu | inst_ldw | inst_stb | inst_sth | inst_stw | inst_bl | inst_jirl; assign alu_op[ 1] = inst_subw; assign alu_op[ 2] = inst_slt | inst_slti; @@ -212,6 +218,9 @@ module id_stage( assign alu_op[ 9] = inst_srlw | inst_srliw; assign alu_op[10] = inst_sraw | inst_sraiw; assign alu_op[11] = inst_lu12iw; + assign alu_op[12] = inst_mulw; + assign alu_op[13] = inst_mulhw; + assign alu_op[14] = inst_mulhwu; assign imm = {32{inst_slti | inst_sltui | inst_addiw | inst_ldb | inst_ldh | inst_ldw | inst_stb | inst_sth | inst_stw | inst_ldbu | inst_ldhu}} & {{20{ds_inst[21]}}, ds_inst[21:10]} | {32{inst_beq | inst_bne | inst_bge | inst_bgeu | inst_blt | inst_bltu | inst_jirl}} & {{14{ds_inst[25]}}, ds_inst[25:10], 2'b0} diff --git a/lacpu/rtl/cpu/mycpu.v b/lacpu/rtl/cpu/mycpu.v index 615e976..f8323e0 100644 --- a/lacpu/rtl/cpu/mycpu.v +++ b/lacpu/rtl/cpu/mycpu.v @@ -3,7 +3,7 @@ `define BR_BUS_WD 33 `define FS_TO_DS_BUS_WD 64 - `define DS_TO_ES_BUS_WD 167 + `define DS_TO_ES_BUS_WD 170 `define ES_TO_MS_BUS_WD 121 `define MS_TO_WS_BUS_WD 70 `define WS_TO_RF_BUS_WD 38