Added support for p.add[u][R]N

This commit is contained in:
Andreas Traber 2016-03-23 13:34:00 +01:00
parent 8cf1e0e845
commit a45273acc6
11 changed files with 256 additions and 121 deletions

85
alu.sv
View file

@ -36,8 +36,8 @@ module riscv_alu
input logic [31:0] operand_c_i,
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 [ 4:0] bmask_a_i,
input logic [ 4:0] bmask_b_i,
input logic [ 1:0] imm_vec_ext_i,
output logic [31:0] result_o,
@ -77,8 +77,9 @@ module riscv_alu
assign operand_b_neg = ~operand_b_i;
logic [5:0] div_shift;
logic div_valid;
logic [5:0] div_shift;
logic div_valid;
logic [31:0] bmask;
//////////////////////////////////////////////////////////////////////////////////////////
// ____ _ _ _ _ _ _ _ _ //
@ -94,11 +95,14 @@ module riscv_alu
logic [31:0] adder_result;
logic [35:0] adder_result_expanded;
assign adder_op_b_negate = (operator_i == `ALU_SUB) || (operator_i == `ALU_SUBR) ||
(operator_i == `ALU_SUBU) || (operator_i == `ALU_SUBR);
// prepare operand a
assign adder_op_a = (operator_i == `ALU_ABS) ? operand_a_neg : operand_a_i;
// prepare operand b
assign adder_op_b = (operator_i == `ALU_SUB) ? operand_b_neg : operand_b_i;
assign adder_op_b = adder_op_b_negate ? operand_b_neg : operand_b_i;
// prepare carry
always_comb
@ -121,7 +125,7 @@ module riscv_alu
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
if (adder_op_b_negate || (operator_i == `ALU_ABS)) begin
// special case for subtractions and absolute number calculations
adder_in_b[0] = 1'b1;
@ -161,11 +165,14 @@ module riscv_alu
adder_result_expanded[8:1]};
// averaging by right shifting of one bit
logic [31:0] result_avg;
// normalization stage
logic [31:0] adder_round_value;
logic [31:0] adder_round_result;
assign result_avg[30:0] = adder_result[31:1];
assign result_avg[31] = (operator_i == `ALU_AVGU) ? 1'b0 : adder_result[31];
assign adder_round_value = ((operator_i == `ALU_ADDR) || (operator_i == `ALU_SUBR) ||
(operator_i == `ALU_ADDUR) || (operator_i == `ALU_SUBUR)) ?
{1'b0, bmask[31:1]} : '0;
assign adder_round_result = adder_result + adder_round_value;
////////////////////////////////////////
@ -181,6 +188,7 @@ module riscv_alu
logic [31:0] shift_amt_left; // amount of shift, if to the left
logic [31:0] shift_amt; // amount of shift, to the right
logic [31:0] shift_amt_int; // amount of shift, used for the actual shifters
logic [31:0] shift_amt_norm; // amount of shift, used for normalization
logic [31:0] shift_op_a; // input of the shifter
logic [31:0] shift_result;
logic [31:0] shift_right_result;
@ -220,9 +228,22 @@ module riscv_alu
(operator_i == `ALU_DIV) || (operator_i == `ALU_DIVU) ||
(operator_i == `ALU_REM) || (operator_i == `ALU_REMU);
assign shift_use_round = (operator_i == `ALU_ADD) || (operator_i == `ALU_SUB) ||
(operator_i == `ALU_ADDR) || (operator_i == `ALU_SUBR) ||
(operator_i == `ALU_ADDU) || (operator_i == `ALU_SUBU) ||
(operator_i == `ALU_ADDUR) || (operator_i == `ALU_SUBUR);
assign shift_arithmetic = (operator_i == `ALU_SRA) ||
(operator_i == `ALU_ADD) || (operator_i == `ALU_SUB) ||
(operator_i == `ALU_ADDR) || (operator_i == `ALU_SUBR);
// choose the bit reversed or the normal input for shift operand a
assign shift_op_a = (shift_left == 1'b1) ? operand_a_rev : operand_a_i;
assign shift_amt_int = (shift_left == 1'b1) ? shift_amt_left : shift_amt;
assign shift_op_a = shift_left ? operand_a_rev :
(shift_use_round ? adder_round_result : operand_a_i);
assign shift_amt_int = shift_use_round ? shift_amt_norm :
(shift_left ? shift_amt_left : shift_amt);
assign shift_amt_norm = {4{3'b000, bmask_b_i}};
// right shifts, we let the synthesizer optimize this
@ -231,7 +252,7 @@ module riscv_alu
case(vector_mode_i)
`VEC_MODE16:
begin
if(operator_i == `ALU_SRA)
if(shift_arithmetic)
begin
shift_right_result[31:16] = $unsigned( $signed(shift_op_a[31:16]) >>> shift_amt_int[19:16] );
shift_right_result[15: 0] = $unsigned( $signed(shift_op_a[15: 0]) >>> shift_amt_int[ 3: 0] );
@ -245,7 +266,7 @@ module riscv_alu
`VEC_MODE8:
begin
if(operator_i == `ALU_SRA)
if(shift_arithmetic)
begin
shift_right_result[31:24] = $unsigned( $signed(shift_op_a[31:24]) >>> shift_amt_int[26:24] );
shift_right_result[23:16] = $unsigned( $signed(shift_op_a[23:16]) >>> shift_amt_int[18:16] );
@ -263,7 +284,7 @@ module riscv_alu
default: // VEC_MODE32
begin
if(operator_i == `ALU_SRA)
if(shift_arithmetic)
shift_right_result = $unsigned( $signed(shift_op_a) >>> shift_amt_int[4:0] );
else if(operator_i == `ALU_ROR)
shift_right_result = {shift_op_a, shift_op_a} >> shift_amt_int[4:0];
@ -461,6 +482,8 @@ module riscv_alu
always_comb
begin
ext_half = 'x;
case (vector_mode_i)
`VEC_MODE16: begin
if (imm_vec_ext_i[0])
@ -490,7 +513,7 @@ module riscv_alu
// sign extend byte
if (operator_i == `ALU_EXTBS)
result_ext = {{24 {operand_a_i[7]}}, ext_half[7:0]};
result_ext = {{24 {ext_half[7]}}, ext_half[7:0]};
// zero extend half word
if(operator_i == `ALU_EXTHZ)
@ -498,7 +521,7 @@ module riscv_alu
// sign extend half word
if(operator_i == `ALU_EXTHS)
result_ext = {{16 {operand_a_i[15]}}, ext_half[15:0]};
result_ext = {{16 {ext_half[15]}}, ext_half[15:0]};
end
@ -739,21 +762,21 @@ module riscv_alu
logic extract_is_signed;
logic extract_sign;
logic [31:0] bmask, bmask_first, bmask_inv;
logic [31:0] bmask_first, bmask_inv;
logic [31:0] bextins_and;
logic [31:0] bextins_result, bclr_result, bset_result;
// construct bit mask for insert/extract/bclr/bset
// bmask looks like this 00..0011..1100..00
assign bmask_first = {32'hFFFFFFFE} << imm_bmask_a_i;
assign bmask = (~bmask_first) << imm_bmask_b_i;
assign bmask_first = {32'hFFFFFFFE} << bmask_a_i;
assign bmask = (~bmask_first) << bmask_b_i;
assign bmask_inv = ~bmask;
assign bextins_and = (operator_i == `ALU_BINS) ? operand_c_i : {32{extract_sign}};
assign extract_is_signed = (operator_i == `ALU_BEXT);
assign extract_sign = extract_is_signed & shift_result[imm_bmask_a_i];
assign extract_sign = extract_is_signed & shift_result[bmask_a_i];
assign bextins_result = (bmask & shift_result) | (bextins_and & bmask_inv);
@ -827,18 +850,15 @@ module riscv_alu
unique case (operator_i)
// Standard Operations
`ALU_ADD,
`ALU_SUB: result_o = adder_result;
`ALU_AVG,
`ALU_AVGU: result_o = result_avg;
`ALU_AND: result_o = operand_a_i & operand_b_i;
`ALU_OR: result_o = operand_a_i | operand_b_i;
`ALU_XOR: result_o = operand_a_i ^ operand_b_i;
// Shift Operations
`ALU_ADD, `ALU_ADDR, `ALU_ADDU, `ALU_ADDUR,
`ALU_SUB, `ALU_SUBR, `ALU_SUBU, `ALU_SUBUR,
`ALU_SLL,
`ALU_SRL,
`ALU_SRA,
`ALU_SRL, `ALU_SRA,
`ALU_ROR: result_o = shift_result;
// bit manipulation instructions
@ -850,10 +870,11 @@ module riscv_alu
`ALU_BSET: result_o = bset_result;
// Extension Operations
`ALU_EXTBZ,
`ALU_EXTBS,
`ALU_EXTHZ,
`ALU_EXTHS: result_o = result_ext;
`ALU_EXTBZ, `ALU_EXTBS,
`ALU_EXTHZ, `ALU_EXTHS: result_o = result_ext;
// pack and shuffle operations
`ALU_SHUF, `ALU_SHUF2, `ALU_PCKLO, `ALU_PCKHI: result_o = pack_result;
// Min/Max/Abs/Ins
`ALU_MIN, `ALU_MINU,
@ -884,8 +905,6 @@ module riscv_alu
`ALU_DIV, `ALU_DIVU,
`ALU_REM, `ALU_REMU: result_o = result_div;
`ALU_SHUF, `ALU_SHUF2, `ALU_PCKLO, `ALU_PCKHI: result_o = pack_result;
default: ; // default case to suppress unique warning
endcase
end

View file

@ -42,7 +42,9 @@ module riscv_decoder
output logic regb_used_o, // rs2 is used by current instruction
output logic regc_used_o, // rs3 is used by current instruction
output logic imm_bmask_needed_o, // immediate registers for bit manipulation mask is needed
output logic bmask_needed_o, // registers for bit manipulation mask is needed
output logic [ 0:0] bmask_a_mux_o, // bit manipulation mask a mux
output logic [ 1:0] bmask_b_mux_o, // bit manipulation mask a mux
// from IF/ID pipeline
input logic [31:0] instr_rdata_i, // instruction read from instr memory/cache
@ -173,7 +175,9 @@ module riscv_decoder
rega_used_o = 1'b0;
regb_used_o = 1'b0;
regc_used_o = 1'b0;
imm_bmask_needed_o = 1'b0;
bmask_needed_o = 1'b1; // TODO: only use when necessary
bmask_a_mux_o = `BMASK_A_ZERO;
bmask_b_mux_o = `BMASK_B_ZERO;
unique case (instr_rdata_i[6:0])
@ -426,11 +430,22 @@ module riscv_decoder
if (instr_rdata_i[31]) begin
// bit-manipulation instructions
alu_op_b_mux_sel_o = `OP_B_IMM;
imm_bmask_needed_o = 1'b1;
bmask_needed_o = 1'b1;
bmask_a_mux_o = `BMASK_A_S3;
bmask_b_mux_o = `BMASK_B_S2;
unique case (instr_rdata_i[14:12])
3'b000: begin alu_operator_o = `ALU_BEXT; imm_b_mux_sel_o = `IMMB_S2; end
3'b001: begin alu_operator_o = `ALU_BEXTU; imm_b_mux_sel_o = `IMMB_S2; end
3'b000: begin
alu_operator_o = `ALU_BEXT;
imm_b_mux_sel_o = `IMMB_S2;
bmask_b_mux_o = `BMASK_B_ZERO;
end
3'b001: begin
alu_operator_o = `ALU_BEXTU;
imm_b_mux_sel_o = `IMMB_S2;
bmask_b_mux_o = `BMASK_B_ZERO;
end
3'b010: begin
alu_operator_o = `ALU_BINS;
imm_b_mux_sel_o = `IMMB_S2;
@ -509,8 +524,8 @@ module riscv_decoder
end
// PULP specific instructions
{6'b00_0010, 3'b000}: alu_operator_o = `ALU_AVG; // Average
{6'b00_0010, 3'b001}: alu_operator_o = `ALU_AVGU; // Average Unsigned
{6'b00_0010, 3'b000}: begin alu_operator_o = `ALU_ADD; bmask_b_mux_o = `BMASK_B_ONE; end // Average
{6'b00_0010, 3'b001}: begin alu_operator_o = `ALU_ADDU; bmask_b_mux_o = `BMASK_B_ONE; end // Average Unsigned
{6'b00_0010, 3'b010}: alu_operator_o = `ALU_SLETS; // Set Lower Equal Than
{6'b00_0010, 3'b011}: alu_operator_o = `ALU_SLETU; // Set Lower Equal Than Unsigned
{6'b00_0010, 3'b100}: alu_operator_o = `ALU_MIN; // Min
@ -576,6 +591,34 @@ module riscv_decoder
mult_mac_en = 1'b1;
end
2'b10: begin // add with normalization and rounding
// decide between using unsigned and rounding, and combinations
// thereof
case ({instr_rdata_i[31],instr_rdata_i[14]})
2'b00: alu_operator_o = `ALU_ADD;
2'b01: alu_operator_o = `ALU_ADDR;
2'b10: alu_operator_o = `ALU_ADDU;
2'b11: alu_operator_o = `ALU_ADDUR;
endcase
bmask_a_mux_o = `BMASK_A_ZERO;
bmask_b_mux_o = `BMASK_B_S3;
end
2'b11: begin // sub with normalization and rounding
// decide between using unsigned and rounding, and combinations
// thereof
case ({instr_rdata_i[31],instr_rdata_i[14]})
2'b00: alu_operator_o = `ALU_SUB;
2'b01: alu_operator_o = `ALU_SUBR;
2'b10: alu_operator_o = `ALU_SUBU;
2'b11: alu_operator_o = `ALU_SUBUR;
endcase
bmask_a_mux_o = `BMASK_A_ZERO;
bmask_b_mux_o = `BMASK_B_S3;
end
default: begin
regfile_alu_we = 1'b0;
illegal_insn_o = 1'b1;
@ -612,21 +655,21 @@ module riscv_decoder
// now decode the instruction
unique case (instr_rdata_i[31:26])
6'b00000_0: begin alu_operator_o = `ALU_ADD; imm_b_mux_sel_o = `IMMB_VS; end // pv.add
6'b00001_0: begin alu_operator_o = `ALU_SUB; imm_b_mux_sel_o = `IMMB_VS; end // pv.sub
6'b00010_0: begin alu_operator_o = `ALU_AVG; imm_b_mux_sel_o = `IMMB_VS; end // pv.avg
6'b00011_0: begin alu_operator_o = `ALU_AVGU; imm_b_mux_sel_o = `IMMB_VU; end // pv.avgu
6'b00100_0: begin alu_operator_o = `ALU_MIN; imm_b_mux_sel_o = `IMMB_VS; end // pv.min
6'b00101_0: begin alu_operator_o = `ALU_MINU; imm_b_mux_sel_o = `IMMB_VU; end // pv.minu
6'b00110_0: begin alu_operator_o = `ALU_MAX; imm_b_mux_sel_o = `IMMB_VS; end // pv.max
6'b00111_0: begin alu_operator_o = `ALU_MAXU; imm_b_mux_sel_o = `IMMB_VU; end // pv.maxu
6'b01000_0: begin alu_operator_o = `ALU_SRL; imm_b_mux_sel_o = `IMMB_VS; end // pv.srl
6'b01001_0: begin alu_operator_o = `ALU_SRA; imm_b_mux_sel_o = `IMMB_VS; end // pv.sra
6'b01010_0: begin alu_operator_o = `ALU_SLL; imm_b_mux_sel_o = `IMMB_VS; end // pv.sll
6'b01011_0: begin alu_operator_o = `ALU_OR; imm_b_mux_sel_o = `IMMB_VS; end // pv.or
6'b01100_0: begin alu_operator_o = `ALU_XOR; imm_b_mux_sel_o = `IMMB_VS; end // pv.xor
6'b01101_0: begin alu_operator_o = `ALU_AND; imm_b_mux_sel_o = `IMMB_VS; end // pv.and
6'b01110_0: begin alu_operator_o = `ALU_ABS; imm_b_mux_sel_o = `IMMB_VS; end // pv.abs
6'b00000_0: begin alu_operator_o = `ALU_ADD; imm_b_mux_sel_o = `IMMB_VS; end // pv.add
6'b00001_0: begin alu_operator_o = `ALU_SUB; imm_b_mux_sel_o = `IMMB_VS; end // pv.sub
6'b00010_0: begin alu_operator_o = `ALU_ADD; imm_b_mux_sel_o = `IMMB_VS; bmask_b_mux_o = `BMASK_B_ONE; end // pv.avg
6'b00011_0: begin alu_operator_o = `ALU_ADDU; imm_b_mux_sel_o = `IMMB_VU; bmask_b_mux_o = `BMASK_B_ONE; end // pv.avgu
6'b00100_0: begin alu_operator_o = `ALU_MIN; imm_b_mux_sel_o = `IMMB_VS; end // pv.min
6'b00101_0: begin alu_operator_o = `ALU_MINU; imm_b_mux_sel_o = `IMMB_VU; end // pv.minu
6'b00110_0: begin alu_operator_o = `ALU_MAX; imm_b_mux_sel_o = `IMMB_VS; end // pv.max
6'b00111_0: begin alu_operator_o = `ALU_MAXU; imm_b_mux_sel_o = `IMMB_VU; end // pv.maxu
6'b01000_0: begin alu_operator_o = `ALU_SRL; imm_b_mux_sel_o = `IMMB_VS; end // pv.srl
6'b01001_0: begin alu_operator_o = `ALU_SRA; imm_b_mux_sel_o = `IMMB_VS; end // pv.sra
6'b01010_0: begin alu_operator_o = `ALU_SLL; imm_b_mux_sel_o = `IMMB_VS; end // pv.sll
6'b01011_0: begin alu_operator_o = `ALU_OR; imm_b_mux_sel_o = `IMMB_VS; end // pv.or
6'b01100_0: begin alu_operator_o = `ALU_XOR; imm_b_mux_sel_o = `IMMB_VS; end // pv.xor
6'b01101_0: begin alu_operator_o = `ALU_AND; imm_b_mux_sel_o = `IMMB_VS; end // pv.and
6'b01110_0: begin alu_operator_o = `ALU_ABS; imm_b_mux_sel_o = `IMMB_VS; end // pv.abs
6'b01111_0: begin // pv.extract
if (instr_rdata_i[12])

View file

@ -39,8 +39,8 @@ module riscv_ex_stage
input logic [31:0] alu_operand_a_i,
input logic [31:0] alu_operand_b_i,
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 [ 4:0] bmask_a_i,
input logic [ 4:0] bmask_b_i,
input logic [ 1:0] imm_vec_ext_i,
input logic [ 1:0] alu_vec_mode_i,
@ -132,8 +132,8 @@ module riscv_ex_stage
.operand_c_i ( alu_operand_c_i ),
.vector_mode_i ( alu_vec_mode_i ),
.imm_bmask_a_i ( imm_bmask_a_i ),
.imm_bmask_b_i ( imm_bmask_b_i ),
.bmask_a_i ( bmask_a_i ),
.bmask_b_i ( bmask_b_i ),
.imm_vec_ext_i ( imm_vec_ext_i ),
.result_o ( alu_result ),

View file

@ -87,8 +87,8 @@ module riscv_id_stage
output logic [31:0] alu_operand_a_ex_o,
output logic [31:0] alu_operand_b_ex_o,
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 [ 4:0] bmask_a_ex_o,
output logic [ 4:0] bmask_b_ex_o,
output logic [ 1:0] imm_vec_ext_ex_o,
output logic [ 1:0] alu_vec_mode_ex_o,
@ -195,7 +195,7 @@ module riscv_id_stage
logic rega_used_dec;
logic regb_used_dec;
logic regc_used_dec;
logic imm_bmask_needed_dec;
logic bmask_needed_dec;
logic branch_taken_ex;
logic [1:0] jump_in_id;
@ -313,8 +313,11 @@ module riscv_id_stage
logic [31:0] alu_operand_c;
// Immediates for ID
logic [ 4:0] imm_bmask_a_id;
logic [ 4:0] imm_bmask_b_id;
logic [0:0] bmask_a_mux;
logic [1:0] bmask_b_mux;
logic [ 4:0] bmask_a_id;
logic [ 4:0] bmask_b_id;
logic [ 1:0] imm_vec_ext_id;
logic [ 1:0] alu_vec_mode;
@ -621,9 +624,24 @@ module riscv_id_stage
// //
///////////////////////////////////////////////////////////////////////////
assign imm_bmask_a_id = imm_s3_type[4:0];
assign imm_bmask_b_id = ((alu_operator == `ALU_BCLR) || (alu_operator == `ALU_BSET) || (alu_operator == `ALU_BINS)) ?
imm_s2_type[4:0] : 0;
always_comb
begin
unique case (bmask_a_mux)
`BMASK_A_ZERO: bmask_a_id = '0;
`BMASK_A_S3: bmask_a_id = imm_s3_type[4:0];
default: bmask_a_id = '0;
endcase
end
always_comb
begin
unique case (bmask_b_mux)
`BMASK_B_ZERO: bmask_b_id = '0;
`BMASK_B_ONE: bmask_b_id = 5'd1;
`BMASK_B_S2: bmask_b_id = imm_s2_type[4:0];
`BMASK_B_S3: bmask_b_id = imm_s3_type[4:0];
default: bmask_b_id = '0;
endcase
end
assign imm_vec_ext_id = imm_vu_type[1:0];
@ -693,7 +711,9 @@ module riscv_id_stage
.regb_used_o ( regb_used_dec ),
.regc_used_o ( regc_used_dec ),
.imm_bmask_needed_o ( imm_bmask_needed_dec ),
.bmask_needed_o ( bmask_needed_dec ),
.bmask_a_mux_o ( bmask_a_mux ),
.bmask_b_mux_o ( bmask_b_mux ),
// from IF/ID pipeline
.instr_rdata_i ( instr ),
@ -968,8 +988,8 @@ module riscv_id_stage
alu_operand_a_ex_o <= '0;
alu_operand_b_ex_o <= '0;
alu_operand_c_ex_o <= '0;
imm_bmask_a_ex_o <= '0;
imm_bmask_b_ex_o <= '0;
bmask_a_ex_o <= '0;
bmask_b_ex_o <= '0;
imm_vec_ext_ex_o <= '0;
alu_vec_mode_ex_o <= '0;
@ -1036,8 +1056,8 @@ module riscv_id_stage
alu_operand_a_ex_o <= alu_operand_a;
alu_operand_b_ex_o <= alu_operand_b;
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;
bmask_a_ex_o <= bmask_a_id;
bmask_b_ex_o <= bmask_b_id;
imm_vec_ext_ex_o <= imm_vec_ext_id;
alu_vec_mode_ex_o <= alu_vec_mode;
end

View file

@ -382,4 +382,12 @@ module riscv_if_stage
assign if_ready_o = valid & id_ready_i;
assign if_valid_o = (~halt_if_i) & if_ready_o;
//----------------------------------------------------------------------------
// Assertions
//----------------------------------------------------------------------------
// there should never be a grant when there is no request
assert property (
@(posedge clk) (instr_gnt_i) |-> (instr_req_o) );
endmodule

View file

@ -29,7 +29,7 @@
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`define TRACE_EXECUTION
//`define SIMCHECKER
`define SIMCHECKER
`endif
@ -90,13 +90,17 @@
`define ALU_OP_WIDTH 6
`define ALU_ADD 6'b100000
`define ALU_SUB 6'b100001
`define ALU_AVG 6'b100010
`define ALU_AVGU 6'b100011
`define ALU_ADD 6'b011000
`define ALU_SUB 6'b011001
`define ALU_ADDU 6'b011010
`define ALU_SUBU 6'b011011
`define ALU_ADDR 6'b011100
`define ALU_SUBR 6'b011101
`define ALU_ADDUR 6'b011110
`define ALU_SUBUR 6'b011111
`define ALU_XOR 6'b011011
`define ALU_OR 6'b011010
`define ALU_XOR 6'b101111
`define ALU_OR 6'b101110
`define ALU_AND 6'b010101
// Shifts
@ -113,10 +117,10 @@
`define ALU_BSET 6'b101100
// Bit counting
`define ALU_FF1 6'b011110
`define ALU_FL1 6'b011111
`define ALU_CNT 6'b011000
`define ALU_CLB 6'b011001
`define ALU_FF1 6'b110110
`define ALU_FL1 6'b110111
`define ALU_CNT 6'b110100
`define ALU_CLB 6'b110101
// Sign-/zero-extensions
`define ALU_EXTHS 6'b111100
@ -244,6 +248,15 @@
`define IMMB_SHUF 4'b1000
`define IMMB_CLIP 4'b1001
// bit mask selection
`define BMASK_A_ZERO 1'b0
`define BMASK_A_S3 1'b1
`define BMASK_B_S2 2'b00
`define BMASK_B_S3 2'b01
`define BMASK_B_ZERO 2'b10
`define BMASK_B_ONE 2'b11
// operand c selection
`define OP_C_REGC_OR_FWD 2'b00
`define OP_C_REGB_OR_FWD 2'b01

View file

@ -55,6 +55,14 @@
`define INSTR_EXTBZ { 7'b0001000, 10'b?, 3'b111, 5'b?, `OPCODE_OP } // pulp specific
`define INSTR_PAVG { 7'b0000010, 10'b?, 3'b000, 5'b?, `OPCODE_OP } // pulp specific
`define INSTR_PAVGU { 7'b0000010, 10'b?, 3'b001, 5'b?, `OPCODE_OP } // pulp specific
`define INSTR_PADDN { 2'b00, 15'b?, 3'b010, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PADDUN { 2'b10, 15'b?, 3'b010, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PADDRN { 2'b00, 15'b?, 3'b110, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PADDURN { 2'b10, 15'b?, 3'b110, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PSUBN { 2'b00, 15'b?, 3'b011, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PSUBUN { 2'b10, 15'b?, 3'b011, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PSUBRN { 2'b00, 15'b?, 3'b111, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PSUBURN { 2'b10, 15'b?, 3'b111, 5'b?, `OPCODE_PULP_OP } // pulp specific
`define INSTR_PABS { 7'b0001010, 10'b?, 3'b000, 5'b?, `OPCODE_OP } // pulp specific
`define INSTR_PCLIP { 7'b0001010, 10'b?, 3'b001, 5'b?, `OPCODE_OP } // pulp specific
`define INSTR_PCLIPU { 7'b0001010, 10'b?, 3'b010, 5'b?, `OPCODE_OP } // pulp specific

View file

@ -128,8 +128,8 @@ module riscv_core
logic [31:0] alu_operand_a_ex;
logic [31:0] alu_operand_b_ex;
logic [31:0] alu_operand_c_ex;
logic [ 4:0] imm_bmask_a_ex;
logic [ 4:0] imm_bmask_b_ex;
logic [ 4:0] bmask_a_ex;
logic [ 4:0] bmask_b_ex;
logic [ 1:0] imm_vec_ext_ex;
logic [ 1:0] alu_vec_mode_ex;
@ -387,8 +387,8 @@ module riscv_core
.alu_operand_a_ex_o ( alu_operand_a_ex ),
.alu_operand_b_ex_o ( alu_operand_b_ex ),
.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 ),
.bmask_a_ex_o ( bmask_a_ex ),
.bmask_b_ex_o ( bmask_b_ex ),
.imm_vec_ext_ex_o ( imm_vec_ext_ex ),
.alu_vec_mode_ex_o ( alu_vec_mode_ex ),
@ -494,8 +494,8 @@ module riscv_core
.alu_operand_a_i ( alu_operand_a_ex ), // from ID/EX pipe registers
.alu_operand_b_i ( alu_operand_b_ex ), // from ID/EX pipe registers
.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
.bmask_a_i ( bmask_a_ex ), // from ID/EX pipe registers
.bmask_b_i ( 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

View file

@ -22,11 +22,17 @@
////////////////////////////////////////////////////////////////////////////////
`include "riscv_defines.sv"
// do not import anything if the simchecker is not used
// this gets rid of warnings during simulation
`ifdef SIMCHECKER
import "DPI-C" function chandle riscv_checker_init(input int boot_addr, input int core_id, input int cluster_id);
import "DPI-C" function int riscv_checker_step(input chandle cpu, input longint simtime, input int cycle, input logic [31:0] pc, input logic [31:0] instr);
import "DPI-C" function void riscv_checker_irq(input chandle cpu, input int irq, input int irq_no);
import "DPI-C" function void riscv_checker_mem_access(input chandle cpu, input int we, input logic [31:0] addr, input logic [31:0] data);
import "DPI-C" function void riscv_checker_reg_access(input chandle cpu, input logic [31:0] addr, input logic [31:0] data);
`endif
module riscv_simchecker
(
@ -76,6 +82,7 @@ module riscv_simchecker
input logic [31:0] wb_data_rdata
);
`ifdef SIMCHECKER
// DPI stuff
chandle dpi_simdata;
@ -318,5 +325,6 @@ module riscv_simchecker
end
end
end
`endif
endmodule

View file

@ -125,7 +125,7 @@ module riscv_tracer
function void printInstrTrace();
mem_acc_t mem_acc;
begin
$fwrite(f, "%t %15d %h %h %-33s", simtime,
$fwrite(f, "%t %15d %h %h %-36s", simtime,
cycles,
pc,
instr,
@ -166,13 +166,22 @@ module riscv_tracer
end
endfunction // printRInstr
function void printAddNInstr(input string mnemonic);
begin
regs_read.push_back({>> {rs1, rs1_value}});
regs_read.push_back({>> {rs2, rs2_value}});
regs_write.push_back({>> {rd, 'x}});
str = $sformatf("%-16s x%0d, x%0d, x%0d, 0x%0d", mnemonic, rd, rs1, rs2, $unsigned(imm_s3_type[4:0]));
end
endfunction // printAddNInstr
function void printR1Instr(input string mnemonic);
begin
regs_read.push_back({>> {rs1, rs1_value}});
regs_write.push_back({>> {rd, 'x}});
str = $sformatf("%-16s x%0d, x%0d", mnemonic, rd, rs1);
end
endfunction // printRInstr
endfunction // printR1Instr
function void printR3Instr(input string mnemonic);
begin
@ -182,7 +191,7 @@ module riscv_tracer
regs_write.push_back({>> {rd, 'x}});
str = $sformatf("%-16s x%0d, x%0d, x%0d", mnemonic, rd, rs1, rs2);
end
endfunction // printRInstr
endfunction // printR3Instr
function void printClipInstr(input string mnemonic);
begin
@ -415,6 +424,22 @@ module riscv_tracer
string str_sci;
string str_imm;
begin
// always read rs1 and write rd
regs_read.push_back({>> {rs1, rs1_value}});
regs_write.push_back({>> {rd, 'x}});
case (instr[14:13])
2'b00: str_sci = "";
2'b10: str_sci = ".sc";
2'b11: str_sci = ".sci";
endcase
if (instr[12])
str_hb = ".b";
else
str_hb = ".h";
// set mnemonic
case (instr[31:26])
6'b000000: begin mnemonic = "pv.add"; str_imm = $sformatf("0x%0d", imm_vs_type); end
@ -432,8 +457,8 @@ module riscv_tracer
6'b011000: begin mnemonic = "pv.xor"; str_imm = $sformatf("0x%0d", imm_vs_type); end
6'b011010: begin mnemonic = "pv.and"; str_imm = $sformatf("0x%0d", imm_vs_type); end
6'b011100: begin mnemonic = "pv.abs"; str_imm = $sformatf("0x%0d", imm_vs_type); end
6'b011110: begin mnemonic = "pv.extract"; str_imm = $sformatf("0x%0d", imm_vs_type); end
6'b100000: begin mnemonic = "pv.extractu"; str_imm = $sformatf("0x%0d", imm_vu_type); end
6'b011110: begin mnemonic = "pv.extract"; str_imm = $sformatf("0x%0d", imm_vs_type); str_sci = ""; end
6'b100000: begin mnemonic = "pv.extractu"; str_imm = $sformatf("0x%0d", imm_vu_type); str_sci = ""; end
6'b100010: begin mnemonic = "pv.insert"; str_imm = $sformatf("0x%0d", imm_vs_type); end
// shuffle/pack
@ -461,33 +486,15 @@ module riscv_tracer
end
endcase
// always read rs1 and write rd
regs_read.push_back({>> {rs1, rs1_value}});
regs_write.push_back({>> {rd, 'x}});
case (instr[14:13])
2'b00: begin
str_sci = "";
str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2);
regs_read.push_back({>> {rs2, rs2_value}});
end
2'b10: begin
str_sci = ".sc";
str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2);
regs_read.push_back({>> {rs2, rs2_value_vec}});
end
2'b11: begin
str_sci = ".sci";
str_args = $sformatf("x%0d, x%0d, %s", rd, rs1, str_imm);
end
endcase
if (instr[12])
str_hb = ".b";
else
str_hb = ".h";
if (str_sci == "") begin
regs_read.push_back({>> {rs2, rs2_value}});
str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2);
end else if (str_sci == ".sc") begin
regs_read.push_back({>> {rs2, rs2_value_vec}});
str_args = $sformatf("x%0d, x%0d, x%0d", rd, rs1, rs2);
end else if (str_sci == ".sci") begin
str_args = $sformatf("x%0d, x%0d, %s", rd, rs1, str_imm);
end
str_asm = $sformatf("%s%s%s", mnemonic, str_sci, str_hb);
@ -650,6 +657,14 @@ module riscv_tracer
`INSTR_EXTBZ: trace.printRInstr("p.extbz");
`INSTR_PAVG: trace.printRInstr("p.avg");
`INSTR_PAVGU: trace.printRInstr("p.avgu");
`INSTR_PADDN: trace.printAddNInstr("p.addN");
`INSTR_PADDUN: trace.printAddNInstr("p.adduN");
`INSTR_PADDRN: trace.printAddNInstr("p.addRN");
`INSTR_PADDURN: trace.printAddNInstr("p.adduRN");
`INSTR_PSUBN: trace.printAddNInstr("p.subN");
`INSTR_PSUBUN: trace.printAddNInstr("p.subuN");
`INSTR_PSUBRN: trace.printAddNInstr("p.subRN");
`INSTR_PSUBURN: trace.printAddNInstr("p.subuRN");
`INSTR_PSLET: trace.printRInstr("p.slet");
`INSTR_PSLETU: trace.printRInstr("p.sletu");
`INSTR_PMIN: trace.printRInstr("p.min");

View file

@ -28,6 +28,7 @@ riscv_vip_rtl:
]
files: [
riscv_tracer.sv,
riscv_simchecker.sv,
]
riscv_regfile_rtl:
incdirs: [