Added partitioned adder for vectorial operations

This takes care of:
 - pv.add
 - pv.sub
 - pv.avg
 - pv.avgu
This commit is contained in:
Andreas Traber 2016-03-02 11:01:35 +01:00
parent 3495998840
commit 06144c2fbe
2 changed files with 66 additions and 19 deletions

83
alu.sv
View file

@ -53,19 +53,19 @@ module riscv_alu
endgenerate
/////////////////////////////////////
// _ _ _ //
// / \ __| | __| | ___ _ __ //
// / _ \ / _` |/ _` |/ _ \ '__| //
// / ___ \ (_| | (_| | __/ | //
// /_/ \_\__,_|\__,_|\___|_| //
// //
/////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// ____ _ _ _ _ _ _ _ _ //
// | _ \ __ _ _ __| |_(_) |_(_) ___ _ __ ___ __| | / \ __| | __| | ___ _ __ //
// | |_) / _` | '__| __| | __| |/ _ \| '_ \ / _ \/ _` | / _ \ / _` |/ _` |/ _ \ '__| //
// | __/ (_| | | | |_| | |_| | (_) | | | | __/ (_| | / ___ \ (_| | (_| | __/ | //
// |_| \__,_|_| \__|_|\__|_|\___/|_| |_|\___|\__,_| /_/ \_\__,_|\__,_|\___|_| //
// //
//////////////////////////////////////////////////////////////////////////////////////////
logic carry_in;
logic [31:0] adder_op_a;
logic [31:0] adder_op_b;
logic [31:0] adder_op_a, adder_op_b;
logic [35:0] adder_in_a, adder_in_b;
logic [31:0] adder_result;
logic [35:0] adder_result_expanded;
// prepare operand a
assign adder_op_a = (operator_i == `ALU_ABS) ? ~operand_a_i : operand_a_i;
@ -76,15 +76,62 @@ module riscv_alu
// prepare carry
always_comb
begin
case (operator_i)
`ALU_SUB,
`ALU_ABS: carry_in = 1'b1;
default: carry_in = 1'b0;
endcase
adder_in_a[ 0] = 1'b1;
adder_in_a[ 8: 1] = adder_op_a[ 7: 0];
adder_in_a[ 9] = 1'b1;
adder_in_a[17:10] = adder_op_a[15: 8];
adder_in_a[ 18] = 1'b1;
adder_in_a[26:19] = adder_op_a[23:16];
adder_in_a[ 27] = 1'b1;
adder_in_a[35:28] = adder_op_a[31:24];
adder_in_b[ 0] = 1'b0;
adder_in_b[ 8: 1] = adder_op_b[ 7: 0];
adder_in_b[ 9] = 1'b0;
adder_in_b[17:10] = adder_op_b[15: 8];
adder_in_b[ 18] = 1'b0;
adder_in_b[26:19] = adder_op_b[23:16];
adder_in_b[ 27] = 1'b0;
adder_in_b[35:28] = adder_op_b[31:24];
if ((operator_i == `ALU_SUB) || (operator_i == `ALU_ABS)) begin
// special case for subtractions and absolute number calculations
adder_in_b[0] = 1'b1;
case (vector_mode_i)
`VEC_MODE16: begin
adder_in_b[18] = 1'b1;
end
`VEC_MODE8: begin
adder_in_b[ 9] = 1'b1;
adder_in_b[18] = 1'b1;
adder_in_b[27] = 1'b1;
end
endcase
end else begin
// take care of partitioning the adder for the addition case
case (vector_mode_i)
`VEC_MODE16: begin
adder_in_a[18] = 1'b0;
end
`VEC_MODE8: begin
adder_in_a[ 9] = 1'b0;
adder_in_a[18] = 1'b0;
adder_in_a[27] = 1'b0;
end
endcase
end
end
// adder
assign adder_result = adder_op_a + adder_op_b + {31'b0, carry_in};
// actual adder
assign adder_result_expanded = adder_in_a + adder_in_b;
assign adder_result = {adder_result_expanded[35:28],
adder_result_expanded[26:19],
adder_result_expanded[17:10],
adder_result_expanded[8:1]};
// averaging by right shifting of one bit

View file

@ -586,7 +586,7 @@ module riscv_decoder
6'b01000_1: begin alu_operator_o = `ALU_LTU; immediate_mux_sel_o = `IMM_VU; end // pv.cmpltu
6'b01001_1: begin alu_operator_o = `ALU_LEU; immediate_mux_sel_o = `IMM_VU; end // pv.cmpleu
default:;
default: illegal_insn_o = 1'b1;
endcase
end