mirror of
https://github.com/lowRISC/ibex.git
synced 2025-04-22 04:47:25 -04:00
Merge branch 'remove_vect'
This commit removes the vectorial ALU and updates RVC to the newest proposal.
This commit is contained in:
commit
b957c6f682
9 changed files with 436 additions and 768 deletions
449
alu.sv
449
alu.sv
|
@ -31,22 +31,18 @@
|
|||
|
||||
module riscv_alu
|
||||
(
|
||||
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 [`ALU_OP_WIDTH-1:0] operator_i,
|
||||
input logic [31:0] operand_a_i,
|
||||
input logic [31:0] operand_b_i,
|
||||
|
||||
input logic [1:0] vector_mode_i,
|
||||
input logic [1:0] cmp_mode_i,
|
||||
input logic [1:0] vec_ext_i,
|
||||
|
||||
output logic [31:0] result_o,
|
||||
output logic flag_o
|
||||
output logic [31:0] result_o,
|
||||
output logic comparison_result_o
|
||||
);
|
||||
|
||||
|
||||
logic [31:0] operand_a_rev; // bit reversed signal of operand_a_i
|
||||
logic [31:0] operand_a_rev;
|
||||
|
||||
// bit reverse operand_a for left shifts
|
||||
// bit reverse operand_a for left shifts and bit counting
|
||||
genvar k;
|
||||
generate
|
||||
for(k = 0; k < 32; k++)
|
||||
|
@ -55,17 +51,17 @@ module riscv_alu
|
|||
end
|
||||
endgenerate
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ____ _ _ _ _ _ _ _ _ //
|
||||
// | _ \ __ _ _ __| |_(_) |_(_) ___ _ __ ___ __| | / \ __| | __| | ___ _ __ //
|
||||
// | |_) / _` | '__| __| | __| |/ _ \| '_ \ / _ \/ _` | / _ \ / _` |/ _` |/ _ \ '__| //
|
||||
// | __/ (_| | | | |_| | |_| | (_) | | | | __/ (_| | / ___ \ (_| | (_| | __/ | //
|
||||
// |_| \__,_|_| \__|_|\__|_|\___/|_| |_|\___|\__,_| /_/ \_\__,_|\__,_|\___|_| //
|
||||
// //
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
logic [3:0] carry_in;
|
||||
logic [3:0] carry_out;
|
||||
/////////////////////////////////////
|
||||
// _ _ _ //
|
||||
// / \ __| | __| | ___ _ __ //
|
||||
// / _ \ / _` |/ _` |/ _ \ '__| //
|
||||
// / ___ \ (_| | (_| | __/ | //
|
||||
// /_/ \_\__,_|\__,_|\___|_| //
|
||||
// //
|
||||
/////////////////////////////////////
|
||||
|
||||
logic carry_in;
|
||||
logic [31:0] adder_op_a;
|
||||
logic [31:0] adder_op_b;
|
||||
logic [31:0] adder_result;
|
||||
|
@ -76,75 +72,25 @@ module riscv_alu
|
|||
// prepare operand b
|
||||
assign adder_op_b = (operator_i == `ALU_SUB) ? ~operand_b_i : operand_b_i;
|
||||
|
||||
// prepare vector carrys
|
||||
// prepare carry
|
||||
always_comb
|
||||
begin
|
||||
carry_in = {carry_out[2], carry_out[1], carry_out[0], 1'b0};
|
||||
|
||||
case (operator_i)
|
||||
`ALU_SUB, `ALU_ABS:
|
||||
begin
|
||||
case (vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
begin
|
||||
carry_in[0] = 1'b1;
|
||||
carry_in[2] = 1'b1;
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
begin
|
||||
carry_in = 4'b1111;
|
||||
end
|
||||
|
||||
default: // VEC_MODE32
|
||||
begin
|
||||
carry_in[0] = 1'b1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
default:
|
||||
begin
|
||||
case (vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
begin
|
||||
carry_in[0] = 1'b0;
|
||||
carry_in[2] = 1'b0;
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
begin
|
||||
carry_in = 4'b0000;
|
||||
end
|
||||
|
||||
default: // VEC_MODE32
|
||||
begin
|
||||
carry_in[0] = 1'b0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
`ALU_SUB,
|
||||
`ALU_ABS: carry_in = 1'b1;
|
||||
default: carry_in = 1'b0;
|
||||
endcase
|
||||
end
|
||||
|
||||
// adder consisting of four slices
|
||||
assign {carry_out[0], adder_result[ 7: 0]} = adder_op_a[ 7: 0] + adder_op_b[ 7: 0] + {7'b0, carry_in[0]};
|
||||
assign {carry_out[1], adder_result[15: 8]} = adder_op_a[15: 8] + adder_op_b[15: 8] + {7'b0, carry_in[1]};
|
||||
assign {carry_out[2], adder_result[23:16]} = adder_op_a[23:16] + adder_op_b[23:16] + {7'b0, carry_in[2]};
|
||||
assign {carry_out[3], adder_result[31:24]} = adder_op_a[31:24] + adder_op_b[31:24] + {7'b0, carry_in[3]};
|
||||
// adder
|
||||
assign adder_result = adder_op_a + adder_op_b + {31'b0, carry_in};
|
||||
|
||||
|
||||
// averaging by right shifting of one bit
|
||||
logic [31:0] result_avg;
|
||||
|
||||
assign result_avg[ 6: 0] = adder_result[ 7: 1];
|
||||
assign result_avg[14: 8] = adder_result[15: 9];
|
||||
assign result_avg[22:16] = adder_result[23:17];
|
||||
assign result_avg[30:24] = adder_result[31:25];
|
||||
|
||||
assign result_avg[ 7] = (vector_mode_i == `VEC_MODE8) ? ((operator_i == `ALU_AVGU) ? 1'b0 : adder_result[ 7]) : adder_result[ 8];
|
||||
assign result_avg[15] = ((vector_mode_i == `VEC_MODE16) || (vector_mode_i == `VEC_MODE8)) ? ((operator_i == `ALU_AVGU) ? 1'b0 : adder_result[15]) : adder_result[16];
|
||||
assign result_avg[23] = (vector_mode_i == `VEC_MODE8) ? ((operator_i == `ALU_AVGU) ? 1'b0 : adder_result[23]) : adder_result[24];
|
||||
assign result_avg[31] = (operator_i == `ALU_AVGU) ? 1'b0 : adder_result[31];
|
||||
assign result_avg[30:0] = adder_result[31:1];
|
||||
assign result_avg[31] = (operator_i == `ALU_AVGU) ? 1'b0 : adder_result[31];
|
||||
|
||||
|
||||
////////////////////////////////////////
|
||||
|
@ -155,90 +101,28 @@ module riscv_alu
|
|||
// |____/|_| |_|___|_| |_| //
|
||||
// //
|
||||
////////////////////////////////////////
|
||||
logic shift_left; // should we shift left?
|
||||
|
||||
logic shift_left; // should we shift left
|
||||
logic [31:0] shift_amt; // amount of shift
|
||||
logic [31:0] shift_amt_left; // amount of shift, adapted to vector mode for sll
|
||||
logic [31:0] shift_amt_int; // amount of shift, adapted to vector mode for sll
|
||||
logic [31:0] shift_op_a; // input of the shifter
|
||||
logic [31:0] shift_result;
|
||||
logic [31:0] shift_left_result;
|
||||
|
||||
|
||||
// by reversing the bits of the input, we also have the reverse the order of shift amounts
|
||||
always_comb
|
||||
begin
|
||||
case(vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
begin
|
||||
shift_amt_left[15: 0] = shift_amt[31:16];
|
||||
shift_amt_left[31:16] = shift_amt[15: 0];
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
begin
|
||||
shift_amt_left[ 7: 0] = shift_amt[31:24];
|
||||
shift_amt_left[15: 8] = shift_amt[23:16];
|
||||
shift_amt_left[23:16] = shift_amt[15: 8];
|
||||
shift_amt_left[31:24] = shift_amt[ 7: 0];
|
||||
end
|
||||
|
||||
default: // VEC_MODE32
|
||||
begin
|
||||
shift_amt_left[31: 0] = shift_amt[31: 0];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
assign shift_left = (operator_i == `ALU_SLL);
|
||||
|
||||
// choose the bit reversed or the normal input for shift operand a
|
||||
assign shift_op_a = (shift_left == 1'b1) ? operand_a_rev : operand_a_i;
|
||||
assign shift_amt_int = (shift_left == 1'b1) ? shift_amt_left : shift_amt;
|
||||
assign shift_op_a = (shift_left == 1'b1) ? operand_a_rev : operand_a_i;
|
||||
|
||||
// right shifts, we let the synthesizer optimize this
|
||||
// right shifts
|
||||
always_comb
|
||||
begin
|
||||
case(vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
begin
|
||||
if(operator_i == `ALU_SRA)
|
||||
begin
|
||||
shift_result[31:16] = $unsigned( $signed(shift_op_a[31:16]) >>> shift_amt_int[19:16] );
|
||||
shift_result[15: 0] = $unsigned( $signed(shift_op_a[15: 0]) >>> shift_amt_int[ 3: 0] );
|
||||
end
|
||||
else
|
||||
begin
|
||||
shift_result[31:16] = shift_op_a[31:16] >> shift_amt_int[19:16];
|
||||
shift_result[15: 0] = shift_op_a[15: 0] >> shift_amt_int[ 3: 0];
|
||||
end
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
begin
|
||||
if(operator_i == `ALU_SRA)
|
||||
begin
|
||||
shift_result[31:24] = $unsigned( $signed(shift_op_a[31:24]) >>> shift_amt_int[26:24] );
|
||||
shift_result[23:16] = $unsigned( $signed(shift_op_a[23:16]) >>> shift_amt_int[18:16] );
|
||||
shift_result[15: 8] = $unsigned( $signed(shift_op_a[15: 8]) >>> shift_amt_int[10: 8] );
|
||||
shift_result[ 7: 0] = $unsigned( $signed(shift_op_a[ 7: 0]) >>> shift_amt_int[ 2: 0] );
|
||||
end
|
||||
else
|
||||
begin
|
||||
shift_result[31:24] = shift_op_a[31:24] >> shift_amt_int[26:24];
|
||||
shift_result[23:16] = shift_op_a[23:16] >> shift_amt_int[18:16];
|
||||
shift_result[15: 8] = shift_op_a[15: 8] >> shift_amt_int[10: 8];
|
||||
shift_result[ 7: 0] = shift_op_a[ 7: 0] >> shift_amt_int[ 2: 0];
|
||||
end
|
||||
end
|
||||
|
||||
default: // VEC_MODE32
|
||||
begin
|
||||
if(operator_i == `ALU_SRA)
|
||||
shift_result = $unsigned( $signed(shift_op_a) >>> shift_amt_int[4:0] );
|
||||
else if(operator_i == `ALU_ROR)
|
||||
shift_result = {shift_op_a, shift_op_a} >> shift_amt_int[4:0];
|
||||
else
|
||||
shift_result = shift_op_a >> shift_amt_int[4:0];
|
||||
end
|
||||
endcase; // case (vec_mode_i)
|
||||
if(operator_i == `ALU_SRA)
|
||||
shift_result = $unsigned( $signed(shift_op_a) >>> shift_amt[4:0] );
|
||||
else if(operator_i == `ALU_ROR)
|
||||
shift_result = {shift_op_a, shift_op_a} >> shift_amt[4:0];
|
||||
else
|
||||
shift_result = shift_op_a >> shift_amt[4:0];
|
||||
end
|
||||
|
||||
// bit reverse the shift_result for left shifts
|
||||
|
@ -251,7 +135,6 @@ module riscv_alu
|
|||
endgenerate
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// ____ ___ __ __ ____ _ ____ ___ ____ ___ _ _ //
|
||||
// / ___/ _ \| \/ | _ \ / \ | _ \|_ _/ ___| / _ \| \ | | //
|
||||
|
@ -261,145 +144,60 @@ module riscv_alu
|
|||
// //
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// results
|
||||
logic [3:0] is_equal;
|
||||
logic [3:0] is_greater; // handles both signed and unsigned forms
|
||||
|
||||
logic [3:0] sel_minmax; // mux control
|
||||
logic [31:0] result_minmax;
|
||||
logic [31:0] minmax_b;
|
||||
|
||||
|
||||
logic do_min;
|
||||
|
||||
// 8-bit vector comparisons, basic building blocks
|
||||
logic [3:0] cmp_sign_mode;
|
||||
logic [3:0] is_equal_vec;
|
||||
logic [3:0] is_greater_vec;
|
||||
|
||||
|
||||
// generate cmp_sign_mode signal that is used for comparisons below
|
||||
always_comb
|
||||
begin
|
||||
cmp_sign_mode[3:0] = 4'b0000; // unsigned mode
|
||||
|
||||
// signed mode
|
||||
if ((operator_i == `ALU_GTS) ||
|
||||
(operator_i == `ALU_GES) ||
|
||||
(operator_i == `ALU_LTS) ||
|
||||
(operator_i == `ALU_SLTS) ||
|
||||
(operator_i == `ALU_SLETS) ||
|
||||
(operator_i == `ALU_LES) ||
|
||||
(operator_i == `ALU_MAX) ||
|
||||
(operator_i == `ALU_MIN) ||
|
||||
(operator_i == `ALU_ABS))
|
||||
begin
|
||||
case (vector_mode_i)
|
||||
`VEC_MODE16: cmp_sign_mode[3:0] = 4'b1010;
|
||||
`VEC_MODE8: cmp_sign_mode[3:0] = 4'b1111;
|
||||
default: cmp_sign_mode[3:0] = 4'b1000;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// generate vector equal and greater than signals, cmp_sign_mode decides if the comparison is done signed or unsigned
|
||||
genvar i;
|
||||
generate
|
||||
for(i = 0; i < 4; i++)
|
||||
begin
|
||||
assign is_equal_vec[i] = (operand_a_i[8*i+7:8*i] == operand_b_i[8*i+7:i*8]);
|
||||
assign is_greater_vec[i] = $signed({operand_a_i[8*i+7] & cmp_sign_mode[i], operand_a_i[8*i+7:8*i]})
|
||||
>
|
||||
$signed({operand_b_i[8*i+7] & cmp_sign_mode[i], operand_b_i[8*i+7:i*8]});
|
||||
end
|
||||
endgenerate
|
||||
logic is_equal;
|
||||
logic is_greater;
|
||||
|
||||
logic cmp_signed;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
is_equal[3:0] = {4{is_equal_vec[3] & is_equal_vec[2] & is_equal_vec[1] & is_equal_vec[0]}};
|
||||
is_greater[3:0] = {4{is_greater_vec[3] | (is_equal_vec[3] & (is_greater_vec[2]
|
||||
| (is_equal_vec[2] & (is_greater_vec[1]
|
||||
| (is_equal_vec[1] & (is_greater_vec[0]))))))}};
|
||||
cmp_signed = 1'b0;
|
||||
|
||||
case(vector_mode_i)
|
||||
`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]}};
|
||||
is_greater[1:0] = {2{is_greater_vec[1] | (is_equal_vec[1] & is_greater_vec[0])}};
|
||||
is_greater[3:2] = {2{is_greater_vec[3] | (is_equal_vec[3] & is_greater_vec[2])}};
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
begin
|
||||
is_equal[3:0] = is_equal_vec[3:0];
|
||||
is_greater[3:0] = is_greater_vec[3:0];
|
||||
end
|
||||
|
||||
default:; // see default assignment
|
||||
case (operator_i)
|
||||
`ALU_GTS,
|
||||
`ALU_GES,
|
||||
`ALU_LTS,
|
||||
`ALU_LES,
|
||||
`ALU_SLTS,
|
||||
`ALU_SLETS,
|
||||
`ALU_MIN,
|
||||
`ALU_MAX,
|
||||
`ALU_ABS: cmp_signed = 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
// generate comparison results
|
||||
logic [3:0] cmp_result;
|
||||
logic any_result;
|
||||
logic all_result;
|
||||
assign is_equal = (operand_a_i == operand_b_i);
|
||||
assign is_greater = $signed({operand_a_i[31] & cmp_signed, operand_a_i[30:0]})
|
||||
>
|
||||
$signed({operand_b_i[31] & cmp_signed, operand_b_i[30:0]});
|
||||
|
||||
// generate comparison result
|
||||
always_comb
|
||||
begin
|
||||
cmp_result = is_equal;
|
||||
comparison_result_o = is_equal;
|
||||
|
||||
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_EQ: comparison_result_o = is_equal;
|
||||
`ALU_NE: comparison_result_o = ~is_equal;
|
||||
`ALU_GTS, `ALU_GTU: comparison_result_o = is_greater;
|
||||
`ALU_GES, `ALU_GEU: comparison_result_o = is_greater | is_equal;
|
||||
`ALU_LTS, `ALU_SLTS,
|
||||
`ALU_LTU, `ALU_SLTU: cmp_result = ~(is_greater | is_equal);
|
||||
`ALU_LTU, `ALU_SLTU: comparison_result_o = ~(is_greater | is_equal);
|
||||
`ALU_SLETS,
|
||||
`ALU_SLETU,
|
||||
`ALU_LES, `ALU_LEU: cmp_result = ~is_greater;
|
||||
default:; // nothing to do
|
||||
endcase //~case(operator_i)
|
||||
`ALU_LES, `ALU_LEU: comparison_result_o = ~is_greater;
|
||||
endcase
|
||||
end
|
||||
|
||||
assign any_result = |cmp_result;
|
||||
assign all_result = &cmp_result;
|
||||
|
||||
logic [31:0] result_minmax;
|
||||
logic sel_minmax;
|
||||
logic [31:0] minmax_b;
|
||||
|
||||
// choose result value for min/max/abs
|
||||
assign minmax_b = (operator_i == `ALU_ABS) ? adder_result : operand_b_i;
|
||||
|
||||
assign do_min = ((operator_i == `ALU_MIN) || (operator_i == `ALU_MINU));
|
||||
|
||||
// reuse the minmax mux also for the cmove instruction
|
||||
// the mux now handles, min, max, abs, cmov, ins
|
||||
always_comb
|
||||
begin
|
||||
sel_minmax[3:0] = is_greater ^ {4{do_min}};
|
||||
|
||||
if(operator_i == `ALU_INS)
|
||||
begin
|
||||
if(vector_mode_i == `VEC_MODE16)
|
||||
begin
|
||||
sel_minmax[1:0] = {2{vec_ext_i[0]}};
|
||||
sel_minmax[3:2] = ~{2{vec_ext_i[0]}};
|
||||
end
|
||||
else // `VEC_MODE8
|
||||
begin
|
||||
sel_minmax[0] = (vec_ext_i != 2'b00);
|
||||
sel_minmax[1] = (vec_ext_i != 2'b01);
|
||||
sel_minmax[2] = (vec_ext_i != 2'b10);
|
||||
sel_minmax[3] = (vec_ext_i != 2'b11);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign result_minmax[31:24] = (sel_minmax[3] == 1'b1) ? operand_a_i[31:24] : minmax_b[31:24];
|
||||
assign result_minmax[23:16] = (sel_minmax[2] == 1'b1) ? operand_a_i[23:16] : minmax_b[23:16];
|
||||
assign result_minmax[15: 8] = (sel_minmax[1] == 1'b1) ? operand_a_i[15: 8] : minmax_b[15: 8];
|
||||
assign result_minmax[ 7: 0] = (sel_minmax[0] == 1'b1) ? operand_a_i[ 7: 0] : minmax_b[ 7: 0];
|
||||
assign sel_minmax = is_greater ^ ((operator_i == `ALU_MIN) || (operator_i == `ALU_MINU));
|
||||
assign result_minmax = sel_minmax ? operand_a_i[31:0] : minmax_b[31:0];
|
||||
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
@ -411,45 +209,27 @@ module riscv_alu
|
|||
// //
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
logic [7:0] ext_byte;
|
||||
logic [15:0] ext_word;
|
||||
logic [31:0] result_ext;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
ext_byte = operand_a_i[7:0];
|
||||
|
||||
if(operator_i == `ALU_EXT)
|
||||
begin
|
||||
case(vec_ext_i)
|
||||
2'b00: ext_byte = operand_a_i[ 7: 0];
|
||||
2'b01: ext_byte = operand_a_i[15: 8];
|
||||
2'b10: ext_byte = operand_a_i[23:16];
|
||||
2'b11: ext_byte = operand_a_i[31:24];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
assign ext_word = ((vec_ext_i[0] == 1'b1) && (operator_i == `ALU_EXT)) ? operand_a_i[31:16] : operand_a_i[15:0];
|
||||
|
||||
always_comb
|
||||
begin
|
||||
// zero extend byte
|
||||
result_ext = {24'b0, ext_byte[7:0]};
|
||||
result_ext = {24'b0, operand_a_i[7:0]};
|
||||
|
||||
// sign extend byte
|
||||
if((operator_i == `ALU_EXTBS) || ((operator_i == `ALU_EXT) && (vector_mode_i == `VEC_MODE8)))
|
||||
result_ext = {{24{ext_byte[7]}}, ext_byte[7:0]};
|
||||
if (operator_i == `ALU_EXTBS)
|
||||
result_ext = {{24 {operand_a_i[7]}}, operand_a_i[7:0]};
|
||||
|
||||
// zero extend half word
|
||||
if(operator_i == `ALU_EXTHZ)
|
||||
result_ext = {16'b0, ext_word[15:0]};
|
||||
result_ext = {16'b0, operand_a_i[15:0]};
|
||||
|
||||
// sign extend half word
|
||||
if((operator_i == `ALU_EXTHS) || ((operator_i == `ALU_EXT) && (vector_mode_i == `VEC_MODE16)))
|
||||
result_ext = {{16{ext_word[15]}}, ext_word[15:0]};
|
||||
if(operator_i == `ALU_EXTHS)
|
||||
result_ext = {{16 {operand_a_i[15]}}, operand_a_i[15:0]};
|
||||
end
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// ____ _ _ ____ _ ___ //
|
||||
// | __ )(_) |_ / ___|___ _ _ _ __ | |_ / _ \ _ __ ___ //
|
||||
|
@ -487,9 +267,8 @@ module riscv_alu
|
|||
assign fl1_result = (ff1_result == 6'd0) ? 6'd0 : (6'd33 - ff1_result);
|
||||
assign clb_result = (ff1_result == 6'd0) ? 6'd0 : (ff1_result - 6'd2);
|
||||
|
||||
|
||||
// count the number of '1's in a word
|
||||
logic [5:0] cnt_result; // holds the number of '1's in a word
|
||||
logic [5:0] cnt_result;
|
||||
logic [1:0] cnt_l1[16];
|
||||
logic [2:0] cnt_l2[8];
|
||||
logic [3:0] cnt_l3[4];
|
||||
|
@ -522,6 +301,7 @@ module riscv_alu
|
|||
|
||||
assign cnt_result = cnt_l4[0] + cnt_l4[1];
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// ____ _ _ __ __ //
|
||||
// | _ \ ___ ___ _ _| | |_ | \/ |_ ___ __ //
|
||||
|
@ -533,77 +313,58 @@ module riscv_alu
|
|||
|
||||
always_comb
|
||||
begin
|
||||
shift_left = 1'b0;
|
||||
shift_amt = operand_b_i;
|
||||
result_o = 'x;
|
||||
flag_o = 1'bx;
|
||||
|
||||
unique case (operator_i)
|
||||
case (operator_i)
|
||||
// Standard Operations
|
||||
`ALU_ADD, `ALU_SUB: result_o = adder_result;
|
||||
`ALU_AVG, `ALU_AVGU: result_o = result_avg;
|
||||
`ALU_AND: result_o = operand_a_i & operand_b_i;
|
||||
`ALU_OR: result_o = operand_a_i | operand_b_i;
|
||||
`ALU_XOR: result_o = operand_a_i ^ operand_b_i;
|
||||
`ALU_ADD,
|
||||
`ALU_SUB: result_o = adder_result;
|
||||
`ALU_AVG,
|
||||
`ALU_AVGU: result_o = result_avg;
|
||||
`ALU_AND: result_o = operand_a_i & operand_b_i;
|
||||
`ALU_OR: result_o = operand_a_i | operand_b_i;
|
||||
`ALU_XOR: result_o = operand_a_i ^ operand_b_i;
|
||||
|
||||
// Shift Operations
|
||||
`ALU_SLL:
|
||||
begin
|
||||
shift_left = 1'b1;
|
||||
result_o = shift_left_result;
|
||||
end
|
||||
`ALU_SLL: result_o = shift_left_result;
|
||||
|
||||
`ALU_SRL, `ALU_SRA, `ALU_ROR: begin
|
||||
shift_left = 1'b0;
|
||||
result_o = shift_result;
|
||||
end
|
||||
`ALU_SRL,
|
||||
`ALU_SRA,
|
||||
`ALU_ROR: result_o = shift_result;
|
||||
|
||||
// Extension Operations
|
||||
`ALU_EXTWZ, `ALU_EXTWS: result_o = operand_a_i;
|
||||
`ALU_EXTBZ, `ALU_EXTBS, `ALU_EXTHZ, `ALU_EXTHS, `ALU_EXT: result_o = result_ext;
|
||||
`ALU_EXTBZ,
|
||||
`ALU_EXTBS,
|
||||
`ALU_EXTHZ,
|
||||
`ALU_EXTHS: result_o = result_ext;
|
||||
|
||||
// Min/Max/Abs, INS
|
||||
`ALU_MIN, `ALU_MINU, `ALU_MAX, `ALU_MAXU, `ALU_ABS, `ALU_INS: result_o = result_minmax;
|
||||
// Min/Max/Abs
|
||||
`ALU_MIN, `ALU_MINU,
|
||||
`ALU_MAX, `ALU_MAXU,
|
||||
`ALU_ABS: result_o = result_minmax;
|
||||
|
||||
// Comparison Operations
|
||||
`ALU_EQ, `ALU_NE, `ALU_GTU, `ALU_GEU, `ALU_LTU, `ALU_LEU, `ALU_GTS, `ALU_GES, `ALU_LTS, `ALU_LES:
|
||||
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]}};
|
||||
|
||||
case (cmp_mode_i)
|
||||
`ALU_CMP_ANY:
|
||||
begin
|
||||
flag_o = any_result;
|
||||
end
|
||||
`ALU_CMP_ALL:
|
||||
begin
|
||||
flag_o = all_result;
|
||||
end
|
||||
`ALU_CMP_FULL:
|
||||
begin
|
||||
flag_o = cmp_result[0];
|
||||
end
|
||||
default:;
|
||||
endcase //~case(cmp_mode_i)
|
||||
// TODO: Check which comparison operations are actually used
|
||||
// Probably it's just slts/stlu/slets/sletu plus what is needed
|
||||
// for branching after the flag is removed
|
||||
result_o = {31'b0, comparison_result_o};
|
||||
end
|
||||
|
||||
// Set Lower Than Operations (result = 1, if a < b)
|
||||
`ALU_SLTS, `ALU_SLTU: result_o = {31'b0, cmp_result[0]};
|
||||
`ALU_SLTS, `ALU_SLTU: result_o = {31'b0, comparison_result_o};
|
||||
|
||||
// Set Lower Equal Than Operations (result = 1, if a <= b)
|
||||
`ALU_SLETS, `ALU_SLETU: result_o = {31'b0, cmp_result[0]};
|
||||
`ALU_SLETS, `ALU_SLETU: result_o = {31'b0, comparison_result_o};
|
||||
|
||||
`ALU_FF1: result_o = {26'h0, ff1_result};
|
||||
`ALU_FL1: result_o = {26'h0, fl1_result};
|
||||
`ALU_CLB: result_o = {26'h0, clb_result};
|
||||
`ALU_CNT: result_o = {26'h0, cnt_result};
|
||||
|
||||
default: ;
|
||||
endcase //~case(operator_i)
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule //~module alu
|
||||
endmodule
|
||||
|
||||
|
|
|
@ -51,44 +51,19 @@ module riscv_compressed_decoder
|
|||
2'b00: begin
|
||||
unique case (instr_i[15:13])
|
||||
3'b000: 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};
|
||||
|
||||
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};
|
||||
end
|
||||
end else begin
|
||||
// c.add -> add rd, rd, rs2
|
||||
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b000, instr_i[11:7], `OPCODE_OP};
|
||||
|
||||
if (instr_i[11:7] == 5'b0) begin
|
||||
// c.ebreak -> ebreak
|
||||
instr_o = {32'h00_10_00_73};
|
||||
if (instr_i[6:2] != 5'b0)
|
||||
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};
|
||||
end
|
||||
end
|
||||
|
||||
// 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};
|
||||
if (instr_i[12:5] == 8'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b010: 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};
|
||||
end
|
||||
|
||||
3'b100: 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};
|
||||
// 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};
|
||||
end
|
||||
|
||||
3'b110: 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};
|
||||
// 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};
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
@ -101,21 +76,89 @@ module riscv_compressed_decoder
|
|||
2'b01: begin
|
||||
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};
|
||||
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;
|
||||
// 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};
|
||||
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};
|
||||
end
|
||||
|
||||
3'b010: 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};
|
||||
// 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};
|
||||
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b110: 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};
|
||||
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
|
||||
3'b011: begin
|
||||
// c.lui -> lui rd, imm
|
||||
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};
|
||||
end else if (instr_i[11:7] == 5'b0) begin
|
||||
illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
if ({instr_i[12], instr_i[6:2]} == 6'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b100: begin
|
||||
unique case (instr_i[11:10])
|
||||
2'b00,
|
||||
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};
|
||||
if (instr_i[12] == 1'b1) illegal_instr_o = 1'b1;
|
||||
if (instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
|
||||
if (instr_i[9:7] == 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};
|
||||
end
|
||||
|
||||
2'b11: begin
|
||||
unique case ({instr_i[12], instr_i[6:5]})
|
||||
3'b001,
|
||||
3'b100,
|
||||
3'b101,
|
||||
3'b110,
|
||||
3'b111: begin
|
||||
// 001: c.sll -> sll rd', rd', rs2'
|
||||
// 100: c.xor -> xor rd', rd', rs2'
|
||||
// 101: c.srl -> srl rd', rd', rs2'
|
||||
// 110: c.or -> or rd', rd', rs2'
|
||||
// 111: c.and -> and rd', rd', rs2'
|
||||
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], instr_i[12], instr_i[6:5], 2'b01, instr_i[9:7], `OPCODE_OP};
|
||||
end
|
||||
|
||||
3'b000,
|
||||
3'b010: begin
|
||||
// 000: c.addw
|
||||
// 010: c.subw
|
||||
illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b011: 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};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
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};
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
@ -127,41 +170,47 @@ module riscv_compressed_decoder
|
|||
// C2
|
||||
2'b10: begin
|
||||
unique case (instr_i[15:13])
|
||||
3'b000, 3'b001: begin
|
||||
// 0: c.j -> jal x0, imm
|
||||
// 1: c.jal -> jal x1, imm
|
||||
instr_o = {instr_i[12], instr_i[11:7], instr_i[2], instr_i[6:3], {9 {instr_i[12]}}, 4'b0, instr_i[13], `OPCODE_JAL};
|
||||
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};
|
||||
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, 3'b011: begin
|
||||
// 0: c.beqz -> beq rs1', x0, imm
|
||||
// 1: c.bnez -> bne rs1', x0, imm
|
||||
instr_o = {{3 {instr_i[12]}}, instr_i[12:10], instr_i[2], 5'b0, 2'b01, instr_i[9:7], 2'b00, instr_i[13], instr_i[6:3], instr_i[12], `OPCODE_BRANCH};
|
||||
end
|
||||
|
||||
3'b100: 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};
|
||||
|
||||
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};
|
||||
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b101: begin
|
||||
// c.lui -> lui rd, imm
|
||||
instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], `OPCODE_LUI};
|
||||
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};
|
||||
|
||||
if (instr_i[11:7] == 5'b0) begin
|
||||
// c.addi16sp -> addi x2, x2, nzimm
|
||||
instr_o = {{3 {instr_i[12]}}, instr_i[4:2], instr_i[5], instr_i[6], 4'b0, 5'h02, 3'b000, 5'h02, `OPCODE_OPIMM};
|
||||
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};
|
||||
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};
|
||||
|
||||
if (instr_i[11:7] == 5'b0) begin
|
||||
// c.ebreak -> ebreak
|
||||
instr_o = {32'h00_10_00_73};
|
||||
if (instr_i[6:2] != 5'b0)
|
||||
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};
|
||||
end
|
||||
end
|
||||
|
||||
if ({instr_i[12], instr_i[6:2]} == 6'b0) illegal_instr_o = 1'b1;
|
||||
end
|
||||
|
||||
3'b110: 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};
|
||||
// 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};
|
||||
end
|
||||
|
||||
default: begin
|
||||
|
@ -170,7 +219,6 @@ module riscv_compressed_decoder
|
|||
endcase
|
||||
end
|
||||
|
||||
// 2'b11:
|
||||
default: begin
|
||||
// 32 bit (or more) instruction
|
||||
instr_o = instr_i;
|
||||
|
|
|
@ -149,7 +149,6 @@ module riscv_controller
|
|||
if (illegal_insn_o) begin
|
||||
$display("%t: Illegal instruction (core %0d) at PC 0x%h:", $time, riscv_core.core_id_i,
|
||||
riscv_id_stage.current_pc_id_i);
|
||||
//prettyPrintInstruction(instr_rdata_i, id_stage.current_pc_id_i);
|
||||
end
|
||||
end
|
||||
// synopsys translate_on
|
||||
|
|
35
decoder.sv
35
decoder.sv
|
@ -50,12 +50,10 @@ module riscv_decoder
|
|||
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
|
||||
output logic [2:0] immediate_mux_sel_o, // immediate selection for operand b
|
||||
output logic alu_op_c_mux_sel_o, // operand c selection: reg value or jump target
|
||||
|
||||
output logic [1:0] vector_mode_o, // selects between 32 bit, 16 bit and 8 bit vectorial modes
|
||||
output logic scalar_replication_o, // activates scalar_replication for vectorial mode
|
||||
output logic [1:0] alu_cmp_mode_o, // selects comparison mode for ALU (i.e. full, any, all)
|
||||
output logic vector_mode_o, // selects between 32 bit, 16 bit and 8 bit vectorial modes
|
||||
|
||||
// MUL related control signals
|
||||
output logic mult_en_o, // perform multiplication
|
||||
|
@ -131,9 +129,7 @@ module riscv_decoder
|
|||
|
||||
immediate_mux_sel_o = `IMM_I;
|
||||
|
||||
vector_mode_o = `VEC_MODE32;
|
||||
scalar_replication_o = 1'b0;
|
||||
alu_cmp_mode_o = `ALU_CMP_FULL;
|
||||
vector_mode_o = 1'b0;
|
||||
|
||||
mult_en = 1'b0;
|
||||
mult_signed_mode_o = 2'b00;
|
||||
|
@ -253,6 +249,9 @@ module riscv_decoder
|
|||
regb_used_o = 1'b1;
|
||||
alu_operator = `ALU_ADD;
|
||||
|
||||
// pass write data through ALU operand c
|
||||
alu_op_c_mux_sel_o = `OP_C_REGB_OR_FWD;
|
||||
|
||||
// post-increment setup
|
||||
if (instr_rdata_i[6:0] == `OPCODE_STORE_POST) begin
|
||||
prepost_useincr_o = 1'b0;
|
||||
|
@ -480,7 +479,7 @@ module riscv_decoder
|
|||
3'b101,
|
||||
3'b110,
|
||||
3'b111: begin // MAC with subword selection
|
||||
vector_mode_o = `VEC_MODE216;
|
||||
vector_mode_o = 1'b1;
|
||||
mult_sel_subword_o = instr_rdata_i[13:12];
|
||||
mult_signed_mode_o = instr_rdata_i[31:30];
|
||||
|
||||
|
@ -516,18 +515,18 @@ module riscv_decoder
|
|||
// TODO: Handle in controller
|
||||
end
|
||||
|
||||
32'h00_10_00_73: // EBREAK
|
||||
32'h00_10_00_73: // ebreak
|
||||
begin
|
||||
// debugger trap
|
||||
trap_insn = 1'b1;
|
||||
end
|
||||
|
||||
32'h10_00_00_73: // ERET
|
||||
32'h10_00_00_73: // eret
|
||||
begin
|
||||
eret_insn = 1'b1;
|
||||
end
|
||||
|
||||
32'h10_20_00_73: // WFI
|
||||
32'h10_20_00_73: // wfi
|
||||
begin
|
||||
// flush pipeline
|
||||
pipe_flush = 1'b1;
|
||||
|
@ -590,13 +589,13 @@ module riscv_decoder
|
|||
hwloop_end_mux_sel_o = 1'b0; // jump target
|
||||
end
|
||||
3'b010: begin
|
||||
// lp.count initialize counter from rs1
|
||||
// lp.count: initialize counter from rs1
|
||||
hwloop_we[2] = 1'b1;
|
||||
hwloop_cnt_mux_sel_o = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
end
|
||||
3'b011: begin
|
||||
// lp.counti initialize counter from I-type immediate
|
||||
// lp.counti: initialize counter from I-type immediate
|
||||
hwloop_we[2] = 1'b1;
|
||||
hwloop_cnt_mux_sel_o = 1'b0;
|
||||
end
|
||||
|
@ -609,16 +608,6 @@ module riscv_decoder
|
|||
hwloop_cnt_mux_sel_o = 1'b1;
|
||||
rega_used_o = 1'b1;
|
||||
end
|
||||
3'b101: begin
|
||||
// lp.setupi: initialize counter from I-type immediate, set start
|
||||
// address to next instruction and end address to PC + shifted
|
||||
// z-type immediate
|
||||
hwloop_we = 3'b111;
|
||||
hwloop_start_mux_sel_o = 1'b1;
|
||||
hwloop_end_mux_sel_o = 1'b1;
|
||||
hwloop_cnt_mux_sel_o = 1'b0;
|
||||
illegal_insn_o = 1'b1; // TODO: PC + z-imm currently not supported
|
||||
end
|
||||
default: begin
|
||||
illegal_insn_o = 1'b1;
|
||||
end
|
||||
|
|
113
ex_stage.sv
113
ex_stage.sv
|
@ -25,7 +25,6 @@
|
|||
// Revision v0.1 - File Created //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "defines.sv"
|
||||
|
@ -33,62 +32,59 @@
|
|||
|
||||
module riscv_ex_stage
|
||||
(
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
input logic clk,
|
||||
input logic rst_n,
|
||||
|
||||
// ALU signals from ID stage
|
||||
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,
|
||||
// ALU signals from ID stage
|
||||
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,
|
||||
|
||||
input logic [1:0] vector_mode_i,
|
||||
input logic [1:0] alu_cmp_mode_i,
|
||||
input logic [1:0] alu_vec_ext_i,
|
||||
input logic vector_mode_i,
|
||||
|
||||
// Multiplier signals
|
||||
input logic mult_en_i,
|
||||
input logic [1:0] mult_sel_subword_i,
|
||||
input logic [1:0] mult_signed_mode_i,
|
||||
input logic mult_mac_en_i,
|
||||
// Multiplier signals
|
||||
input logic mult_en_i,
|
||||
input logic [1:0] mult_sel_subword_i,
|
||||
input logic [1:0] mult_signed_mode_i,
|
||||
input logic mult_mac_en_i,
|
||||
|
||||
// input from ID stage
|
||||
input logic [4:0] regfile_alu_waddr_i,
|
||||
input logic regfile_alu_we_i,
|
||||
// input from ID stage
|
||||
input logic [4:0] regfile_alu_waddr_i,
|
||||
input logic regfile_alu_we_i,
|
||||
|
||||
// directly passed through to WB stage, not used in EX
|
||||
input logic regfile_we_i,
|
||||
input logic [4:0] regfile_waddr_i,
|
||||
// directly passed through to WB stage, not used in EX
|
||||
input logic regfile_we_i,
|
||||
input logic [4:0] regfile_waddr_i,
|
||||
|
||||
// CSR access
|
||||
input logic csr_access_i,
|
||||
input logic [31:0] csr_rdata_i,
|
||||
// CSR access
|
||||
input logic csr_access_i,
|
||||
input logic [31:0] csr_rdata_i,
|
||||
|
||||
// Output of EX stage pipeline
|
||||
output logic [4:0] regfile_waddr_wb_o,
|
||||
output logic regfile_we_wb_o,
|
||||
// Output of EX stage pipeline
|
||||
output logic [4:0] regfile_waddr_wb_o,
|
||||
output logic regfile_we_wb_o,
|
||||
|
||||
// Forwarding ports : to ID stage
|
||||
output logic [4:0] regfile_alu_waddr_fw_o,
|
||||
output logic regfile_alu_we_fw_o,
|
||||
output logic [31:0] regfile_alu_wdata_fw_o, // forward to RF and ID/EX pipe, ALU & MUL
|
||||
// Forwarding ports : to ID stage
|
||||
output logic [4:0] regfile_alu_waddr_fw_o,
|
||||
output logic regfile_alu_we_fw_o,
|
||||
output logic [31:0] regfile_alu_wdata_fw_o, // forward to RF and ID/EX pipe, ALU & MUL
|
||||
|
||||
// To IF: Jump and branch target and decision
|
||||
output logic [31:0] jump_target_o,
|
||||
output logic branch_decision_o,
|
||||
// To IF: Jump and branch target and decision
|
||||
output logic [31:0] jump_target_o,
|
||||
output logic branch_decision_o,
|
||||
|
||||
// Stall Control
|
||||
input logic lsu_ready_ex_i, // EX part of LSU is done
|
||||
// Stall Control
|
||||
input logic lsu_ready_ex_i, // EX part of LSU is done
|
||||
|
||||
output logic ex_ready_o, // EX stage ready for new data
|
||||
output logic ex_valid_o, // EX stage gets new data
|
||||
input logic wb_ready_i // WB stage ready for new data
|
||||
output logic ex_ready_o, // EX stage ready for new data
|
||||
output logic ex_valid_o, // EX stage gets new data
|
||||
input logic wb_ready_i // WB stage ready for new data
|
||||
);
|
||||
|
||||
|
||||
// Internal output of the LU
|
||||
logic [31:0] alu_result;
|
||||
logic alu_flag;
|
||||
logic alu_cmp_result;
|
||||
|
||||
logic [31:0] mult_result;
|
||||
|
||||
|
@ -96,6 +92,8 @@ module riscv_ex_stage
|
|||
assign regfile_alu_we_fw_o = regfile_alu_we_i;
|
||||
assign regfile_alu_waddr_fw_o = regfile_alu_waddr_i;
|
||||
|
||||
|
||||
// EX stage result mux (ALU, MAC unit, CSR)
|
||||
always_comb
|
||||
begin
|
||||
regfile_alu_wdata_fw_o = alu_result;
|
||||
|
@ -107,8 +105,9 @@ module riscv_ex_stage
|
|||
regfile_alu_wdata_fw_o = csr_rdata_i;
|
||||
end
|
||||
|
||||
// Branch is taken when result[0] == 1'b1
|
||||
assign branch_decision_o = alu_flag;
|
||||
|
||||
// branch handling
|
||||
assign branch_decision_o = alu_cmp_result;
|
||||
assign jump_target_o = alu_operand_c_i;
|
||||
|
||||
|
||||
|
@ -120,18 +119,15 @@ module riscv_ex_stage
|
|||
// /_/ \_\_____\___/ //
|
||||
// //
|
||||
////////////////////////////
|
||||
|
||||
riscv_alu alu_i
|
||||
(
|
||||
.operator_i ( alu_operator_i ),
|
||||
.operand_a_i ( alu_operand_a_i ),
|
||||
.operand_b_i ( alu_operand_b_i ),
|
||||
.operator_i ( alu_operator_i ),
|
||||
.operand_a_i ( alu_operand_a_i ),
|
||||
.operand_b_i ( alu_operand_b_i ),
|
||||
|
||||
.vector_mode_i ( vector_mode_i ),
|
||||
.cmp_mode_i ( alu_cmp_mode_i ),
|
||||
.vec_ext_i ( alu_vec_ext_i ),
|
||||
|
||||
.result_o ( alu_result ),
|
||||
.flag_o ( alu_flag )
|
||||
.result_o ( alu_result ),
|
||||
.comparison_result_o ( alu_cmp_result )
|
||||
);
|
||||
|
||||
|
||||
|
@ -143,6 +139,7 @@ module riscv_ex_stage
|
|||
// |_| |_|\___/|_____|_| |___|_| |_____|___|_____|_| \_\ //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
riscv_mult mult_i
|
||||
(
|
||||
.vector_mode_i ( vector_mode_i ),
|
||||
|
@ -165,19 +162,19 @@ module riscv_ex_stage
|
|||
begin : EX_WB_Pipeline_Register
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
regfile_waddr_wb_o <= 5'b0_0000;
|
||||
regfile_we_wb_o <= 1'b0;
|
||||
regfile_waddr_wb_o <= 5'b0_0000;
|
||||
regfile_we_wb_o <= 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (ex_valid_o) // wb_ready_i is implied
|
||||
begin
|
||||
regfile_we_wb_o <= regfile_we_i;
|
||||
regfile_waddr_wb_o <= regfile_waddr_i;
|
||||
regfile_we_wb_o <= regfile_we_i;
|
||||
regfile_waddr_wb_o <= regfile_waddr_i;
|
||||
end else if (wb_ready_i) begin
|
||||
// we are ready for a new instruction, but there is none available,
|
||||
// so we just flush the current one out of the pipe
|
||||
regfile_we_wb_o <= 1'b0;
|
||||
regfile_we_wb_o <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
67
id_stage.sv
67
id_stage.sv
|
@ -78,7 +78,6 @@ module riscv_id_stage
|
|||
input logic wb_valid_i, // WB stage is done
|
||||
|
||||
// To the Pipeline ID/EX
|
||||
output logic [31:0] regfile_rb_data_ex_o,
|
||||
output logic [31:0] alu_operand_a_ex_o,
|
||||
output logic [31:0] alu_operand_b_ex_o,
|
||||
output logic [31:0] alu_operand_c_ex_o,
|
||||
|
@ -92,9 +91,7 @@ module riscv_id_stage
|
|||
// ALU
|
||||
output logic [`ALU_OP_WIDTH-1:0] alu_operator_ex_o,
|
||||
|
||||
output logic [1:0] vector_mode_ex_o,
|
||||
output logic [1:0] alu_cmp_mode_ex_o,
|
||||
output logic [1:0] alu_vec_ext_ex_o,
|
||||
output logic vector_mode_ex_o,
|
||||
|
||||
// MUL
|
||||
output logic mult_en_ex_o,
|
||||
|
@ -219,15 +216,11 @@ module riscv_id_stage
|
|||
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 alu_op_c_mux_sel;
|
||||
logic scalar_replication;
|
||||
logic [1:0] alu_op_c_mux_sel;
|
||||
|
||||
logic [1:0] vector_mode;
|
||||
logic [1:0] alu_cmp_mode;
|
||||
logic [1:0] alu_vec_ext;
|
||||
logic vector_mode;
|
||||
|
||||
logic [2:0] immediate_mux_sel;
|
||||
|
||||
logic [1:0] jump_target_mux_sel;
|
||||
|
||||
// Multiplier Control
|
||||
|
@ -278,13 +271,11 @@ module riscv_id_stage
|
|||
logic [1:0] operand_c_fw_mux_sel;
|
||||
logic [31:0] operand_a_fw_id;
|
||||
logic [31:0] operand_b_fw_id;
|
||||
logic [31:0] operand_c_fw_id;
|
||||
|
||||
logic [31:0] alu_operand_a;
|
||||
logic [31:0] alu_operand_b;
|
||||
logic [31:0] alu_operand_c;
|
||||
logic [31:0] operand_b; // before going through the scalar replication mux
|
||||
logic [31:0] operand_b_vec; // scalar replication of operand_b for 8 and 16 bit
|
||||
logic [31:0] operand_c;
|
||||
|
||||
|
||||
assign instr = instr_rdata_i;
|
||||
|
@ -307,9 +298,6 @@ module riscv_id_stage
|
|||
// destination registers
|
||||
assign regfile_waddr_id = instr[`REG_D];
|
||||
|
||||
//assign alu_vec_ext = instr[9:8]; TODO
|
||||
assign alu_vec_ext = '0;
|
||||
|
||||
// Second Register Write Adress Selection
|
||||
// Used for prepost load/store and multiplier
|
||||
assign regfile_alu_waddr_id = regfile_alu_waddr_mux_sel ?
|
||||
|
@ -423,7 +411,6 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : immediate_mux
|
||||
unique case (immediate_mux_sel)
|
||||
//`IMM_VEC: immediate_b = immediate_vec_id;
|
||||
`IMM_I: immediate_b = imm_i_type;
|
||||
`IMM_S: immediate_b = imm_s_type;
|
||||
`IMM_U: immediate_b = imm_u_type;
|
||||
|
@ -436,20 +423,13 @@ 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 = alu_operand_c;
|
||||
`OP_B_IMM: operand_b = immediate_b;
|
||||
default: operand_b = operand_b_fw_id;
|
||||
`OP_B_REGB_OR_FWD: alu_operand_b = operand_b_fw_id;
|
||||
`OP_B_REGC_OR_FWD: alu_operand_b = operand_c_fw_id;
|
||||
`OP_B_IMM: alu_operand_b = immediate_b;
|
||||
default: alu_operand_b = operand_b_fw_id;
|
||||
endcase // case (alu_op_b_mux_sel)
|
||||
end
|
||||
|
||||
// scalar replication for operand B
|
||||
assign operand_b_vec = (vector_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;
|
||||
|
||||
|
||||
// Operand b forwarding mux
|
||||
always_comb
|
||||
begin : operand_b_fw_mux
|
||||
|
@ -475,8 +455,10 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : alu_operand_c_mux
|
||||
case (alu_op_c_mux_sel)
|
||||
`OP_C_JT: operand_c = jump_target;
|
||||
default: operand_c = regfile_data_rc_id;
|
||||
`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
|
||||
|
||||
|
@ -484,11 +466,11 @@ module riscv_id_stage
|
|||
always_comb
|
||||
begin : operand_c_fw_mux
|
||||
case (operand_c_fw_mux_sel)
|
||||
`SEL_FW_EX: alu_operand_c = regfile_alu_wdata_fw_i;
|
||||
`SEL_FW_WB: alu_operand_c = regfile_wdata_wb_i;
|
||||
`SEL_REGFILE: alu_operand_c = operand_c;
|
||||
default: alu_operand_c = operand_c;
|
||||
endcase; // case (operand_b_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;
|
||||
default: operand_c_fw_id = regfile_data_rc_id;
|
||||
endcase; // case (operand_c_fw_mux_sel)
|
||||
end
|
||||
|
||||
|
||||
|
@ -555,7 +537,6 @@ module riscv_id_stage
|
|||
.regb_used_o ( regb_used_dec ),
|
||||
.regc_used_o ( regc_used_dec ),
|
||||
|
||||
|
||||
// from IF/ID pipeline
|
||||
.instr_rdata_i ( instr ),
|
||||
.illegal_c_insn_i ( illegal_c_insn_i ),
|
||||
|
@ -568,8 +549,6 @@ module riscv_id_stage
|
|||
.immediate_mux_sel_o ( immediate_mux_sel ),
|
||||
|
||||
.vector_mode_o ( vector_mode ),
|
||||
.scalar_replication_o ( scalar_replication ),
|
||||
.alu_cmp_mode_o ( alu_cmp_mode ),
|
||||
|
||||
// MUL signals
|
||||
.mult_en_o ( mult_en ),
|
||||
|
@ -615,6 +594,7 @@ module riscv_id_stage
|
|||
// \____\___/|_| \_| |_| |_| \_\\___/|_____|_____|_____|_| \_\ //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
riscv_controller controller_i
|
||||
(
|
||||
.clk ( clk ),
|
||||
|
@ -830,16 +810,12 @@ module riscv_id_stage
|
|||
begin : ID_EX_PIPE_REGISTERS
|
||||
if (rst_n == 1'b0)
|
||||
begin
|
||||
regfile_rb_data_ex_o <= 32'h0000_0000;
|
||||
|
||||
alu_operator_ex_o <= `ALU_NOP;
|
||||
alu_operand_a_ex_o <= 32'h0000_0000;
|
||||
alu_operand_b_ex_o <= 32'h0000_0000;
|
||||
alu_operand_c_ex_o <= 32'h0000_0000;
|
||||
|
||||
vector_mode_ex_o <= `VEC_MODE32;
|
||||
alu_cmp_mode_ex_o <= `ALU_CMP_FULL;
|
||||
alu_vec_ext_ex_o <= 2'h0;
|
||||
vector_mode_ex_o <= '0;
|
||||
|
||||
mult_en_ex_o <= 1'b0;
|
||||
mult_sel_subword_ex_o <= 2'b0;
|
||||
|
@ -890,23 +866,18 @@ module riscv_id_stage
|
|||
else if (~data_misaligned_i) begin
|
||||
if (id_valid_o)
|
||||
begin // unstall the whole pipeline
|
||||
regfile_rb_data_ex_o <= operand_b_fw_id;
|
||||
|
||||
alu_operator_ex_o <= alu_operator;
|
||||
alu_operand_a_ex_o <= alu_operand_a;
|
||||
alu_operand_b_ex_o <= alu_operand_b;
|
||||
alu_operand_c_ex_o <= alu_operand_c;
|
||||
|
||||
vector_mode_ex_o <= vector_mode;
|
||||
alu_cmp_mode_ex_o <= alu_cmp_mode;
|
||||
alu_vec_ext_ex_o <= alu_vec_ext;
|
||||
|
||||
mult_en_ex_o <= mult_en;
|
||||
mult_sel_subword_ex_o <= mult_sel_subword;
|
||||
mult_signed_mode_ex_o <= mult_signed_mode;
|
||||
mult_mac_en_ex_o <= mult_mac_en;
|
||||
|
||||
|
||||
regfile_waddr_ex_o <= regfile_waddr_id;
|
||||
regfile_we_ex_o <= regfile_we_id;
|
||||
|
||||
|
|
|
@ -29,6 +29,8 @@
|
|||
`ifndef _CORE_DEFINES
|
||||
`define _CORE_DEFINES
|
||||
|
||||
`define TRACE_EXECUTION
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// ___ ____ _ //
|
||||
|
@ -74,16 +76,6 @@
|
|||
`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 }
|
||||
// LOAD
|
||||
`define INSTR_LB { 17'b?, 3'b000, 5'b?, `OPCODE_LOAD }
|
||||
`define INSTR_LH { 17'b?, 3'b001, 5'b?, `OPCODE_LOAD }
|
||||
`define INSTR_LW { 17'b?, 3'b010, 5'b?, `OPCODE_LOAD }
|
||||
`define INSTR_LBU { 17'b?, 3'b100, 5'b?, `OPCODE_LOAD }
|
||||
`define INSTR_LHU { 17'b?, 3'b101, 5'b?, `OPCODE_LOAD }
|
||||
// STORE
|
||||
`define INSTR_SB { 17'b?, 3'b000, 5'b?, `OPCODE_STORE }
|
||||
`define INSTR_SH { 17'b?, 3'b001, 5'b?, `OPCODE_STORE }
|
||||
`define INSTR_SW { 17'b?, 3'b010, 5'b?, `OPCODE_STORE }
|
||||
// OPIMM
|
||||
`define INSTR_ADDI { 17'b?, 3'b000, 5'b?, `OPCODE_OPIMM }
|
||||
`define INSTR_SLTI { 17'b?, 3'b010, 5'b?, `OPCODE_OPIMM }
|
||||
|
@ -119,12 +111,6 @@
|
|||
`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 }
|
||||
`define INSTR_RDCYCLE { 5'b11000, 5'b0, 2'b00, 5'b0, 3'b010, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_RDCYCLEH { 5'b11001, 5'b0, 2'b00, 5'b0, 3'b010, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_RDTIME { 5'b11000, 5'b0, 2'b01, 5'b0, 3'b010, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_RDTIMEH { 5'b11001, 5'b0, 2'b01, 5'b0, 3'b010, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_RDINSTRET { 5'b11000, 5'b0, 2'b10, 5'b0, 3'b010, 5'b?, `OPCODE_SYSTEM }
|
||||
`define INSTR_RDINSTRETH { 5'b11001, 5'b0, 2'b10, 5'b0, 3'b010, 5'b?, `OPCODE_SYSTEM }
|
||||
|
||||
// RV32M
|
||||
`define INSTR_MUL { 7'b0000001, 10'b?, 3'b000, 5'b?, `OPCODE_OP }
|
||||
|
@ -146,40 +132,6 @@
|
|||
`define REG_D 11:07
|
||||
|
||||
|
||||
`ifndef SYNTHESIS
|
||||
// synopsys translate_off
|
||||
`define TRACE_EXECUTION
|
||||
|
||||
function void prettyPrintInstruction(input [31:0] instr, input [31:0] pc);
|
||||
string opcode;
|
||||
begin
|
||||
unique case (instr[6:0])
|
||||
`OPCODE_SYSTEM: opcode = "SYSTEM";
|
||||
`OPCODE_FENCE: opcode = "FENCE";
|
||||
`OPCODE_OP: opcode = "OP";
|
||||
`OPCODE_OPIMM: opcode = "OPIMM";
|
||||
`OPCODE_STORE: opcode = "STORE";
|
||||
`OPCODE_LOAD: opcode = "LOAD";
|
||||
`OPCODE_BRANCH: opcode = "BRANCH";
|
||||
`OPCODE_JALR: opcode = "JALR";
|
||||
`OPCODE_JAL: opcode = "JAL";
|
||||
`OPCODE_AUIPC: opcode = "AUIPC";
|
||||
`OPCODE_LUI: opcode = "LUI";
|
||||
default: opcode = "Unknown";
|
||||
endcase // unique case (instr[6:0])
|
||||
|
||||
$display("%t: %s Instruction 0x%h at 0x%h.", $time, opcode, instr[31:0], pc[31:0]);
|
||||
$display("%t: | fct7 | rs2 | rs1 | | rd | opc. |", $time);
|
||||
$display("%t: 0b %b %b %b %b %b %b", $time, instr[31:25], instr[`REG_S2],
|
||||
instr[`REG_S1], instr[14:12], instr[`REG_D], instr[6:0]);
|
||||
$display();
|
||||
end
|
||||
endfunction // prettyPrintInstruction
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// _ _ _ _ ___ _ _ //
|
||||
// / \ | | | | | | / _ \ _ __ ___ _ __ __ _| |_(_) ___ _ __ ___ //
|
||||
|
@ -191,35 +143,37 @@ endfunction // prettyPrintInstruction
|
|||
|
||||
`define ALU_OP_WIDTH 6
|
||||
|
||||
// Standard Operations
|
||||
// No operation
|
||||
`define ALU_NOP 6'b011111
|
||||
|
||||
// Standard arithmetic operations
|
||||
`define ALU_ADD 6'b000_000
|
||||
`define ALU_SUB 6'b000_010
|
||||
`define ALU_AND 6'b000_011
|
||||
`define ALU_OR 6'b000_100
|
||||
`define ALU_XOR 6'b000_101
|
||||
`define ALU_OR 6'b000_100
|
||||
`define ALU_AND 6'b000_011
|
||||
|
||||
`define ALU_AVG 6'b000_110
|
||||
`define ALU_AVGU 6'b000_111
|
||||
// Shift Operations
|
||||
`define ALU_SLL 6'b0010_00
|
||||
`define ALU_SRL 6'b0010_01
|
||||
`define ALU_SRA 6'b0010_10
|
||||
`define ALU_ROR 6'b0010_11
|
||||
// Set Lower Than Operations
|
||||
// Set Lower Than operations
|
||||
`define ALU_SLTS 6'b0011_00
|
||||
`define ALU_SLTU 6'b0011_01
|
||||
`define ALU_SLETS 6'b0011_10
|
||||
`define ALU_SLETU 6'b0011_11
|
||||
// Extension Operations
|
||||
|
||||
// Shifts
|
||||
`define ALU_SLL 6'b0010_00
|
||||
`define ALU_SRL 6'b0010_01
|
||||
`define ALU_SRA 6'b0010_10
|
||||
`define ALU_ROR 6'b0010_11
|
||||
|
||||
// Sign-/zero-extensions
|
||||
`define ALU_EXTHS 6'b010_000
|
||||
`define ALU_EXTWS 6'b010_001
|
||||
`define ALU_EXTBS 6'b010_010
|
||||
`define ALU_EXTWZ 6'b010_011
|
||||
`define ALU_EXTHZ 6'b010_100
|
||||
`define ALU_EXTBZ 6'b010_110
|
||||
// No Operation
|
||||
`define ALU_NOP 6'b011111
|
||||
// Comparison Operations
|
||||
|
||||
// Comparisons
|
||||
`define ALU_EQ 6'b10_0000
|
||||
`define ALU_NE 6'b10_0001
|
||||
`define ALU_GTU 6'b10_0010
|
||||
|
@ -231,34 +185,24 @@ endfunction // prettyPrintInstruction
|
|||
`define ALU_LTS 6'b10_1100
|
||||
`define ALU_LES 6'b10_1101
|
||||
|
||||
// Min/max/avg
|
||||
`define ALU_AVG 6'b000_110
|
||||
`define ALU_AVGU 6'b000_111
|
||||
`define ALU_MIN 6'b10_1110
|
||||
`define ALU_MINU 6'b11_1110
|
||||
`define ALU_MAX 6'b10_1111
|
||||
`define ALU_MAXU 6'b11_1111
|
||||
|
||||
// Absolute value
|
||||
`define ALU_ABS 6'b11_1010
|
||||
|
||||
`define ALU_INS 6'b11_1101
|
||||
`define ALU_EXT 6'b11_1100
|
||||
|
||||
// Bit counting
|
||||
`define ALU_CNT 6'b11_0000
|
||||
`define ALU_FF1 6'b11_0010
|
||||
`define ALU_FL1 6'b11_0011
|
||||
`define ALU_CLB 6'b11_0001
|
||||
|
||||
|
||||
// Vector Mode
|
||||
`define VEC_MODE32 2'b00
|
||||
`define VEC_MODE16 2'b10
|
||||
`define VEC_MODE8 2'b11
|
||||
`define VEC_MODE216 2'b01
|
||||
|
||||
// ALU comparison mode
|
||||
`define ALU_CMP_FULL 2'b00
|
||||
`define ALU_CMP_ANY 2'b01
|
||||
`define ALU_CMP_ALL 2'b10
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// ____ ____ ____ _ _ //
|
||||
// / ___/ ___| | _ \ ___ __ _(_)___| |_ ___ _ __ //
|
||||
|
@ -281,9 +225,6 @@ endfunction // prettyPrintInstruction
|
|||
`define CSR_OP_CLEAR 2'b11
|
||||
|
||||
|
||||
// SPR for HWLoops
|
||||
`define SP_GRP_HWLP 5'h0C
|
||||
|
||||
// SPR for debugger, not accessible by CPU
|
||||
`define SP_DVR0 16'h3000
|
||||
`define SP_DCR0 16'h3008
|
||||
|
@ -328,8 +269,9 @@ endfunction // prettyPrintInstruction
|
|||
`define IMM_PCINCR 3'b011
|
||||
|
||||
// operand c selection
|
||||
`define OP_C_REGC_OR_FWD 1'b0
|
||||
`define OP_C_JT 1'b1
|
||||
`define OP_C_REGC_OR_FWD 2'b00
|
||||
`define OP_C_REGB_OR_FWD 2'b01
|
||||
`define OP_C_JT 2'b10
|
||||
|
||||
// branch types
|
||||
`define BRANCH_NONE 2'b00
|
||||
|
@ -403,6 +345,4 @@ endfunction // prettyPrintInstruction
|
|||
`define DSR_INTE 1
|
||||
|
||||
|
||||
//`define BRANCH_PREDICTION
|
||||
|
||||
`endif
|
||||
|
|
66
mult.sv
66
mult.sv
|
@ -24,44 +24,37 @@
|
|||
// selection. There are no flags for multiplications anymore! //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
`include "defines.sv"
|
||||
|
||||
|
||||
module riscv_mult
|
||||
(
|
||||
input logic [1:0] vector_mode_i,
|
||||
input logic [1:0] sel_subword_i,
|
||||
input logic [1:0] signed_mode_i,
|
||||
input logic mac_en_i,
|
||||
input logic mac_en_i,
|
||||
input logic vector_mode_i,
|
||||
input logic [1:0] sel_subword_i,
|
||||
input logic [1:0] signed_mode_i,
|
||||
|
||||
input logic [31:0] op_a_i,
|
||||
input logic [31:0] op_b_i,
|
||||
input logic [31:0] mac_i,
|
||||
input logic [31:0] op_a_i,
|
||||
input logic [31:0] op_b_i,
|
||||
input logic [31:0] mac_i,
|
||||
|
||||
output logic [31:0] result_o
|
||||
output logic [31:0] result_o
|
||||
);
|
||||
|
||||
logic [31:0] result;
|
||||
|
||||
logic [31:0] op_a_sel;
|
||||
logic [31:0] op_b_sel;
|
||||
logic [31:0] mac_int;
|
||||
logic [31:0] op_a_sel;
|
||||
logic [31:0] op_b_sel;
|
||||
logic [31:0] mac_int;
|
||||
|
||||
|
||||
assign mac_int = (mac_en_i == 1'b1) ? mac_i : 32'b0;
|
||||
|
||||
// this block performs the subword selection and sign extensions
|
||||
// perform subword selection and sign extensions
|
||||
always_comb
|
||||
begin
|
||||
op_a_sel = op_a_i;
|
||||
op_b_sel = op_b_i;
|
||||
|
||||
if(vector_mode_i == `VEC_MODE216)
|
||||
if(vector_mode_i)
|
||||
begin
|
||||
if(sel_subword_i[1] == 1'b1)
|
||||
op_a_sel[15:0] = op_a_i[31:16];
|
||||
|
@ -78,32 +71,7 @@ module riscv_mult
|
|||
end
|
||||
end
|
||||
|
||||
assign mac_int = (mac_en_i == 1'b1) ? mac_i : 32'b0;
|
||||
assign result_o = mac_int + op_a_sel * op_b_sel;
|
||||
|
||||
always_comb
|
||||
begin
|
||||
case(vector_mode_i)
|
||||
`VEC_MODE16:
|
||||
begin
|
||||
result[15: 0] = mac_int[15: 0] + op_a_sel[15: 0] * op_b_sel[15: 0];
|
||||
result[31:16] = mac_int[31:16] + op_a_sel[31:16] * op_b_sel[31:16];
|
||||
end
|
||||
|
||||
`VEC_MODE8:
|
||||
begin
|
||||
result[ 7: 0] = mac_int[ 7: 0] + op_a_sel[ 7: 0] * op_b_sel[ 7: 0];
|
||||
result[15: 8] = mac_int[15: 8] + op_a_sel[15: 8] * op_b_sel[15: 8];
|
||||
result[23:16] = mac_int[23:16] + op_a_sel[23:16] * op_b_sel[23:16];
|
||||
result[31:24] = mac_int[31:24] + op_a_sel[31:24] * op_b_sel[31:24];
|
||||
end
|
||||
|
||||
default: // VEC_MODE32, VEC_MODE216
|
||||
begin
|
||||
result[31: 0] = mac_int + op_a_sel * op_b_sel;
|
||||
end
|
||||
endcase; // case (vec_mode_i)
|
||||
end
|
||||
|
||||
assign result_o = result[31:0];
|
||||
|
||||
endmodule // mult
|
||||
|
||||
endmodule
|
||||
|
|
175
riscv_core.sv
175
riscv_core.sv
|
@ -61,8 +61,8 @@ module riscv_core
|
|||
input logic [31:0] data_rdata_i,
|
||||
|
||||
// Interrupt inputs
|
||||
input logic irq_i, // level-triggered IR line
|
||||
input logic irq_nm_i, // level-triggered IR line for non-maskable IRQ
|
||||
input logic irq_i, // level-triggered IR line
|
||||
input logic irq_nm_i, // level-triggered IR line for non-maskable IRQ
|
||||
|
||||
// Debug Interface
|
||||
input logic dbginf_stall_i,
|
||||
|
@ -83,23 +83,22 @@ module riscv_core
|
|||
|
||||
|
||||
// IF/ID signals
|
||||
logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
|
||||
logic is_compressed_id;
|
||||
logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage
|
||||
logic [31:0] current_pc_if; // Current Program counter
|
||||
logic [31:0] current_pc_id; // Current Program counter
|
||||
logic pc_set;
|
||||
logic [2:0] pc_mux_sel_id; // Mux selector for next PC
|
||||
logic [1:0] exc_pc_mux_id; // Mux selector for exception PC
|
||||
logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
|
||||
logic is_compressed_id;
|
||||
logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage
|
||||
logic [31:0] current_pc_if; // Current Program counter
|
||||
logic [31:0] current_pc_id; // Current Program counter
|
||||
logic pc_set;
|
||||
logic [2:0] pc_mux_sel_id; // Mux selector for next PC
|
||||
logic [1:0] exc_pc_mux_id; // Mux selector for exception PC
|
||||
|
||||
logic branch_done; // Branch already done
|
||||
logic branch_done; // Branch already done
|
||||
|
||||
// ID performance counter signals
|
||||
logic is_decoding;
|
||||
logic is_decoding;
|
||||
|
||||
|
||||
logic useincr_addr_ex; // Active when post increment
|
||||
logic data_misaligned;
|
||||
logic useincr_addr_ex; // Active when post increment
|
||||
logic data_misaligned;
|
||||
|
||||
// Jump and branch target and decision (EX->IF)
|
||||
logic [31:0] jump_target_id, jump_target_ex;
|
||||
|
@ -107,24 +106,16 @@ module riscv_core
|
|||
logic [1:0] jump_in_ex;
|
||||
logic branch_decision;
|
||||
|
||||
|
||||
logic core_busy;
|
||||
logic if_busy;
|
||||
|
||||
|
||||
// Register Data
|
||||
logic [31:0] regfile_rb_data_ex; // from id stage to load/store unit and ex stage
|
||||
|
||||
|
||||
// ALU Control
|
||||
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;
|
||||
|
||||
logic [1:0] vector_mode_ex;
|
||||
logic [1:0] alu_cmp_mode_ex;
|
||||
logic [1:0] alu_vec_ext_ex;
|
||||
logic [31:0] alu_operand_a_ex;
|
||||
logic [31:0] alu_operand_b_ex;
|
||||
logic [31:0] alu_operand_c_ex;
|
||||
logic vector_mode_ex;
|
||||
|
||||
// Multiplier Control
|
||||
logic mult_en_ex;
|
||||
|
@ -253,7 +244,7 @@ module riscv_core
|
|||
.instr_rdata_i ( instr_rdata_i ),
|
||||
|
||||
// outputs to ID stage
|
||||
.instr_rdata_id_o ( instr_rdata_id ), // Output of IF Pipeline stage
|
||||
.instr_rdata_id_o ( instr_rdata_id ),
|
||||
.is_compressed_id_o ( is_compressed_id ),
|
||||
.illegal_c_insn_id_o ( illegal_c_insn_id ),
|
||||
.current_pc_if_o ( current_pc_if ), // current pc in IF stage
|
||||
|
@ -261,7 +252,7 @@ module riscv_core
|
|||
|
||||
// control signals
|
||||
.pc_set_i ( pc_set ),
|
||||
.exception_pc_reg_i ( epcr ), // Exception PC register
|
||||
.exception_pc_reg_i ( epcr ), // exception return address
|
||||
.pc_mux_sel_i ( pc_mux_sel_id ), // sel for pc multiplexer
|
||||
.exc_pc_mux_i ( exc_pc_mux_id ), // selector for exception multiplexer
|
||||
|
||||
|
@ -345,7 +336,6 @@ module riscv_core
|
|||
.wb_valid_i ( wb_valid ),
|
||||
|
||||
// From the Pipeline ID/EX
|
||||
.regfile_rb_data_ex_o ( regfile_rb_data_ex ),
|
||||
.alu_operand_a_ex_o ( alu_operand_a_ex ),
|
||||
.alu_operand_b_ex_o ( alu_operand_b_ex ),
|
||||
.alu_operand_c_ex_o ( alu_operand_c_ex ),
|
||||
|
@ -358,10 +348,7 @@ module riscv_core
|
|||
|
||||
// ALU
|
||||
.alu_operator_ex_o ( alu_operator_ex ),
|
||||
|
||||
.vector_mode_ex_o ( vector_mode_ex ), // from ID to EX stage
|
||||
.alu_cmp_mode_ex_o ( alu_cmp_mode_ex ), // from ID to EX stage
|
||||
.alu_vec_ext_ex_o ( alu_vec_ext_ex ), // from ID to EX stage
|
||||
|
||||
// MUL
|
||||
.mult_en_ex_o ( mult_en_ex ), // from ID to EX stage
|
||||
|
@ -446,8 +433,6 @@ module riscv_core
|
|||
.alu_operand_c_i ( alu_operand_c_ex ), // from ID/EX pipe registers
|
||||
|
||||
.vector_mode_i ( vector_mode_ex ), // from ID/EX pipe registers
|
||||
.alu_cmp_mode_i ( alu_cmp_mode_ex ), // from ID/EX pipe registers
|
||||
.alu_vec_ext_i ( alu_vec_ext_ex ), // from ID/EX pipe registers
|
||||
|
||||
// Multipler
|
||||
.mult_en_i ( mult_en_ex ),
|
||||
|
@ -496,46 +481,48 @@ module riscv_core
|
|||
// |_____\___/_/ \_\____/ |____/ |_| \___/|_| \_\_____| \___/|_| \_|___| |_| //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
riscv_load_store_unit load_store_unit_i
|
||||
(
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
.clk ( clk ),
|
||||
.rst_n ( rst_n ),
|
||||
|
||||
// signal from ex stage
|
||||
.data_we_ex_i ( data_we_ex ),
|
||||
.data_type_ex_i ( data_type_ex ),
|
||||
.data_wdata_ex_i ( regfile_rb_data_ex ),
|
||||
.data_reg_offset_ex_i ( data_reg_offset_ex ),
|
||||
.data_sign_ext_ex_i ( data_sign_ext_ex ), // sign extension
|
||||
.data_we_ex_i ( data_we_ex ),
|
||||
.data_type_ex_i ( data_type_ex ),
|
||||
.data_wdata_ex_i ( alu_operand_c_ex ),
|
||||
.data_reg_offset_ex_i ( data_reg_offset_ex ),
|
||||
.data_sign_ext_ex_i ( data_sign_ext_ex ), // sign extension
|
||||
|
||||
.data_rdata_ex_o ( regfile_wdata ),
|
||||
.data_req_ex_i ( data_req_ex ),
|
||||
.operand_a_ex_i ( alu_operand_a_ex ),
|
||||
.operand_b_ex_i ( alu_operand_b_ex ),
|
||||
.addr_useincr_ex_i ( useincr_addr_ex ),
|
||||
.data_rdata_ex_o ( regfile_wdata ),
|
||||
.data_req_ex_i ( data_req_ex ),
|
||||
.operand_a_ex_i ( alu_operand_a_ex ),
|
||||
.operand_b_ex_i ( alu_operand_b_ex ),
|
||||
.addr_useincr_ex_i ( useincr_addr_ex ),
|
||||
|
||||
.data_misaligned_ex_i ( data_misaligned_ex ), // from ID/EX pipeline
|
||||
.data_misaligned_o ( data_misaligned ),
|
||||
.data_misaligned_ex_i ( data_misaligned_ex ), // from ID/EX pipeline
|
||||
.data_misaligned_o ( data_misaligned ),
|
||||
|
||||
//output to data memory
|
||||
.data_req_o ( data_req_o ),
|
||||
.data_gnt_i ( data_gnt_i ),
|
||||
.data_rvalid_i ( data_rvalid_i ),
|
||||
.data_req_o ( data_req_o ),
|
||||
.data_gnt_i ( data_gnt_i ),
|
||||
.data_rvalid_i ( data_rvalid_i ),
|
||||
|
||||
.data_addr_o ( data_addr_o ),
|
||||
.data_we_o ( data_we_o ),
|
||||
.data_be_o ( data_be_o ),
|
||||
.data_wdata_o ( data_wdata_o ),
|
||||
.data_rdata_i ( data_rdata_i ),
|
||||
.data_addr_o ( data_addr_o ),
|
||||
.data_we_o ( data_we_o ),
|
||||
.data_be_o ( data_be_o ),
|
||||
.data_wdata_o ( data_wdata_o ),
|
||||
.data_rdata_i ( data_rdata_i ),
|
||||
|
||||
.lsu_ready_ex_o ( lsu_ready_ex ),
|
||||
.lsu_ready_wb_o ( lsu_ready_wb ),
|
||||
.lsu_ready_ex_o ( lsu_ready_ex ),
|
||||
.lsu_ready_wb_o ( lsu_ready_wb ),
|
||||
|
||||
.ex_valid_i ( ex_valid )
|
||||
.ex_valid_i ( ex_valid )
|
||||
);
|
||||
|
||||
assign wb_valid = lsu_ready_wb;
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// ____ ____ ____ //
|
||||
// / ___/ ___|| _ \ ___ //
|
||||
|
@ -545,6 +532,7 @@ module riscv_core
|
|||
// //
|
||||
// Control and Status Registers //
|
||||
//////////////////////////////////////
|
||||
|
||||
riscv_cs_registers
|
||||
#(
|
||||
.N_EXT_PERF_COUNTERS ( N_EXT_PERF_COUNTERS )
|
||||
|
@ -606,6 +594,7 @@ module riscv_core
|
|||
// |____/|_____|____/ \___/ \____| \___/|_| \_|___| |_| //
|
||||
// //
|
||||
/////////////////////////////////////////////////////////////
|
||||
|
||||
riscv_debug_unit debug_unit_i
|
||||
(
|
||||
.clk ( clk ),
|
||||
|
@ -730,10 +719,6 @@ module riscv_core
|
|||
`INSTR_BGE: printSBInstr("BGE");
|
||||
`INSTR_BLTU: printSBInstr("BLTU");
|
||||
`INSTR_BGEU: printSBInstr("BGEU");
|
||||
// STORE
|
||||
`INSTR_SB: printSInstr("SB");
|
||||
`INSTR_SH: printSInstr("SH");
|
||||
`INSTR_SW: printSInstr("SW");
|
||||
// OPIMM
|
||||
`INSTR_ADDI: printIInstr("ADDI");
|
||||
`INSTR_SLTI: printIInstr("SLTI");
|
||||
|
@ -770,12 +755,6 @@ module riscv_core
|
|||
`INSTR_EBREAK: printMnemonic("EBREAK");
|
||||
`INSTR_ERET: printMnemonic("ERET");
|
||||
`INSTR_WFI: printMnemonic("WFI");
|
||||
`INSTR_RDCYCLE: printRDInstr("RDCYCLE");
|
||||
`INSTR_RDCYCLEH: printRDInstr("RDCYCLEH");
|
||||
`INSTR_RDTIME: printRDInstr("RDTIME");
|
||||
`INSTR_RDTIMEH: printRDInstr("RDTIMEH");
|
||||
`INSTR_RDINSTRET: printRDInstr("RDINSTRET");
|
||||
`INSTR_RDINSTRETH: printRDInstr("RDINSTRETH");
|
||||
// RV32M
|
||||
`INSTR_MUL: printRInstr("MUL");
|
||||
`INSTR_MULH: printRInstr("MULH");
|
||||
|
@ -792,6 +771,7 @@ module riscv_core
|
|||
{25'b?, `OPCODE_LOAD_POST}: printLoadInstr();
|
||||
{25'b?, `OPCODE_STORE}: printStoreInstr();
|
||||
{25'b?, `OPCODE_STORE_POST}: printStoreInstr();
|
||||
{25'b?, `OPCODE_HWLOOP}: printHwloopInstr();
|
||||
default: printMnemonic("INVALID");
|
||||
endcase // unique case (instr)
|
||||
|
||||
|
@ -839,15 +819,6 @@ module riscv_core
|
|||
end
|
||||
endfunction // printIInstr
|
||||
|
||||
function void printSInstr(input string mnemonic);
|
||||
begin
|
||||
riscv_core.mnemonic = mnemonic;
|
||||
imm = id_stage_i.imm_s_type;
|
||||
$fdisplay(f, "%7s\tx%0d (0x%h), x%0d (0x%h), 0x%0h (imm) (-> 0x%h)", mnemonic,
|
||||
rs1, rs1_value, rs2, rs2_value, imm, imm+rs1_value);
|
||||
end
|
||||
endfunction // printSInstr
|
||||
|
||||
function void printSBInstr(input string mnemonic);
|
||||
begin
|
||||
riscv_core.mnemonic = mnemonic;
|
||||
|
@ -865,13 +836,6 @@ module riscv_core
|
|||
end
|
||||
endfunction // printUJInstr
|
||||
|
||||
function void printRDInstr(input string mnemonic);
|
||||
begin
|
||||
riscv_core.mnemonic = mnemonic;
|
||||
$fdisplay(f, "%7s\tx%0d", mnemonic, rd);
|
||||
end
|
||||
endfunction // printRDInstr
|
||||
|
||||
function void printCSRInstr(input string mnemonic);
|
||||
logic [11:0] csr;
|
||||
begin
|
||||
|
@ -978,11 +942,42 @@ module riscv_core
|
|||
end
|
||||
end
|
||||
endfunction // printSInstr
|
||||
|
||||
function void printHwloopInstr();
|
||||
string mnemonic;
|
||||
begin
|
||||
// set mnemonic
|
||||
case (instr[14:12])
|
||||
3'b000: mnemonic = "LSTARTI";
|
||||
3'b001: mnemonic = "LENDI";
|
||||
3'b010: mnemonic = "LCOUNT";
|
||||
3'b011: mnemonic = "LCOUNTI";
|
||||
3'b100: mnemonic = "LSETUP";
|
||||
3'b111: begin
|
||||
printMnemonic("INVALID");
|
||||
return;
|
||||
end
|
||||
endcase
|
||||
riscv_core.mnemonic = mnemonic;
|
||||
|
||||
// decode and print instruction
|
||||
imm = id_stage_i.imm_i_type;
|
||||
case (instr[14:12])
|
||||
// lp.starti and lp.endi
|
||||
3'b000,
|
||||
3'b001: $fdisplay(f, "%7s\tx%0d, 0x%h (-> 0x%h)", mnemonic, rd, imm, pc+imm);
|
||||
// lp.count
|
||||
3'b010: $fdisplay(f, "%7s\tx%0d, x%0d (0x%h)", mnemonic, rd, rs1, rs1_value);
|
||||
// lp.counti
|
||||
3'b011: $fdisplay(f, "%7s\tx%0d, 0x%h", mnemonic, rd, imm);
|
||||
// lp.setup
|
||||
3'b100: $fdisplay(f, "%7s\tx%0d, x%0d (0x%h), 0x%h (-> 0x%h)", mnemonic,
|
||||
rd, rs1, rs1_value, imm, pc+imm);
|
||||
endcase
|
||||
end
|
||||
endfunction
|
||||
`endif // TRACE_EXECUTION
|
||||
// synopsys translate_on
|
||||
`endif
|
||||
|
||||
|
||||
///////////////////
|
||||
endmodule // cpu //
|
||||
///////////////////
|
||||
endmodule
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue