Added support for pv.insert, pv.extract and pv.extractu

All untested so far
This commit is contained in:
Andreas Traber 2016-03-02 14:04:07 +01:00
parent 09d6de8e42
commit 3b127ca326
6 changed files with 82 additions and 21 deletions

68
alu.sv
View file

@ -35,6 +35,7 @@ module riscv_alu
input logic [ 1:0] vector_mode_i,
input logic [ 4:0] imm_bmask_a_i,
input logic [ 4:0] imm_bmask_b_i,
input logic [ 1:0] imm_vec_ext_i,
output logic [31:0] result_o,
output logic comparison_result_o
@ -379,21 +380,21 @@ module riscv_alu
begin
sel_minmax[3:0] = is_greater ^ {4{do_min}};
// if(operator_i == `ALU_INS)
// begin
// if(vector_mode_i == `VEC_MODE16)
// begin
// sel_minmax[1:0] = {2{vec_ext_i[0]}};
// sel_minmax[3:2] = ~{2{vec_ext_i[0]}};
// end
// else // `VEC_MODE8
// begin
// sel_minmax[0] = (vec_ext_i != 2'b00);
// sel_minmax[1] = (vec_ext_i != 2'b01);
// sel_minmax[2] = (vec_ext_i != 2'b10);
// sel_minmax[3] = (vec_ext_i != 2'b11);
// end
// end
if(operator_i == `ALU_INS)
begin
if(vector_mode_i == `VEC_MODE16)
begin
sel_minmax[1:0] = {2{imm_vec_ext_i[0]}};
sel_minmax[3:2] = ~{2{imm_vec_ext_i[0]}};
end
else // `VEC_MODE8
begin
sel_minmax[0] = (imm_vec_ext_i != 2'b00);
sel_minmax[1] = (imm_vec_ext_i != 2'b01);
sel_minmax[2] = (imm_vec_ext_i != 2'b10);
sel_minmax[3] = (imm_vec_ext_i != 2'b11);
end
end
end
assign result_minmax[31:24] = (sel_minmax[3] == 1'b1) ? operand_a_i[31:24] : minmax_b[31:24];
@ -413,23 +414,47 @@ module riscv_alu
//////////////////////////////////////////////////
logic [31:0] result_ext;
logic [15:0] ext_half;
always_comb
begin
case (vector_mode_i)
`VEC_MODE16: begin
if (imm_vec_ext_i[0])
ext_half[15:0] = operand_a_i[31:16];
else
ext_half[15:0] = operand_a_i[15: 0];
end
`VEC_MODE8: begin
case (imm_vec_ext_i[1:0])
2'b11: ext_half[7:0] = operand_a_i[31:24];
2'b10: ext_half[7:0] = operand_a_i[23:16];
2'b01: ext_half[7:0] = operand_a_i[15: 8];
2'b00: ext_half[7:0] = operand_a_i[ 7: 0];
endcase
end
default: ext_half[15:0] = operand_a_i[15:0];
endcase
end
always_comb
begin
// zero extend byte
result_ext = {24'b0, operand_a_i[7:0]};
result_ext = {24'b0, ext_half[7:0]};
// sign extend byte
if (operator_i == `ALU_EXTBS)
result_ext = {{24 {operand_a_i[7]}}, operand_a_i[7:0]};
result_ext = {{24 {operand_a_i[7]}}, ext_half[7:0]};
// zero extend half word
if(operator_i == `ALU_EXTHZ)
result_ext = {16'b0, operand_a_i[15:0]};
result_ext = {16'b0, ext_half[15:0]};
// sign extend half word
if(operator_i == `ALU_EXTHS)
result_ext = {{16 {operand_a_i[15]}}, operand_a_i[15:0]};
result_ext = {{16 {operand_a_i[15]}}, ext_half[15:0]};
end
@ -581,10 +606,11 @@ module riscv_alu
`ALU_EXTHZ,
`ALU_EXTHS: result_o = result_ext;
// Min/Max/Abs
// Min/Max/Abs/Ins
`ALU_MIN, `ALU_MINU,
`ALU_MAX, `ALU_MAXU,
`ALU_ABS: result_o = result_minmax;
`ALU_ABS,
`ALU_INS: result_o = result_minmax;
// Comparison Operations
`ALU_EQ, `ALU_NE, `ALU_GTU, `ALU_GEU, `ALU_LTU, `ALU_LEU, `ALU_GTS, `ALU_GES, `ALU_LTS, `ALU_LES:

View file

@ -574,6 +574,27 @@ module riscv_decoder
6'b01101_0: begin alu_operator_o = `ALU_AND; immediate_mux_sel_o = `IMM_VS; end // pv.and
6'b01110_0: begin alu_operator_o = `ALU_ABS; immediate_mux_sel_o = `IMM_VS; end // pv.abs
6'b01111_0: begin // pv.extract
if (instr_rdata_i[12])
alu_operator_o = `ALU_EXTBS;
else
alu_operator_o = `ALU_EXTHS;
end
6'b10000_0: begin // pv.extractu
if (instr_rdata_i[12])
alu_operator_o = `ALU_EXTBZ;
else
alu_operator_o = `ALU_EXTHZ;
end
6'b10001_0: begin // pv.insert
alu_operator_o = `ALU_INS;
regc_used_o = 1'b1;
regc_mux_o = `REGC_RD;
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
end
// comparisons, always have bit 26 set
6'b00000_1: begin alu_operator_o = `ALU_EQ; immediate_mux_sel_o = `IMM_VS; end // pv.cmpeq
6'b00001_1: begin alu_operator_o = `ALU_NE; immediate_mux_sel_o = `IMM_VS; end // pv.cmpne

View file

@ -41,6 +41,7 @@ module riscv_ex_stage
input logic [31:0] alu_operand_c_i,
input logic [ 4:0] imm_bmask_a_i,
input logic [ 4:0] imm_bmask_b_i,
input logic [ 1:0] imm_vec_ext_i,
input logic [ 1:0] alu_vec_mode_i,
// Multiplier signals
@ -128,6 +129,7 @@ module riscv_ex_stage
.vector_mode_i ( alu_vec_mode_i ),
.imm_bmask_a_i ( imm_bmask_a_i ),
.imm_bmask_b_i ( imm_bmask_b_i ),
.imm_vec_ext_i ( imm_vec_ext_i ),
.result_o ( alu_result ),
.comparison_result_o ( alu_cmp_result )

View file

@ -89,6 +89,7 @@ module riscv_id_stage
output logic [31:0] alu_operand_c_ex_o,
output logic [ 4:0] imm_bmask_a_ex_o,
output logic [ 4:0] imm_bmask_b_ex_o,
output logic [ 1:0] imm_vec_ext_ex_o,
output logic [ 1:0] alu_vec_mode_ex_o,
output logic [4:0] regfile_waddr_ex_o,
@ -306,6 +307,7 @@ module riscv_id_stage
// Immediates for ID
logic [ 4:0] imm_bmask_a_id;
logic [ 4:0] imm_bmask_b_id;
logic [ 1:0] imm_vec_ext_id;
logic [ 1:0] alu_vec_mode;
logic scalar_replication;
@ -594,6 +596,7 @@ module riscv_id_stage
assign imm_bmask_b_id = ((alu_operator == `ALU_BCLR) || (alu_operator == `ALU_BSET) || (alu_operator == `ALU_BINS)) ?
imm_s2_type[4:0] : 0;
assign imm_vec_ext_id = imm_vu_type[1:0];
/////////////////////////////////////////////////////////
// ____ _____ ____ ___ ____ _____ _____ ____ ____ //
@ -936,6 +939,7 @@ module riscv_id_stage
alu_operand_c_ex_o <= '0;
imm_bmask_a_ex_o <= '0;
imm_bmask_b_ex_o <= '0;
imm_vec_ext_ex_o <= '0;
alu_vec_mode_ex_o <= '0;
mult_operand_a_ex_o <= '0;
@ -1001,6 +1005,7 @@ module riscv_id_stage
alu_operand_c_ex_o <= alu_operand_c;
imm_bmask_a_ex_o <= imm_bmask_a_id;
imm_bmask_b_ex_o <= imm_bmask_b_id;
imm_vec_ext_ex_o <= imm_vec_ext_id;
alu_vec_mode_ex_o <= alu_vec_mode;
end

View file

@ -145,11 +145,15 @@
// Absolute value
`define ALU_ABS 6'b010100
// Insert/extract
`define ALU_INS 6'b101101
// min/max
`define ALU_MIN 6'b010000
`define ALU_MINU 6'b010001
`define ALU_MAX 6'b010010
`define ALU_MAXU 6'b010011
`define ALU_MAXU 6'b010011
// vector modes

View file

@ -129,6 +129,7 @@ module riscv_core
logic [31:0] alu_operand_c_ex;
logic [ 4:0] imm_bmask_a_ex;
logic [ 4:0] imm_bmask_b_ex;
logic [ 1:0] imm_vec_ext_ex;
logic [ 1:0] alu_vec_mode_ex;
// Multiplier Control
@ -383,6 +384,7 @@ module riscv_core
.alu_operand_c_ex_o ( alu_operand_c_ex ),
.imm_bmask_a_ex_o ( imm_bmask_a_ex ),
.imm_bmask_b_ex_o ( imm_bmask_b_ex ),
.imm_vec_ext_ex_o ( imm_vec_ext_ex ),
.alu_vec_mode_ex_o ( alu_vec_mode_ex ),
.regfile_waddr_ex_o ( regfile_waddr_ex ),
@ -486,6 +488,7 @@ module riscv_core
.alu_operand_c_i ( alu_operand_c_ex ), // from ID/EX pipe registers
.imm_bmask_a_i ( imm_bmask_a_ex ), // from ID/EX pipe registers
.imm_bmask_b_i ( imm_bmask_b_ex ), // from ID/EX pipe registers
.imm_vec_ext_i ( imm_vec_ext_ex ), // from ID/EX pipe registers
.alu_vec_mode_i ( alu_vec_mode_ex ), // from ID/EX pipe registers
// Multipler