mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-23 05:27:30 -04:00
Merge branch 'sv-packages' into 'master'
Sv packages moved to sv-packages in the riscv core. (no more defines) See merge request !3
This commit is contained in:
commit
840f500e79
20 changed files with 920 additions and 923 deletions
258
alu.sv
258
alu.sv
|
@ -23,14 +23,14 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_alu
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
input logic [`ALU_OP_WIDTH-1:0] operator_i,
|
||||
input logic [ALU_OP_WIDTH-1:0] operator_i,
|
||||
input logic [31:0] operand_a_i,
|
||||
input logic [31:0] operand_b_i,
|
||||
input logic [31:0] operand_c_i,
|
||||
|
@ -96,11 +96,11 @@ 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);
|
||||
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;
|
||||
assign adder_op_a = (operator_i == ALU_ABS) ? operand_a_neg : operand_a_i;
|
||||
|
||||
// prepare operand b
|
||||
assign adder_op_b = adder_op_b_negate ? operand_b_neg : operand_b_i;
|
||||
|
@ -126,16 +126,16 @@ module riscv_alu
|
|||
adder_in_b[ 27] = 1'b0;
|
||||
adder_in_b[35:28] = adder_op_b[31:24];
|
||||
|
||||
if (adder_op_b_negate || (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;
|
||||
|
||||
case (vector_mode_i)
|
||||
`VEC_MODE16: begin
|
||||
VEC_MODE16: begin
|
||||
adder_in_b[18] = 1'b1;
|
||||
end
|
||||
|
||||
`VEC_MODE8: begin
|
||||
VEC_MODE8: begin
|
||||
adder_in_b[ 9] = 1'b1;
|
||||
adder_in_b[18] = 1'b1;
|
||||
adder_in_b[27] = 1'b1;
|
||||
|
@ -145,11 +145,11 @@ module riscv_alu
|
|||
end else begin
|
||||
// take care of partitioning the adder for the addition case
|
||||
case (vector_mode_i)
|
||||
`VEC_MODE16: begin
|
||||
VEC_MODE16: begin
|
||||
adder_in_a[18] = 1'b0;
|
||||
end
|
||||
|
||||
`VEC_MODE8: begin
|
||||
VEC_MODE8: begin
|
||||
adder_in_a[ 9] = 1'b0;
|
||||
adder_in_a[18] = 1'b0;
|
||||
adder_in_a[27] = 1'b0;
|
||||
|
@ -170,8 +170,8 @@ module riscv_alu
|
|||
logic [31:0] adder_round_value;
|
||||
logic [31:0] adder_round_result;
|
||||
|
||||
assign adder_round_value = ((operator_i == `ALU_ADDR) || (operator_i == `ALU_SUBR) ||
|
||||
(operator_i == `ALU_ADDUR) || (operator_i == `ALU_SUBUR)) ?
|
||||
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;
|
||||
|
||||
|
@ -205,13 +205,13 @@ module riscv_alu
|
|||
always_comb
|
||||
begin
|
||||
case(vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
VEC_MODE16:
|
||||
begin
|
||||
shift_amt_left[15: 0] = shift_amt[31:16];
|
||||
shift_amt_left[31:16] = shift_amt[15: 0];
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
VEC_MODE8:
|
||||
begin
|
||||
shift_amt_left[ 7: 0] = shift_amt[31:24];
|
||||
shift_amt_left[15: 8] = shift_amt[23:16];
|
||||
|
@ -226,20 +226,20 @@ module riscv_alu
|
|||
endcase
|
||||
end
|
||||
|
||||
// `ALU_FL1 and `ALU_CBL are used for the bit counting ops later
|
||||
assign shift_left = (operator_i == `ALU_SLL) || (operator_i == `ALU_BINS) ||
|
||||
(operator_i == `ALU_FL1) || (operator_i == `ALU_CLB) ||
|
||||
(operator_i == `ALU_DIV) || (operator_i == `ALU_DIVU) ||
|
||||
(operator_i == `ALU_REM) || (operator_i == `ALU_REMU);
|
||||
// ALU_FL1 and ALU_CBL are used for the bit counting ops later
|
||||
assign shift_left = (operator_i == ALU_SLL) || (operator_i == ALU_BINS) ||
|
||||
(operator_i == ALU_FL1) || (operator_i == ALU_CLB) ||
|
||||
(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_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);
|
||||
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 ? operand_a_rev :
|
||||
|
@ -254,7 +254,7 @@ module riscv_alu
|
|||
always_comb
|
||||
begin
|
||||
case(vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
VEC_MODE16:
|
||||
begin
|
||||
if(shift_arithmetic)
|
||||
begin
|
||||
|
@ -268,7 +268,7 @@ module riscv_alu
|
|||
end
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
VEC_MODE8:
|
||||
begin
|
||||
if(shift_arithmetic)
|
||||
begin
|
||||
|
@ -290,7 +290,7 @@ module riscv_alu
|
|||
begin
|
||||
if(shift_arithmetic)
|
||||
shift_right_result = $unsigned( $signed(shift_op_a) >>> shift_amt_int[4:0] );
|
||||
else if(operator_i == `ALU_ROR)
|
||||
else if(operator_i == ALU_ROR)
|
||||
shift_right_result = {shift_op_a, shift_op_a} >> shift_amt_int[4:0];
|
||||
else
|
||||
shift_right_result = shift_op_a >> shift_amt_int[4:0];
|
||||
|
@ -332,20 +332,20 @@ module riscv_alu
|
|||
cmp_signed = 4'b0;
|
||||
|
||||
unique case (operator_i)
|
||||
`ALU_GTS,
|
||||
`ALU_GES,
|
||||
`ALU_LTS,
|
||||
`ALU_LES,
|
||||
`ALU_SLTS,
|
||||
`ALU_SLETS,
|
||||
`ALU_MIN,
|
||||
`ALU_MAX,
|
||||
`ALU_ABS,
|
||||
`ALU_CLIP,
|
||||
`ALU_CLIPU: begin
|
||||
ALU_GTS,
|
||||
ALU_GES,
|
||||
ALU_LTS,
|
||||
ALU_LES,
|
||||
ALU_SLTS,
|
||||
ALU_SLETS,
|
||||
ALU_MIN,
|
||||
ALU_MAX,
|
||||
ALU_ABS,
|
||||
ALU_CLIP,
|
||||
ALU_CLIPU: begin
|
||||
case (vector_mode_i)
|
||||
`VEC_MODE8: cmp_signed[3:0] = 4'b1111;
|
||||
`VEC_MODE16: cmp_signed[3:0] = 4'b1010;
|
||||
VEC_MODE8: cmp_signed[3:0] = 4'b1111;
|
||||
VEC_MODE16: cmp_signed[3:0] = 4'b1010;
|
||||
default: cmp_signed[3:0] = 4'b1000;
|
||||
endcase
|
||||
end
|
||||
|
@ -378,7 +378,7 @@ module riscv_alu
|
|||
| (is_equal_vec[1] & (is_greater_vec[0]))))))}};
|
||||
|
||||
case(vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
VEC_MODE16:
|
||||
begin
|
||||
is_equal[1:0] = {2{is_equal_vec[0] & is_equal_vec[1]}};
|
||||
is_equal[3:2] = {2{is_equal_vec[2] & is_equal_vec[3]}};
|
||||
|
@ -386,7 +386,7 @@ module riscv_alu
|
|||
is_greater[3:2] = {2{is_greater_vec[3] | (is_equal_vec[3] & is_greater_vec[2])}};
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
VEC_MODE8:
|
||||
begin
|
||||
is_equal[3:0] = is_equal_vec[3:0];
|
||||
is_greater[3:0] = is_greater_vec[3:0];
|
||||
|
@ -408,16 +408,16 @@ module riscv_alu
|
|||
cmp_result = is_equal;
|
||||
|
||||
unique case (operator_i)
|
||||
`ALU_EQ: cmp_result = is_equal;
|
||||
`ALU_NE: cmp_result = ~is_equal;
|
||||
`ALU_GTS, `ALU_GTU: cmp_result = is_greater;
|
||||
`ALU_GES, `ALU_GEU: cmp_result = is_greater | is_equal;
|
||||
`ALU_LTS, `ALU_SLTS,
|
||||
`ALU_LTU, `ALU_SLTU: cmp_result = ~(is_greater | is_equal);
|
||||
`ALU_SLETS,
|
||||
`ALU_SLETU,
|
||||
`ALU_LES, `ALU_LEU: cmp_result = ~is_greater;
|
||||
`ALU_EQALL: cmp_result = {4{cmp_eqall}};
|
||||
ALU_EQ: cmp_result = is_equal;
|
||||
ALU_NE: cmp_result = ~is_equal;
|
||||
ALU_GTS, ALU_GTU: cmp_result = is_greater;
|
||||
ALU_GES, ALU_GEU: cmp_result = is_greater | is_equal;
|
||||
ALU_LTS, ALU_SLTS,
|
||||
ALU_LTU, ALU_SLTU: cmp_result = ~(is_greater | is_equal);
|
||||
ALU_SLETS,
|
||||
ALU_SLETU,
|
||||
ALU_LES, ALU_LEU: cmp_result = ~is_greater;
|
||||
ALU_EQALL: cmp_result = {4{cmp_eqall}};
|
||||
|
||||
default: ;
|
||||
endcase
|
||||
|
@ -432,10 +432,10 @@ module riscv_alu
|
|||
logic do_min;
|
||||
logic [31:0] minmax_b;
|
||||
|
||||
assign minmax_b = (operator_i == `ALU_ABS) ? adder_result : operand_b_i;
|
||||
assign minmax_b = (operator_i == ALU_ABS) ? adder_result : operand_b_i;
|
||||
|
||||
assign do_min = (operator_i == `ALU_MIN) || (operator_i == `ALU_MINU) ||
|
||||
(operator_i == `ALU_CLIP) || (operator_i == `ALU_CLIPU);
|
||||
assign do_min = (operator_i == ALU_MIN) || (operator_i == ALU_MINU) ||
|
||||
(operator_i == ALU_CLIP) || (operator_i == ALU_CLIPU);
|
||||
|
||||
assign sel_minmax[3:0] = is_greater ^ {4{do_min}};
|
||||
|
||||
|
@ -451,7 +451,7 @@ module riscv_alu
|
|||
logic clip_is_lower_u; // only signed comparison; used for clipu, checks for negative number
|
||||
|
||||
assign clip_is_lower_neg = $signed(operand_a_i) < $signed(operand_b_neg);
|
||||
assign clip_is_lower_u = (operator_i == `ALU_CLIPU) && operand_a_i[31];
|
||||
assign clip_is_lower_u = (operator_i == ALU_CLIPU) && operand_a_i[31];
|
||||
|
||||
assign clip_result = clip_is_lower_u ? '0 : (clip_is_lower_neg ? operand_b_neg : result_minmax);
|
||||
|
||||
|
@ -484,11 +484,11 @@ module riscv_alu
|
|||
shuffle_through = '1;
|
||||
|
||||
unique case(operator_i)
|
||||
`ALU_EXT, `ALU_EXTS: begin
|
||||
if (operator_i == `ALU_EXTS)
|
||||
ALU_EXT, ALU_EXTS: begin
|
||||
if (operator_i == ALU_EXTS)
|
||||
shuffle_reg1_sel = 2'b11;
|
||||
|
||||
if (vector_mode_i == `VEC_MODE8) begin
|
||||
if (vector_mode_i == VEC_MODE8) begin
|
||||
shuffle_reg_sel[3:1] = 3'b111;
|
||||
shuffle_reg_sel[0] = 1'b0;
|
||||
end else begin
|
||||
|
@ -497,10 +497,10 @@ module riscv_alu
|
|||
end
|
||||
end
|
||||
|
||||
`ALU_PCKLO: begin
|
||||
ALU_PCKLO: begin
|
||||
shuffle_reg1_sel = 2'b00;
|
||||
|
||||
if (vector_mode_i == `VEC_MODE8) begin
|
||||
if (vector_mode_i == VEC_MODE8) begin
|
||||
shuffle_through = 4'b0011;
|
||||
shuffle_reg_sel = 4'b0001;
|
||||
end else begin
|
||||
|
@ -508,23 +508,23 @@ module riscv_alu
|
|||
end
|
||||
end
|
||||
|
||||
`ALU_PCKHI: begin
|
||||
ALU_PCKHI: begin
|
||||
shuffle_reg1_sel = 2'b00;
|
||||
|
||||
shuffle_reg_sel = 4'b0100;
|
||||
shuffle_through = 4'b1100;
|
||||
end
|
||||
|
||||
`ALU_SHUF2: begin
|
||||
ALU_SHUF2: begin
|
||||
unique case (vector_mode_i)
|
||||
`VEC_MODE8: begin
|
||||
VEC_MODE8: begin
|
||||
shuffle_reg_sel[3] = operand_b_i[26];
|
||||
shuffle_reg_sel[2] = operand_b_i[18];
|
||||
shuffle_reg_sel[1] = operand_b_i[10];
|
||||
shuffle_reg_sel[0] = operand_b_i[ 2];
|
||||
end
|
||||
|
||||
`VEC_MODE16: begin
|
||||
VEC_MODE16: begin
|
||||
shuffle_reg_sel[3] = operand_b_i[17];
|
||||
shuffle_reg_sel[2] = operand_b_i[17];
|
||||
shuffle_reg_sel[1] = operand_b_i[ 1];
|
||||
|
@ -534,9 +534,9 @@ module riscv_alu
|
|||
endcase
|
||||
end
|
||||
|
||||
`ALU_INS: begin
|
||||
ALU_INS: begin
|
||||
unique case (vector_mode_i)
|
||||
`VEC_MODE8: begin
|
||||
VEC_MODE8: begin
|
||||
shuffle_reg0_sel = 2'b00;
|
||||
unique case (imm_vec_ext_i)
|
||||
2'b00: begin
|
||||
|
@ -554,7 +554,7 @@ module riscv_alu
|
|||
default:;
|
||||
endcase
|
||||
end
|
||||
`VEC_MODE16: begin
|
||||
VEC_MODE16: begin
|
||||
shuffle_reg0_sel = 2'b01;
|
||||
shuffle_reg_sel[3] = ~imm_vec_ext_i[ 0];
|
||||
shuffle_reg_sel[2] = ~imm_vec_ext_i[ 0];
|
||||
|
@ -575,17 +575,17 @@ module riscv_alu
|
|||
|
||||
// byte selector
|
||||
unique case (operator_i)
|
||||
`ALU_EXTS,
|
||||
`ALU_EXT: begin
|
||||
ALU_EXTS,
|
||||
ALU_EXT: begin
|
||||
unique case (vector_mode_i)
|
||||
`VEC_MODE8: begin
|
||||
VEC_MODE8: begin
|
||||
shuffle_byte_sel[3] = imm_vec_ext_i[1:0];
|
||||
shuffle_byte_sel[2] = imm_vec_ext_i[1:0];
|
||||
shuffle_byte_sel[1] = imm_vec_ext_i[1:0];
|
||||
shuffle_byte_sel[0] = imm_vec_ext_i[1:0];
|
||||
end
|
||||
|
||||
`VEC_MODE16: begin
|
||||
VEC_MODE16: begin
|
||||
shuffle_byte_sel[3] = {imm_vec_ext_i[0], 1'b1};
|
||||
shuffle_byte_sel[2] = {imm_vec_ext_i[0], 1'b1};
|
||||
shuffle_byte_sel[1] = {imm_vec_ext_i[0], 1'b1};
|
||||
|
@ -596,17 +596,17 @@ module riscv_alu
|
|||
endcase
|
||||
end
|
||||
|
||||
`ALU_PCKLO,
|
||||
`ALU_PCKHI: begin
|
||||
ALU_PCKLO,
|
||||
ALU_PCKHI: begin
|
||||
unique case (vector_mode_i)
|
||||
`VEC_MODE8: begin
|
||||
VEC_MODE8: begin
|
||||
shuffle_byte_sel[3] = 2'b00;
|
||||
shuffle_byte_sel[2] = 2'b00;
|
||||
shuffle_byte_sel[1] = 2'b00;
|
||||
shuffle_byte_sel[0] = 2'b00;
|
||||
end
|
||||
|
||||
`VEC_MODE16: begin
|
||||
VEC_MODE16: begin
|
||||
shuffle_byte_sel[3] = 2'b01;
|
||||
shuffle_byte_sel[2] = 2'b00;
|
||||
shuffle_byte_sel[1] = 2'b01;
|
||||
|
@ -617,17 +617,17 @@ module riscv_alu
|
|||
endcase
|
||||
end
|
||||
|
||||
`ALU_SHUF2,
|
||||
`ALU_SHUF: begin
|
||||
ALU_SHUF2,
|
||||
ALU_SHUF: begin
|
||||
unique case (vector_mode_i)
|
||||
`VEC_MODE8: begin
|
||||
VEC_MODE8: begin
|
||||
shuffle_byte_sel[3] = operand_b_i[25:24];
|
||||
shuffle_byte_sel[2] = operand_b_i[17:16];
|
||||
shuffle_byte_sel[1] = operand_b_i[ 9: 8];
|
||||
shuffle_byte_sel[0] = operand_b_i[ 1: 0];
|
||||
end
|
||||
|
||||
`VEC_MODE16: begin
|
||||
VEC_MODE16: begin
|
||||
shuffle_byte_sel[3] = {operand_b_i[16], 1'b1};
|
||||
shuffle_byte_sel[2] = {operand_b_i[16], 1'b0};
|
||||
shuffle_byte_sel[1] = {operand_b_i[ 0], 1'b1};
|
||||
|
@ -637,7 +637,7 @@ module riscv_alu
|
|||
endcase
|
||||
end
|
||||
|
||||
`ALU_INS: begin
|
||||
ALU_INS: begin
|
||||
shuffle_byte_sel[3] = 2'b11;
|
||||
shuffle_byte_sel[2] = 2'b10;
|
||||
shuffle_byte_sel[1] = 2'b01;
|
||||
|
@ -721,15 +721,15 @@ module riscv_alu
|
|||
ff_input = 'x;
|
||||
|
||||
case (operator_i)
|
||||
`ALU_FF1: ff_input = operand_a_i;
|
||||
ALU_FF1: ff_input = operand_a_i;
|
||||
|
||||
`ALU_DIVU,
|
||||
`ALU_REMU,
|
||||
`ALU_FL1: ff_input = operand_a_rev;
|
||||
ALU_DIVU,
|
||||
ALU_REMU,
|
||||
ALU_FL1: ff_input = operand_a_rev;
|
||||
|
||||
`ALU_DIV,
|
||||
`ALU_REM,
|
||||
`ALU_CLB: begin
|
||||
ALU_DIV,
|
||||
ALU_REM,
|
||||
ALU_CLB: begin
|
||||
if (operand_a_i[31])
|
||||
ff_input = operand_a_neg_rev;
|
||||
else
|
||||
|
@ -754,10 +754,10 @@ module riscv_alu
|
|||
begin
|
||||
bitop_result = 'x;
|
||||
case (operator_i)
|
||||
`ALU_FF1: bitop_result = ff_no_one ? 6'd32 : {1'b0, ff1_result};
|
||||
`ALU_FL1: bitop_result = ff_no_one ? 6'd32 : {1'b0, fl1_result};
|
||||
`ALU_CNT: bitop_result = cnt_result;
|
||||
`ALU_CLB: begin
|
||||
ALU_FF1: bitop_result = ff_no_one ? 6'd32 : {1'b0, ff1_result};
|
||||
ALU_FL1: bitop_result = ff_no_one ? 6'd32 : {1'b0, fl1_result};
|
||||
ALU_CNT: bitop_result = cnt_result;
|
||||
ALU_CLB: begin
|
||||
if (ff_no_one) begin
|
||||
if (operand_a_i[31])
|
||||
bitop_result = 6'd31;
|
||||
|
@ -794,9 +794,9 @@ module riscv_alu
|
|||
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 bextins_and = (operator_i == ALU_BINS) ? operand_c_i : {32{extract_sign}};
|
||||
|
||||
assign extract_is_signed = (operator_i == `ALU_BEXT);
|
||||
assign extract_is_signed = (operator_i == ALU_BEXT);
|
||||
assign extract_sign = extract_is_signed & shift_result[bmask_a_i];
|
||||
|
||||
assign bextins_result = (bmask & shift_result) | (bextins_and & bmask_inv);
|
||||
|
@ -829,8 +829,8 @@ module riscv_alu
|
|||
assign div_shift_int = ff_no_one ? 6'd31 : clb_result;
|
||||
assign div_shift = div_shift_int + (div_op_a_signed ? 6'd0 : 6'd1);
|
||||
|
||||
assign div_valid = (operator_i == `ALU_DIV) || (operator_i == `ALU_DIVU) ||
|
||||
(operator_i == `ALU_REM) || (operator_i == `ALU_REMU);
|
||||
assign div_valid = (operator_i == ALU_DIV) || (operator_i == ALU_DIVU) ||
|
||||
(operator_i == ALU_REM) || (operator_i == ALU_REMU);
|
||||
|
||||
|
||||
// inputs A and B are swapped
|
||||
|
@ -871,57 +871,57 @@ module riscv_alu
|
|||
|
||||
unique case (operator_i)
|
||||
// Standard Operations
|
||||
`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;
|
||||
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_ROR: result_o = shift_result;
|
||||
ALU_ADD, ALU_ADDR, ALU_ADDU, ALU_ADDUR,
|
||||
ALU_SUB, ALU_SUBR, ALU_SUBU, ALU_SUBUR,
|
||||
ALU_SLL,
|
||||
ALU_SRL, ALU_SRA,
|
||||
ALU_ROR: result_o = shift_result;
|
||||
|
||||
// bit manipulation instructions
|
||||
`ALU_BINS,
|
||||
`ALU_BEXT,
|
||||
`ALU_BEXTU: result_o = bextins_result;
|
||||
ALU_BINS,
|
||||
ALU_BEXT,
|
||||
ALU_BEXTU: result_o = bextins_result;
|
||||
|
||||
`ALU_BCLR: result_o = bclr_result;
|
||||
`ALU_BSET: result_o = bset_result;
|
||||
ALU_BCLR: result_o = bclr_result;
|
||||
ALU_BSET: result_o = bset_result;
|
||||
|
||||
// pack and shuffle operations
|
||||
`ALU_SHUF, `ALU_SHUF2,
|
||||
`ALU_PCKLO, `ALU_PCKHI,
|
||||
`ALU_EXT, `ALU_EXTS,
|
||||
`ALU_INS: result_o = pack_result;
|
||||
ALU_SHUF, ALU_SHUF2,
|
||||
ALU_PCKLO, ALU_PCKHI,
|
||||
ALU_EXT, ALU_EXTS,
|
||||
ALU_INS: result_o = pack_result;
|
||||
|
||||
// Min/Max/Abs/Ins
|
||||
`ALU_MIN, `ALU_MINU,
|
||||
`ALU_MAX, `ALU_MAXU,
|
||||
`ALU_ABS: result_o = result_minmax;
|
||||
ALU_MIN, ALU_MINU,
|
||||
ALU_MAX, ALU_MAXU,
|
||||
ALU_ABS: result_o = result_minmax;
|
||||
|
||||
`ALU_CLIP, `ALU_CLIPU: result_o = clip_result;
|
||||
ALU_CLIP, ALU_CLIPU: result_o = clip_result;
|
||||
|
||||
// Comparison Operations
|
||||
`ALU_EQ, `ALU_NE,
|
||||
`ALU_GTU, `ALU_GEU,
|
||||
`ALU_LTU, `ALU_LEU,
|
||||
`ALU_GTS, `ALU_GES,
|
||||
`ALU_LTS, `ALU_LES: begin
|
||||
ALU_EQ, ALU_NE,
|
||||
ALU_GTU, ALU_GEU,
|
||||
ALU_LTU, ALU_LEU,
|
||||
ALU_GTS, ALU_GES,
|
||||
ALU_LTS, ALU_LES: begin
|
||||
result_o[31:24] = {8{cmp_result[3]}};
|
||||
result_o[23:16] = {8{cmp_result[2]}};
|
||||
result_o[15: 8] = {8{cmp_result[1]}};
|
||||
result_o[ 7: 0] = {8{cmp_result[0]}};
|
||||
end
|
||||
`ALU_SLTS, `ALU_SLTU,
|
||||
`ALU_SLETS, `ALU_SLETU: result_o = {31'b0, comparison_result_o};
|
||||
ALU_SLTS, ALU_SLTU,
|
||||
ALU_SLETS, ALU_SLETU: result_o = {31'b0, comparison_result_o};
|
||||
|
||||
`ALU_FF1, `ALU_FL1, `ALU_CLB, `ALU_CNT: result_o = {26'h0, bitop_result[5:0]};
|
||||
ALU_FF1, ALU_FL1, ALU_CLB, ALU_CNT: result_o = {26'h0, bitop_result[5:0]};
|
||||
|
||||
// Division Unit Commands
|
||||
`ALU_DIV, `ALU_DIVU,
|
||||
`ALU_REM, `ALU_REMU: result_o = result_div;
|
||||
ALU_DIV, ALU_DIVU,
|
||||
ALU_REM, ALU_REMU: result_o = result_div;
|
||||
|
||||
default: ; // default case to suppress unique warning
|
||||
endcase
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_compressed_decoder
|
||||
(
|
||||
|
@ -51,18 +51,18 @@ module riscv_compressed_decoder
|
|||
unique case (instr_i[15:13])
|
||||
3'b000: begin
|
||||
// c.addi4spn -> addi rd', x2, imm
|
||||
instr_o = {2'b0, instr_i[10:7], instr_i[12:11], instr_i[5], instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], `OPCODE_OPIMM};
|
||||
instr_o = {2'b0, instr_i[10:7], instr_i[12:11], instr_i[5], instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], OPCODE_OPIMM};
|
||||
if (instr_i[12:5] == 8'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b010: begin
|
||||
// c.lw -> lw rd', imm(rs1')
|
||||
instr_o = {5'b0, instr_i[5], instr_i[12:10], instr_i[6], 2'b00, 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], `OPCODE_LOAD};
|
||||
instr_o = {5'b0, instr_i[5], instr_i[12:10], instr_i[6], 2'b00, 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], OPCODE_LOAD};
|
||||
end
|
||||
|
||||
3'b110: begin
|
||||
// c.sw -> sw rs2', imm(rs1')
|
||||
instr_o = {5'b0, instr_i[5], instr_i[12], 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6], 2'b00, `OPCODE_STORE};
|
||||
instr_o = {5'b0, instr_i[5], instr_i[12], 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6], 2'b00, OPCODE_STORE};
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
@ -77,28 +77,28 @@ module riscv_compressed_decoder
|
|||
3'b000: begin
|
||||
// c.addi -> addi rd, rd, nzimm
|
||||
// c.nop
|
||||
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], `OPCODE_OPIMM};
|
||||
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], OPCODE_OPIMM};
|
||||
end
|
||||
|
||||
3'b001, 3'b101: begin
|
||||
// 001: c.jal -> jal x1, imm
|
||||
// 101: c.j -> jal x0, imm
|
||||
instr_o = {instr_i[12], instr_i[8], instr_i[10:9], instr_i[6], instr_i[7], instr_i[2], instr_i[11], instr_i[5:3], {9 {instr_i[12]}}, 4'b0, ~instr_i[15], `OPCODE_JAL};
|
||||
instr_o = {instr_i[12], instr_i[8], instr_i[10:9], instr_i[6], instr_i[7], instr_i[2], instr_i[11], instr_i[5:3], {9 {instr_i[12]}}, 4'b0, ~instr_i[15], OPCODE_JAL};
|
||||
end
|
||||
|
||||
3'b010: begin
|
||||
// c.li -> addi rd, x0, nzimm
|
||||
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], `OPCODE_OPIMM};
|
||||
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], OPCODE_OPIMM};
|
||||
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b011: begin
|
||||
// c.lui -> lui rd, imm
|
||||
instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], `OPCODE_LUI};
|
||||
instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], OPCODE_LUI};
|
||||
|
||||
if (instr_i[11:7] == 5'h02) begin
|
||||
// c.addi16sp -> addi x2, x2, nzimm
|
||||
instr_o = {{3 {instr_i[12]}}, instr_i[4:3], instr_i[5], instr_i[2], instr_i[6], 4'b0, 5'h02, 3'b000, 5'h02, `OPCODE_OPIMM};
|
||||
instr_o = {{3 {instr_i[12]}}, instr_i[4:3], instr_i[5], instr_i[2], instr_i[6], 4'b0, 5'h02, 3'b000, 5'h02, OPCODE_OPIMM};
|
||||
end else if (instr_i[11:7] == 5'b0) begin
|
||||
illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
@ -112,36 +112,36 @@ module riscv_compressed_decoder
|
|||
2'b01: begin
|
||||
// 00: c.srli -> srli rd, rd, shamt
|
||||
// 01: c.srai -> srai rd, rd, shamt
|
||||
instr_o = {1'b0, instr_i[10], 5'b0, instr_i[6:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[9:7], `OPCODE_OPIMM};
|
||||
instr_o = {1'b0, instr_i[10], 5'b0, instr_i[6:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[9:7], OPCODE_OPIMM};
|
||||
if (instr_i[12] == 1'b1) illegal_instr_o = 1'b1;
|
||||
if (instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
2'b10: begin
|
||||
// c.andi -> andi rd, rd, imm
|
||||
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], `OPCODE_OPIMM};
|
||||
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], OPCODE_OPIMM};
|
||||
end
|
||||
|
||||
2'b11: begin
|
||||
unique case ({instr_i[12], instr_i[6:5]})
|
||||
3'b000: begin
|
||||
// c.sub -> sub rd', rd', rs2'
|
||||
instr_o = {2'b01, 5'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], `OPCODE_OP};
|
||||
instr_o = {2'b01, 5'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], OPCODE_OP};
|
||||
end
|
||||
|
||||
3'b001: begin
|
||||
// c.xor -> xor rd', rd', rs2'
|
||||
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], `OPCODE_OP};
|
||||
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], OPCODE_OP};
|
||||
end
|
||||
|
||||
3'b010: begin
|
||||
// c.or -> or rd', rd', rs2'
|
||||
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[9:7], `OPCODE_OP};
|
||||
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[9:7], OPCODE_OP};
|
||||
end
|
||||
|
||||
3'b011: begin
|
||||
// c.and -> and rd', rd', rs2'
|
||||
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], `OPCODE_OP};
|
||||
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], OPCODE_OP};
|
||||
end
|
||||
|
||||
3'b100,
|
||||
|
@ -160,7 +160,7 @@ module riscv_compressed_decoder
|
|||
3'b110, 3'b111: begin
|
||||
// 0: c.beqz -> beq rs1', x0, imm
|
||||
// 1: c.bnez -> bne rs1', x0, imm
|
||||
instr_o = {{4 {instr_i[12]}}, instr_i[6:5], instr_i[2], 5'b0, 2'b01, instr_i[9:7], 2'b00, instr_i[13], instr_i[11:10], instr_i[4:3], instr_i[12], `OPCODE_BRANCH};
|
||||
instr_o = {{4 {instr_i[12]}}, instr_i[6:5], instr_i[2], 5'b0, 2'b01, instr_i[9:7], 2'b00, instr_i[13], instr_i[11:10], instr_i[4:3], instr_i[12], OPCODE_BRANCH};
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
@ -174,29 +174,29 @@ module riscv_compressed_decoder
|
|||
unique case (instr_i[15:13])
|
||||
3'b000: begin
|
||||
// c.slli -> slli rd, rd, shamt
|
||||
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b001, instr_i[11:7], `OPCODE_OPIMM};
|
||||
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b001, instr_i[11:7], OPCODE_OPIMM};
|
||||
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
|
||||
if (instr_i[12] == 1'b1 || instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b010: begin
|
||||
// c.lwsp -> lw rd, imm(x2)
|
||||
instr_o = {4'b0, instr_i[3:2], instr_i[12], instr_i[6:4], 2'b00, 5'h02, 3'b010, instr_i[11:7], `OPCODE_LOAD};
|
||||
instr_o = {4'b0, instr_i[3:2], instr_i[12], instr_i[6:4], 2'b00, 5'h02, 3'b010, instr_i[11:7], OPCODE_LOAD};
|
||||
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b100: begin
|
||||
if (instr_i[12] == 1'b0) begin
|
||||
// c.mv -> add rd/rs1, x0, rs2
|
||||
instr_o = {7'b0, instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], `OPCODE_OP};
|
||||
instr_o = {7'b0, instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], OPCODE_OP};
|
||||
|
||||
if (instr_i[6:2] == 5'b0) begin
|
||||
// c.jr -> jalr x0, rd/rs1, 0
|
||||
instr_o = {12'b0, instr_i[11:7], 3'b0, 5'b0, `OPCODE_JALR};
|
||||
instr_o = {12'b0, instr_i[11:7], 3'b0, 5'b0, OPCODE_JALR};
|
||||
end
|
||||
end else begin
|
||||
// c.add -> add rd, rd, rs2
|
||||
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], `OPCODE_OP};
|
||||
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], OPCODE_OP};
|
||||
|
||||
if (instr_i[11:7] == 5'b0) begin
|
||||
// c.ebreak -> ebreak
|
||||
|
@ -205,14 +205,14 @@ module riscv_compressed_decoder
|
|||
illegal_instr_o = 1'b1;
|
||||
end else if (instr_i[6:2] == 5'b0) begin
|
||||
// c.jalr -> jalr x1, rs1, 0
|
||||
instr_o = {12'b0, instr_i[11:7], 3'b000, 5'b00001, `OPCODE_JALR};
|
||||
instr_o = {12'b0, instr_i[11:7], 3'b000, 5'b00001, OPCODE_JALR};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
3'b110: begin
|
||||
// c.swsp -> sw rs2, imm(x2)
|
||||
instr_o = {4'b0, instr_i[8:7], instr_i[12], instr_i[6:2], 5'h02, 3'b010, instr_i[11:9], 2'b00, `OPCODE_STORE};
|
||||
instr_o = {4'b0, instr_i[8:7], instr_i[12], instr_i[6:2], 5'h02, 3'b010, instr_i[11:9], 2'b00, OPCODE_STORE};
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_controller
|
||||
(
|
||||
|
@ -172,7 +172,7 @@ module riscv_controller
|
|||
exc_save_id_o = 1'b0;
|
||||
exc_restore_id_o = 1'b0;
|
||||
|
||||
pc_mux_o = `PC_BOOT;
|
||||
pc_mux_o = PC_BOOT;
|
||||
pc_set_o = 1'b0;
|
||||
jump_done = jump_done_q;
|
||||
|
||||
|
@ -205,7 +205,7 @@ module riscv_controller
|
|||
BOOT_SET:
|
||||
begin
|
||||
instr_req_o = 1'b1;
|
||||
pc_mux_o = `PC_BOOT;
|
||||
pc_mux_o = PC_BOOT;
|
||||
pc_set_o = 1'b1;
|
||||
|
||||
ctrl_fsm_ns = FIRST_FETCH;
|
||||
|
@ -248,7 +248,7 @@ module riscv_controller
|
|||
|
||||
// handle exceptions
|
||||
if (exc_req_i) begin
|
||||
pc_mux_o = `PC_EXCEPTION;
|
||||
pc_mux_o = PC_EXCEPTION;
|
||||
pc_set_o = 1'b1;
|
||||
exc_ack_o = 1'b1;
|
||||
|
||||
|
@ -273,8 +273,8 @@ module riscv_controller
|
|||
// we can jump directly since we know the address already
|
||||
// we don't need to worry about conditional branches here as they
|
||||
// will be evaluated in the EX stage
|
||||
if (jump_in_dec_i == `BRANCH_JALR || jump_in_dec_i == `BRANCH_JAL) begin
|
||||
pc_mux_o = `PC_JUMP;
|
||||
if (jump_in_dec_i == BRANCH_JALR || jump_in_dec_i == BRANCH_JAL) begin
|
||||
pc_mux_o = PC_JUMP;
|
||||
|
||||
// if there is a jr stall, wait for it to be gone
|
||||
if ((~jr_stall_o) && (~jump_done_q)) begin
|
||||
|
@ -288,7 +288,7 @@ module riscv_controller
|
|||
end else begin
|
||||
// handle exceptions
|
||||
if (exc_req_i) begin
|
||||
pc_mux_o = `PC_EXCEPTION;
|
||||
pc_mux_o = PC_EXCEPTION;
|
||||
pc_set_o = 1'b1;
|
||||
exc_ack_o = 1'b1;
|
||||
|
||||
|
@ -303,7 +303,7 @@ module riscv_controller
|
|||
end
|
||||
|
||||
if (eret_insn_i) begin
|
||||
pc_mux_o = `PC_ERET;
|
||||
pc_mux_o = PC_ERET;
|
||||
exc_restore_id_o = 1'b1;
|
||||
|
||||
if ((~jump_done_q)) begin
|
||||
|
@ -332,7 +332,7 @@ module riscv_controller
|
|||
// make sure the current instruction has been executed
|
||||
// before changing state to non-decode
|
||||
if (id_ready_i) begin
|
||||
if (jump_in_id_i == `BRANCH_COND)
|
||||
if (jump_in_id_i == BRANCH_COND)
|
||||
ctrl_fsm_ns = DBG_WAIT_BRANCH;
|
||||
else
|
||||
ctrl_fsm_ns = DBG_SIGNAL;
|
||||
|
@ -352,7 +352,7 @@ module riscv_controller
|
|||
// handle conditional branches
|
||||
if (branch_taken_ex_i) begin
|
||||
// there is a branch in the EX stage that is taken
|
||||
pc_mux_o = `PC_BRANCH;
|
||||
pc_mux_o = PC_BRANCH;
|
||||
pc_set_o = 1'b1;
|
||||
|
||||
is_decoding_o = 1'b0; // we are not decoding the current instruction in the ID stage
|
||||
|
@ -374,7 +374,7 @@ module riscv_controller
|
|||
|
||||
if (branch_taken_ex_i) begin
|
||||
// there is a branch in the EX stage that is taken
|
||||
pc_mux_o = `PC_BRANCH;
|
||||
pc_mux_o = PC_BRANCH;
|
||||
pc_set_o = 1'b1;
|
||||
end
|
||||
|
||||
|
@ -406,7 +406,7 @@ module riscv_controller
|
|||
halt_if_o = 1'b1;
|
||||
|
||||
if (dbg_jump_req_i) begin
|
||||
pc_mux_o = `PC_DBG_NPC;
|
||||
pc_mux_o = PC_DBG_NPC;
|
||||
pc_set_o = 1'b1;
|
||||
ctrl_fsm_ns = DBG_WAIT;
|
||||
end
|
||||
|
@ -423,7 +423,7 @@ module riscv_controller
|
|||
halt_if_o = 1'b1;
|
||||
|
||||
if (dbg_jump_req_i) begin
|
||||
pc_mux_o = `PC_DBG_NPC;
|
||||
pc_mux_o = PC_DBG_NPC;
|
||||
pc_set_o = 1'b1;
|
||||
ctrl_fsm_ns = DBG_WAIT;
|
||||
end
|
||||
|
@ -506,7 +506,7 @@ module riscv_controller
|
|||
// - always stall if a result is to be forwarded to the PC
|
||||
// we don't care about in which state the ctrl_fsm is as we deassert_we
|
||||
// anyway when we are not in DECODE
|
||||
if ((jump_in_dec_i == `BRANCH_JALR) &&
|
||||
if ((jump_in_dec_i == BRANCH_JALR) &&
|
||||
(((regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_a_i == 1'b1)) ||
|
||||
((regfile_we_ex_i == 1'b1) && (reg_d_ex_is_reg_a_i == 1'b1)) ||
|
||||
((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1))) )
|
||||
|
@ -524,39 +524,39 @@ module riscv_controller
|
|||
always_comb
|
||||
begin
|
||||
// default assignements
|
||||
operand_a_fw_mux_sel_o = `SEL_REGFILE;
|
||||
operand_b_fw_mux_sel_o = `SEL_REGFILE;
|
||||
operand_c_fw_mux_sel_o = `SEL_REGFILE;
|
||||
operand_a_fw_mux_sel_o = SEL_REGFILE;
|
||||
operand_b_fw_mux_sel_o = SEL_REGFILE;
|
||||
operand_c_fw_mux_sel_o = SEL_REGFILE;
|
||||
|
||||
// Forwarding WB -> ID
|
||||
if (regfile_we_wb_i == 1'b1)
|
||||
begin
|
||||
if (reg_d_wb_is_reg_a_i == 1'b1)
|
||||
operand_a_fw_mux_sel_o = `SEL_FW_WB;
|
||||
operand_a_fw_mux_sel_o = SEL_FW_WB;
|
||||
if (reg_d_wb_is_reg_b_i == 1'b1)
|
||||
operand_b_fw_mux_sel_o = `SEL_FW_WB;
|
||||
operand_b_fw_mux_sel_o = SEL_FW_WB;
|
||||
if (reg_d_wb_is_reg_c_i == 1'b1)
|
||||
operand_c_fw_mux_sel_o = `SEL_FW_WB;
|
||||
operand_c_fw_mux_sel_o = SEL_FW_WB;
|
||||
end
|
||||
|
||||
// Forwarding EX -> ID
|
||||
if (regfile_alu_we_fw_i == 1'b1)
|
||||
begin
|
||||
if (reg_d_alu_is_reg_a_i == 1'b1)
|
||||
operand_a_fw_mux_sel_o = `SEL_FW_EX;
|
||||
operand_a_fw_mux_sel_o = SEL_FW_EX;
|
||||
if (reg_d_alu_is_reg_b_i == 1'b1)
|
||||
operand_b_fw_mux_sel_o = `SEL_FW_EX;
|
||||
operand_b_fw_mux_sel_o = SEL_FW_EX;
|
||||
if (reg_d_alu_is_reg_c_i == 1'b1)
|
||||
operand_c_fw_mux_sel_o = `SEL_FW_EX;
|
||||
operand_c_fw_mux_sel_o = SEL_FW_EX;
|
||||
end
|
||||
|
||||
// for misaligned memory accesses
|
||||
if (data_misaligned_i)
|
||||
begin
|
||||
operand_a_fw_mux_sel_o = `SEL_FW_EX;
|
||||
operand_b_fw_mux_sel_o = `SEL_REGFILE;
|
||||
operand_a_fw_mux_sel_o = SEL_FW_EX;
|
||||
operand_b_fw_mux_sel_o = SEL_REGFILE;
|
||||
end else if (mult_multicycle_i) begin
|
||||
operand_c_fw_mux_sel_o = `SEL_FW_EX;
|
||||
operand_c_fw_mux_sel_o = SEL_FW_EX;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -578,7 +578,7 @@ module riscv_controller
|
|||
end
|
||||
|
||||
// Performance Counters
|
||||
assign perf_jump_o = (jump_in_id_i == `BRANCH_JAL || jump_in_id_i == `BRANCH_JALR);
|
||||
assign perf_jump_o = (jump_in_id_i == BRANCH_JAL || jump_in_id_i == BRANCH_JALR);
|
||||
assign perf_jr_stall_o = jr_stall_o;
|
||||
assign perf_ld_stall_o = load_stall_o;
|
||||
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
`ifndef PULP_FPGA_EMUL
|
||||
`ifdef SYNTHESIS
|
||||
`define ASIC_SYNTHESIS
|
||||
`endif
|
||||
`ifdef SYNTHESIS
|
||||
`define ASIC_SYNTHESIS
|
||||
`endif
|
||||
`endif
|
||||
|
||||
module riscv_cs_registers
|
||||
|
@ -135,7 +135,7 @@ module riscv_cs_registers
|
|||
////////////////////////////////////////////
|
||||
// ____ ____ ____ ____ //
|
||||
// / ___/ ___|| _ \ | _ \ ___ __ _ //
|
||||
// | | \___ \| |_) | | |_) / _ \/ _` | //
|
||||
// | | \___ \| |_) | | |_) / _ \/ _` | //
|
||||
// | |___ ___) | _ < | _ < __/ (_| | //
|
||||
// \____|____/|_| \_\ |_| \_\___|\__, | //
|
||||
// |___/ //
|
||||
|
@ -239,11 +239,11 @@ module riscv_cs_registers
|
|||
csr_we_int = 1'b1;
|
||||
|
||||
unique case (csr_op_i)
|
||||
`CSR_OP_WRITE: csr_wdata_int = csr_wdata_i;
|
||||
`CSR_OP_SET: csr_wdata_int = csr_wdata_i | csr_rdata_o;
|
||||
`CSR_OP_CLEAR: csr_wdata_int = (~csr_wdata_i) & csr_rdata_o;
|
||||
CSR_OP_WRITE: csr_wdata_int = csr_wdata_i;
|
||||
CSR_OP_SET: csr_wdata_int = csr_wdata_i | csr_rdata_o;
|
||||
CSR_OP_CLEAR: csr_wdata_int = (~csr_wdata_i) & csr_rdata_o;
|
||||
|
||||
`CSR_OP_NONE: begin
|
||||
CSR_OP_NONE: begin
|
||||
csr_wdata_int = csr_wdata_i;
|
||||
csr_we_int = 1'b0;
|
||||
end
|
||||
|
@ -378,10 +378,10 @@ module riscv_cs_registers
|
|||
|
||||
if (is_pccr == 1'b1) begin
|
||||
unique case (csr_op_i)
|
||||
`CSR_OP_NONE: ;
|
||||
`CSR_OP_WRITE: PCCR_n[0] = csr_wdata_i;
|
||||
`CSR_OP_SET: PCCR_n[0] = csr_wdata_i | PCCR_q[0];
|
||||
`CSR_OP_CLEAR: PCCR_n[0] = csr_wdata_i & ~(PCCR_q[0]);
|
||||
CSR_OP_NONE: ;
|
||||
CSR_OP_WRITE: PCCR_n[0] = csr_wdata_i;
|
||||
CSR_OP_SET: PCCR_n[0] = csr_wdata_i | PCCR_q[0];
|
||||
CSR_OP_CLEAR: PCCR_n[0] = csr_wdata_i & ~(PCCR_q[0]);
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -399,10 +399,10 @@ module riscv_cs_registers
|
|||
|
||||
if (is_pccr == 1'b1 && (pccr_all_sel == 1'b1 || pccr_index == i)) begin
|
||||
unique case (csr_op_i)
|
||||
`CSR_OP_NONE: ;
|
||||
`CSR_OP_WRITE: PCCR_n[i] = csr_wdata_i;
|
||||
`CSR_OP_SET: PCCR_n[i] = csr_wdata_i | PCCR_q[i];
|
||||
`CSR_OP_CLEAR: PCCR_n[i] = csr_wdata_i & ~(PCCR_q[i]);
|
||||
CSR_OP_NONE: ;
|
||||
CSR_OP_WRITE: PCCR_n[i] = csr_wdata_i;
|
||||
CSR_OP_SET: PCCR_n[i] = csr_wdata_i | PCCR_q[i];
|
||||
CSR_OP_CLEAR: PCCR_n[i] = csr_wdata_i & ~(PCCR_q[i]);
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
@ -417,19 +417,19 @@ module riscv_cs_registers
|
|||
|
||||
if (is_pcmr) begin
|
||||
unique case (csr_op_i)
|
||||
`CSR_OP_NONE: ;
|
||||
`CSR_OP_WRITE: PCMR_n = csr_wdata_i[1:0];
|
||||
`CSR_OP_SET: PCMR_n = csr_wdata_i[1:0] | PCMR_q;
|
||||
`CSR_OP_CLEAR: PCMR_n = csr_wdata_i[1:0] & ~(PCMR_q);
|
||||
CSR_OP_NONE: ;
|
||||
CSR_OP_WRITE: PCMR_n = csr_wdata_i[1:0];
|
||||
CSR_OP_SET: PCMR_n = csr_wdata_i[1:0] | PCMR_q;
|
||||
CSR_OP_CLEAR: PCMR_n = csr_wdata_i[1:0] & ~(PCMR_q);
|
||||
endcase
|
||||
end
|
||||
|
||||
if (is_pcer) begin
|
||||
unique case (csr_op_i)
|
||||
`CSR_OP_NONE: ;
|
||||
`CSR_OP_WRITE: PCER_n = csr_wdata_i[N_PERF_COUNTERS-1:0];
|
||||
`CSR_OP_SET: PCER_n = csr_wdata_i[N_PERF_COUNTERS-1:0] | PCER_q;
|
||||
`CSR_OP_CLEAR: PCER_n = csr_wdata_i[N_PERF_COUNTERS-1:0] & ~(PCER_q);
|
||||
CSR_OP_NONE: ;
|
||||
CSR_OP_WRITE: PCER_n = csr_wdata_i[N_PERF_COUNTERS-1:0];
|
||||
CSR_OP_SET: PCER_n = csr_wdata_i[N_PERF_COUNTERS-1:0] | PCER_q;
|
||||
CSR_OP_CLEAR: PCER_n = csr_wdata_i[N_PERF_COUNTERS-1:0] & ~(PCER_q);
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_debug_unit
|
||||
(
|
||||
|
@ -41,7 +41,7 @@ module riscv_debug_unit
|
|||
input logic debug_resume_i,
|
||||
|
||||
// signals to core
|
||||
output logic [`DBG_SETS_W-1:0] settings_o,
|
||||
output logic [DBG_SETS_W-1:0] settings_o,
|
||||
|
||||
input logic trap_i, // trap found, need to stop the core now
|
||||
input logic [5:0] exc_cause_i, // if it was a trap, then the exception controller knows more
|
||||
|
@ -87,7 +87,7 @@ module riscv_debug_unit
|
|||
|
||||
enum logic [0:0] {FIRST, SECOND} state_q, state_n;
|
||||
|
||||
logic [`DBG_SETS_W-1:0] settings_q, settings_n;
|
||||
logic [DBG_SETS_W-1:0] settings_q, settings_n;
|
||||
|
||||
// for timing critical register file access we need to keep those in FFs
|
||||
logic [14:0] addr_q;
|
||||
|
@ -177,16 +177,16 @@ module riscv_debug_unit
|
|||
end
|
||||
end
|
||||
|
||||
settings_n[`DBG_SETS_SSTE] = debug_wdata_i[0];
|
||||
settings_n[DBG_SETS_SSTE] = debug_wdata_i[0];
|
||||
end
|
||||
5'b0_0001: begin // DBG_HIT
|
||||
ssth_clear = debug_wdata_i[0];
|
||||
end
|
||||
5'b0_0010: begin // DBG_IE
|
||||
settings_n[`DBG_SETS_ECALL] = debug_wdata_i[11];
|
||||
settings_n[`DBG_SETS_ELSU] = debug_wdata_i[7] | debug_wdata_i[5];
|
||||
settings_n[`DBG_SETS_EBRK] = debug_wdata_i[3];
|
||||
settings_n[`DBG_SETS_EILL] = debug_wdata_i[2];
|
||||
settings_n[DBG_SETS_ECALL] = debug_wdata_i[11];
|
||||
settings_n[DBG_SETS_ELSU] = debug_wdata_i[7] | debug_wdata_i[5];
|
||||
settings_n[DBG_SETS_EBRK] = debug_wdata_i[3];
|
||||
settings_n[DBG_SETS_EILL] = debug_wdata_i[2];
|
||||
end
|
||||
default:;
|
||||
endcase
|
||||
|
@ -271,19 +271,19 @@ module riscv_debug_unit
|
|||
case (rdata_sel_q)
|
||||
RD_DBGA: begin
|
||||
unique case (addr_q[6:2])
|
||||
5'h00: dbg_rdata[31:0] = {15'b0, debug_halted_o, 15'b0, settings_q[`DBG_SETS_SSTE]}; // DBG_CTRL
|
||||
5'h00: dbg_rdata[31:0] = {15'b0, debug_halted_o, 15'b0, settings_q[DBG_SETS_SSTE]}; // DBG_CTRL
|
||||
5'h01: dbg_rdata[31:0] = {15'b0, sleeping_i, 15'b0, dbg_ssth_q}; // DBG_HIT
|
||||
5'h02: begin // DBG_IE
|
||||
dbg_rdata[31:16] = '0;
|
||||
dbg_rdata[15:12] = '0;
|
||||
dbg_rdata[11] = settings_q[`DBG_SETS_ECALL];
|
||||
dbg_rdata[11] = settings_q[DBG_SETS_ECALL];
|
||||
dbg_rdata[10: 8] = '0;
|
||||
dbg_rdata[ 7] = settings_q[`DBG_SETS_ELSU];
|
||||
dbg_rdata[ 7] = settings_q[DBG_SETS_ELSU];
|
||||
dbg_rdata[ 6] = 1'b0;
|
||||
dbg_rdata[ 5] = settings_q[`DBG_SETS_ELSU];
|
||||
dbg_rdata[ 5] = settings_q[DBG_SETS_ELSU];
|
||||
dbg_rdata[ 4] = 1'b0;
|
||||
dbg_rdata[ 3] = settings_q[`DBG_SETS_EBRK];
|
||||
dbg_rdata[ 2] = settings_q[`DBG_SETS_EILL];
|
||||
dbg_rdata[ 3] = settings_q[DBG_SETS_EBRK];
|
||||
dbg_rdata[ 2] = settings_q[DBG_SETS_EILL];
|
||||
dbg_rdata[ 1: 0] = '0;
|
||||
end
|
||||
5'h03: dbg_rdata = {dbg_cause_q[5], 26'b0, dbg_cause_q[4:0]}; // DBG_CAUSE
|
||||
|
@ -359,12 +359,12 @@ module riscv_debug_unit
|
|||
stall_ns = HALT_REQ;
|
||||
|
||||
if (trap_i) begin
|
||||
if (settings_q[`DBG_SETS_SSTE])
|
||||
if (settings_q[DBG_SETS_SSTE])
|
||||
dbg_ssth_n = 1'b1;
|
||||
|
||||
dbg_cause_n = exc_cause_i;
|
||||
end else begin
|
||||
dbg_cause_n = `DBG_CAUSE_HALT;
|
||||
dbg_cause_n = DBG_CAUSE_HALT;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -398,7 +398,7 @@ module riscv_debug_unit
|
|||
begin
|
||||
if (~rst_n) begin
|
||||
stall_cs <= RUNNING;
|
||||
dbg_cause_q <= `DBG_CAUSE_HALT;
|
||||
dbg_cause_q <= DBG_CAUSE_HALT;
|
||||
dbg_ssth_q <= 1'b0;
|
||||
end else begin
|
||||
stall_cs <= stall_ns;
|
||||
|
|
486
decoder.sv
486
decoder.sv
|
@ -24,7 +24,7 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_decoder
|
||||
(
|
||||
|
@ -52,7 +52,7 @@ module riscv_decoder
|
|||
input logic illegal_c_insn_i, // compressed instruction decode failed
|
||||
|
||||
// ALU signals
|
||||
output logic [`ALU_OP_WIDTH-1:0] alu_operator_o, // ALU operation selection
|
||||
output logic [ALU_OP_WIDTH-1:0] alu_operator_o, // ALU operation selection
|
||||
output logic [1:0] alu_op_a_mux_sel_o, // operand a selection: reg value, PC, immediate or zero
|
||||
output logic [1:0] alu_op_b_mux_sel_o, // operand b selection: reg value or immediate
|
||||
output logic [1:0] alu_op_c_mux_sel_o, // operand c selection: reg value or jump target
|
||||
|
@ -127,23 +127,23 @@ module riscv_decoder
|
|||
|
||||
always_comb
|
||||
begin
|
||||
jump_in_id = `BRANCH_NONE;
|
||||
jump_target_mux_sel_o = `JT_JAL;
|
||||
jump_in_id = BRANCH_NONE;
|
||||
jump_target_mux_sel_o = JT_JAL;
|
||||
|
||||
alu_operator_o = `ALU_SLTU;
|
||||
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGB_OR_FWD;
|
||||
alu_op_c_mux_sel_o = `OP_C_REGC_OR_FWD;
|
||||
alu_vec_mode_o = `VEC_MODE32;
|
||||
alu_operator_o = ALU_SLTU;
|
||||
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGB_OR_FWD;
|
||||
alu_op_c_mux_sel_o = OP_C_REGC_OR_FWD;
|
||||
alu_vec_mode_o = VEC_MODE32;
|
||||
scalar_replication_o = 1'b0;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
imm_a_mux_sel_o = `IMMA_ZERO;
|
||||
imm_b_mux_sel_o = `IMMB_I;
|
||||
regc_mux_o = REGC_ZERO;
|
||||
imm_a_mux_sel_o = IMMA_ZERO;
|
||||
imm_b_mux_sel_o = IMMB_I;
|
||||
|
||||
mult_operator_o = `MUL_I;
|
||||
mult_operator_o = MUL_I;
|
||||
mult_int_en_o = 1'b0;
|
||||
mult_dot_en_o = 1'b0;
|
||||
mult_imm_mux_o = `MIMM_ZERO;
|
||||
mult_imm_mux_o = MIMM_ZERO;
|
||||
mult_signed_mode_o = 2'b00;
|
||||
mult_sel_subword_o = 1'b0;
|
||||
mult_dot_signed_o = 2'b00;
|
||||
|
@ -160,7 +160,7 @@ module riscv_decoder
|
|||
hwloop_cnt_mux_sel_o = 1'b0;
|
||||
|
||||
csr_access_o = 1'b0;
|
||||
csr_op = `CSR_OP_NONE;
|
||||
csr_op = CSR_OP_NONE;
|
||||
|
||||
data_we_o = 1'b0;
|
||||
data_type_o = 2'b00;
|
||||
|
@ -179,8 +179,8 @@ module riscv_decoder
|
|||
regb_used_o = 1'b0;
|
||||
regc_used_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;
|
||||
bmask_a_mux_o = BMASK_A_ZERO;
|
||||
bmask_b_mux_o = BMASK_B_ZERO;
|
||||
|
||||
|
||||
unique case (instr_rdata_i[6:0])
|
||||
|
@ -194,52 +194,52 @@ module riscv_decoder
|
|||
// //
|
||||
//////////////////////////////////////
|
||||
|
||||
`OPCODE_JAL: begin // Jump and Link
|
||||
jump_target_mux_sel_o = `JT_JAL;
|
||||
jump_in_id = `BRANCH_JAL;
|
||||
OPCODE_JAL: begin // Jump and Link
|
||||
jump_target_mux_sel_o = JT_JAL;
|
||||
jump_in_id = BRANCH_JAL;
|
||||
// Calculate and store PC+4
|
||||
alu_op_a_mux_sel_o = `OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_PCINCR;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_PCINCR;
|
||||
alu_operator_o = ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
// Calculate jump target (= PC + UJ imm)
|
||||
end
|
||||
|
||||
`OPCODE_JALR: begin // Jump and Link Register
|
||||
jump_target_mux_sel_o = `JT_JALR;
|
||||
jump_in_id = `BRANCH_JALR;
|
||||
OPCODE_JALR: begin // Jump and Link Register
|
||||
jump_target_mux_sel_o = JT_JALR;
|
||||
jump_in_id = BRANCH_JALR;
|
||||
// Calculate and store PC+4
|
||||
alu_op_a_mux_sel_o = `OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_PCINCR;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_PCINCR;
|
||||
alu_operator_o = ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
// Calculate jump target (= RS1 + I imm)
|
||||
rega_used_o = 1'b1;
|
||||
|
||||
if (instr_rdata_i[14:12] != 3'b0) begin
|
||||
jump_in_id = `BRANCH_NONE;
|
||||
jump_in_id = BRANCH_NONE;
|
||||
regfile_alu_we = 1'b0;
|
||||
illegal_insn_o = 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
`OPCODE_BRANCH: begin // Branch
|
||||
jump_target_mux_sel_o = `JT_COND;
|
||||
jump_in_id = `BRANCH_COND;
|
||||
alu_op_c_mux_sel_o = `OP_C_JT;
|
||||
OPCODE_BRANCH: begin // Branch
|
||||
jump_target_mux_sel_o = JT_COND;
|
||||
jump_in_id = BRANCH_COND;
|
||||
alu_op_c_mux_sel_o = OP_C_JT;
|
||||
rega_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
|
||||
unique case (instr_rdata_i[14:12])
|
||||
3'b000: alu_operator_o = `ALU_EQ;
|
||||
3'b001: alu_operator_o = `ALU_NE;
|
||||
3'b100: alu_operator_o = `ALU_LTS;
|
||||
3'b101: alu_operator_o = `ALU_GES;
|
||||
3'b110: alu_operator_o = `ALU_LTU;
|
||||
3'b111: alu_operator_o = `ALU_GEU;
|
||||
3'b010: alu_operator_o = `ALU_EQALL;
|
||||
3'b000: alu_operator_o = ALU_EQ;
|
||||
3'b001: alu_operator_o = ALU_NE;
|
||||
3'b100: alu_operator_o = ALU_LTS;
|
||||
3'b101: alu_operator_o = ALU_GES;
|
||||
3'b110: alu_operator_o = ALU_LTU;
|
||||
3'b111: alu_operator_o = ALU_GEU;
|
||||
3'b010: alu_operator_o = ALU_EQALL;
|
||||
|
||||
default: begin
|
||||
illegal_insn_o = 1'b1;
|
||||
|
@ -257,19 +257,19 @@ module riscv_decoder
|
|||
// //
|
||||
//////////////////////////////////
|
||||
|
||||
`OPCODE_STORE,
|
||||
`OPCODE_STORE_POST: begin
|
||||
OPCODE_STORE,
|
||||
OPCODE_STORE_POST: begin
|
||||
data_req = 1'b1;
|
||||
data_we_o = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
alu_operator_o = ALU_ADD;
|
||||
|
||||
// pass write data through ALU operand c
|
||||
alu_op_c_mux_sel_o = `OP_C_REGB_OR_FWD;
|
||||
alu_op_c_mux_sel_o = OP_C_REGB_OR_FWD;
|
||||
|
||||
// post-increment setup
|
||||
if (instr_rdata_i[6:0] == `OPCODE_STORE_POST) begin
|
||||
if (instr_rdata_i[6:0] == OPCODE_STORE_POST) begin
|
||||
prepost_useincr_o = 1'b0;
|
||||
regfile_alu_waddr_sel_o = 1'b0;
|
||||
regfile_alu_we = 1'b1;
|
||||
|
@ -277,13 +277,13 @@ module riscv_decoder
|
|||
|
||||
if (instr_rdata_i[14] == 1'b0) begin
|
||||
// offset from immediate
|
||||
imm_b_mux_sel_o = `IMMB_S;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_S;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
end else begin
|
||||
// offset from register
|
||||
regc_used_o = 1'b1;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_RD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = REGC_RD;
|
||||
end
|
||||
|
||||
// store size
|
||||
|
@ -299,20 +299,20 @@ module riscv_decoder
|
|||
endcase
|
||||
end
|
||||
|
||||
`OPCODE_LOAD,
|
||||
`OPCODE_LOAD_POST: begin
|
||||
OPCODE_LOAD,
|
||||
OPCODE_LOAD_POST: begin
|
||||
data_req = 1'b1;
|
||||
regfile_mem_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
data_type_o = 2'b00;
|
||||
|
||||
// offset from immediate
|
||||
alu_operator_o = `ALU_ADD;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_I;
|
||||
alu_operator_o = ALU_ADD;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_I;
|
||||
|
||||
// post-increment setup
|
||||
if (instr_rdata_i[6:0] == `OPCODE_LOAD_POST) begin
|
||||
if (instr_rdata_i[6:0] == OPCODE_LOAD_POST) begin
|
||||
prepost_useincr_o = 1'b0;
|
||||
regfile_alu_waddr_sel_o = 1'b0;
|
||||
regfile_alu_we = 1'b1;
|
||||
|
@ -333,7 +333,7 @@ module riscv_decoder
|
|||
if (instr_rdata_i[14:12] == 3'b111) begin
|
||||
// offset from RS2
|
||||
regb_used_o = 1'b1;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGB_OR_FWD;
|
||||
|
||||
// sign/zero extension
|
||||
data_sign_extension_o = ~instr_rdata_i[30];
|
||||
|
@ -371,48 +371,48 @@ module riscv_decoder
|
|||
// //
|
||||
//////////////////////////
|
||||
|
||||
`OPCODE_LUI: begin // Load Upper Immediate
|
||||
alu_op_a_mux_sel_o = `OP_A_IMM;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_a_mux_sel_o = `IMMA_ZERO;
|
||||
imm_b_mux_sel_o = `IMMB_U;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
OPCODE_LUI: begin // Load Upper Immediate
|
||||
alu_op_a_mux_sel_o = OP_A_IMM;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_a_mux_sel_o = IMMA_ZERO;
|
||||
imm_b_mux_sel_o = IMMB_U;
|
||||
alu_operator_o = ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
end
|
||||
|
||||
`OPCODE_AUIPC: begin // Add Upper Immediate to PC
|
||||
alu_op_a_mux_sel_o = `OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_U;
|
||||
alu_operator_o = `ALU_ADD;
|
||||
OPCODE_AUIPC: begin // Add Upper Immediate to PC
|
||||
alu_op_a_mux_sel_o = OP_A_CURRPC;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_U;
|
||||
alu_operator_o = ALU_ADD;
|
||||
regfile_alu_we = 1'b1;
|
||||
end
|
||||
|
||||
`OPCODE_OPIMM: begin // Register-Immediate ALU Operations
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_I;
|
||||
OPCODE_OPIMM: begin // Register-Immediate ALU Operations
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_I;
|
||||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
|
||||
unique case (instr_rdata_i[14:12])
|
||||
3'b000: alu_operator_o = `ALU_ADD; // Add Immediate
|
||||
3'b010: alu_operator_o = `ALU_SLTS; // Set to one if Lower Than Immediate
|
||||
3'b011: alu_operator_o = `ALU_SLTU; // Set to one if Lower Than Immediate Unsigned
|
||||
3'b100: alu_operator_o = `ALU_XOR; // Exclusive Or with Immediate
|
||||
3'b110: alu_operator_o = `ALU_OR; // Or with Immediate
|
||||
3'b111: alu_operator_o = `ALU_AND; // And with Immediate
|
||||
3'b000: alu_operator_o = ALU_ADD; // Add Immediate
|
||||
3'b010: alu_operator_o = ALU_SLTS; // Set to one if Lower Than Immediate
|
||||
3'b011: alu_operator_o = ALU_SLTU; // Set to one if Lower Than Immediate Unsigned
|
||||
3'b100: alu_operator_o = ALU_XOR; // Exclusive Or with Immediate
|
||||
3'b110: alu_operator_o = ALU_OR; // Or with Immediate
|
||||
3'b111: alu_operator_o = ALU_AND; // And with Immediate
|
||||
|
||||
3'b001: begin
|
||||
alu_operator_o = `ALU_SLL; // Shift Left Logical by Immediate
|
||||
alu_operator_o = ALU_SLL; // Shift Left Logical by Immediate
|
||||
if (instr_rdata_i[31:25] != 7'b0)
|
||||
illegal_insn_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b101: begin
|
||||
if (instr_rdata_i[31:25] == 7'b0)
|
||||
alu_operator_o = `ALU_SRL; // Shift Right Logical by Immediate
|
||||
alu_operator_o = ALU_SRL; // Shift Right Logical by Immediate
|
||||
else if (instr_rdata_i[31:25] == 7'b010_0000)
|
||||
alu_operator_o = `ALU_SRA; // Shift Right Arithmetically by Immediate
|
||||
alu_operator_o = ALU_SRA; // Shift Right Arithmetically by Immediate
|
||||
else
|
||||
illegal_insn_o = 1'b1;
|
||||
end
|
||||
|
@ -421,38 +421,38 @@ module riscv_decoder
|
|||
endcase
|
||||
end
|
||||
|
||||
`OPCODE_OP: begin // Register-Register ALU operation
|
||||
OPCODE_OP: begin // Register-Register ALU operation
|
||||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
|
||||
if (instr_rdata_i[31]) begin
|
||||
// bit-manipulation instructions
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
bmask_needed_o = 1'b1;
|
||||
bmask_a_mux_o = `BMASK_A_S3;
|
||||
bmask_b_mux_o = `BMASK_B_S2;
|
||||
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;
|
||||
bmask_b_mux_o = `BMASK_B_ZERO;
|
||||
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;
|
||||
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;
|
||||
alu_operator_o = ALU_BINS;
|
||||
imm_b_mux_sel_o = IMMB_S2;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
end
|
||||
|
||||
3'b011: begin alu_operator_o = `ALU_BCLR; end
|
||||
3'b100: begin alu_operator_o = `ALU_BSET; end
|
||||
3'b011: begin alu_operator_o = ALU_BCLR; end
|
||||
3'b100: begin alu_operator_o = ALU_BSET; end
|
||||
|
||||
default: illegal_insn_o = 1'b1;
|
||||
endcase
|
||||
|
@ -465,126 +465,126 @@ module riscv_decoder
|
|||
|
||||
unique case ({instr_rdata_i[30:25], instr_rdata_i[14:12]})
|
||||
// RV32I ALU operations
|
||||
{6'b00_0000, 3'b000}: alu_operator_o = `ALU_ADD; // Add
|
||||
{6'b10_0000, 3'b000}: alu_operator_o = `ALU_SUB; // Sub
|
||||
{6'b00_0000, 3'b010}: alu_operator_o = `ALU_SLTS; // Set Lower Than
|
||||
{6'b00_0000, 3'b011}: alu_operator_o = `ALU_SLTU; // Set Lower Than Unsigned
|
||||
{6'b00_0000, 3'b100}: alu_operator_o = `ALU_XOR; // Xor
|
||||
{6'b00_0000, 3'b110}: alu_operator_o = `ALU_OR; // Or
|
||||
{6'b00_0000, 3'b111}: alu_operator_o = `ALU_AND; // And
|
||||
{6'b00_0000, 3'b001}: alu_operator_o = `ALU_SLL; // Shift Left Logical
|
||||
{6'b00_0000, 3'b101}: alu_operator_o = `ALU_SRL; // Shift Right Logical
|
||||
{6'b10_0000, 3'b101}: alu_operator_o = `ALU_SRA; // Shift Right Arithmetic
|
||||
{6'b00_0000, 3'b000}: alu_operator_o = ALU_ADD; // Add
|
||||
{6'b10_0000, 3'b000}: alu_operator_o = ALU_SUB; // Sub
|
||||
{6'b00_0000, 3'b010}: alu_operator_o = ALU_SLTS; // Set Lower Than
|
||||
{6'b00_0000, 3'b011}: alu_operator_o = ALU_SLTU; // Set Lower Than Unsigned
|
||||
{6'b00_0000, 3'b100}: alu_operator_o = ALU_XOR; // Xor
|
||||
{6'b00_0000, 3'b110}: alu_operator_o = ALU_OR; // Or
|
||||
{6'b00_0000, 3'b111}: alu_operator_o = ALU_AND; // And
|
||||
{6'b00_0000, 3'b001}: alu_operator_o = ALU_SLL; // Shift Left Logical
|
||||
{6'b00_0000, 3'b101}: alu_operator_o = ALU_SRL; // Shift Right Logical
|
||||
{6'b10_0000, 3'b101}: alu_operator_o = ALU_SRA; // Shift Right Arithmetic
|
||||
|
||||
// supported RV32M instructions
|
||||
{6'b00_0001, 3'b000}: begin // mul
|
||||
mult_int_en_o = 1'b1;
|
||||
mult_operator_o = `MUL_MAC32;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
mult_operator_o = MUL_MAC32;
|
||||
regc_mux_o = REGC_ZERO;
|
||||
end
|
||||
{6'b00_0001, 3'b001}: begin // mulh
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
regc_mux_o = REGC_ZERO;
|
||||
mult_signed_mode_o = 2'b11;
|
||||
mult_int_en_o = 1'b1;
|
||||
mult_operator_o = `MUL_H;
|
||||
mult_operator_o = MUL_H;
|
||||
end
|
||||
{6'b00_0001, 3'b010}: begin // mulhsu
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
regc_mux_o = REGC_ZERO;
|
||||
mult_signed_mode_o = 2'b01;
|
||||
mult_int_en_o = 1'b1;
|
||||
mult_operator_o = `MUL_H;
|
||||
mult_operator_o = MUL_H;
|
||||
end
|
||||
{6'b00_0001, 3'b011}: begin // mulhu
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
regc_mux_o = REGC_ZERO;
|
||||
mult_signed_mode_o = 2'b00;
|
||||
mult_int_en_o = 1'b1;
|
||||
mult_operator_o = `MUL_H;
|
||||
mult_operator_o = MUL_H;
|
||||
end
|
||||
{6'b00_0001, 3'b100}: begin // div
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
alu_op_a_mux_sel_o = OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_DIV;
|
||||
alu_operator_o = ALU_DIV;
|
||||
end
|
||||
{6'b00_0001, 3'b101}: begin // divu
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
alu_op_a_mux_sel_o = OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_DIVU;
|
||||
alu_operator_o = ALU_DIVU;
|
||||
end
|
||||
{6'b00_0001, 3'b110}: begin // rem
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
alu_op_a_mux_sel_o = OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_REM;
|
||||
alu_operator_o = ALU_REM;
|
||||
end
|
||||
{6'b00_0001, 3'b111}: begin // remu
|
||||
alu_op_a_mux_sel_o = `OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = `REGC_S1;
|
||||
alu_op_a_mux_sel_o = OP_A_REGB_OR_FWD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGC_OR_FWD;
|
||||
regc_mux_o = REGC_S1;
|
||||
regc_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
rega_used_o = 1'b0;
|
||||
alu_operator_o = `ALU_REMU;
|
||||
alu_operator_o = ALU_REMU;
|
||||
end
|
||||
|
||||
// PULP specific instructions
|
||||
{6'b10_0001, 3'b000}: begin // p.mac
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
mult_int_en_o = 1'b1;
|
||||
mult_operator_o = `MUL_MAC32;
|
||||
mult_operator_o = MUL_MAC32;
|
||||
end
|
||||
{6'b10_0001, 3'b001}: begin // p.msu
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
mult_int_en_o = 1'b1;
|
||||
mult_operator_o = `MUL_MSU32;
|
||||
mult_operator_o = MUL_MSU32;
|
||||
end
|
||||
|
||||
{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
|
||||
{6'b00_0010, 3'b101}: alu_operator_o = `ALU_MINU; // Min Unsigned
|
||||
{6'b00_0010, 3'b110}: alu_operator_o = `ALU_MAX; // Max
|
||||
{6'b00_0010, 3'b111}: alu_operator_o = `ALU_MAXU; // Max 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
|
||||
{6'b00_0010, 3'b101}: alu_operator_o = ALU_MINU; // Min Unsigned
|
||||
{6'b00_0010, 3'b110}: alu_operator_o = ALU_MAX; // Max
|
||||
{6'b00_0010, 3'b111}: alu_operator_o = ALU_MAXU; // Max Unsigned
|
||||
|
||||
{6'b00_0100, 3'b101}: alu_operator_o = `ALU_ROR; // Rotate Right
|
||||
{6'b00_0100, 3'b101}: alu_operator_o = ALU_ROR; // Rotate Right
|
||||
|
||||
// PULP specific instructions using only one source register
|
||||
{6'b00_1000, 3'b000}: alu_operator_o = `ALU_FF1; // Find First 1
|
||||
{6'b00_1000, 3'b001}: alu_operator_o = `ALU_FL1; // Find Last 1
|
||||
{6'b00_1000, 3'b010}: alu_operator_o = `ALU_CLB; // Count Leading Bits
|
||||
{6'b00_1000, 3'b011}: alu_operator_o = `ALU_CNT; // Count set bits (popcount)
|
||||
{6'b00_1000, 3'b100}: begin alu_operator_o = `ALU_EXTS; alu_vec_mode_o = `VEC_MODE16; end // Sign-extend Half-word
|
||||
{6'b00_1000, 3'b101}: begin alu_operator_o = `ALU_EXT; alu_vec_mode_o = `VEC_MODE16; end // Zero-extend Half-word
|
||||
{6'b00_1000, 3'b110}: begin alu_operator_o = `ALU_EXTS; alu_vec_mode_o = `VEC_MODE8; end // Sign-extend Byte
|
||||
{6'b00_1000, 3'b111}: begin alu_operator_o = `ALU_EXT; alu_vec_mode_o = `VEC_MODE8; end // Zero-extend Byte
|
||||
{6'b00_1000, 3'b000}: alu_operator_o = ALU_FF1; // Find First 1
|
||||
{6'b00_1000, 3'b001}: alu_operator_o = ALU_FL1; // Find Last 1
|
||||
{6'b00_1000, 3'b010}: alu_operator_o = ALU_CLB; // Count Leading Bits
|
||||
{6'b00_1000, 3'b011}: alu_operator_o = ALU_CNT; // Count set bits (popcount)
|
||||
{6'b00_1000, 3'b100}: begin alu_operator_o = ALU_EXTS; alu_vec_mode_o = VEC_MODE16; end // Sign-extend Half-word
|
||||
{6'b00_1000, 3'b101}: begin alu_operator_o = ALU_EXT; alu_vec_mode_o = VEC_MODE16; end // Zero-extend Half-word
|
||||
{6'b00_1000, 3'b110}: begin alu_operator_o = ALU_EXTS; alu_vec_mode_o = VEC_MODE8; end // Sign-extend Byte
|
||||
{6'b00_1000, 3'b111}: begin alu_operator_o = ALU_EXT; alu_vec_mode_o = VEC_MODE8; end // Zero-extend Byte
|
||||
|
||||
{6'b00_0010, 3'b000}: alu_operator_o = `ALU_ABS; // p.abs
|
||||
{6'b00_0010, 3'b000}: alu_operator_o = ALU_ABS; // p.abs
|
||||
|
||||
{6'b00_1010, 3'b001}: begin // p.clip
|
||||
alu_operator_o = `ALU_CLIP;
|
||||
alu_op_b_mux_sel_o = `OP_A_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_CLIP;
|
||||
alu_operator_o = ALU_CLIP;
|
||||
alu_op_b_mux_sel_o = OP_A_IMM;
|
||||
imm_b_mux_sel_o = IMMB_CLIP;
|
||||
end
|
||||
|
||||
{6'b00_1010, 3'b010}: begin // p.clipu
|
||||
alu_operator_o = `ALU_CLIPU;
|
||||
alu_op_b_mux_sel_o = `OP_A_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_CLIP;
|
||||
alu_operator_o = ALU_CLIPU;
|
||||
alu_op_b_mux_sel_o = OP_A_IMM;
|
||||
imm_b_mux_sel_o = IMMB_CLIP;
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
@ -594,7 +594,7 @@ module riscv_decoder
|
|||
end
|
||||
end
|
||||
|
||||
`OPCODE_PULP_OP: begin // PULP specific ALU instructions with three source operands
|
||||
OPCODE_PULP_OP: begin // PULP specific ALU instructions with three source operands
|
||||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
regb_used_o = 1'b1;
|
||||
|
@ -604,14 +604,14 @@ module riscv_decoder
|
|||
mult_sel_subword_o = instr_rdata_i[30];
|
||||
mult_signed_mode_o = {2{instr_rdata_i[31]}};
|
||||
|
||||
mult_imm_mux_o = `MIMM_S3;
|
||||
regc_mux_o = `REGC_ZERO;
|
||||
mult_imm_mux_o = MIMM_S3;
|
||||
regc_mux_o = REGC_ZERO;
|
||||
mult_int_en_o = 1'b1;
|
||||
|
||||
if (instr_rdata_i[14])
|
||||
mult_operator_o = `MUL_IR;
|
||||
mult_operator_o = MUL_IR;
|
||||
else
|
||||
mult_operator_o = `MUL_I;
|
||||
mult_operator_o = MUL_I;
|
||||
end
|
||||
|
||||
2'b01: begin // MAC with subword selection
|
||||
|
@ -619,42 +619,42 @@ module riscv_decoder
|
|||
mult_signed_mode_o = {2{instr_rdata_i[31]}};
|
||||
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
mult_imm_mux_o = `MIMM_S3;
|
||||
regc_mux_o = REGC_RD;
|
||||
mult_imm_mux_o = MIMM_S3;
|
||||
mult_int_en_o = 1'b1;
|
||||
|
||||
if (instr_rdata_i[14])
|
||||
mult_operator_o = `MUL_IR;
|
||||
mult_operator_o = MUL_IR;
|
||||
else
|
||||
mult_operator_o = `MUL_I;
|
||||
mult_operator_o = MUL_I;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
bmask_a_mux_o = BMASK_A_ZERO;
|
||||
bmask_b_mux_o = BMASK_B_S3;
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
@ -664,18 +664,18 @@ module riscv_decoder
|
|||
endcase
|
||||
end
|
||||
|
||||
`OPCODE_VECOP: begin
|
||||
OPCODE_VECOP: begin
|
||||
regfile_alu_we = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
imm_b_mux_sel_o = `IMMB_VS;
|
||||
imm_b_mux_sel_o = IMMB_VS;
|
||||
|
||||
// vector size
|
||||
if (instr_rdata_i[12]) begin
|
||||
alu_vec_mode_o = `VEC_MODE8;
|
||||
mult_operator_o = `MUL_DOT8;
|
||||
alu_vec_mode_o = VEC_MODE8;
|
||||
mult_operator_o = MUL_DOT8;
|
||||
end else begin
|
||||
alu_vec_mode_o = `VEC_MODE16;
|
||||
mult_operator_o = `MUL_DOT16;
|
||||
alu_vec_mode_o = VEC_MODE16;
|
||||
mult_operator_o = MUL_DOT16;
|
||||
end
|
||||
|
||||
// distinguish normal vector, sc and sci modes
|
||||
|
@ -684,7 +684,7 @@ module riscv_decoder
|
|||
|
||||
if (instr_rdata_i[13]) begin
|
||||
// immediate scalar replication, .sci
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
end else begin
|
||||
// register scalar replication, .sc
|
||||
regb_used_o = 1'b1;
|
||||
|
@ -696,69 +696,69 @@ 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_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'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
|
||||
|
||||
// shuffle/pack
|
||||
6'b11101_0, // pv.shuffleI1
|
||||
6'b11110_0, // pv.shuffleI2
|
||||
6'b11111_0, // pv.shuffleI3
|
||||
6'b11000_0: begin // pv.shuffle, pv.shuffleI0
|
||||
alu_operator_o = `ALU_SHUF;
|
||||
imm_b_mux_sel_o = `IMMB_SHUF;
|
||||
alu_operator_o = ALU_SHUF;
|
||||
imm_b_mux_sel_o = IMMB_SHUF;
|
||||
regb_used_o = 1'b1;
|
||||
scalar_replication_o = 1'b0;
|
||||
end
|
||||
6'b11001_0: begin // pv.shuffle2
|
||||
alu_operator_o = `ALU_SHUF2;
|
||||
alu_operator_o = ALU_SHUF2;
|
||||
regb_used_o = 1'b1;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
scalar_replication_o = 1'b0;
|
||||
end
|
||||
6'b11010_0: begin // pv.pack
|
||||
alu_operator_o = `ALU_PCKLO;
|
||||
alu_operator_o = ALU_PCKLO;
|
||||
regb_used_o = 1'b1;
|
||||
end
|
||||
6'b11011_0: begin // pv.packhi
|
||||
alu_operator_o = `ALU_PCKHI;
|
||||
alu_operator_o = ALU_PCKHI;
|
||||
regb_used_o = 1'b1;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
end
|
||||
6'b11100_0: begin // pv.packlo
|
||||
alu_operator_o = `ALU_PCKLO;
|
||||
alu_operator_o = ALU_PCKLO;
|
||||
regb_used_o = 1'b1;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
end
|
||||
|
||||
6'b01111_0: begin // pv.extract
|
||||
alu_operator_o = `ALU_EXTS;
|
||||
alu_operator_o = ALU_EXTS;
|
||||
end
|
||||
|
||||
6'b10010_0: begin // pv.extractu
|
||||
alu_operator_o = `ALU_EXT;
|
||||
alu_operator_o = ALU_EXT;
|
||||
end
|
||||
|
||||
6'b10110_0: begin // pv.insert
|
||||
alu_operator_o = `ALU_INS;
|
||||
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;
|
||||
regc_mux_o = REGC_RD;
|
||||
alu_op_b_mux_sel_o = OP_B_REGC_OR_FWD;
|
||||
end
|
||||
|
||||
6'b10000_0: begin // pv.dotup
|
||||
|
@ -777,32 +777,32 @@ module riscv_decoder
|
|||
mult_dot_en_o = 1'b1;
|
||||
mult_dot_signed_o = 2'b00;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
end
|
||||
6'b10101_0: begin // pv.sdotusp
|
||||
mult_dot_en_o = 1'b1;
|
||||
mult_dot_signed_o = 2'b01;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
end
|
||||
6'b10111_0: begin // pv.sdotsp
|
||||
mult_dot_en_o = 1'b1;
|
||||
mult_dot_signed_o = 2'b11;
|
||||
regc_used_o = 1'b1;
|
||||
regc_mux_o = `REGC_RD;
|
||||
regc_mux_o = REGC_RD;
|
||||
end
|
||||
|
||||
// comparisons, always have bit 26 set
|
||||
6'b00000_1: begin alu_operator_o = `ALU_EQ; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpeq
|
||||
6'b00001_1: begin alu_operator_o = `ALU_NE; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpne
|
||||
6'b00010_1: begin alu_operator_o = `ALU_GTS; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpgt
|
||||
6'b00011_1: begin alu_operator_o = `ALU_GES; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmpge
|
||||
6'b00100_1: begin alu_operator_o = `ALU_LTS; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmplt
|
||||
6'b00101_1: begin alu_operator_o = `ALU_LES; imm_b_mux_sel_o = `IMMB_VS; end // pv.cmple
|
||||
6'b00110_1: begin alu_operator_o = `ALU_GTU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpgtu
|
||||
6'b00111_1: begin alu_operator_o = `ALU_GEU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpgeu
|
||||
6'b01000_1: begin alu_operator_o = `ALU_LTU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpltu
|
||||
6'b01001_1: begin alu_operator_o = `ALU_LEU; imm_b_mux_sel_o = `IMMB_VU; end // pv.cmpleu
|
||||
6'b00000_1: begin alu_operator_o = ALU_EQ; imm_b_mux_sel_o = IMMB_VS; end // pv.cmpeq
|
||||
6'b00001_1: begin alu_operator_o = ALU_NE; imm_b_mux_sel_o = IMMB_VS; end // pv.cmpne
|
||||
6'b00010_1: begin alu_operator_o = ALU_GTS; imm_b_mux_sel_o = IMMB_VS; end // pv.cmpgt
|
||||
6'b00011_1: begin alu_operator_o = ALU_GES; imm_b_mux_sel_o = IMMB_VS; end // pv.cmpge
|
||||
6'b00100_1: begin alu_operator_o = ALU_LTS; imm_b_mux_sel_o = IMMB_VS; end // pv.cmplt
|
||||
6'b00101_1: begin alu_operator_o = ALU_LES; imm_b_mux_sel_o = IMMB_VS; end // pv.cmple
|
||||
6'b00110_1: begin alu_operator_o = ALU_GTU; imm_b_mux_sel_o = IMMB_VU; end // pv.cmpgtu
|
||||
6'b00111_1: begin alu_operator_o = ALU_GEU; imm_b_mux_sel_o = IMMB_VU; end // pv.cmpgeu
|
||||
6'b01000_1: begin alu_operator_o = ALU_LTU; imm_b_mux_sel_o = IMMB_VU; end // pv.cmpltu
|
||||
6'b01001_1: begin alu_operator_o = ALU_LEU; imm_b_mux_sel_o = IMMB_VU; end // pv.cmpleu
|
||||
|
||||
default: illegal_insn_o = 1'b1;
|
||||
endcase
|
||||
|
@ -818,7 +818,7 @@ module riscv_decoder
|
|||
// //
|
||||
////////////////////////////////////////////////
|
||||
|
||||
`OPCODE_SYSTEM: begin
|
||||
OPCODE_SYSTEM: begin
|
||||
if (instr_rdata_i[14:12] == 3'b000)
|
||||
begin
|
||||
// non CSR related SYSTEM instructions
|
||||
|
@ -857,22 +857,22 @@ module riscv_decoder
|
|||
// instruction to read/modify CSR
|
||||
csr_access_o = 1'b1;
|
||||
regfile_alu_we = 1'b1;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_a_mux_sel_o = `IMMA_Z;
|
||||
imm_b_mux_sel_o = `IMMB_I; // CSR address is encoded in I imm
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_a_mux_sel_o = IMMA_Z;
|
||||
imm_b_mux_sel_o = IMMB_I; // CSR address is encoded in I imm
|
||||
|
||||
if (instr_rdata_i[14] == 1'b1) begin
|
||||
// rs1 field is used as immediate
|
||||
alu_op_a_mux_sel_o = `OP_A_IMM;
|
||||
alu_op_a_mux_sel_o = OP_A_IMM;
|
||||
end else begin
|
||||
rega_used_o = 1'b1;
|
||||
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
|
||||
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
|
||||
end
|
||||
|
||||
unique case (instr_rdata_i[13:12])
|
||||
2'b01: csr_op = `CSR_OP_WRITE;
|
||||
2'b10: csr_op = `CSR_OP_SET;
|
||||
2'b11: csr_op = `CSR_OP_CLEAR;
|
||||
2'b01: csr_op = CSR_OP_WRITE;
|
||||
2'b10: csr_op = CSR_OP_SET;
|
||||
2'b11: csr_op = CSR_OP_CLEAR;
|
||||
default: illegal_insn_o = 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
@ -889,7 +889,7 @@ module riscv_decoder
|
|||
// //
|
||||
///////////////////////////////////////////////
|
||||
|
||||
`OPCODE_HWLOOP: begin
|
||||
OPCODE_HWLOOP: begin
|
||||
hwloop_target_mux_sel_o = 1'b0;
|
||||
|
||||
unique case (instr_rdata_i[14:12])
|
||||
|
@ -957,9 +957,9 @@ module riscv_decoder
|
|||
begin
|
||||
// only part of the pipeline is unstalled, make sure that the
|
||||
// correct operands are sent to the AGU
|
||||
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
|
||||
alu_op_b_mux_sel_o = `OP_B_IMM;
|
||||
imm_b_mux_sel_o = `IMMB_PCINCR;
|
||||
alu_op_a_mux_sel_o = OP_A_REGA_OR_FWD;
|
||||
alu_op_b_mux_sel_o = OP_B_IMM;
|
||||
imm_b_mux_sel_o = IMMB_PCINCR;
|
||||
|
||||
// if prepost increments are used, we do not write back the
|
||||
// second address since the first calculated address was
|
||||
|
@ -972,7 +972,7 @@ module riscv_decoder
|
|||
// we do not want to replicate operand_b
|
||||
scalar_replication_o = 1'b0;
|
||||
end else if (mult_multicycle_i) begin
|
||||
alu_op_c_mux_sel_o = `OP_C_REGC_OR_FWD;
|
||||
alu_op_c_mux_sel_o = OP_C_REGC_OR_FWD;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -981,8 +981,8 @@ module riscv_decoder
|
|||
assign regfile_alu_we_o = (deassert_we_i) ? 1'b0 : regfile_alu_we;
|
||||
assign data_req_o = (deassert_we_i) ? 1'b0 : data_req;
|
||||
assign hwloop_we_o = (deassert_we_i) ? 3'b0 : hwloop_we;
|
||||
assign csr_op_o = (deassert_we_i) ? `CSR_OP_NONE : csr_op;
|
||||
assign jump_in_id_o = (deassert_we_i) ? `BRANCH_NONE : jump_in_id;
|
||||
assign csr_op_o = (deassert_we_i) ? CSR_OP_NONE : csr_op;
|
||||
assign jump_in_id_o = (deassert_we_i) ? BRANCH_NONE : jump_in_id;
|
||||
assign ebrk_insn_o = (deassert_we_i) ? 1'b0 : ebrk_insn;
|
||||
assign eret_insn_o = (deassert_we_i) ? 1'b0 : eret_insn; // TODO: do not deassert?
|
||||
assign pipe_flush_o = (deassert_we_i) ? 1'b0 : pipe_flush; // TODO: do not deassert?
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
|
||||
module riscv_ex_stage
|
||||
|
@ -35,7 +35,7 @@ module riscv_ex_stage
|
|||
input logic rst_n,
|
||||
|
||||
// ALU signals from ID stage
|
||||
input logic [`ALU_OP_WIDTH-1:0] alu_operator_i,
|
||||
input logic [ALU_OP_WIDTH-1:0] alu_operator_i,
|
||||
input logic [31:0] alu_operand_a_i,
|
||||
input logic [31:0] alu_operand_b_i,
|
||||
input logic [31:0] alu_operand_c_i,
|
||||
|
|
|
@ -22,8 +22,7 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_exc_controller
|
||||
(
|
||||
|
@ -58,7 +57,7 @@ module riscv_exc_controller
|
|||
output logic save_cause_o,
|
||||
|
||||
// from debug unit
|
||||
input logic [`DBG_SETS_W-1:0] dbg_settings_i
|
||||
input logic [DBG_SETS_W-1:0] dbg_settings_i
|
||||
);
|
||||
|
||||
|
||||
|
@ -78,13 +77,13 @@ module riscv_exc_controller
|
|||
// - illegal instruction exception and IIE bit is set
|
||||
// - IRQ and INTE bit is set and no exception is currently running
|
||||
// - Debuger requests halt
|
||||
assign trap_o = (dbg_settings_i[`DBG_SETS_SSTE])
|
||||
| (ecall_insn_i & dbg_settings_i[`DBG_SETS_ECALL])
|
||||
| (lsu_load_err_i & dbg_settings_i[`DBG_SETS_ELSU])
|
||||
| (lsu_store_err_i & dbg_settings_i[`DBG_SETS_ELSU])
|
||||
| (ebrk_insn_i & dbg_settings_i[`DBG_SETS_EBRK])
|
||||
| (illegal_insn_i & dbg_settings_i[`DBG_SETS_EILL])
|
||||
| (irq_enable_i & (|irq_i) & dbg_settings_i[`DBG_SETS_IRQ]);
|
||||
assign trap_o = (dbg_settings_i[DBG_SETS_SSTE])
|
||||
| (ecall_insn_i & dbg_settings_i[DBG_SETS_ECALL])
|
||||
| (lsu_load_err_i & dbg_settings_i[DBG_SETS_ELSU])
|
||||
| (lsu_store_err_i & dbg_settings_i[DBG_SETS_ELSU])
|
||||
| (ebrk_insn_i & dbg_settings_i[DBG_SETS_EBRK])
|
||||
| (illegal_insn_i & dbg_settings_i[DBG_SETS_EILL])
|
||||
| (irq_enable_i & (|irq_i) & dbg_settings_i[DBG_SETS_IRQ]);
|
||||
|
||||
// request for exception/interrupt
|
||||
assign req_int = ecall_insn_i
|
||||
|
@ -103,7 +102,7 @@ module riscv_exc_controller
|
|||
if (irq_enable_i) begin
|
||||
// pc_mux_int is a critical signal, so try to get it as soon as possible
|
||||
if (|irq_i)
|
||||
pc_mux_int = `EXC_PC_IRQ;
|
||||
pc_mux_int = EXC_PC_IRQ;
|
||||
|
||||
for (i = 31; i >= 0; i--)
|
||||
begin
|
||||
|
@ -120,22 +119,22 @@ module riscv_exc_controller
|
|||
|
||||
if (ecall_insn_i) begin
|
||||
cause_int = 6'b0_01011;
|
||||
pc_mux_int = `EXC_PC_ECALL;
|
||||
pc_mux_int = EXC_PC_ECALL;
|
||||
end
|
||||
|
||||
if (illegal_insn_i) begin
|
||||
cause_int = 6'b0_00010;
|
||||
pc_mux_int = `EXC_PC_ILLINSN;
|
||||
pc_mux_int = EXC_PC_ILLINSN;
|
||||
end
|
||||
|
||||
if (lsu_load_err_i) begin
|
||||
cause_int = 6'b0_00101;
|
||||
pc_mux_int = `EXC_PC_LOAD;
|
||||
pc_mux_int = EXC_PC_LOAD;
|
||||
end
|
||||
|
||||
if (lsu_store_err_i) begin
|
||||
cause_int = 6'b0_00111;
|
||||
pc_mux_int = `EXC_PC_STORE;
|
||||
pc_mux_int = EXC_PC_STORE;
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
|
||||
module riscv_hwloop_controller
|
||||
#(
|
||||
parameter N_REGS = 2
|
||||
|
|
|
@ -22,9 +22,6 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
|
||||
module riscv_hwloop_regs
|
||||
#(
|
||||
parameter N_REGS = 2,
|
||||
|
|
116
id_stage.sv
116
id_stage.sv
|
@ -26,7 +26,13 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
// Source/Destination register instruction index
|
||||
`define REG_S1 19:15
|
||||
`define REG_S2 24:20
|
||||
`define REG_S3 29:25
|
||||
`define REG_D 11:07
|
||||
|
||||
module riscv_id_stage
|
||||
#(
|
||||
|
@ -99,7 +105,7 @@ module riscv_id_stage
|
|||
output logic regfile_alu_we_ex_o,
|
||||
|
||||
// ALU
|
||||
output logic [`ALU_OP_WIDTH-1:0] alu_operator_ex_o,
|
||||
output logic [ALU_OP_WIDTH-1:0] alu_operator_ex_o,
|
||||
|
||||
|
||||
// MUL
|
||||
|
@ -159,7 +165,7 @@ module riscv_id_stage
|
|||
input logic lsu_store_err_i,
|
||||
|
||||
// Debug Unit Signals
|
||||
input logic [`DBG_SETS_W-1:0] dbg_settings_i,
|
||||
input logic [DBG_SETS_W-1:0] dbg_settings_i,
|
||||
input logic dbg_req_i,
|
||||
output logic dbg_ack_o,
|
||||
input logic dbg_stall_i,
|
||||
|
@ -259,7 +265,7 @@ module riscv_id_stage
|
|||
logic [31:0] regfile_data_rc_id;
|
||||
|
||||
// ALU Control
|
||||
logic [`ALU_OP_WIDTH-1:0] alu_operator;
|
||||
logic [ALU_OP_WIDTH-1:0] alu_operator;
|
||||
logic [1:0] alu_op_a_mux_sel;
|
||||
logic [1:0] alu_op_b_mux_sel;
|
||||
logic [1:0] alu_op_c_mux_sel;
|
||||
|
@ -386,9 +392,9 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin
|
||||
unique case (regc_mux)
|
||||
`REGC_ZERO: regfile_addr_rc_id = '0;
|
||||
`REGC_RD: regfile_addr_rc_id = instr[`REG_D];
|
||||
`REGC_S1: regfile_addr_rc_id = instr[`REG_S1];
|
||||
REGC_ZERO: regfile_addr_rc_id = '0;
|
||||
REGC_RD: regfile_addr_rc_id = instr[`REG_D];
|
||||
REGC_S1: regfile_addr_rc_id = instr[`REG_S1];
|
||||
default: regfile_addr_rc_id = '0;
|
||||
endcase
|
||||
end
|
||||
|
@ -485,11 +491,11 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : jump_target_mux
|
||||
unique case (jump_target_mux_sel)
|
||||
`JT_JAL: jump_target = pc_id_i + imm_uj_type;
|
||||
`JT_COND: jump_target = pc_id_i + imm_sb_type;
|
||||
JT_JAL: jump_target = pc_id_i + imm_uj_type;
|
||||
JT_COND: jump_target = pc_id_i + imm_sb_type;
|
||||
|
||||
// JALR: Cannot forward RS1, since the path is too long
|
||||
`JT_JALR: jump_target = regfile_data_ra_id + imm_i_type;
|
||||
JT_JALR: jump_target = regfile_data_ra_id + imm_i_type;
|
||||
default: jump_target = regfile_data_ra_id + imm_i_type;
|
||||
endcase
|
||||
end
|
||||
|
@ -510,10 +516,10 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : alu_operand_a_mux
|
||||
case (alu_op_a_mux_sel)
|
||||
`OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
|
||||
`OP_A_REGB_OR_FWD: alu_operand_a = operand_b_fw_id;
|
||||
`OP_A_CURRPC: alu_operand_a = pc_id_i;
|
||||
`OP_A_IMM: alu_operand_a = imm_a;
|
||||
OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
|
||||
OP_A_REGB_OR_FWD: alu_operand_a = operand_b_fw_id;
|
||||
OP_A_CURRPC: alu_operand_a = pc_id_i;
|
||||
OP_A_IMM: alu_operand_a = imm_a;
|
||||
default: alu_operand_a = operand_a_fw_id;
|
||||
endcase; // case (alu_op_a_mux_sel)
|
||||
end
|
||||
|
@ -521,8 +527,8 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : immediate_a_mux
|
||||
unique case (imm_a_mux_sel)
|
||||
`IMMA_Z: imm_a = imm_z_type;
|
||||
`IMMA_ZERO: imm_a = '0;
|
||||
IMMA_Z: imm_a = imm_z_type;
|
||||
IMMA_ZERO: imm_a = '0;
|
||||
default: imm_a = '0;
|
||||
endcase
|
||||
end
|
||||
|
@ -531,9 +537,9 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : operand_a_fw_mux
|
||||
case (operand_a_fw_mux_sel)
|
||||
`SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i;
|
||||
`SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i;
|
||||
`SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id;
|
||||
SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i;
|
||||
SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i;
|
||||
SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id;
|
||||
default: operand_a_fw_id = regfile_data_ra_id;
|
||||
endcase; // case (operand_a_fw_mux_sel)
|
||||
end
|
||||
|
@ -553,16 +559,16 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : immediate_b_mux
|
||||
unique case (imm_b_mux_sel)
|
||||
`IMMB_I: imm_b = imm_i_type;
|
||||
`IMMB_S: imm_b = imm_s_type;
|
||||
`IMMB_U: imm_b = imm_u_type;
|
||||
`IMMB_PCINCR: imm_b = (is_compressed_i && (~data_misaligned_i)) ? 32'h2 : 32'h4;
|
||||
`IMMB_S2: imm_b = imm_s2_type;
|
||||
`IMMB_S3: imm_b = imm_s3_type;
|
||||
`IMMB_VS: imm_b = imm_vs_type;
|
||||
`IMMB_VU: imm_b = imm_vu_type;
|
||||
`IMMB_SHUF: imm_b = imm_shuffle_type;
|
||||
`IMMB_CLIP: imm_b = {1'b0, imm_clip_type[31:1]};
|
||||
IMMB_I: imm_b = imm_i_type;
|
||||
IMMB_S: imm_b = imm_s_type;
|
||||
IMMB_U: imm_b = imm_u_type;
|
||||
IMMB_PCINCR: imm_b = (is_compressed_i && (~data_misaligned_i)) ? 32'h2 : 32'h4;
|
||||
IMMB_S2: imm_b = imm_s2_type;
|
||||
IMMB_S3: imm_b = imm_s3_type;
|
||||
IMMB_VS: imm_b = imm_vs_type;
|
||||
IMMB_VU: imm_b = imm_vu_type;
|
||||
IMMB_SHUF: imm_b = imm_shuffle_type;
|
||||
IMMB_CLIP: imm_b = {1'b0, imm_clip_type[31:1]};
|
||||
default: imm_b = imm_i_type;
|
||||
endcase
|
||||
end
|
||||
|
@ -571,16 +577,16 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : alu_operand_b_mux
|
||||
case (alu_op_b_mux_sel)
|
||||
`OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id;
|
||||
`OP_B_REGC_OR_FWD: operand_b = operand_c_fw_id;
|
||||
`OP_B_IMM: operand_b = imm_b;
|
||||
OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id;
|
||||
OP_B_REGC_OR_FWD: operand_b = operand_c_fw_id;
|
||||
OP_B_IMM: operand_b = imm_b;
|
||||
default: operand_b = operand_b_fw_id;
|
||||
endcase // case (alu_op_b_mux_sel)
|
||||
end
|
||||
|
||||
|
||||
// scalar replication for operand B
|
||||
assign operand_b_vec = (alu_vec_mode == `VEC_MODE8) ? {4{operand_b[7:0]}} : {2{operand_b[15:0]}};
|
||||
assign operand_b_vec = (alu_vec_mode == VEC_MODE8) ? {4{operand_b[7:0]}} : {2{operand_b[15:0]}};
|
||||
|
||||
// choose normal or scalar replicated version of operand b
|
||||
assign alu_operand_b = (scalar_replication == 1'b1) ? operand_b_vec : operand_b;
|
||||
|
@ -590,9 +596,9 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : operand_b_fw_mux
|
||||
case (operand_b_fw_mux_sel)
|
||||
`SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
|
||||
`SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i;
|
||||
`SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id;
|
||||
SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
|
||||
SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i;
|
||||
SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id;
|
||||
default: operand_b_fw_id = regfile_data_rb_id;
|
||||
endcase; // case (operand_b_fw_mux_sel)
|
||||
end
|
||||
|
@ -611,9 +617,9 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : alu_operand_c_mux
|
||||
case (alu_op_c_mux_sel)
|
||||
`OP_C_REGC_OR_FWD: alu_operand_c = operand_c_fw_id;
|
||||
`OP_C_REGB_OR_FWD: alu_operand_c = operand_b_fw_id;
|
||||
`OP_C_JT: alu_operand_c = jump_target;
|
||||
OP_C_REGC_OR_FWD: alu_operand_c = operand_c_fw_id;
|
||||
OP_C_REGB_OR_FWD: alu_operand_c = operand_b_fw_id;
|
||||
OP_C_JT: alu_operand_c = jump_target;
|
||||
default: alu_operand_c = operand_c_fw_id;
|
||||
endcase // case (alu_op_c_mux_sel)
|
||||
end
|
||||
|
@ -622,9 +628,9 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : operand_c_fw_mux
|
||||
case (operand_c_fw_mux_sel)
|
||||
`SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i;
|
||||
`SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i;
|
||||
`SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id;
|
||||
SEL_FW_EX: operand_c_fw_id = regfile_alu_wdata_fw_i;
|
||||
SEL_FW_WB: operand_c_fw_id = regfile_wdata_wb_i;
|
||||
SEL_REGFILE: operand_c_fw_id = regfile_data_rc_id;
|
||||
default: operand_c_fw_id = regfile_data_rc_id;
|
||||
endcase; // case (operand_c_fw_mux_sel)
|
||||
end
|
||||
|
@ -642,18 +648,18 @@ module riscv_id_stage
|
|||
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];
|
||||
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];
|
||||
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
|
||||
|
@ -664,8 +670,8 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin
|
||||
unique case (mult_imm_mux)
|
||||
`MIMM_ZERO: mult_imm_id = '0;
|
||||
`MIMM_S3: mult_imm_id = imm_s3_type[4:0];
|
||||
MIMM_ZERO: mult_imm_id = '0;
|
||||
MIMM_S3: mult_imm_id = imm_s3_type[4:0];
|
||||
default: mult_imm_id = '0;
|
||||
endcase
|
||||
end
|
||||
|
@ -1004,7 +1010,7 @@ module riscv_id_stage
|
|||
begin : ID_EX_PIPE_REGISTERS
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
alu_operator_ex_o <= `ALU_SLTU;
|
||||
alu_operator_ex_o <= ALU_SLTU;
|
||||
alu_operand_a_ex_o <= '0;
|
||||
alu_operand_b_ex_o <= '0;
|
||||
alu_operand_c_ex_o <= '0;
|
||||
|
@ -1035,7 +1041,7 @@ module riscv_id_stage
|
|||
prepost_useincr_ex_o <= 1'b0;
|
||||
|
||||
csr_access_ex_o <= 1'b0;
|
||||
csr_op_ex_o <= `CSR_OP_NONE;
|
||||
csr_op_ex_o <= CSR_OP_NONE;
|
||||
|
||||
data_we_ex_o <= 1'b0;
|
||||
data_type_ex_o <= 2'b0;
|
||||
|
@ -1137,11 +1143,11 @@ module riscv_id_stage
|
|||
|
||||
data_misaligned_ex_o <= 1'b0;
|
||||
|
||||
if ((jump_in_id == `BRANCH_COND) || data_load_event_id) begin
|
||||
if ((jump_in_id == BRANCH_COND) || data_load_event_id) begin
|
||||
pc_ex_o <= pc_id_i;
|
||||
end
|
||||
|
||||
branch_in_ex_o <= jump_in_id == `BRANCH_COND;
|
||||
branch_in_ex_o <= jump_in_id == BRANCH_COND;
|
||||
end else if(ex_ready_i) begin
|
||||
// EX stage is ready but we don't have a new instruction for it,
|
||||
// so we set all write enables to 0, but unstall the pipe
|
||||
|
@ -1150,7 +1156,7 @@ module riscv_id_stage
|
|||
|
||||
regfile_alu_we_ex_o <= 1'b0;
|
||||
|
||||
csr_op_ex_o <= `CSR_OP_NONE;
|
||||
csr_op_ex_o <= CSR_OP_NONE;
|
||||
|
||||
data_req_ex_o <= 1'b0;
|
||||
data_load_event_ex_o <= 1'b0;
|
||||
|
|
22
if_stage.sv
22
if_stage.sv
|
@ -26,7 +26,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_if_stage
|
||||
#(
|
||||
|
@ -122,10 +122,10 @@ module riscv_if_stage
|
|||
exc_pc = 'x;
|
||||
|
||||
unique case (exc_pc_mux_i)
|
||||
`EXC_PC_ILLINSN: exc_pc = { boot_addr_i[31:8], `EXC_OFF_ILLINSN };
|
||||
`EXC_PC_ECALL: exc_pc = { boot_addr_i[31:8], `EXC_OFF_ECALL };
|
||||
`EXC_PC_LOAD: exc_pc = { boot_addr_i[31:8], `EXC_OFF_LSUERR };
|
||||
`EXC_PC_IRQ: exc_pc = { boot_addr_i[31:8], 1'b0, exc_vec_pc_mux_i[4:0], 2'b0 };
|
||||
EXC_PC_ILLINSN: exc_pc = { boot_addr_i[31:8], EXC_OFF_ILLINSN };
|
||||
EXC_PC_ECALL: exc_pc = { boot_addr_i[31:8], EXC_OFF_ECALL };
|
||||
EXC_PC_LOAD: exc_pc = { boot_addr_i[31:8], EXC_OFF_LSUERR };
|
||||
EXC_PC_IRQ: exc_pc = { boot_addr_i[31:8], 1'b0, exc_vec_pc_mux_i[4:0], 2'b0 };
|
||||
// TODO: Add case for EXC_PC_STORE as soon as it differs from load
|
||||
|
||||
default:;
|
||||
|
@ -138,12 +138,12 @@ module riscv_if_stage
|
|||
fetch_addr_n = 'x;
|
||||
|
||||
unique case (pc_mux_i)
|
||||
`PC_BOOT: fetch_addr_n = {boot_addr_i[31:8], `EXC_OFF_RST};
|
||||
`PC_JUMP: fetch_addr_n = jump_target_id_i;
|
||||
`PC_BRANCH: fetch_addr_n = jump_target_ex_i;
|
||||
`PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler
|
||||
`PC_ERET: fetch_addr_n = exception_pc_reg_i; // PC is restored when returning from IRQ/exception
|
||||
`PC_DBG_NPC: fetch_addr_n = dbg_jump_addr_i; // PC is taken from debug unit
|
||||
PC_BOOT: fetch_addr_n = {boot_addr_i[31:8], EXC_OFF_RST};
|
||||
PC_JUMP: fetch_addr_n = jump_target_id_i;
|
||||
PC_BRANCH: fetch_addr_n = jump_target_ex_i;
|
||||
PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler
|
||||
PC_ERET: fetch_addr_n = exception_pc_reg_i; // PC is restored when returning from IRQ/exception
|
||||
PC_DBG_NPC: fetch_addr_n = dbg_jump_addr_i; // PC is taken from debug unit
|
||||
|
||||
default:;
|
||||
endcase
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`ifndef _CORE_DEFINES
|
||||
`define _CORE_DEFINES
|
||||
package riscv_defines;
|
||||
|
||||
|
||||
|
||||
// no traces for synthesis, they are not synthesizable
|
||||
`ifndef SYNTHESIS
|
||||
|
@ -44,40 +45,32 @@
|
|||
// |_| //
|
||||
////////////////////////////////////////////////
|
||||
|
||||
`define OPCODE_SYSTEM 7'h73
|
||||
`define OPCODE_FENCE 7'h0f
|
||||
`define OPCODE_OP 7'h33
|
||||
`define OPCODE_OPIMM 7'h13
|
||||
`define OPCODE_STORE 7'h23
|
||||
`define OPCODE_LOAD 7'h03
|
||||
`define OPCODE_BRANCH 7'h63
|
||||
`define OPCODE_JALR 7'h67
|
||||
`define OPCODE_JAL 7'h6f
|
||||
`define OPCODE_AUIPC 7'h17
|
||||
`define OPCODE_LUI 7'h37
|
||||
parameter OPCODE_SYSTEM = 7'h73;
|
||||
parameter OPCODE_FENCE = 7'h0f;
|
||||
parameter OPCODE_OP = 7'h33;
|
||||
parameter OPCODE_OPIMM = 7'h13;
|
||||
parameter OPCODE_STORE = 7'h23;
|
||||
parameter OPCODE_LOAD = 7'h03;
|
||||
parameter OPCODE_BRANCH = 7'h63;
|
||||
parameter OPCODE_JALR = 7'h67;
|
||||
parameter OPCODE_JAL = 7'h6f;
|
||||
parameter OPCODE_AUIPC = 7'h17;
|
||||
parameter OPCODE_LUI = 7'h37;
|
||||
|
||||
// those opcodes are now used for PULP custom instructions
|
||||
// `define OPCODE_CUST0 7'h0b
|
||||
// `define OPCODE_CUST1 7'h2b
|
||||
// parameter OPCODE_CUST0 = 7'h0b
|
||||
// parameter OPCODE_CUST1 = 7'h2b
|
||||
|
||||
// PULP custom
|
||||
`define OPCODE_LOAD_POST 7'h0b
|
||||
`define OPCODE_STORE_POST 7'h2b
|
||||
`define OPCODE_PULP_OP 7'h5b
|
||||
`define OPCODE_VECOP 7'h57
|
||||
`define OPCODE_HWLOOP 7'h7b
|
||||
parameter OPCODE_LOAD_POST = 7'h0b;
|
||||
parameter OPCODE_STORE_POST = 7'h2b;
|
||||
parameter OPCODE_PULP_OP = 7'h5b;
|
||||
parameter OPCODE_VECOP = 7'h57;
|
||||
parameter OPCODE_HWLOOP = 7'h7b;
|
||||
|
||||
|
||||
// Source/Destination register instruction index
|
||||
`define REG_S1 19:15
|
||||
`define REG_S2 24:20
|
||||
`define REG_S3 29:25
|
||||
`define REG_D 11:07
|
||||
|
||||
|
||||
`define REGC_S1 2'b10
|
||||
`define REGC_RD 2'b01
|
||||
`define REGC_ZERO 2'b11
|
||||
parameter REGC_S1 = 2'b10;
|
||||
parameter REGC_RD = 2'b01;
|
||||
parameter REGC_ZERO = 2'b11;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -89,101 +82,101 @@
|
|||
// |_| //
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`define ALU_OP_WIDTH 6
|
||||
parameter ALU_OP_WIDTH = 6;
|
||||
|
||||
`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
|
||||
parameter ALU_ADD = 6'b011000;
|
||||
parameter ALU_SUB = 6'b011001;
|
||||
parameter ALU_ADDU = 6'b011010;
|
||||
parameter ALU_SUBU = 6'b011011;
|
||||
parameter ALU_ADDR = 6'b011100;
|
||||
parameter ALU_SUBR = 6'b011101;
|
||||
parameter ALU_ADDUR = 6'b011110;
|
||||
parameter ALU_SUBUR = 6'b011111;
|
||||
|
||||
`define ALU_XOR 6'b101111
|
||||
`define ALU_OR 6'b101110
|
||||
`define ALU_AND 6'b010101
|
||||
parameter ALU_XOR = 6'b101111;
|
||||
parameter ALU_OR = 6'b101110;
|
||||
parameter ALU_AND = 6'b010101;
|
||||
|
||||
// Shifts
|
||||
`define ALU_SRA 6'b100100
|
||||
`define ALU_SRL 6'b100101
|
||||
`define ALU_ROR 6'b100110
|
||||
`define ALU_SLL 6'b100111
|
||||
parameter ALU_SRA = 6'b100100;
|
||||
parameter ALU_SRL = 6'b100101;
|
||||
parameter ALU_ROR = 6'b100110;
|
||||
parameter ALU_SLL = 6'b100111;
|
||||
|
||||
// bit manipulation
|
||||
`define ALU_BEXT 6'b101000
|
||||
`define ALU_BEXTU 6'b101001
|
||||
`define ALU_BINS 6'b101010
|
||||
`define ALU_BCLR 6'b101011
|
||||
`define ALU_BSET 6'b101100
|
||||
parameter ALU_BEXT = 6'b101000;
|
||||
parameter ALU_BEXTU = 6'b101001;
|
||||
parameter ALU_BINS = 6'b101010;
|
||||
parameter ALU_BCLR = 6'b101011;
|
||||
parameter ALU_BSET = 6'b101100;
|
||||
|
||||
// Bit counting
|
||||
`define ALU_FF1 6'b110110
|
||||
`define ALU_FL1 6'b110111
|
||||
`define ALU_CNT 6'b110100
|
||||
`define ALU_CLB 6'b110101
|
||||
parameter ALU_FF1 = 6'b110110;
|
||||
parameter ALU_FL1 = 6'b110111;
|
||||
parameter ALU_CNT = 6'b110100;
|
||||
parameter ALU_CLB = 6'b110101;
|
||||
|
||||
// Sign-/zero-extensions
|
||||
`define ALU_EXTS 6'b111110
|
||||
`define ALU_EXT 6'b111111
|
||||
parameter ALU_EXTS = 6'b111110;
|
||||
parameter ALU_EXT = 6'b111111;
|
||||
|
||||
// Comparisons
|
||||
`define ALU_LTS 6'b000000
|
||||
`define ALU_LTU 6'b000001
|
||||
`define ALU_LES 6'b000100
|
||||
`define ALU_LEU 6'b000101
|
||||
`define ALU_GTS 6'b001000
|
||||
`define ALU_GTU 6'b001001
|
||||
`define ALU_GES 6'b001010
|
||||
`define ALU_GEU 6'b001011
|
||||
`define ALU_EQ 6'b001100
|
||||
`define ALU_NE 6'b001101
|
||||
`define ALU_EQALL 6'b001110
|
||||
parameter ALU_LTS = 6'b000000;
|
||||
parameter ALU_LTU = 6'b000001;
|
||||
parameter ALU_LES = 6'b000100;
|
||||
parameter ALU_LEU = 6'b000101;
|
||||
parameter ALU_GTS = 6'b001000;
|
||||
parameter ALU_GTU = 6'b001001;
|
||||
parameter ALU_GES = 6'b001010;
|
||||
parameter ALU_GEU = 6'b001011;
|
||||
parameter ALU_EQ = 6'b001100;
|
||||
parameter ALU_NE = 6'b001101;
|
||||
parameter ALU_EQALL = 6'b001110;
|
||||
|
||||
// Set Lower Than operations
|
||||
`define ALU_SLTS 6'b000010
|
||||
`define ALU_SLTU 6'b000011
|
||||
`define ALU_SLETS 6'b000110
|
||||
`define ALU_SLETU 6'b000111
|
||||
parameter ALU_SLTS = 6'b000010;
|
||||
parameter ALU_SLTU = 6'b000011;
|
||||
parameter ALU_SLETS = 6'b000110;
|
||||
parameter ALU_SLETU = 6'b000111;
|
||||
|
||||
// Absolute value
|
||||
`define ALU_ABS 6'b010100
|
||||
`define ALU_CLIP 6'b010110
|
||||
`define ALU_CLIPU 6'b010111
|
||||
parameter ALU_ABS = 6'b010100;
|
||||
parameter ALU_CLIP = 6'b010110;
|
||||
parameter ALU_CLIPU = 6'b010111;
|
||||
|
||||
// Insert/extract
|
||||
`define ALU_INS 6'b101101
|
||||
parameter 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
|
||||
parameter ALU_MIN = 6'b010000;
|
||||
parameter ALU_MINU = 6'b010001;
|
||||
parameter ALU_MAX = 6'b010010;
|
||||
parameter ALU_MAXU = 6'b010011;
|
||||
|
||||
// div/rem
|
||||
`define ALU_DIVU 6'b110000 // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
`define ALU_DIV 6'b110001 // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
`define ALU_REMU 6'b110010 // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
`define ALU_REM 6'b110011 // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
parameter ALU_DIVU = 6'b110000; // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
parameter ALU_DIV = 6'b110001; // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
parameter ALU_REMU = 6'b110010; // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
parameter ALU_REM = 6'b110011; // bit 0 is used for signed mode, bit 1 is used for remdiv
|
||||
|
||||
`define ALU_SHUF 6'b111010
|
||||
`define ALU_SHUF2 6'b111011
|
||||
`define ALU_PCKLO 6'b111000
|
||||
`define ALU_PCKHI 6'b111001
|
||||
parameter ALU_SHUF = 6'b111010;
|
||||
parameter ALU_SHUF2 = 6'b111011;
|
||||
parameter ALU_PCKLO = 6'b111000;
|
||||
parameter ALU_PCKHI = 6'b111001;
|
||||
|
||||
|
||||
`define MUL_MAC32 3'b000
|
||||
`define MUL_MSU32 3'b001
|
||||
`define MUL_I 3'b010
|
||||
`define MUL_IR 3'b011
|
||||
`define MUL_DOT8 3'b100
|
||||
`define MUL_DOT16 3'b101
|
||||
`define MUL_H 3'b110
|
||||
parameter MUL_MAC32 = 3'b000;
|
||||
parameter MUL_MSU32 = 3'b001;
|
||||
parameter MUL_I = 3'b010;
|
||||
parameter MUL_IR = 3'b011;
|
||||
parameter MUL_DOT8 = 3'b100;
|
||||
parameter MUL_DOT16 = 3'b101;
|
||||
parameter MUL_H = 3'b110;
|
||||
|
||||
// vector modes
|
||||
`define VEC_MODE32 2'b00
|
||||
`define VEC_MODE16 2'b10
|
||||
`define VEC_MODE8 2'b11
|
||||
parameter VEC_MODE32 = 2'b00;
|
||||
parameter VEC_MODE16 = 2'b10;
|
||||
parameter VEC_MODE8 = 2'b11;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
@ -196,22 +189,22 @@
|
|||
/////////////////////////////////////////////////////////
|
||||
|
||||
// CSR operations
|
||||
`define CSR_OP_NONE 2'b00
|
||||
`define CSR_OP_WRITE 2'b01
|
||||
`define CSR_OP_SET 2'b10
|
||||
`define CSR_OP_CLEAR 2'b11
|
||||
parameter CSR_OP_NONE = 2'b00;
|
||||
parameter CSR_OP_WRITE = 2'b01;
|
||||
parameter CSR_OP_SET = 2'b10;
|
||||
parameter CSR_OP_CLEAR = 2'b11;
|
||||
|
||||
|
||||
// SPR for debugger, not accessible by CPU
|
||||
`define SP_DVR0 16'h3000
|
||||
`define SP_DCR0 16'h3008
|
||||
`define SP_DMR1 16'h3010
|
||||
`define SP_DMR2 16'h3011
|
||||
parameter SP_DVR0 = 16'h3000;
|
||||
parameter SP_DCR0 = 16'h3008;
|
||||
parameter SP_DMR1 = 16'h3010;
|
||||
parameter SP_DMR2 = 16'h3011;
|
||||
|
||||
`define SP_DVR_MSB 8'h00
|
||||
`define SP_DCR_MSB 8'h01
|
||||
`define SP_DMR_MSB 8'h02
|
||||
`define SP_DSR_MSB 8'h04
|
||||
parameter SP_DVR_MSB = 8'h00;
|
||||
parameter SP_DCR_MSB = 8'h01;
|
||||
parameter SP_DMR_MSB = 8'h02;
|
||||
parameter SP_DSR_MSB = 8'h04;
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -224,65 +217,65 @@
|
|||
///////////////////////////////////////////////
|
||||
|
||||
// forwarding operand mux
|
||||
`define SEL_REGFILE 2'b00
|
||||
`define SEL_FW_EX 2'b01
|
||||
`define SEL_FW_WB 2'b10
|
||||
parameter SEL_REGFILE = 2'b00;
|
||||
parameter SEL_FW_EX = 2'b01;
|
||||
parameter SEL_FW_WB = 2'b10;
|
||||
|
||||
// operand a selection
|
||||
`define OP_A_REGA_OR_FWD 2'b00
|
||||
`define OP_A_CURRPC 2'b01
|
||||
`define OP_A_IMM 2'b10
|
||||
`define OP_A_REGB_OR_FWD 2'b11
|
||||
parameter OP_A_REGA_OR_FWD = 2'b00;
|
||||
parameter OP_A_CURRPC = 2'b01;
|
||||
parameter OP_A_IMM = 2'b10;
|
||||
parameter OP_A_REGB_OR_FWD = 2'b11;
|
||||
|
||||
// immediate a selection
|
||||
`define IMMA_Z 1'b0
|
||||
`define IMMA_ZERO 1'b1
|
||||
parameter IMMA_Z = 1'b0;
|
||||
parameter IMMA_ZERO = 1'b1;
|
||||
|
||||
// operand b selection
|
||||
`define OP_B_REGB_OR_FWD 2'b00
|
||||
`define OP_B_REGC_OR_FWD 2'b01
|
||||
`define OP_B_IMM 2'b10
|
||||
parameter OP_B_REGB_OR_FWD = 2'b00;
|
||||
parameter OP_B_REGC_OR_FWD = 2'b01;
|
||||
parameter OP_B_IMM = 2'b10;
|
||||
|
||||
// immediate b selection
|
||||
`define IMMB_I 4'b0000
|
||||
`define IMMB_S 4'b0001
|
||||
`define IMMB_U 4'b0010
|
||||
`define IMMB_PCINCR 4'b0011
|
||||
`define IMMB_S2 4'b0100
|
||||
`define IMMB_S3 4'b0101
|
||||
`define IMMB_VS 4'b0110
|
||||
`define IMMB_VU 4'b0111
|
||||
`define IMMB_SHUF 4'b1000
|
||||
`define IMMB_CLIP 4'b1001
|
||||
parameter IMMB_I = 4'b0000;
|
||||
parameter IMMB_S = 4'b0001;
|
||||
parameter IMMB_U = 4'b0010;
|
||||
parameter IMMB_PCINCR = 4'b0011;
|
||||
parameter IMMB_S2 = 4'b0100;
|
||||
parameter IMMB_S3 = 4'b0101;
|
||||
parameter IMMB_VS = 4'b0110;
|
||||
parameter IMMB_VU = 4'b0111;
|
||||
parameter IMMB_SHUF = 4'b1000;
|
||||
parameter IMMB_CLIP = 4'b1001;
|
||||
|
||||
// bit mask selection
|
||||
`define BMASK_A_ZERO 1'b0
|
||||
`define BMASK_A_S3 1'b1
|
||||
parameter BMASK_A_ZERO = 1'b0;
|
||||
parameter 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
|
||||
parameter BMASK_B_S2 = 2'b00;
|
||||
parameter BMASK_B_S3 = 2'b01;
|
||||
parameter BMASK_B_ZERO = 2'b10;
|
||||
parameter BMASK_B_ONE = 2'b11;
|
||||
|
||||
// multiplication immediates
|
||||
`define MIMM_ZERO 1'b0
|
||||
`define MIMM_S3 1'b1
|
||||
parameter MIMM_ZERO = 1'b0;
|
||||
parameter MIMM_S3 = 1'b1;
|
||||
|
||||
// operand c selection
|
||||
`define OP_C_REGC_OR_FWD 2'b00
|
||||
`define OP_C_REGB_OR_FWD 2'b01
|
||||
`define OP_C_JT 2'b10
|
||||
parameter OP_C_REGC_OR_FWD = 2'b00;
|
||||
parameter OP_C_REGB_OR_FWD = 2'b01;
|
||||
parameter OP_C_JT = 2'b10;
|
||||
|
||||
// branch types
|
||||
`define BRANCH_NONE 2'b00
|
||||
`define BRANCH_JAL 2'b01
|
||||
`define BRANCH_JALR 2'b10
|
||||
`define BRANCH_COND 2'b11 // conditional branches
|
||||
parameter BRANCH_NONE = 2'b00;
|
||||
parameter BRANCH_JAL = 2'b01;
|
||||
parameter BRANCH_JALR = 2'b10;
|
||||
parameter BRANCH_COND = 2'b11; // conditional branches
|
||||
|
||||
// jump target mux
|
||||
`define JT_JAL 2'b01
|
||||
`define JT_JALR 2'b10
|
||||
`define JT_COND 2'b11
|
||||
parameter JT_JAL = 2'b01;
|
||||
parameter JT_JALR = 2'b10;
|
||||
parameter JT_COND = 2'b11;
|
||||
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
@ -295,40 +288,39 @@
|
|||
///////////////////////////////////////////////
|
||||
|
||||
// PC mux selector defines
|
||||
`define PC_BOOT 3'b000
|
||||
`define PC_JUMP 3'b010
|
||||
`define PC_BRANCH 3'b011
|
||||
`define PC_EXCEPTION 3'b100
|
||||
`define PC_ERET 3'b101
|
||||
`define PC_DBG_NPC 3'b111
|
||||
parameter PC_BOOT = 3'b000;
|
||||
parameter PC_JUMP = 3'b010;
|
||||
parameter PC_BRANCH = 3'b011;
|
||||
parameter PC_EXCEPTION = 3'b100;
|
||||
parameter PC_ERET = 3'b101;
|
||||
parameter PC_DBG_NPC = 3'b111;
|
||||
|
||||
// Exception PC mux selector defines
|
||||
`define EXC_PC_ILLINSN 2'b00
|
||||
`define EXC_PC_ECALL 2'b01
|
||||
`define EXC_PC_LOAD 2'b10
|
||||
`define EXC_PC_STORE 2'b10
|
||||
`define EXC_PC_IRQ 2'b11
|
||||
parameter EXC_PC_ILLINSN = 2'b00;
|
||||
parameter EXC_PC_ECALL = 2'b01;
|
||||
parameter EXC_PC_LOAD = 2'b10;
|
||||
parameter EXC_PC_STORE = 2'b10;
|
||||
parameter EXC_PC_IRQ = 2'b11;
|
||||
|
||||
// Exceptions offsets
|
||||
// target address = {boot_addr[31:8], EXC_OFF} (boot_addr must be 32 BYTE aligned!)
|
||||
// offset 00 to 7e is used for external interrupts
|
||||
`define EXC_OFF_RST 8'h80
|
||||
`define EXC_OFF_ILLINSN 8'h84
|
||||
`define EXC_OFF_ECALL 8'h88
|
||||
`define EXC_OFF_LSUERR 8'h8c
|
||||
parameter EXC_OFF_RST = 8'h80;
|
||||
parameter EXC_OFF_ILLINSN = 8'h84;
|
||||
parameter EXC_OFF_ECALL = 8'h88;
|
||||
parameter EXC_OFF_LSUERR = 8'h8c;
|
||||
|
||||
|
||||
// Debug module
|
||||
`define DBG_SETS_W 6
|
||||
parameter DBG_SETS_W = 6;
|
||||
|
||||
`define DBG_SETS_IRQ 5
|
||||
`define DBG_SETS_ECALL 4
|
||||
`define DBG_SETS_EILL 3
|
||||
`define DBG_SETS_ELSU 2
|
||||
`define DBG_SETS_EBRK 1
|
||||
`define DBG_SETS_SSTE 0
|
||||
parameter DBG_SETS_IRQ = 5;
|
||||
parameter DBG_SETS_ECALL = 4;
|
||||
parameter DBG_SETS_EILL = 3;
|
||||
parameter DBG_SETS_ELSU = 2;
|
||||
parameter DBG_SETS_EBRK = 1;
|
||||
parameter DBG_SETS_SSTE = 0;
|
||||
|
||||
`define DBG_CAUSE_HALT 6'h1F
|
||||
parameter DBG_CAUSE_HALT = 6'h1F;
|
||||
|
||||
|
||||
`endif
|
||||
endpackage
|
||||
|
|
|
@ -8,101 +8,100 @@
|
|||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations under the License.
|
||||
|
||||
`ifndef _CORE_TRACER_DEFINES
|
||||
`define _CORE_TRACER_DEFINES
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
package riscv_tracer_defines;
|
||||
import riscv_defines::*;
|
||||
|
||||
// instruction masks (for tracer)
|
||||
// `define INSTR_CUSTOM0 { 25'b?, `OPCODE_CUST0 }
|
||||
// `define INSTR_CUSTOM1 { 25'b?, `OPCODE_CUST1 }
|
||||
`define INSTR_LUI { 25'b?, `OPCODE_LUI }
|
||||
`define INSTR_AUIPC { 25'b?, `OPCODE_AUIPC }
|
||||
`define INSTR_JAL { 25'b?, `OPCODE_JAL }
|
||||
`define INSTR_JALR { 17'b?, 3'b000, 5'b?, `OPCODE_JALR }
|
||||
// parameter INSTR_CUSTOM0 = { 25'b?, OPCODE_CUST0 };
|
||||
// parameter INSTR_CUSTOM1 = { 25'b?, OPCODE_CUST1 };
|
||||
parameter INSTR_LUI = { 25'b?, OPCODE_LUI };
|
||||
parameter INSTR_AUIPC = { 25'b?, OPCODE_AUIPC };
|
||||
parameter INSTR_JAL = { 25'b?, OPCODE_JAL };
|
||||
parameter INSTR_JALR = { 17'b?, 3'b000, 5'b?, OPCODE_JALR };
|
||||
// BRANCH
|
||||
`define INSTR_BEQ { 17'b?, 3'b000, 5'b?, `OPCODE_BRANCH }
|
||||
`define INSTR_BNE { 17'b?, 3'b001, 5'b?, `OPCODE_BRANCH }
|
||||
`define INSTR_BLT { 17'b?, 3'b100, 5'b?, `OPCODE_BRANCH }
|
||||
`define INSTR_BGE { 17'b?, 3'b101, 5'b?, `OPCODE_BRANCH }
|
||||
`define INSTR_BLTU { 17'b?, 3'b110, 5'b?, `OPCODE_BRANCH }
|
||||
`define INSTR_BGEU { 17'b?, 3'b111, 5'b?, `OPCODE_BRANCH }
|
||||
`define INSTR_BALL { 17'b?, 3'b010, 5'b?, `OPCODE_BRANCH }
|
||||
parameter INSTR_BEQ = { 17'b?, 3'b000, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BNE = { 17'b?, 3'b001, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BLT = { 17'b?, 3'b100, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BGE = { 17'b?, 3'b101, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BLTU = { 17'b?, 3'b110, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BGEU = { 17'b?, 3'b111, 5'b?, OPCODE_BRANCH };
|
||||
parameter INSTR_BALL = { 17'b?, 3'b010, 5'b?, OPCODE_BRANCH };
|
||||
// OPIMM
|
||||
`define INSTR_ADDI { 17'b?, 3'b000, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_SLTI { 17'b?, 3'b010, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_SLTIU { 17'b?, 3'b011, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_XORI { 17'b?, 3'b100, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_ORI { 17'b?, 3'b110, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_ANDI { 17'b?, 3'b111, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_SLLI { 7'b0000000, 10'b?, 3'b001, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_SRLI { 7'b0000000, 10'b?, 3'b101, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_SRAI { 7'b0100000, 10'b?, 3'b101, 5'b?, `OPCODE_OPIMM }
|
||||
parameter INSTR_ADDI = { 17'b?, 3'b000, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SLTI = { 17'b?, 3'b010, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SLTIU = { 17'b?, 3'b011, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_XORI = { 17'b?, 3'b100, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_ORI = { 17'b?, 3'b110, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_ANDI = { 17'b?, 3'b111, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SLLI = { 7'b0000000, 10'b?, 3'b001, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SRLI = { 7'b0000000, 10'b?, 3'b101, 5'b?, OPCODE_OPIMM };
|
||||
parameter INSTR_SRAI = { 7'b0100000, 10'b?, 3'b101, 5'b?, OPCODE_OPIMM };
|
||||
// OP
|
||||
`define INSTR_ADD { 7'b0000000, 10'b?, 3'b000, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_SUB { 7'b0100000, 10'b?, 3'b000, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_SLL { 7'b0000000, 10'b?, 3'b001, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_SLT { 7'b0000000, 10'b?, 3'b010, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_SLTU { 7'b0000000, 10'b?, 3'b011, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_XOR { 7'b0000000, 10'b?, 3'b100, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_SRL { 7'b0000000, 10'b?, 3'b101, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_SRA { 7'b0100000, 10'b?, 3'b101, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_OR { 7'b0000000, 10'b?, 3'b110, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_AND { 7'b0000000, 10'b?, 3'b111, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_EXTHS { 7'b0001000, 10'b?, 3'b100, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_EXTHZ { 7'b0001000, 10'b?, 3'b101, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_EXTBS { 7'b0001000, 10'b?, 3'b110, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`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
|
||||
`define INSTR_PSLET { 7'b0000010, 10'b?, 3'b010, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PSLETU { 7'b0000010, 10'b?, 3'b011, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PMIN { 7'b0000010, 10'b?, 3'b100, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PMINU { 7'b0000010, 10'b?, 3'b101, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PMAX { 7'b0000010, 10'b?, 3'b110, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PMAXU { 7'b0000010, 10'b?, 3'b111, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PBEXT { 2'b11, 5'b?, 5'b?, 5'b?, 3'b000, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PBEXTU { 2'b11, 5'b?, 5'b?, 5'b?, 3'b001, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PBINS { 2'b11, 5'b?, 5'b?, 5'b?, 3'b010, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PBCLR { 2'b11, 5'b?, 5'b?, 5'b?, 3'b100, 5'b?, `OPCODE_OP } // pulp specific
|
||||
`define INSTR_PBSET { 2'b11, 5'b?, 5'b?, 5'b?, 3'b011, 5'b?, `OPCODE_OP } // pulp specific
|
||||
parameter INSTR_ADD = { 7'b0000000, 10'b?, 3'b000, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SUB = { 7'b0100000, 10'b?, 3'b000, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SLL = { 7'b0000000, 10'b?, 3'b001, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SLT = { 7'b0000000, 10'b?, 3'b010, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SLTU = { 7'b0000000, 10'b?, 3'b011, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_XOR = { 7'b0000000, 10'b?, 3'b100, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SRL = { 7'b0000000, 10'b?, 3'b101, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_SRA = { 7'b0100000, 10'b?, 3'b101, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_OR = { 7'b0000000, 10'b?, 3'b110, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_AND = { 7'b0000000, 10'b?, 3'b111, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_EXTHS = { 7'b0001000, 10'b?, 3'b100, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_EXTHZ = { 7'b0001000, 10'b?, 3'b101, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_EXTBS = { 7'b0001000, 10'b?, 3'b110, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_EXTBZ = { 7'b0001000, 10'b?, 3'b111, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PAVG = { 7'b0000010, 10'b?, 3'b000, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PAVGU = { 7'b0000010, 10'b?, 3'b001, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PADDN = { 2'b00, 15'b?, 3'b010, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PADDUN = { 2'b10, 15'b?, 3'b010, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PADDRN = { 2'b00, 15'b?, 3'b110, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PADDURN = { 2'b10, 15'b?, 3'b110, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PSUBN = { 2'b00, 15'b?, 3'b011, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PSUBUN = { 2'b10, 15'b?, 3'b011, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PSUBRN = { 2'b00, 15'b?, 3'b111, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PSUBURN = { 2'b10, 15'b?, 3'b111, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
parameter INSTR_PABS = { 7'b0001010, 10'b?, 3'b000, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PCLIP = { 7'b0001010, 10'b?, 3'b001, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PCLIPU = { 7'b0001010, 10'b?, 3'b010, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PSLET = { 7'b0000010, 10'b?, 3'b010, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PSLETU = { 7'b0000010, 10'b?, 3'b011, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PMIN = { 7'b0000010, 10'b?, 3'b100, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PMINU = { 7'b0000010, 10'b?, 3'b101, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PMAX = { 7'b0000010, 10'b?, 3'b110, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PMAXU = { 7'b0000010, 10'b?, 3'b111, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PBEXT = { 2'b11, 5'b?, 5'b?, 5'b?, 3'b000, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PBEXTU = { 2'b11, 5'b?, 5'b?, 5'b?, 3'b001, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PBINS = { 2'b11, 5'b?, 5'b?, 5'b?, 3'b010, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PBCLR = { 2'b11, 5'b?, 5'b?, 5'b?, 3'b100, 5'b?, OPCODE_OP }; // pulp specific
|
||||
parameter INSTR_PBSET = { 2'b11, 5'b?, 5'b?, 5'b?, 3'b011, 5'b?, OPCODE_OP }; // pulp specific
|
||||
// FENCE
|
||||
`define INSTR_FENCE { 4'b0, 8'b?, 13'b0, `OPCODE_FENCE }
|
||||
`define INSTR_FENCEI { 17'b0, 3'b001, 5'b0, `OPCODE_FENCE }
|
||||
parameter INSTR_FENCE = { 4'b0, 8'b?, 13'b0, OPCODE_FENCE };
|
||||
parameter INSTR_FENCEI = { 17'b0, 3'b001, 5'b0, OPCODE_FENCE };
|
||||
// SYSTEM
|
||||
`define INSTR_CSRRW { 17'b?, 3'b001, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_CSRRS { 17'b?, 3'b010, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_CSRRC { 17'b?, 3'b011, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_CSRRWI { 17'b?, 3'b101, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_CSRRSI { 17'b?, 3'b110, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_CSRRCI { 17'b?, 3'b111, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_ECALL { 12'b000000000000, 13'b0, `OPCODE_SYSTEM }
|
||||
`define INSTR_EBREAK { 12'b000000000001, 13'b0, `OPCODE_SYSTEM }
|
||||
`define INSTR_ERET { 12'b000100000000, 13'b0, `OPCODE_SYSTEM }
|
||||
`define INSTR_WFI { 12'b000100000010, 13'b0, `OPCODE_SYSTEM }
|
||||
parameter INSTR_CSRRW = { 17'b?, 3'b001, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRS = { 17'b?, 3'b010, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRC = { 17'b?, 3'b011, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRWI = { 17'b?, 3'b101, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRSI = { 17'b?, 3'b110, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_CSRRCI = { 17'b?, 3'b111, 5'b?, OPCODE_SYSTEM };
|
||||
parameter INSTR_ECALL = { 12'b000000000000, 13'b0, OPCODE_SYSTEM };
|
||||
parameter INSTR_EBREAK = { 12'b000000000001, 13'b0, OPCODE_SYSTEM };
|
||||
parameter INSTR_ERET = { 12'b000100000000, 13'b0, OPCODE_SYSTEM };
|
||||
parameter INSTR_WFI = { 12'b000100000010, 13'b0, OPCODE_SYSTEM };
|
||||
|
||||
// RV32M
|
||||
`define INSTR_PMUL { 7'b0000001, 10'b?, 3'b000, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_DIV { 7'b0000001, 10'b?, 3'b100, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_DIVU { 7'b0000001, 10'b?, 3'b101, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_REM { 7'b0000001, 10'b?, 3'b110, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_REMU { 7'b0000001, 10'b?, 3'b111, 5'b?, `OPCODE_OP }
|
||||
`define INSTR_PMAC { 7'b0000001, 10'b?, 3'b001, 5'b?, `OPCODE_OP }
|
||||
parameter INSTR_PMUL = { 7'b0000001, 10'b?, 3'b000, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_DIV = { 7'b0000001, 10'b?, 3'b100, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_DIVU = { 7'b0000001, 10'b?, 3'b101, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_REM = { 7'b0000001, 10'b?, 3'b110, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_REMU = { 7'b0000001, 10'b?, 3'b111, 5'b?, OPCODE_OP };
|
||||
parameter INSTR_PMAC = { 7'b0000001, 10'b?, 3'b001, 5'b?, OPCODE_OP };
|
||||
|
||||
`define INSTR_PMULRN { 2'b??, 5'b?,10'b?, 3'b?0?, 5'b?, `OPCODE_PULP_OP } // pulp specific
|
||||
parameter INSTR_PMULRN = { 2'b??, 5'b?,10'b?, 3'b?0?, 5'b?, OPCODE_PULP_OP }; // pulp specific
|
||||
|
||||
// PULP custom instructions
|
||||
`define INSTR_MAC { 2'b00, 15'b?, 3'b000, 5'b?, `OPCODE_PULP_OP }
|
||||
|
||||
`endif
|
||||
parameter INSTR_MAC = { 2'b00, 15'b?, 3'b000, 5'b?, OPCODE_PULP_OP };
|
||||
|
||||
endpackage
|
|
@ -24,8 +24,6 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
|
||||
module riscv_load_store_unit
|
||||
(
|
||||
input logic clk,
|
||||
|
|
24
mult.sv
24
mult.sv
|
@ -22,7 +22,7 @@
|
|||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
|
||||
module riscv_mult
|
||||
|
@ -60,7 +60,7 @@ module riscv_mult
|
|||
///////////////////////////////////////////////////////////////
|
||||
// ___ _ _ _____ ___ ___ ___ ___ __ __ _ _ _ _____ //
|
||||
// |_ _| \| |_ _| __/ __| __| _ \ | \/ | | | | ||_ _| //
|
||||
// | || .` | | | | _| (_ | _|| / | |\/| | |_| | |__| | //
|
||||
// | || . | | | | _| (_ | _|| / | |\/| | |_| | |__| | //
|
||||
// |___|_|\_| |_| |___\___|___|_|_\ |_| |_|\___/|____|_| //
|
||||
// //
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
@ -90,7 +90,7 @@ module riscv_mult
|
|||
|
||||
// prepare the rounding value
|
||||
assign short_round_tmp = (32'h00000001) << imm_i;
|
||||
assign short_round = (operator_i == `MUL_IR) ? {1'b0, short_round_tmp[31:1]} : '0;
|
||||
assign short_round = (operator_i == MUL_IR) ? {1'b0, short_round_tmp[31:1]} : '0;
|
||||
|
||||
// perform subword selection and sign extensions
|
||||
assign short_op_a[15:0] = short_subword[0] ? op_a_i[31:16] : op_a_i[15:0];
|
||||
|
@ -129,7 +129,7 @@ module riscv_mult
|
|||
mulh_active = 1'b0;
|
||||
mulh_ready = 1'b1;
|
||||
|
||||
if ((operator_i == `MUL_H) && enable_i) begin
|
||||
if ((operator_i == MUL_H) && enable_i) begin
|
||||
mulh_ready = 1'b0;
|
||||
mulh_NS = STEP0;
|
||||
end
|
||||
|
@ -196,7 +196,7 @@ module riscv_mult
|
|||
|
||||
logic int_is_msu;
|
||||
|
||||
assign int_is_msu = (operator_i == `MUL_MSU32); // TODO: think about using a separate signal here, could prevent some switching
|
||||
assign int_is_msu = (operator_i == MUL_MSU32); // TODO: think about using a separate signal here, could prevent some switching
|
||||
|
||||
assign int_op_a_msu = op_a_i ^ {32{int_is_msu}};
|
||||
assign int_op_b_msu = op_b_i & {32{int_is_msu}};
|
||||
|
@ -268,12 +268,12 @@ module riscv_mult
|
|||
result_o = 'x;
|
||||
|
||||
unique case (operator_i)
|
||||
`MUL_MAC32, `MUL_MSU32: result_o = int_result[31:0];
|
||||
MUL_MAC32, MUL_MSU32: result_o = int_result[31:0];
|
||||
|
||||
`MUL_I, `MUL_IR, `MUL_H: result_o = short_result[31:0];
|
||||
MUL_I, MUL_IR, MUL_H: result_o = short_result[31:0];
|
||||
|
||||
`MUL_DOT8: result_o = dot_char_result[31:0];
|
||||
`MUL_DOT16: result_o = dot_short_result[31:0];
|
||||
MUL_DOT8: result_o = dot_char_result[31:0];
|
||||
MUL_DOT16: result_o = dot_short_result[31:0];
|
||||
|
||||
default: ; // default case to suppress unique warning
|
||||
endcase
|
||||
|
@ -288,19 +288,19 @@ module riscv_mult
|
|||
|
||||
// check multiplication result for mulh
|
||||
assert property (
|
||||
@(posedge clk) ((mulh_CS == FINISH) && (operator_i == `MUL_H) && (short_signed_i == 2'b11))
|
||||
@(posedge clk) ((mulh_CS == FINISH) && (operator_i == MUL_H) && (short_signed_i == 2'b11))
|
||||
|->
|
||||
(result_o == (($signed({{32{op_a_i[31]}}, op_a_i}) * $signed({{32{op_b_i[31]}}, op_b_i})) >>> 32) ) );
|
||||
|
||||
// check multiplication result for mulhsu
|
||||
assert property (
|
||||
@(posedge clk) ((mulh_CS == FINISH) && (operator_i == `MUL_H) && (short_signed_i == 2'b01))
|
||||
@(posedge clk) ((mulh_CS == FINISH) && (operator_i == MUL_H) && (short_signed_i == 2'b01))
|
||||
|->
|
||||
(result_o == (($signed({{32{op_a_i[31]}}, op_a_i}) * {32'b0, op_b_i}) >> 32) ) );
|
||||
|
||||
// check multiplication result for mulhu
|
||||
assert property (
|
||||
@(posedge clk) ((mulh_CS == FINISH) && (operator_i == `MUL_H) && (short_signed_i == 2'b00))
|
||||
@(posedge clk) ((mulh_CS == FINISH) && (operator_i == MUL_H) && (short_signed_i == 2'b00))
|
||||
|->
|
||||
(result_o == (({32'b0, op_a_i} * {32'b0, op_b_i}) >> 32) ) );
|
||||
endmodule
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
module riscv_core
|
||||
#(
|
||||
|
@ -128,7 +128,7 @@ module riscv_core
|
|||
logic [31:0] pc_ex; // PC of last executed branch or p.elw
|
||||
|
||||
// ALU Control
|
||||
logic [`ALU_OP_WIDTH-1:0] alu_operator_ex;
|
||||
logic [ALU_OP_WIDTH-1:0] alu_operator_ex;
|
||||
logic [31:0] alu_operand_a_ex;
|
||||
logic [31:0] alu_operand_b_ex;
|
||||
logic [31:0] alu_operand_c_ex;
|
||||
|
@ -226,7 +226,7 @@ module riscv_core
|
|||
|
||||
|
||||
// Debug Unit
|
||||
logic [`DBG_SETS_W-1:0] dbg_settings;
|
||||
logic [DBG_SETS_W-1:0] dbg_settings;
|
||||
logic dbg_req;
|
||||
logic dbg_ack;
|
||||
logic dbg_stall;
|
||||
|
@ -746,8 +746,8 @@ module riscv_core
|
|||
assign csr_addr = (dbg_csr_req == 1'b0) ? csr_addr_int : dbg_csr_addr;
|
||||
assign csr_wdata = (dbg_csr_req == 1'b0) ? alu_operand_a_ex : dbg_csr_wdata;
|
||||
assign csr_op = (dbg_csr_req == 1'b0) ? csr_op_ex
|
||||
: (dbg_csr_we == 1'b1 ? `CSR_OP_WRITE
|
||||
: `CSR_OP_NONE );
|
||||
: (dbg_csr_we == 1'b1 ? CSR_OP_WRITE
|
||||
: CSR_OP_NONE );
|
||||
assign csr_addr_int = csr_access_ex ? alu_operand_b_ex[11:0] : '0;
|
||||
|
||||
|
||||
|
@ -877,7 +877,7 @@ module riscv_core
|
|||
|
||||
`ifdef SIMCHECKER
|
||||
logic is_interrupt;
|
||||
assign is_interrupt = (pc_mux_id == `PC_EXCEPTION) && (exc_pc_mux_id == `EXC_PC_IRQ);
|
||||
assign is_interrupt = (pc_mux_id == PC_EXCEPTION) && (exc_pc_mux_id == EXC_PC_IRQ);
|
||||
|
||||
riscv_simchecker riscv_simchecker_i
|
||||
(
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_defines.sv"
|
||||
import riscv_defines::*;
|
||||
|
||||
// do not import anything if the simchecker is not used
|
||||
// this gets rid of warnings during simulation
|
||||
|
|
183
riscv_tracer.sv
183
riscv_tracer.sv
|
@ -22,7 +22,14 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "riscv_tracer_defines.sv"
|
||||
import riscv_defines::*;
|
||||
import riscv_tracer_defines::*;
|
||||
|
||||
// Source/Destination register instruction index
|
||||
`define REG_S1 19:15
|
||||
`define REG_S2 24:20
|
||||
`define REG_S3 29:25
|
||||
`define REG_D 11:07
|
||||
|
||||
module riscv_tracer
|
||||
(
|
||||
|
@ -306,7 +313,7 @@ module riscv_tracer
|
|||
|
||||
if (instr[14:12] != 3'b111) begin
|
||||
// regular load
|
||||
if (instr[6:0] != `OPCODE_LOAD_POST) begin
|
||||
if (instr[6:0] != OPCODE_LOAD_POST) begin
|
||||
regs_read.push_back('{rs1, rs1_value});
|
||||
str = $sformatf("%-16s x%0d, %0d(x%0d)", mnemonic, rd, $signed(imm_i_type), rs1);
|
||||
end else begin
|
||||
|
@ -316,7 +323,7 @@ module riscv_tracer
|
|||
end
|
||||
end else begin
|
||||
// reg-reg load
|
||||
if (instr[6:0] != `OPCODE_LOAD_POST) begin
|
||||
if (instr[6:0] != OPCODE_LOAD_POST) begin
|
||||
regs_read.push_back('{rs2, rs2_value});
|
||||
regs_read.push_back('{rs1, rs1_value});
|
||||
str = $sformatf("%-16s x%0d, x%0d(x%0d)", mnemonic, rd, rs2, rs1);
|
||||
|
@ -346,7 +353,7 @@ module riscv_tracer
|
|||
|
||||
if (instr[14] == 1'b0) begin
|
||||
// regular store
|
||||
if (instr[6:0] != `OPCODE_STORE_POST) begin
|
||||
if (instr[6:0] != OPCODE_STORE_POST) begin
|
||||
regs_read.push_back('{rs2, rs2_value});
|
||||
regs_read.push_back('{rs1, rs1_value});
|
||||
str = $sformatf("%-16s x%0d, %0d(x%0d)", mnemonic, rs2, $signed(imm_s_type), rs1);
|
||||
|
@ -358,7 +365,7 @@ module riscv_tracer
|
|||
end
|
||||
end else begin
|
||||
// reg-reg store
|
||||
if (instr[6:0] != `OPCODE_STORE_POST) begin
|
||||
if (instr[6:0] != OPCODE_STORE_POST) begin
|
||||
regs_read.push_back('{rs2, rs2_value});
|
||||
regs_read.push_back('{rs3, rs3_value});
|
||||
regs_read.push_back('{rs1, rs1_value});
|
||||
|
@ -658,97 +665,97 @@ module riscv_tracer
|
|||
// Aliases
|
||||
32'h00_00_00_13: trace.printMnemonic("nop");
|
||||
// Regular opcodes
|
||||
`INSTR_LUI: trace.printUInstr("lui");
|
||||
`INSTR_AUIPC: trace.printUInstr("auipc");
|
||||
`INSTR_JAL: trace.printUJInstr("jal");
|
||||
`INSTR_JALR: trace.printIInstr("jalr");
|
||||
INSTR_LUI: trace.printUInstr("lui");
|
||||
INSTR_AUIPC: trace.printUInstr("auipc");
|
||||
INSTR_JAL: trace.printUJInstr("jal");
|
||||
INSTR_JALR: trace.printIInstr("jalr");
|
||||
// BRANCH
|
||||
`INSTR_BEQ: trace.printSBInstr("beq");
|
||||
`INSTR_BNE: trace.printSBInstr("bne");
|
||||
`INSTR_BLT: trace.printSBInstr("blt");
|
||||
`INSTR_BGE: trace.printSBInstr("bge");
|
||||
`INSTR_BLTU: trace.printSBInstr("bltu");
|
||||
`INSTR_BGEU: trace.printSBInstr("bgeu");
|
||||
`INSTR_BALL: trace.printSBallInstr("pv.ball");
|
||||
INSTR_BEQ: trace.printSBInstr("beq");
|
||||
INSTR_BNE: trace.printSBInstr("bne");
|
||||
INSTR_BLT: trace.printSBInstr("blt");
|
||||
INSTR_BGE: trace.printSBInstr("bge");
|
||||
INSTR_BLTU: trace.printSBInstr("bltu");
|
||||
INSTR_BGEU: trace.printSBInstr("bgeu");
|
||||
INSTR_BALL: trace.printSBallInstr("pv.ball");
|
||||
// OPIMM
|
||||
`INSTR_ADDI: trace.printIInstr("addi");
|
||||
`INSTR_SLTI: trace.printIInstr("slti");
|
||||
`INSTR_SLTIU: trace.printIInstr("sltiu");
|
||||
`INSTR_XORI: trace.printIInstr("xori");
|
||||
`INSTR_ORI: trace.printIInstr("ori");
|
||||
`INSTR_ANDI: trace.printIInstr("andi");
|
||||
`INSTR_SLLI: trace.printIuInstr("slli");
|
||||
`INSTR_SRLI: trace.printIuInstr("srli");
|
||||
`INSTR_SRAI: trace.printIuInstr("srai");
|
||||
INSTR_ADDI: trace.printIInstr("addi");
|
||||
INSTR_SLTI: trace.printIInstr("slti");
|
||||
INSTR_SLTIU: trace.printIInstr("sltiu");
|
||||
INSTR_XORI: trace.printIInstr("xori");
|
||||
INSTR_ORI: trace.printIInstr("ori");
|
||||
INSTR_ANDI: trace.printIInstr("andi");
|
||||
INSTR_SLLI: trace.printIuInstr("slli");
|
||||
INSTR_SRLI: trace.printIuInstr("srli");
|
||||
INSTR_SRAI: trace.printIuInstr("srai");
|
||||
// OP
|
||||
`INSTR_ADD: trace.printRInstr("add");
|
||||
`INSTR_SUB: trace.printRInstr("sub");
|
||||
`INSTR_SLL: trace.printRInstr("sll");
|
||||
`INSTR_SLT: trace.printRInstr("slt");
|
||||
`INSTR_SLTU: trace.printRInstr("sltu");
|
||||
`INSTR_XOR: trace.printRInstr("xor");
|
||||
`INSTR_SRL: trace.printRInstr("srl");
|
||||
`INSTR_SRA: trace.printRInstr("sra");
|
||||
`INSTR_OR: trace.printRInstr("or");
|
||||
`INSTR_AND: trace.printRInstr("and");
|
||||
`INSTR_EXTHS: trace.printRInstr("p.exths");
|
||||
`INSTR_EXTHZ: trace.printRInstr("p.exthz");
|
||||
`INSTR_EXTBS: trace.printRInstr("p.extbs");
|
||||
`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");
|
||||
`INSTR_PMINU: trace.printRInstr("p.minu");
|
||||
`INSTR_PMAX: trace.printRInstr("p.max");
|
||||
`INSTR_PMAXU: trace.printRInstr("p.maxu");
|
||||
`INSTR_PABS: trace.printR1Instr("p.abs");
|
||||
`INSTR_PCLIP: trace.printClipInstr("p.clip");
|
||||
`INSTR_PCLIPU: trace.printClipInstr("p.clipu");
|
||||
`INSTR_PBEXT: trace.printBit1Instr("p.extract");
|
||||
`INSTR_PBEXTU: trace.printBit1Instr("p.extractu");
|
||||
`INSTR_PBINS: trace.printBit2Instr("p.insert");
|
||||
`INSTR_PBCLR: trace.printBit1Instr("p.bclr");
|
||||
`INSTR_PBSET: trace.printBit1Instr("p.bset");
|
||||
INSTR_ADD: trace.printRInstr("add");
|
||||
INSTR_SUB: trace.printRInstr("sub");
|
||||
INSTR_SLL: trace.printRInstr("sll");
|
||||
INSTR_SLT: trace.printRInstr("slt");
|
||||
INSTR_SLTU: trace.printRInstr("sltu");
|
||||
INSTR_XOR: trace.printRInstr("xor");
|
||||
INSTR_SRL: trace.printRInstr("srl");
|
||||
INSTR_SRA: trace.printRInstr("sra");
|
||||
INSTR_OR: trace.printRInstr("or");
|
||||
INSTR_AND: trace.printRInstr("and");
|
||||
INSTR_EXTHS: trace.printRInstr("p.exths");
|
||||
INSTR_EXTHZ: trace.printRInstr("p.exthz");
|
||||
INSTR_EXTBS: trace.printRInstr("p.extbs");
|
||||
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");
|
||||
INSTR_PMINU: trace.printRInstr("p.minu");
|
||||
INSTR_PMAX: trace.printRInstr("p.max");
|
||||
INSTR_PMAXU: trace.printRInstr("p.maxu");
|
||||
INSTR_PABS: trace.printR1Instr("p.abs");
|
||||
INSTR_PCLIP: trace.printClipInstr("p.clip");
|
||||
INSTR_PCLIPU: trace.printClipInstr("p.clipu");
|
||||
INSTR_PBEXT: trace.printBit1Instr("p.extract");
|
||||
INSTR_PBEXTU: trace.printBit1Instr("p.extractu");
|
||||
INSTR_PBINS: trace.printBit2Instr("p.insert");
|
||||
INSTR_PBCLR: trace.printBit1Instr("p.bclr");
|
||||
INSTR_PBSET: trace.printBit1Instr("p.bset");
|
||||
// FENCE
|
||||
`INSTR_FENCE: trace.printMnemonic("fence");
|
||||
`INSTR_FENCEI: trace.printMnemonic("fencei");
|
||||
INSTR_FENCE: trace.printMnemonic("fence");
|
||||
INSTR_FENCEI: trace.printMnemonic("fencei");
|
||||
// SYSTEM (CSR manipulation)
|
||||
`INSTR_CSRRW: trace.printCSRInstr("csrrw");
|
||||
`INSTR_CSRRS: trace.printCSRInstr("csrrs");
|
||||
`INSTR_CSRRC: trace.printCSRInstr("csrrc");
|
||||
`INSTR_CSRRWI: trace.printCSRInstr("csrrwi");
|
||||
`INSTR_CSRRSI: trace.printCSRInstr("csrrsi");
|
||||
`INSTR_CSRRCI: trace.printCSRInstr("csrrci");
|
||||
INSTR_CSRRW: trace.printCSRInstr("csrrw");
|
||||
INSTR_CSRRS: trace.printCSRInstr("csrrs");
|
||||
INSTR_CSRRC: trace.printCSRInstr("csrrc");
|
||||
INSTR_CSRRWI: trace.printCSRInstr("csrrwi");
|
||||
INSTR_CSRRSI: trace.printCSRInstr("csrrsi");
|
||||
INSTR_CSRRCI: trace.printCSRInstr("csrrci");
|
||||
// SYSTEM (others)
|
||||
`INSTR_ECALL: trace.printMnemonic("ecall");
|
||||
`INSTR_EBREAK: trace.printMnemonic("ebreak");
|
||||
`INSTR_ERET: trace.printMnemonic("eret");
|
||||
`INSTR_WFI: trace.printMnemonic("wfi");
|
||||
INSTR_ECALL: trace.printMnemonic("ecall");
|
||||
INSTR_EBREAK: trace.printMnemonic("ebreak");
|
||||
INSTR_ERET: trace.printMnemonic("eret");
|
||||
INSTR_WFI: trace.printMnemonic("wfi");
|
||||
// PULP MULTIPLIER
|
||||
`INSTR_PMUL: trace.printRInstr("p.mul");
|
||||
`INSTR_PMAC: trace.printR3Instr("p.mac");
|
||||
`INSTR_DIV: trace.printRInstr("div");
|
||||
`INSTR_DIVU: trace.printRInstr("divu");
|
||||
`INSTR_REM: trace.printRInstr("rem");
|
||||
`INSTR_REMU: trace.printRInstr("remu");
|
||||
INSTR_PMUL: trace.printRInstr("p.mul");
|
||||
INSTR_PMAC: trace.printR3Instr("p.mac");
|
||||
INSTR_DIV: trace.printRInstr("div");
|
||||
INSTR_DIVU: trace.printRInstr("divu");
|
||||
INSTR_REM: trace.printRInstr("rem");
|
||||
INSTR_REMU: trace.printRInstr("remu");
|
||||
// opcodes with custom decoding
|
||||
{25'b?, `OPCODE_LOAD}: trace.printLoadInstr();
|
||||
{25'b?, `OPCODE_LOAD_POST}: trace.printLoadInstr();
|
||||
{25'b?, `OPCODE_STORE}: trace.printStoreInstr();
|
||||
{25'b?, `OPCODE_STORE_POST}: trace.printStoreInstr();
|
||||
{25'b?, `OPCODE_HWLOOP}: trace.printHwloopInstr();
|
||||
{25'b?, `OPCODE_VECOP}: trace.printVecInstr();
|
||||
`INSTR_PMULRN: trace.printMulInstr();
|
||||
{25'b?, OPCODE_LOAD}: trace.printLoadInstr();
|
||||
{25'b?, OPCODE_LOAD_POST}: trace.printLoadInstr();
|
||||
{25'b?, OPCODE_STORE}: trace.printStoreInstr();
|
||||
{25'b?, OPCODE_STORE_POST}: trace.printStoreInstr();
|
||||
{25'b?, OPCODE_HWLOOP}: trace.printHwloopInstr();
|
||||
{25'b?, OPCODE_VECOP}: trace.printVecInstr();
|
||||
INSTR_PMULRN: trace.printMulInstr();
|
||||
default: trace.printMnemonic("INVALID");
|
||||
endcase // unique case (instr)
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ riscv:
|
|||
include,
|
||||
]
|
||||
files: [
|
||||
include/riscv_defines.sv,
|
||||
include/riscv_tracer_defines.sv,
|
||||
alu.sv,
|
||||
alu_div.sv,
|
||||
compressed_decoder.sv,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue