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:
Michael Gautschi 2016-06-13 16:27:13 +02:00
commit 840f500e79
20 changed files with 920 additions and 923 deletions

258
alu.sv
View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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?

View file

@ -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,

View file

@ -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

View file

@ -22,9 +22,6 @@
// //
////////////////////////////////////////////////////////////////////////////////
`include "riscv_defines.sv"
module riscv_hwloop_controller
#(
parameter N_REGS = 2

View file

@ -22,9 +22,6 @@
// //
////////////////////////////////////////////////////////////////////////////////
`include "riscv_defines.sv"
module riscv_hwloop_regs
#(
parameter N_REGS = 2,

View file

@ -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;

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -24,8 +24,6 @@
////////////////////////////////////////////////////////////////////////////////
`include "riscv_defines.sv"
module riscv_load_store_unit
(
input logic clk,

24
mult.sv
View file

@ -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

View file

@ -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
(

View file

@ -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

View file

@ -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)

View file

@ -3,6 +3,8 @@ riscv:
include,
]
files: [
include/riscv_defines.sv,
include/riscv_tracer_defines.sv,
alu.sv,
alu_div.sv,
compressed_decoder.sv,