mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-23 05:27:30 -04:00
Added support for p.add[u][R]N
This commit is contained in:
parent
8cf1e0e845
commit
a45273acc6
11 changed files with 256 additions and 121 deletions
85
alu.sv
85
alu.sv
|
@ -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
|
||||
|
|
87
decoder.sv
87
decoder.sv
|
@ -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])
|
||||
|
|
|
@ -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 ),
|
||||
|
|
46
id_stage.sv
46
id_stage.sv
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -28,6 +28,7 @@ riscv_vip_rtl:
|
|||
]
|
||||
files: [
|
||||
riscv_tracer.sv,
|
||||
riscv_simchecker.sv,
|
||||
]
|
||||
riscv_regfile_rtl:
|
||||
incdirs: [
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue