From ed3a4ea13bd11aebd2ef237892ddc984d69b7ea9 Mon Sep 17 00:00:00 2001 From: Florian Zaruba Date: Wed, 26 Jul 2017 17:48:14 +0200 Subject: [PATCH] Add multiplication encoding --- src/decoder.sv | 47 +++++++++++------- src/mult.sv | 126 +++++++++++++++++++++++++------------------------ 2 files changed, 94 insertions(+), 79 deletions(-) diff --git a/src/decoder.sv b/src/decoder.sv index 1ab808710..af3bb4140 100644 --- a/src/decoder.sv +++ b/src/decoder.sv @@ -222,22 +222,31 @@ module decoder ( // Reg-Reg Operations // -------------------------- OPCODE_OP: begin - instruction_o.fu = ALU; + instruction_o.fu = (instr.rtype.funct7 == 7'b000_0001) ? MULT : ALU; instruction_o.rs1 = instr.rtype.rs1; instruction_o.rs2 = instr.rtype.rs2; instruction_o.rd = instr.rtype.rd; unique case ({instr.rtype.funct7, instr.rtype.funct3}) - {6'b00_0000, 3'b000}: instruction_o.op = ADD; // Add - {6'b10_0000, 3'b000}: instruction_o.op = SUB; // Sub - {6'b00_0000, 3'b010}: instruction_o.op = SLTS; // Set Lower Than - {6'b00_0000, 3'b011}: instruction_o.op = SLTU; // Set Lower Than Unsigned - {6'b00_0000, 3'b100}: instruction_o.op = XORL; // Xor - {6'b00_0000, 3'b110}: instruction_o.op = ORL; // Or - {6'b00_0000, 3'b111}: instruction_o.op = ANDL; // And - {6'b00_0000, 3'b001}: instruction_o.op = SLL; // Shift Left Logical - {6'b00_0000, 3'b101}: instruction_o.op = SRL; // Shift Right Logical - {6'b10_0000, 3'b101}: instruction_o.op = SRA; // Shift Right Arithmetic + {7'b000_0000, 3'b000}: instruction_o.op = ADD; // Add + {7'b010_0000, 3'b000}: instruction_o.op = SUB; // Sub + {7'b000_0000, 3'b010}: instruction_o.op = SLTS; // Set Lower Than + {7'b000_0000, 3'b011}: instruction_o.op = SLTU; // Set Lower Than Unsigned + {7'b000_0000, 3'b100}: instruction_o.op = XORL; // Xor + {7'b000_0000, 3'b110}: instruction_o.op = ORL; // Or + {7'b000_0000, 3'b111}: instruction_o.op = ANDL; // And + {7'b000_0000, 3'b001}: instruction_o.op = SLL; // Shift Left Logical + {7'b000_0000, 3'b101}: instruction_o.op = SRL; // Shift Right Logical + {7'b010_0000, 3'b101}: instruction_o.op = SRA; // Shift Right Arithmetic + // Multiplications + {7'b000_0001, 3'b000}: instruction_o.op = MUL; + {7'b000_0001, 3'b001}: instruction_o.op = MULH; + {7'b000_0001, 3'b010}: instruction_o.op = MULHSU; + {7'b000_0001, 3'b011}: instruction_o.op = MULHU; + {7'b000_0001, 3'b100}: instruction_o.op = DIV; + {7'b000_0001, 3'b101}: instruction_o.op = DIVU; + {7'b000_0001, 3'b110}: instruction_o.op = REM; + {7'b000_0001, 3'b111}: instruction_o.op = REMU; default: begin illegal_instr = 1'b1; end @@ -256,12 +265,16 @@ module decoder ( if (~instr.instr[28]) unique case ({instr.rtype.funct7, instr.rtype.funct3}) - {6'b00_0000, 3'b000}: instruction_o.op = ADDW; // addw - {6'b10_0000, 3'b000}: instruction_o.op = SUBW; // subw - {6'b00_0000, 3'b001}: instruction_o.op = SLLW; // sllw - {6'b00_0000, 3'b101}: instruction_o.op = SRLW; // srlw - {6'b10_0000, 3'b101}: instruction_o.op = SRAW; // sraw - // multiplications + {7'b000_0000, 3'b000}: instruction_o.op = ADDW; // addw + {7'b010_0000, 3'b000}: instruction_o.op = SUBW; // subw + {7'b000_0000, 3'b001}: instruction_o.op = SLLW; // sllw + {7'b000_0000, 3'b101}: instruction_o.op = SRLW; // srlw + {7'b010_0000, 3'b101}: instruction_o.op = SRAW; // sraw + // Multiplications + {7'b000_0001, 3'b000}: instruction_o.op = MULW; + {7'b000_0001, 3'b100}: instruction_o.op = DIVW; + {7'b000_0001, 3'b110}: instruction_o.op = REMW; + {7'b000_0001, 3'b111}: instruction_o.op = REMUW; default: illegal_instr = 1'b1; endcase diff --git a/src/mult.sv b/src/mult.sv index ea2694891..6364dbe82 100644 --- a/src/mult.sv +++ b/src/mult.sv @@ -36,77 +36,79 @@ module mult output logic mult_ready_o, output logic [TRANS_ID_BITS-1:0] mult_trans_id_o ); - // MUL and MULH is a two cycle instructions - logic signed [63:0] result_mult; - logic signed [63:0] result_multh; - enum logic {FIRST_CYCLE, SECOND_CYCLE} multCS, multNS; - logic [TRANS_ID_BITS-1:0] mult_trans_q, mult_trans_n; + // // MUL and MULH is a two cycle instructions + // logic signed [63:0] result_mult; + // logic signed [63:0] result_multh; + // enum logic {FIRST_CYCLE, SECOND_CYCLE} multCS, multNS; + // logic [TRANS_ID_BITS-1:0] mult_trans_q, mult_trans_n; - assign mult_trans_id_o = mult_trans_q; - assign result_o = is_low_part_i ? result_mult : result_multh; + // assign mult_trans_id_o = mult_trans_q; + // assign result_o = is_low_part_i ? result_mult : result_multh; - mult_datapath - mult_dp - ( - .operand_a_i (operand_a_i ), - .operand_b_i (operand_b_i ), - .sign_a_i (sign_a_i ), - .sign_b_i (sign_b_i ), - .result_low_o (result_mult ), - .result_high_o (result_multh ) - ); + // mult_datapath + // mult_dp + // ( + // .operand_a_i (operand_a_i ), + // .operand_b_i (operand_b_i ), + // .sign_a_i (sign_a_i ), + // .sign_b_i (sign_b_i ), + // .result_low_o (result_mult ), + // .result_high_o (result_multh ) + // ); - always_comb begin - mult_valid_o = 1'b0; - mult_ready_o = 1'b0; - multNS = multCS; - mult_trans_n = mult_trans_q; - unique case (multCS) - FIRST_CYCLE: begin - mult_valid_o = 1'b0; - mult_ready_o = 1'b0; - multNS = mult_valid_i ? SECOND_CYCLE : multCS; - end - SECOND_CYCLE: begin - multNS = FIRST_CYCLE; - mult_valid_o = 1'b1; - mult_ready_o = 1'b1; - end - default:; - endcase - end + // always_comb begin + // mult_valid_o = 1'b0; + // mult_ready_o = 1'b0; + // multNS = multCS; + // mult_trans_n = mult_trans_q; + // unique case (multCS) + // FIRST_CYCLE: begin + // mult_valid_o = 1'b0; + // mult_ready_o = 1'b0; + // multNS = mult_valid_i ? SECOND_CYCLE : multCS; + // end + // SECOND_CYCLE: begin + // multNS = FIRST_CYCLE; + // mult_valid_o = 1'b1; + // mult_ready_o = 1'b1; + // end + // default:; + // endcase + // end - always_ff @(posedge clk_i or negedge rst_ni) begin - if(~rst_ni) begin - multCS <= FIRST_CYCLE; - end else begin - multCS <= multNS; - mult_trans_n <= mult_trans_q; - end - end + // always_ff @(posedge clk_i or negedge rst_ni) begin + // if(~rst_ni) begin + // multCS <= FIRST_CYCLE; + // end else begin + // multCS <= multNS; + // mult_trans_n <= mult_trans_q; + // end + // end + + // Check if we need sign extension endmodule -module mult_datapath -( - input logic [63:0] operand_a_i, - input logic [63:0] operand_b_i, - input logic sign_a_i, - input logic sign_b_i, - output logic [63:0] result_low_o, - output logic [63:0] result_high_o -); +// module mult_datapath +// ( +// input logic [63:0] operand_a_i, +// input logic [63:0] operand_b_i, +// input logic sign_a_i, +// input logic sign_b_i, +// output logic [63:0] result_low_o, +// output logic [63:0] result_high_o +// ); - logic signed [129:0] mult_result; - logic signed [64:0] operand_a_ext; - logic signed [64:0] operand_b_ext; +// logic signed [129:0] mult_result; +// logic signed [64:0] operand_a_ext; +// logic signed [64:0] operand_b_ext; - assign operand_a_ext = $signed({sign_a_i & operand_a_i[63], operand_a_i}); - assign operand_b_ext = $signed({sign_b_i & operand_b_i[63], operand_b_i}); +// assign operand_a_ext = $signed({sign_a_i & operand_a_i[63], operand_a_i}); +// assign operand_b_ext = $signed({sign_b_i & operand_b_i[63], operand_b_i}); - assign mult_result = operand_a_ext * operand_b_ext; +// assign mult_result = operand_a_ext * operand_b_ext; - assign result_low_o = $signed(mult_result[ 63: 0]); - assign result_high_o = $signed(mult_result[127:64]); +// assign result_low_o = $signed(mult_result[ 63: 0]); +// assign result_high_o = $signed(mult_result[127:64]); -endmodule +// endmodule