mirror of
https://github.com/openhwgroup/cva6.git
synced 2025-04-23 21:57:11 -04:00
Add multiplication encoding
This commit is contained in:
parent
6560ef9520
commit
ed3a4ea13b
2 changed files with 94 additions and 79 deletions
|
@ -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
|
||||
|
|
126
src/mult.sv
126
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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue