Compile all files

This commit is contained in:
Markus Wegmann 2017-01-12 19:34:41 +01:00
parent fdfca50e16
commit f1b2c869f5
67 changed files with 98 additions and 11694 deletions

572
alu.sv
View file

@ -37,24 +37,8 @@ module riscv_alu
input logic [31:0] operand_b_i,
input logic [31:0] operand_c_i,
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
input logic [ 1:0] vector_mode_i,
`endif // VEC_SUPPORT
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
input logic [ 4:0] bmask_a_i,
input logic [ 4:0] bmask_b_i,
`endif // BIT_SUPPORT
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
input logic [ 1:0] imm_vec_ext_i,
`endif // VEC_SUPPORT
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
output logic [31:0] adder_result_o,
`endif // LSU_ADDER_SUPPORT
output logic [31:0] result_o,
output logic comparison_result_o,
@ -92,16 +76,7 @@ module riscv_alu
assign operand_b_neg = ~operand_b_i;
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
logic [5:0] div_shift;
logic div_valid;
`endif // MUL_SUPPORT
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
logic [31:0] bmask;
`endif // BIT_SUPPORT
//////////////////////////////////////////////////////////////////////////////////////////
// ____ _ _ _ _ _ _ _ _ //
@ -152,37 +127,8 @@ module riscv_alu
// special case for subtractions and absolute number calculations
adder_in_b[0] = 1'b1;
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
case (vector_mode_i)
VEC_MODE16: begin
adder_in_b[18] = 1'b1;
end
VEC_MODE8: begin
adder_in_b[ 9] = 1'b1;
adder_in_b[18] = 1'b1;
adder_in_b[27] = 1'b1;
end
endcase
`endif // VEC_SUPPORT
end else begin
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
// take care of partitioning the adder for the addition case
case (vector_mode_i)
VEC_MODE16: begin
adder_in_a[18] = 1'b0;
end
VEC_MODE8: begin
adder_in_a[ 9] = 1'b0;
adder_in_a[18] = 1'b0;
adder_in_a[27] = 1'b0;
end
endcase
`endif // VEC_SUPPORT
end
end
@ -198,21 +144,10 @@ module riscv_alu
logic [31:0] adder_round_value;
logic [31:0] adder_round_result;
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
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;
`else
assign adder_round_value = '0;
assign adder_round_result = adder_result;
`endif // BIT_SUPPORT
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
assign adder_result_o = adder_result;
`endif // LSU_ADDER_SUPPORT
////////////////////////////////////////
// ____ _ _ ___ _____ _____ //
@ -236,44 +171,14 @@ module riscv_alu
logic [31:0] shift_right_result;
logic [31:0] shift_left_result;
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// shifter is also used for preparing operand for division
assign shift_amt = div_valid ? div_shift : operand_b_i;
`else
assign shift_amt = operand_b_i;
`endif // MUL_SUPPORT
// by reversing the bits of the input, we also have to reverse the order of shift amounts
always_comb
begin
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
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
`else
begin
shift_amt_left[31: 0] = shift_amt[31: 0];
end
`endif // VEC_SUPPORT
end
// ALU_FL1 and ALU_CBL are used for the bit counting ops later
@ -299,12 +204,7 @@ module riscv_alu
assign shift_amt_int = shift_use_round ? shift_amt_norm :
(shift_left ? shift_amt_left : shift_amt);
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
assign shift_amt_norm = {4{3'b000, bmask_b_i}};
`else
assign shift_amt_norm = '0;
`endif // BIT_SUPPORT
// right shifts, we let the synthesizer optimize this
logic [63:0] shift_op_a_32;
@ -313,33 +213,9 @@ module riscv_alu
always_comb
begin
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
case(vector_mode_i)
VEC_MODE16:
begin
shift_right_result[31:16] = $signed( {shift_arithmetic & shift_op_a[31], shift_op_a[31:16] }) >>> shift_amt_int[19:16];
shift_right_result[15: 0] = $signed( {shift_arithmetic & shift_op_a[15], shift_op_a[15: 0] }) >>> shift_amt_int[ 3: 0];
end
VEC_MODE8:
begin
shift_right_result[31:24] = $signed( {shift_arithmetic & shift_op_a[31], shift_op_a[31:24] }) >>> shift_amt_int[26:24];
shift_right_result[23:16] = $signed( {shift_arithmetic & shift_op_a[23], shift_op_a[23:16] }) >>> shift_amt_int[18:16];
shift_right_result[15: 8] = $signed( {shift_arithmetic & shift_op_a[15], shift_op_a[15: 8] }) >>> shift_amt_int[10: 8];
shift_right_result[ 7: 0] = $signed( {shift_arithmetic & shift_op_a[ 7], shift_op_a[ 7: 0] }) >>> shift_amt_int[ 2: 0];
end
default: // VEC_MODE32
begin
shift_right_result = shift_op_a_32 >> shift_amt_int[4:0];
end
endcase; // case (vec_mode_i)
`else
begin
shift_right_result = shift_op_a_32 >> shift_amt_int[4:0];
end
`endif // VEC_SUPPORT
end
// bit reverse the shift_right_result for left shifts
@ -387,16 +263,7 @@ module riscv_alu
ALU_ABS,
ALU_CLIP,
ALU_CLIPU: begin
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
case (vector_mode_i)
VEC_MODE8: cmp_signed[3:0] = 4'b1111;
VEC_MODE16: cmp_signed[3:0] = 4'b1010;
default: cmp_signed[3:0] = 4'b1000;
endcase
`else
cmp_signed[3:0] = 4'b1000;
`endif // VEC_SUPPORT
end
default:;
@ -426,26 +293,6 @@ module riscv_alu
| (is_equal_vec[2] & (is_greater_vec[1]
| (is_equal_vec[1] & (is_greater_vec[0]))))))}};
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
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
endcase
`endif
end
// generate comparison result
@ -510,253 +357,6 @@ module riscv_alu
// //
//////////////////////////////////////////////////
// CONFIG_REGION: MATH_SPECIAL_SUPPORT
`ifdef MATH_SPECIAL_SUPPORT
logic [ 3: 0][1:0] shuffle_byte_sel; // select byte in register: 31:24, 23:16, 15:8, 7:0
logic [ 3: 0] shuffle_reg_sel; // select register: rD/rS2 or rS1
logic [ 1: 0] shuffle_reg1_sel; // select register rD or rS2 for next stage
logic [ 1: 0] shuffle_reg0_sel;
logic [ 3: 0] shuffle_through;
logic [31: 0] shuffle_r1, shuffle_r0;
logic [31: 0] shuffle_r1_in, shuffle_r0_in;
logic [31: 0] shuffle_result;
logic [31: 0] pack_result;
always_comb
begin
shuffle_reg_sel = '0;
shuffle_reg1_sel = 2'b01;
shuffle_reg0_sel = 2'b10;
shuffle_through = '1;
unique case(operator_i)
ALU_EXT, ALU_EXTS: begin
if (operator_i == ALU_EXTS)
shuffle_reg1_sel = 2'b11;
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
if (vector_mode_i == VEC_MODE8) begin
shuffle_reg_sel[3:1] = 3'b111;
shuffle_reg_sel[0] = 1'b0;
end else begin
shuffle_reg_sel[3:2] = 2'b11;
shuffle_reg_sel[1:0] = 2'b00;
end
`else
shuffle_reg_sel[3:2] = 2'b11;
shuffle_reg_sel[1:0] = 2'b00;
`endif // VEC_SUPPORT
end
ALU_PCKLO: begin
shuffle_reg1_sel = 2'b00;
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
if (vector_mode_i == VEC_MODE8) begin
shuffle_through = 4'b0011;
shuffle_reg_sel = 4'b0001;
end else begin
shuffle_reg_sel = 4'b0011;
end
`else
shuffle_reg_sel = 4'b0011;
`endif // VEC_SUPPORT
end
ALU_PCKHI: begin
shuffle_reg1_sel = 2'b00;
shuffle_reg_sel = 4'b0100;
shuffle_through = 4'b1100;
end
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
ALU_SHUF2: begin
unique case (vector_mode_i)
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
shuffle_reg_sel[3] = ~operand_b_i[17];
shuffle_reg_sel[2] = ~operand_b_i[17];
shuffle_reg_sel[1] = ~operand_b_i[ 1];
shuffle_reg_sel[0] = ~operand_b_i[ 1];
end
default:;
endcase
end
ALU_INS: begin
unique case (vector_mode_i)
VEC_MODE8: begin
shuffle_reg0_sel = 2'b00;
unique case (imm_vec_ext_i)
2'b00: begin
shuffle_reg_sel[3:0] = 4'b1110;
end
2'b01: begin
shuffle_reg_sel[3:0] = 4'b1101;
end
2'b10: begin
shuffle_reg_sel[3:0] = 4'b1011;
end
2'b11: begin
shuffle_reg_sel[3:0] = 4'b0111;
end
default:;
endcase
end
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];
shuffle_reg_sel[1] = imm_vec_ext_i[ 0];
shuffle_reg_sel[0] = imm_vec_ext_i[ 0];
end
default:;
endcase
end
`endif // VEC_SUPPORT
default:;
endcase
end
always_comb
begin
shuffle_byte_sel = 'x;
// byte selector
unique case (operator_i)
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
ALU_EXTS,
ALU_EXT: begin
unique case (vector_mode_i)
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
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};
shuffle_byte_sel[0] = {imm_vec_ext_i[0], 1'b0};
end
default:;
endcase
end
ALU_PCKLO,
ALU_PCKHI: begin
unique case (vector_mode_i)
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
shuffle_byte_sel[3] = 2'b01;
shuffle_byte_sel[2] = 2'b00;
shuffle_byte_sel[1] = 2'b01;
shuffle_byte_sel[0] = 2'b00;
end
default:;
endcase
end
ALU_SHUF2,
ALU_SHUF: begin
unique case (vector_mode_i)
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
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};
shuffle_byte_sel[0] = {operand_b_i[ 0], 1'b0};
end
default:;
endcase
end
`endif // VEC_SUPPORT
ALU_INS: begin
shuffle_byte_sel[3] = 2'b11;
shuffle_byte_sel[2] = 2'b10;
shuffle_byte_sel[1] = 2'b01;
shuffle_byte_sel[0] = 2'b00;
end
default:;
endcase
end
assign shuffle_r0_in = shuffle_reg0_sel[1] ?
operand_a_i :
(shuffle_reg0_sel[0] ? {2{operand_a_i[15:0]}} : {4{operand_a_i[7:0]}});
assign shuffle_r1_in = shuffle_reg1_sel[1] ?
{{8{operand_a_i[31]}}, {8{operand_a_i[23]}}, {8{operand_a_i[15]}}, {8{operand_a_i[7]}}} :
(shuffle_reg1_sel[0] ? operand_c_i : operand_b_i);
assign shuffle_r0[31:24] = shuffle_byte_sel[3][1] ?
(shuffle_byte_sel[3][0] ? shuffle_r0_in[31:24] : shuffle_r0_in[23:16]) :
(shuffle_byte_sel[3][0] ? shuffle_r0_in[15: 8] : shuffle_r0_in[ 7: 0]);
assign shuffle_r0[23:16] = shuffle_byte_sel[2][1] ?
(shuffle_byte_sel[2][0] ? shuffle_r0_in[31:24] : shuffle_r0_in[23:16]) :
(shuffle_byte_sel[2][0] ? shuffle_r0_in[15: 8] : shuffle_r0_in[ 7: 0]);
assign shuffle_r0[15: 8] = shuffle_byte_sel[1][1] ?
(shuffle_byte_sel[1][0] ? shuffle_r0_in[31:24] : shuffle_r0_in[23:16]) :
(shuffle_byte_sel[1][0] ? shuffle_r0_in[15: 8] : shuffle_r0_in[ 7: 0]);
assign shuffle_r0[ 7: 0] = shuffle_byte_sel[0][1] ?
(shuffle_byte_sel[0][0] ? shuffle_r0_in[31:24] : shuffle_r0_in[23:16]) :
(shuffle_byte_sel[0][0] ? shuffle_r0_in[15: 8] : shuffle_r0_in[ 7: 0]);
assign shuffle_r1[31:24] = shuffle_byte_sel[3][1] ?
(shuffle_byte_sel[3][0] ? shuffle_r1_in[31:24] : shuffle_r1_in[23:16]) :
(shuffle_byte_sel[3][0] ? shuffle_r1_in[15: 8] : shuffle_r1_in[ 7: 0]);
assign shuffle_r1[23:16] = shuffle_byte_sel[2][1] ?
(shuffle_byte_sel[2][0] ? shuffle_r1_in[31:24] : shuffle_r1_in[23:16]) :
(shuffle_byte_sel[2][0] ? shuffle_r1_in[15: 8] : shuffle_r1_in[ 7: 0]);
assign shuffle_r1[15: 8] = shuffle_byte_sel[1][1] ?
(shuffle_byte_sel[1][0] ? shuffle_r1_in[31:24] : shuffle_r1_in[23:16]) :
(shuffle_byte_sel[1][0] ? shuffle_r1_in[15: 8] : shuffle_r1_in[ 7: 0]);
assign shuffle_r1[ 7: 0] = shuffle_byte_sel[0][1] ?
(shuffle_byte_sel[0][0] ? shuffle_r1_in[31:24] : shuffle_r1_in[23:16]) :
(shuffle_byte_sel[0][0] ? shuffle_r1_in[15: 8] : shuffle_r1_in[ 7: 0]);
assign shuffle_result[31:24] = shuffle_reg_sel[3] ? shuffle_r1[31:24] : shuffle_r0[31:24];
assign shuffle_result[23:16] = shuffle_reg_sel[2] ? shuffle_r1[23:16] : shuffle_r0[23:16];
assign shuffle_result[15: 8] = shuffle_reg_sel[1] ? shuffle_r1[15: 8] : shuffle_r0[15: 8];
assign shuffle_result[ 7: 0] = shuffle_reg_sel[0] ? shuffle_r1[ 7: 0] : shuffle_r0[ 7: 0];
assign pack_result[31:24] = shuffle_through[3] ? shuffle_result[31:24] : operand_c_i[31:24];
assign pack_result[23:16] = shuffle_through[2] ? shuffle_result[23:16] : operand_c_i[23:16];
assign pack_result[15: 8] = shuffle_through[1] ? shuffle_result[15: 8] : operand_c_i[15: 8];
assign pack_result[ 7: 0] = shuffle_through[0] ? shuffle_result[ 7: 0] : operand_c_i[ 7: 0];
`endif // MATH_SPECIAL_SUPPORT
/////////////////////////////////////////////////////////////////////
@ -768,79 +368,6 @@ module riscv_alu
// |_| //
/////////////////////////////////////////////////////////////////////
// CONFIG_REGION: MATH_SPECIAL_SUPPORT
`ifdef MATH_SPECIAL_SUPPORT
logic [31:0] ff_input; // either op_a_i or its bit reversed version
logic [5:0] cnt_result; // population count
logic [5:0] clb_result; // count leading bits
logic [4:0] ff1_result; // holds the index of the first '1'
logic ff_no_one; // if no ones are found
logic [4:0] fl1_result; // holds the index of the last '1'
logic [5:0] bitop_result; // result of all bitop operations muxed together
alu_popcnt alu_popcnt_i
(
.in_i ( operand_a_i ),
.result_o ( cnt_result )
);
always_comb
begin
ff_input = 'x;
case (operator_i)
ALU_FF1: ff_input = operand_a_i;
ALU_DIVU,
ALU_REMU,
ALU_FL1: ff_input = operand_a_rev;
ALU_DIV,
ALU_REM,
ALU_CLB: begin
if (operand_a_i[31])
ff_input = operand_a_neg_rev;
else
ff_input = operand_a_rev;
end
endcase
end
alu_ff alu_ff_i
(
.in_i ( ff_input ),
.first_one_o ( ff1_result ),
.no_ones_o ( ff_no_one )
);
// special case if ff1_res is 0 (no 1 found), then we keep the 0
// this is done in the result mux
assign fl1_result = 5'd31 - ff1_result;
assign clb_result = ff1_result - 5'd1;
always_comb
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
if (ff_no_one) begin
if (operand_a_i[31])
bitop_result = 6'd31;
else
bitop_result = '0;
end else begin
bitop_result = clb_result;
end
end
default:;
endcase
end
`endif // MATH_SPECIAL_SUPPORT
////////////////////////////////////////////////
@ -852,30 +379,6 @@ module riscv_alu
// |_| //
////////////////////////////////////////////////
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
logic extract_is_signed;
logic extract_sign;
logic [31:0] bmask_first, bmask_inv;
logic [31:0] bextins_and;
logic [31:0] bextins_result, bclr_result, bset_result;
// construct bit mask for insert/extract/bclr/bset
// bmask looks like this 00..0011..1100..00
assign bmask_first = {32'hFFFFFFFE} << bmask_a_i;
assign bmask = (~bmask_first) << bmask_b_i;
assign bmask_inv = ~bmask;
assign bextins_and = (operator_i == ALU_BINS) ? operand_c_i : {32{extract_sign}};
assign extract_is_signed = (operator_i == ALU_BEXT);
assign extract_sign = extract_is_signed & shift_result[bmask_a_i];
assign bextins_result = (bmask & shift_result) | (bextins_and & bmask_inv);
assign bclr_result = operand_a_i & bmask_inv;
assign bset_result = operand_a_i | bmask;
`endif // BIT_SUPPORT
////////////////////////////////////////////////////
// ____ _____ __ __ ____ _____ __ __ //
@ -887,53 +390,6 @@ module riscv_alu
////////////////////////////////////////////////////
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
logic [31:0] result_div;
logic div_ready;
logic div_signed;
logic div_op_a_signed;
logic div_op_b_signed;
logic [5:0] div_shift_int;
assign div_signed = operator_i[0];
assign div_op_a_signed = operand_a_i[31] & div_signed;
assign div_op_b_signed = operand_b_i[31] & div_signed;
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);
// inputs A and B are swapped
riscv_alu_div div_i
(
.Clk_CI ( clk ),
.Rst_RBI ( rst_n ),
// input IF
.OpA_DI ( operand_b_i ),
.OpB_DI ( shift_left_result ),
.OpBShift_DI ( div_shift ),
.OpBIsZero_SI ( (cnt_result == 0) ),
.OpBSign_SI ( div_op_a_signed ),
.OpCode_SI ( operator_i[1:0] ),
.Res_DO ( result_div ),
// Hand-Shake
.InVld_SI ( div_valid ),
.OutRdy_SI ( ex_ready_i ),
.OutVld_SO ( div_ready )
);
`endif // MUL_SUPPORT
////////////////////////////////////////////////////////
// ____ _ _ __ __ //
@ -961,19 +417,7 @@ module riscv_alu
ALU_SRL, ALU_SRA,
ALU_ROR: result_o = shift_result;
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
// bit manipulation instructions
ALU_BINS,
ALU_BEXT,
ALU_BEXTU: result_o = bextins_result;
ALU_BCLR: result_o = bclr_result;
ALU_BSET: result_o = bset_result;
`endif // BIT_SUPPORT
// CONFIG_REGION: MATH_SPECIAL_SUPPORT
`ifdef MATH_SPECIAL_SUPPORT
// pack and shuffle operations
ALU_SHUF, ALU_SHUF2,
ALU_PCKLO, ALU_PCKHI,
@ -986,7 +430,6 @@ module riscv_alu
ALU_ABS: result_o = result_minmax;
ALU_CLIP, ALU_CLIPU: result_o = clip_result;
`endif // MATH_SPECIAL_SUPPORT
// Comparison Operations
ALU_EQ, ALU_NE,
@ -1002,28 +445,13 @@ module riscv_alu
ALU_SLTS, ALU_SLTU,
ALU_SLETS, ALU_SLETU: result_o = {31'b0, comparison_result_o};
// CONFIG_REGION: MATH_SPECIAL_SUPPORT
`ifdef MATH_SPECIAL_SUPPORT
ALU_FF1, ALU_FL1, ALU_CLB, ALU_CNT: result_o = {26'h0, bitop_result[5:0]};
`endif // MATH_SPECIAL_SUPPORT
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// Division Unit Commands
ALU_DIV, ALU_DIVU,
ALU_REM, ALU_REMU: result_o = result_div;
`endif // MUL_SUPPORT
default: ; // default case to suppress unique warning
endcase
end
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
assign ready_o = div_ready;
`else
assign ready_o = 1'b1;
`endif // MUL_SUPPORT
endmodule

View file

@ -34,10 +34,7 @@ module riscv_alu_simplified
input logic [31:0] operand_a_i,
input logic [31:0] operand_b_i,
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
output logic [31:0] adder_result_o,
`endif // LSU_ADDER_SUPPORT
output logic [31:0] result_o,
output logic comparison_result_o
@ -117,10 +114,7 @@ module riscv_alu_simplified
// actual adder
assign adder_result = adder_in_a + adder_in_b;
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
assign adder_result_o = adder_result;
`endif // LSU_ADDER_SUPPORT
////////////////////////////////////////
// ____ _ _ ___ _____ _____ //

View file

@ -35,10 +35,7 @@ module riscv_alu_simplified_splitted
input logic [31:0] operand_b_i,
input logic req_i,
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
output logic [31:0] adder_result_o,
`endif // LSU_ADDER_SUPPORT
output logic ready_o,
output logic [31:0] result_o,
@ -130,10 +127,7 @@ module riscv_alu_simplified_splitted
assign adder_result = {adder_partial_result_n[15:0], adder_partial_result_Q[15:0]};
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
assign adder_result_o = adder_result;
`endif // LSU_ADDER_SUPPORT
////////////////////////////////////////
// ____ _ _ ___ _____ _____ //

View file

@ -31,12 +31,7 @@ import riscv_defines::*;
module riscv_controller
#(
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter REG_ADDR_WIDTH = 4
`else
parameter REG_ADDR_WIDTH = 5
`endif // RV32E
)
(
input logic clk,
@ -54,10 +49,6 @@ module riscv_controller
input logic rega_used_i, // register A is used
input logic regb_used_i, // register B is used
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
input logic regc_used_i, // register C is used
`endif // THREE_PORT_REG_FILE
// from IF/ID pipeline
input logic instr_valid_i, // instruction coming from IF/ID pipeline is valid
@ -72,17 +63,9 @@ module riscv_controller
// LSU
input logic data_req_ex_i, // data memory access is currently performed in EX stage
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
input logic data_misaligned_i,
`endif // ONLY_ALIGNED
input logic data_load_event_i,
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// from ALU
input logic mult_multicycle_i, // multiplier is taken multiple cycles and uses op c as storage
`endif // MUL_SUPPORT
// jump/branch signals
input logic branch_taken_ex_i, // branch taken signal from EX ALU
@ -108,10 +91,6 @@ module riscv_controller
// Forwarding signals from regfile
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
input logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_ex_i, // FW: write address from EX stage
`endif // THREE_PORT_REG_FILE
input logic regfile_we_ex_i, // FW: write enable from EX stage
input logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_wb_i, // FW: write address from WB stage
input logic regfile_we_wb_i, // FW: write enable from WB stage
@ -122,51 +101,20 @@ module riscv_controller
// forwarding signals
output logic [1:0] operand_a_fw_mux_sel_o, // regfile ra data selector form ID stage
output logic [1:0] operand_b_fw_mux_sel_o, // regfile rb data selector form ID stage
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
output logic [1:0] operand_c_fw_mux_sel_o, // regfile rc data selector form ID stage
`endif // THREE_PORT_REG_FILE
// forwarding detection signals
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
input logic reg_d_ex_is_reg_a_i,
input logic reg_d_ex_is_reg_b_i,
input logic reg_d_ex_is_reg_c_i,
input logic reg_d_wb_is_reg_a_i,
input logic reg_d_wb_is_reg_b_i,
input logic reg_d_wb_is_reg_c_i,
input logic reg_d_alu_is_reg_a_i,
input logic reg_d_alu_is_reg_b_i,
input logic reg_d_alu_is_reg_c_i,
`else
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
input logic reg_d_wb_is_reg_a_i,
input logic reg_d_wb_is_reg_b_i,
`else
input logic reg_d_wb_is_reg_a_i,
input logic reg_d_wb_is_reg_b_i,
input logic reg_d_alu_is_reg_a_i,
input logic reg_d_alu_is_reg_b_i,
`endif // MERGE_ID_EX
`endif // THREE_PORT_REG_FILE
// stall signals
output logic halt_if_o,
output logic halt_id_o,
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
output logic misaligned_stall_o,
`endif // ONLY_ALIGNED
output logic jr_stall_o,
output logic load_stall_o,
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
output logic branch_2nd_stage_o,
`endif
input logic id_ready_i, // ID stage is ready
@ -181,29 +129,13 @@ module riscv_controller
);
// FSM state encoding
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
DECODE, BRANCH_2ND_STAGE,
FLUSH_WB,
DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns;
`else
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
DECODE,
FLUSH_EX, FLUSH_WB,
DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns;
`endif
`else
enum logic [3:0] { RESET, BOOT_SET, SLEEP, FIRST_FETCH,
DECODE, WAIT_JUMP_EX,
FLUSH_EX, FLUSH_WB,
DBG_SIGNAL, DBG_SIGNAL_SLEEP, DBG_WAIT, DBG_WAIT_BRANCH, DBG_WAIT_SLEEP } ctrl_fsm_cs, ctrl_fsm_ns;
`endif
logic jump_done, jump_done_q;
@ -256,10 +188,7 @@ module riscv_controller
halt_id_o = 1'b0;
dbg_ack_o = 1'b0;
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
branch_2nd_stage_o = 1'b0;
`endif
unique case (ctrl_fsm_cs)
@ -339,8 +268,6 @@ module riscv_controller
begin
is_decoding_o = 1'b0;
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
// decode and execute instructions only if the current conditional
// branch in the EX stage is either not taken, or there is no
// conditional branch in the EX stage
@ -351,8 +278,6 @@ module riscv_controller
// handle conditional branches
if ((jump_in_dec_i == BRANCH_COND) & branch_taken_ex_i & id_ready_i) begin
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
halt_if_o = 1'b1;
//halt_id_o = 1'b1;
ctrl_fsm_ns = BRANCH_2ND_STAGE;
@ -375,31 +300,6 @@ module riscv_controller
end
*/
`else
// there is a branch in the EX stage that is taken
pc_mux_o = PC_BRANCH;
pc_set_o = 1'b1;
// if we want to debug, flush the pipeline
// the current_pc_if will take the value of the next instruction to
// be executed (NPC)
if (ext_req_i) begin
pc_mux_o = PC_EXCEPTION;
pc_set_o = 1'b1;
exc_ack_o = 1'b1;
exc_save_takenbranch_o = 1'b1;
// we don't have to change our current state here as the prefetch
// buffer is automatically invalidated, thus the next instruction
// that is served to the ID stage is the one of the jump to the
// exception handler
end
if (dbg_req_i)
begin
ctrl_fsm_ns = DBG_SIGNAL;
end
`endif
end
else begin
@ -487,195 +387,9 @@ module riscv_controller
`else // MERGE_ID_EX
// decode and execute instructions only if the current conditional
// branch in the EX stage is either not taken, or there is no
// conditional branch in the EX stage
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
if (instr_valid_i && (~branch_taken_ex_i) && ex_valid_i)
`else
if (instr_valid_i && (~branch_taken_ex_i))
`endif
begin // now analyze the current instruction in the ID stage
is_decoding_o = 1'b1;
// handle unconditional jumps
// 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
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
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
pc_set_o = 1'b1;
jump_done = 1'b1;
end
// we don't have to change our current state here as the prefetch
// buffer is automatically invalidated, thus the next instruction
// that is served to the ID stage is the one of the jump target
`else
halt_if_o = 1'b1;
// if there is a jr stall, wait for it to be gone
if (id_ready_i && (~jr_stall_o) && (~jump_done_q)) begin
ctrl_fsm_ns = WAIT_JUMP_EX;
end
`endif
end else begin
// handle exceptions
if (exc_req_i) begin
pc_mux_o = PC_EXCEPTION;
pc_set_o = 1'b1;
exc_ack_o = 1'b1;
exc_save_id_o = 1'b1;
// we don't have to change our current state here as the prefetch
// buffer is automatically invalidated, thus the next instruction
// that is served to the ID stage is the one of the jump to the
// exception handler
end
end
if (eret_insn_i) begin
pc_mux_o = PC_ERET;
exc_restore_id_o = 1'b1;
if ((~jump_done_q)) begin
pc_set_o = 1'b1;
jump_done = 1'b1;
end
end
// handle WFI instruction, flush pipeline and (potentially) go to
// sleep
// also handles eret when the core should go back to sleep
if (pipe_flush_i || (eret_insn_i && (~fetch_enable_i)))
begin
halt_if_o = 1'b1;
halt_id_o = 1'b1;
ctrl_fsm_ns = FLUSH_EX;
end
else if (dbg_req_i)
begin
// take care of debug
// branch conditional will be handled in next state
// halt pipeline immediately
halt_if_o = 1'b1;
// 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)
ctrl_fsm_ns = DBG_WAIT_BRANCH;
else
ctrl_fsm_ns = DBG_SIGNAL;
end else if (data_load_event_i) begin
// special case for p.elw
// If there was a load event (which means p.elw), we go to debug
// even though we are still blocked
// we don't have to distuinguish between branch and non-branch,
// since the p.elw sits in the EX stage
ctrl_fsm_ns = DBG_SIGNAL;
end
end
end
if (~instr_valid_i && (~branch_taken_ex_i))
begin
if (ext_req_i) begin
pc_mux_o = PC_EXCEPTION;
pc_set_o = 1'b1;
exc_ack_o = 1'b1;
halt_id_o = 1'b1; // we don't want to propagate this instruction to EX
exc_save_if_o = 1'b1;
// we don't have to change our current state here as the prefetch
// buffer is automatically invalidated, thus the next instruction
// that is served to the ID stage is the one of the jump to the
// exception handler
end
end
// TODO: make sure this is not done multiple times in a row (RI5CY)!!!
// maybe with an assertion?
// handle conditional branches
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
if (branch_taken_ex_i & ex_valid_i) begin
`else
if (branch_taken_ex_i) begin
`endif
// there is a branch in the EX stage that is taken
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
// if we want to debug, flush the pipeline
// the current_pc_if will take the value of the next instruction to
// be executed (NPC)
if (ext_req_i) begin
pc_mux_o = PC_EXCEPTION;
pc_set_o = 1'b1;
exc_ack_o = 1'b1;
halt_id_o = 1'b1; // we don't want to propagate this instruction to EX
exc_save_takenbranch_o = 1'b1;
// we don't have to change our current state here as the prefetch
// buffer is automatically invalidated, thus the next instruction
// that is served to the ID stage is the one of the jump to the
// exception handler
end
if (dbg_req_i)
begin
ctrl_fsm_ns = DBG_SIGNAL;
end
end
`endif // MERGE_ID_EX
end
// CONFIG_REGION: JUMP_IN_ID
`ifndef JUMP_IN_ID
// a jump was in ID and now has to be applied to IF from EX
WAIT_JUMP_EX:
begin
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
if (ex_valid_i) begin
pc_mux_o = PC_JUMP;
pc_set_o = 1'b1;
jump_done = 1'b1;
ctrl_fsm_ns = DECODE;
end
else
halt_if_o = 1'b1;
`else
pc_mux_o = PC_JUMP;
pc_set_o = 1'b1;
jump_done = 1'b1;
ctrl_fsm_ns = DECODE;
`endif
end
`endif // JUMP_IN_ID
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
BRANCH_2ND_STAGE:
begin
// there is a branch in the EX stage that is taken
@ -706,23 +420,7 @@ module riscv_controller
ctrl_fsm_ns = DBG_SIGNAL;
end
end
`endif // NO_JUMP_ADDER
`else
// a branch was in ID when a debug trap is hit
DBG_WAIT_BRANCH:
begin
halt_if_o = 1'b1;
if (branch_taken_ex_i) begin
// there is a branch in the EX stage that is taken
pc_mux_o = PC_BRANCH;
pc_set_o = 1'b1;
end
ctrl_fsm_ns = DBG_SIGNAL;
end
`endif
// now we can signal to the debugger that our pipeline is empty and it
// can examine our current state
@ -776,18 +474,6 @@ module riscv_controller
end
end
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
// flush the pipeline, insert NOP into EX stage
FLUSH_EX:
begin
halt_if_o = 1'b1;
halt_id_o = 1'b1;
if (ex_valid_i)
ctrl_fsm_ns = FLUSH_WB;
end
`endif
// flush the pipeline, insert NOP into EX and WB stage
FLUSH_WB:
@ -841,25 +527,6 @@ module riscv_controller
deassert_we_o = 1'b1;
// Stall because of load operation
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if ((data_req_ex_i == 1'b1) && (regfile_we_ex_i == 1'b1) &&
((reg_d_ex_is_reg_a_i == 1'b1) || (reg_d_ex_is_reg_b_i == 1'b1) || (reg_d_ex_is_reg_c_i == 1'b1)) )
begin
deassert_we_o = 1'b1;
load_stall_o = 1'b1;
end
`else
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
if ((data_req_ex_i == 1'b1) && (regfile_we_ex_i == 1'b1) &&
((reg_d_alu_is_reg_a_i == 1'b1) || (reg_d_alu_is_reg_b_i == 1'b1)) )
begin
deassert_we_o = 1'b1;
load_stall_o = 1'b1;
end
`endif // MERGE_ID_EX
`endif // THREE_PORT_REG_FILE
// Stall because of jr path
@ -867,42 +534,15 @@ module riscv_controller
// we don't care about in which state the ctrl_fsm is as we deassert_we
// anyway when we are not in DECODE
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
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))) )
begin
jr_stall_o = 1'b1;
deassert_we_o = 1'b1;
end
`else
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
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_alu_is_reg_a_i == 1'b1)) ||
((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_a_i == 1'b1))) )
begin
jr_stall_o = 1'b1;
deassert_we_o = 1'b1;
end
`else
if ((jump_in_dec_i == BRANCH_JALR) && (regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_a_i == 1'b1))
begin
jr_stall_o = 1'b1;
deassert_we_o = 1'b1;
end
`endif
`endif // THREE_PORT_REG_FILE
end
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
// stall because of misaligned data access
assign misaligned_stall_o = data_misaligned_i;
`endif // ONLY_ALIGNED
// Forwarding control unit
@ -911,25 +551,9 @@ module riscv_controller
// default assignements
operand_a_fw_mux_sel_o = SEL_REGFILE;
operand_b_fw_mux_sel_o = SEL_REGFILE;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
operand_c_fw_mux_sel_o = SEL_REGFILE;
`endif // THREE_PORT_REG_FILE:
// Forwarding WB -> ID
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
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;
if (reg_d_wb_is_reg_b_i == 1'b1)
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;
end
`else
if (regfile_we_wb_i == 1'b1)
begin
if (reg_d_wb_is_reg_a_i == 1'b1)
@ -937,51 +561,16 @@ module riscv_controller
if (reg_d_wb_is_reg_b_i == 1'b1)
operand_b_fw_mux_sel_o = SEL_FW_WB;
end
`endif // THREE_PORT_REG_FILE
// Forwarding EX -> ID
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
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;
if (reg_d_alu_is_reg_b_i == 1'b1)
operand_b_fw_mux_sel_o = SEL_FW_EX;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if (reg_d_alu_is_reg_c_i == 1'b1)
operand_c_fw_mux_sel_o = SEL_FW_EX;
`endif // THREE_PORT_REG_FILE
end
`endif // MERGE_ID_EX
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
// for misaligned memory accesses
if (data_misaligned_i)
begin
operand_a_fw_mux_sel_o = SEL_MISALIGNED;
operand_b_fw_mux_sel_o = SEL_REGFILE;
end
`else
// 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;
end
`endif
`endif // ONLY_ALIGNED
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
else if (mult_multicycle_i) begin
operand_c_fw_mux_sel_o = SEL_FW_EX;
end
`endif
end
// update registers
@ -1011,13 +600,6 @@ module riscv_controller
// Assertions
//----------------------------------------------------------------------------
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
// make sure that taken branches do not happen back-to-back, as this is not
// possible without branch prediction in the IF stage
assert property (
@(posedge clk) (branch_taken_ex_i) |=> (~branch_taken_ex_i) ) else $warning("Two branches back-to-back are taken");
`endif // NO_JUMP_ADDER
assert property (
@(posedge clk) (~(dbg_req_i & ext_req_i)) ) else $warning("Both dbg_req_i and ext_req_i are active");

View file

@ -35,11 +35,6 @@ import riscv_defines::*;
module riscv_cs_registers
#(
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
parameter N_HWLP = 2,
parameter N_HWLP_BITS = $clog2(N_HWLP),
`endif // HWLP_SUPPORT
parameter N_EXT_CNT = 0
)
(
@ -65,10 +60,6 @@ module riscv_cs_registers
input logic [31:0] pc_if_i,
input logic [31:0] pc_id_i,
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
input logic [31:0] pc_ex_i,
`endif
input logic [31:0] branch_target_i,
input logic data_load_event_ex_i,
input logic exc_save_if_i,
@ -79,17 +70,6 @@ module riscv_cs_registers
input logic [5:0] exc_cause_i,
input logic save_exc_cause_i,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// Hardware loops
input logic [N_HWLP-1:0] [31:0] hwlp_start_i,
input logic [N_HWLP-1:0] [31:0] hwlp_end_i,
input logic [N_HWLP-1:0] [31:0] hwlp_cnt_i,
output logic [31:0] hwlp_data_o,
output logic [N_HWLP_BITS-1:0] hwlp_regid_o,
output logic [2:0] hwlp_we_o,
`endif // HWLP_SUPPORT
// Performance Counters
input logic id_valid_i, // ID stage is done
@ -176,16 +156,6 @@ module riscv_cs_registers
// mhartid: unique hardware thread id
12'hF10: csr_rdata_int = {21'b0, cluster_id_i[5:0], 1'b0, core_id_i[3:0]};
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// hardware loops
12'h7B0: csr_rdata_int = hwlp_start_i[0];
12'h7B1: csr_rdata_int = hwlp_end_i[0];
12'h7B2: csr_rdata_int = hwlp_cnt_i[0];
12'h7B4: csr_rdata_int = hwlp_start_i[1];
12'h7B5: csr_rdata_int = hwlp_end_i[1];
12'h7B6: csr_rdata_int = hwlp_cnt_i[1];
`endif // HWLP_SUPPORT
12'h7C0: csr_rdata_int = {29'b0, 2'b11, mestatus_q};
endcase
@ -199,11 +169,6 @@ module riscv_cs_registers
mestatus_n = mestatus_q;
mstatus_n = mstatus_q;
exc_cause_n = exc_cause;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
hwlp_we_o = '0;
hwlp_regid_o = '0;
`endif // HWLP_SUPPORT
case (csr_addr_i)
// mstatus: IE bit
@ -214,16 +179,6 @@ module riscv_cs_registers
// mcause
12'h342: if (csr_we_int) exc_cause_n = {csr_wdata_int[5], csr_wdata_int[4:0]};
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// hardware loops
12'h7B0: if (csr_we_int) begin hwlp_we_o = 3'b001; hwlp_regid_o = 1'b0; end
12'h7B1: if (csr_we_int) begin hwlp_we_o = 3'b010; hwlp_regid_o = 1'b0; end
12'h7B2: if (csr_we_int) begin hwlp_we_o = 3'b100; hwlp_regid_o = 1'b0; end
12'h7B4: if (csr_we_int) begin hwlp_we_o = 3'b001; hwlp_regid_o = 1'b1; end
12'h7B5: if (csr_we_int) begin hwlp_we_o = 3'b010; hwlp_regid_o = 1'b1; end
12'h7B6: if (csr_we_int) begin hwlp_we_o = 3'b100; hwlp_regid_o = 1'b1; end
`endif // HWLP_SUPPORT
// mestatus: machine exception status
12'h7C0: if (csr_we_int) mestatus_n = csr_wdata_int[0];
@ -235,12 +190,7 @@ module riscv_cs_registers
mstatus_n = 1'b0;
if (data_load_event_ex_i) begin
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
mepc_n = pc_id_i;
`else
mepc_n = pc_ex_i;
`endif
end else if (exc_save_takenbranch_i) begin
mepc_n = branch_target_i;
end else begin
@ -259,10 +209,6 @@ module riscv_cs_registers
end
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign hwlp_data_o = csr_wdata_int;
`endif // HWLP_SUPPORT
// CSR operation logic
always_comb

View file

@ -25,12 +25,7 @@ import riscv_defines::*;
module riscv_debug_unit
#(
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter REG_ADDR_WIDTH = 4
`else
parameter REG_ADDR_WIDTH = 5
`endif // RV32E
)
(
input logic clk,
@ -78,10 +73,6 @@ module riscv_debug_unit
// Signals for PPC & NPC register
input logic [31:0] pc_if_i,
input logic [31:0] pc_id_i,
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
input logic [31:0] pc_ex_i,
`endif
input logic data_load_event_i,
input logic instr_valid_id_i,
@ -437,25 +428,13 @@ module riscv_debug_unit
end
IFEX: begin
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
ppc_int = pc_ex_i;
npc_int = pc_id_i;
`else
ppc_int = pc_id_i;
npc_int = pc_if_i;
`endif
end
IDEX: begin
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
ppc_int = pc_ex_i;
npc_int = pc_id_i;
`else
ppc_int = pc_id_i;
npc_int = pc_if_i;
`endif
if (jump_req_o)

File diff suppressed because it is too large Load diff

View file

@ -1,97 +0,0 @@
ROOT_DIR = .
CONTENT_SRC = content
MAIN_SRC = datasheet
FIG_DIR = figures
FIG_RAW_DIR = figures_raw
# Get only the path to the Tgif source files.
TGIF_SRCS = $(wildcard $(ROOT_DIR)/$(FIG_RAW_DIR)/*.obj)
TGIF_SRCS_NAMES = $(basename $(TGIF_SRCS))
# Get only the path to the Tgif destination files.
TGIF_DEST = $(wildcard $(ROOT_DIR)/$(FIG_DIR)/*.obj)
TGIF_DEST_NAMES = $(basename $(TGIF_SRCS))
# Derive the file names for the resulting EPS and PDF file names for
# the TGIF sources.
TGIF_OUTP_NAMES = $(addprefix $(ROOT_DIR)/$(FIG_DIR)/, $(notdir $(TGIF_SRCS_NAMES)))
TGIF_OUTP_EPS_NAMES = $(addsuffix .eps, $(TGIF_OUTP_NAMES))
TGIF_OUTP_PDF_NAMES = $(addsuffix .pdf, $(TGIF_OUTP_NAMES))
######################################################################
##### #
##### Main Targets #
##### #
######################################################################
do: pdf
all: figures pdf
make -B pdf
make -B pdf
pdf: $(MAIN_SRC).pdf
%.pdf: %.tex $(CONTENT_SRC) preamble/preamble.tex
pdflatex $(MAIN_SRC).tex
clean: clean-figures
@echo "***** Cleaning the LaTeX directory structure."
@rm -rf $(ROOT_DIR)/*.acr $(ROOT_DIR)/*.alg $(ROOT_DIR)/*.bbl
@rm -rf $(ROOT_DIR)/*.blg $(ROOT_DIR)/*.glg $(ROOT_DIR)/*.gls
@rm -rf $(ROOT_DIR)/*.aux $(ROOT_DIR)/*.glo $(ROOT_DIR)/*.ist
@rm -rf $(ROOT_DIR)/*.lof $(ROOT_DIR)/*.log $(ROOT_DIR)/*.lot
@rm -rf $(ROOT_DIR)/*.toc $(ROOT_DIR)/*.acn $(ROOT_DIR)/*.out
@rm -rf $(ROOT_DIR)/*.tex~ $(ROOT_DIR)/*.tex.backup
@rm -rf $(ROOT_DIR)/*.fdb_latexmk $(ROOT_DIR)/*.fls
@rm -rf $(ROOT_DIR)/Makefile~ $(ROOT_DIR)/pso.conv-*
@rm -rf $(ROOT_DIR)/auto
@rm -rf $(ROOT_DIR)/content/*.tex~ $(ROOT_DIR)/content/*.aux
@rm -rf $(ROOT_DIR)/content/*.log $(ROOT_DIR)/content/auto
@rm -rf $(ROOT_DIR)/content/*.tex.backup
@rm -rf $(ROOT_DIR)/content/*.fdb_latexmk $(ROOT_DIR)/content/*.fls
@rm -rf $(ROOT_DIR)/glossaries/*.tex~ $(ROOT_DIR)/glossaries/auto
@rm -rf $(ROOT_DIR)/preamble/auto $(ROOT_DIR)/preamble/*.tex~
@rm -rf $(ROOT_DIR)/preamble/*.log
@rm -rf $(ROOT_DIR)/bib/auto $(ROOT_DIR)/bib/*.bib~
@rm -rf $(ROOT_DIR)/bib/*.bib.backup
@rm -rf $(ROOT_DIR)/*.mtc* $(ROOT_DIR)/*.maf
######################################################################
##### #
##### Sub Targets #
##### #
######################################################################
figures: tgif_figures
tgif_figures: $(TGIF_OUTP_PDF_NAMES)
$(TGIF_OUTP_PDF_NAMES): $(ROOT_DIR)/$(FIG_DIR)/%.pdf : $(ROOT_DIR)/$(FIG_RAW_DIR)/%.obj
@echo "*****"
@echo "***** Printing Tgif figure:"
@echo "***************************"
@echo "***** $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.eps"
@tgif -print -epsi -color -quiet $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.obj
@echo "*****"
@echo "***** Converting Tgif EPS to PDF:"
@echo "*********************************"
@echo "***** $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.eps --> $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.pdf"
@epstopdf $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.eps
@echo "*****"
@echo "***** Moving EPS and PDF figures"
@echo "********************************"
@echo "***** $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.eps --> $(ROOT_DIR)/$(FIG_DIR)/$*.eps"
@echo "***** $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.pdf --> $(ROOT_DIR)/$(FIG_DIR)/$*.pdf"
-@mv $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.eps $(ROOT_DIR)/$(FIG_DIR)/
-@mv $(ROOT_DIR)/$(FIG_RAW_DIR)/$*.pdf $(ROOT_DIR)/$(FIG_DIR)/
@echo "*****"
clean-tgif-figures:
-@rm -f $(TGIF_OUTP_EPS_NAMES) $(TGIF_OUTP_PDF_NAMES)
clean-figures: clean-tgif-figures

View file

@ -1,453 +0,0 @@
\chapter{PULP ALU Extensions}
\label{chap:aluext}
\rvcore supports advanced ALU operations that allow to perform multiple
instructions that are specified in the base instruction set in one single
instruction and thus increases efficiency of the core.
For example those instructions include zero-/sign-extension instructions for
8-bit and 16-bit operands, simple bit manipulation/counting instructions and
min/max/avg instructions.
\section{Instructions}
\subsection{p.avg rD, rs1, rs2}
Performs an arithmetic right shift after the addition of rs1 and rs2.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 000 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = (rs1 + rs2) >> 1}
\subsection{p.avgu rD, rs1, rs2}
Performs a logical right shift after the addition of rs1 and rs2.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 001 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = (rs1 + rs2) >> 1}
\subsection{p.slet rD, rs1, rs2}
Performs an signed smaller than or equal comparison between rs1 and rs2.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 010 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = (rs1 <= rs2) ? -1 : 0}
\subsection{p.sletu rD, rs1, rs2}
Performs an unsigned smaller than or equal comparison between rs1 and rs2.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 011 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = (rs1 <= rs2) ? -1 : 0}
\subsection{p.min rD, rs1, rs2}
Sets rD to the minimum of rs1 and rs2, assuming both are signed 32-bit values.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 100 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = rs1 < rs2 ? rs1 : rs2}
\subsection{p.minu rD, rs1, rs2}
Sets rD to the minimum of rs1 and rs2, assuming both are unsigned 32-bit
values.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 101 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = rs1 < rs2 ? rs1 : rs2}
\subsection{p.max rD, rs1, rs2}
Sets rD to the maximum of rs1 and rs2, assuming both are signed 32-bit values.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 110 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = rs1 > rs2 ? rs1 : rs2}
\subsection{p.maxu rD, rs1, rs2}
Sets rD to the maximum of rs1 and rs2, assuming both are unsigned 32-bit
values.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0010}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 111 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = rs1 > rs2 ? rs1 : rs2}
\subsection{p.abs rD, rs1}
Computes the absolute value of the signed 32-bit operand rs1.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1010}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 000 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = rs1 < 0 ? -rs1 : rs1}
\subsection{p.ror rD, rs1, rs2}
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0100}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 101 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = RotateRight(rs1, rs2)}
\subsection{p.exths rD, rs1}
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 100 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Sext(rs1[15:0])}
\subsection{p.exthz rD, rs1}
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 101 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Zext(rs1[15:0])}
\subsection{p.extbs rD, rs1}
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 110 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Sext(rs1[7:0])}
\subsection{p.extbz rD, rs1}
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 111 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Zext(rs1[7:0])}
\subsection{p.ff1 rD, rs1}
Returns position of first bit that is \texttt{1} starting from LSB, 32 if none.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 000 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = FindFirst1(rs1)}
\subsection{p.fl1 rD, rs1}
Returns position of first bit that is \texttt{1} starting from MSB, 32 if none.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 001 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = FindLast1(rs1)}
\subsection{p.clb rD, rs1}
Count leading bits in rs1, i.e. the number of consecutive \texttt{1} or
\texttt{0} bits from MSB.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 010 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = CountLeadingBits(rs1)}
\subsection{p.cnt rD, rs1}
Count the number of bits set to \texttt{1} in rs1. This is also known as
population count.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ 00000 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 011 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = PopCount(rs1)}

View file

@ -1,122 +0,0 @@
\chapter{Control and Status Registers}
\label{chap:csr}
\rvcore does not implement all control and status registers specified in the
\riscv privileged specifications, but is limited to the registers that were
needed for the PULP system.
The reason for this is that we wanted to keep the footprint of the core as low
as possible and avoid any overhead that we do not explicitely need.
\begin{landscape}
\begin{table}[H]
\caption{Control and Status Register Map}
\label{tab:csr_map}
\centering\begin{tabularx}{\linewidth}{@{}|cccc|c|l|l|X|@{}} \toprule
\multicolumn{4}{|c|}{\textbf{CSR Address}} & \textbf{Hex} & \textbf{Name} & \textbf{Access} & \textbf{Description} \\ \hline
\textbf{[11:10]} & \textbf{[9:8]} & \textbf{[7:6]} & \textbf{[5:0]} & & & & \\ \toprule
00 & 11 & 00 & 000000 & 0x300 & MSTATUS & R/W & Machine Status Register \\ \hline
00 & 11 & 01 & 000001 & 0x341 & MEPC & R/W & Machine exception program counter \\ \hline
00 & 11 & 01 & 000010 & 0x342 & MCAUSE & R/W & Machine trap cause \\ \hline
01 & 11 & 00 & 0XXXXX & 0x780 - 0x79F & PCCRs & R/W & Performance Counter Counter Registers \\ \hline
01 & 11 & 10 & 100000 & 0x7A0 & PCER & R/W & Performance Counter Enable Register \\ \hline
01 & 11 & 10 & 100001 & 0x7A1 & PCMR & R/W & Performance Counter Mode Register \\ \hline
01 & 11 & 10 & 110XXX & 0x7B0 - 0x7B6 & HWLP & R/W & Hardware Loop Registers \\ \hline
01 & 11 & 10 & 111000 & 0x7C0 & MESTATUS & R/W & Machine exception Status Register \\ \hline
11 & 11 & 00 & 000000 & 0xF00 & MCPUID & R & CPU description \\ \hline
11 & 11 & 00 & 000001 & 0xF01 & MIMPID & R & Vendor ID and version number \\ \hline
11 & 11 & 00 & 010000 & 0xF10 & MHARTID & R & Hardware Thread ID \\ \bottomrule
\end{tabularx}
\end{table}
\end{landscape}
\section{Register Description}
\subsection{MSTATUS}
\csrDesc{0x300}{0x0000\_0006}{MSTATUS}{
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,2,1,0} \\
\bitbox{29}{ Unused }
\bitbox{2}{\rotatebox{90}{\tiny PRV[1:0] }}
\bitbox{1}{\rotatebox{90}{\tiny Interrupt Enable }}
\end{bytefield}
}
Note that \signal{PRV[1:0]} is statically \signal{2'b11} and cannot be altered (read-only).
When en exception is encountered, \signal{Interrupt Enable} will be set to
\signal{1'b0}. When the \signal{eret} instruction is executed, the original
value of \signal{Interrupt Enable} will be restored, as \signal{MESTATUS} will
replace \signal{MSTATUS}.
If you want to enable interrupt handling in your exception hanlder, set the
\signal{Interrupt Enable} to \signal{1'b1} inside your handler code.
\subsection{MESTATUS}
\csrDesc{0x7C0}{0x0000\_0006}{MESTATUS}{
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,2,1,0} \\
\bitbox{29}{ Unused }
\bitbox{2}{\rotatebox{90}{\tiny PRV[1:0] }}
\bitbox{1}{\rotatebox{90}{\tiny Interrupt Enable }}
\end{bytefield}
}
Note that \signal{PRV[1:0]} is statically \signal{2'b11} and cannot be altered (read-only).
When an exception is encountered, the current value of \signal{MSTATUS} is saved
in \signal{MESTATUS}. When an \instr{eret} instruction is executed, the value
from \signal{MESTATUS} replaces the \signal{MSTATUS} register.
\subsection{MEPC}
\csrDesc{0x341}{0x0000\_0000}{MEPC}{
\begin{bytefield}[endianness=big]{32}
\bitheader{31,0} \\
\bitbox{32}{ mepc }
\end{bytefield}
}
When an exception is encountered, the current program counter is saved in
\signal{MEPC}, and the core jumps to the exception address. When an \instr{eret}
instruction is executed, the value from \signal{MEPC} replaces the current
program counter.
\subsection{MCAUSE}
\csrDesc{0x341}{0x0000\_0000}{MCAUSE}{
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,30,4,0} \\
\bitbox{1}{\rotatebox{90}{\tiny Interrupt }}
\bitbox{27}{ Unused }
\bitbox{5}{\rotatebox{90}{\tiny Exception Code }}
\end{bytefield}
}
\subsection{MCPUID}
\csrDesc{0xF00}{0x0000\_0100}{MCPUID}{
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,29,26,25,0} \\
\bitbox{2}{\rotatebox{90}{\tiny Base }}
\bitbox{4}{ 0 }
\bitbox{26}{ Extensions }
\end{bytefield}
}
\subsection{MIMPID}
\csrDesc{0xF01}{0x0000\_8000}{MIMPID}{
\begin{bytefield}[endianness=big]{32}
\bitheader{31,16,15,0} \\
\bitbox{16}{ Implementation }
\bitbox{16}{ Source }
\end{bytefield}
}
\subsection{MHARTID}
\csrDesc{0xF10}{Defined}{MHARTID}{
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,9,5,4,0} \\
\bitbox{22}{ Unused }
\bitbox{5}{\rotatebox{90}{\tiny Cluster ID }}
\bitbox{5}{\rotatebox{90}{\tiny Core ID }}
\end{bytefield}
}
Both \signal{core id} and \signal{cluster id} are set on the top-level module
of the core and are read-only.

View file

@ -1,89 +0,0 @@
\chapter{Debug}
\label{chap:debug}
\rvcore has full support for software breakpoints (\instr{ebreak}), access to
general-purpose and control and status registers via a debug port. It is also
possible to halt the core from the debug port and put it into single-stepping
mode. Similarly when an interrupt occurs, instead of jumping to the interrupt
handler the core can trap to an attached debugger.
The debug port uses the following interface:
\begin{table}[H]
\caption{Debug Signals}
\label{tab:debug_signals}
\begin{tabularx}{\textwidth}{@{}llX@{}} \toprule
\textbf{Signal} & \textbf{Direction} & \textbf{Description} \\ \toprule
\signal{dbginf\_strobe\_i} & \textbf{input} & Command request \\ \hline
\signal{dbginf\_we\_i} & \textbf{input} & Write Enable \\ \hline
\signal{dbginf\_addr\_i[15:0]} & \textbf{input} & Address \\ \hline
\signal{dbginf\_data\_i[31:0]} & \textbf{input} & Input data \\ \hline
\signal{dbginf\_data\_o} & \textbf{output} & Output data \\ \hline
\signal{dbginf\_ack\_o} & \textbf{output} & Command was executed \\ \hline
\signal{dbginf\_stall\_i} & \textbf{input} & Stall the core \\ \hline
\signal{dbginf\_bp\_o} & \textbf{output} & Breakpoint hit \\ \bottomrule
\end{tabularx}
\end{table}
This interface is natively supported by the advanced debug bridge that is used
by \pulp and \pulpino, see also the documentation of this bridge.
\section{Debug Address Map}
This debug address map is not optimal and should be changed!
See the OpenSoC debug project for a proposal for a better address map.
\begin{table}[H]
\caption{Control and Status Register Map}
\label{tab:debug_map}
\centering\begin{tabularx}{\linewidth}{@{}|cc|c|l|X|@{}} \toprule
\multicolumn{2}{|c|}{\textbf{Dbginf Addr [15:0]}} & \textbf{Hex} & \textbf{Name} & \textbf{Description} \\ \hline
Grp [15:11] & Addr [10:0] & & & \\ \toprule
\texttt{0\_0001} & \texttt{000\_000X\_XXXX} & \texttt{0x0800 - 0x081F} & GPR & General-Purpose Registers \\ \hline
\texttt{0\_0110} & \texttt{000\_0000\_0000} & \texttt{0x3000 - 0x3014} & Debug & Debug Registers \\ \hline
\texttt{?\_????} & \texttt{XXX\_XXXX\_XXXX} & \texttt{ } & CSR & Everything else is mapped to CSR \\ \bottomrule
\end{tabularx}
\end{table}
\subsection{Debug Register: DMR1}
\textbf{CSR Address:} \texttt{0x3010} \\
\textbf{Reset Value:} \texttt{0x0000\_0000} \\
\begin{figure}[H]
\centering
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,23,22,0} \\
\bitbox{9}{ Unused }
\bitbox{1}{\rotatebox{90}{\tiny Single-Stepping }}
\bitbox{22}{ Unused }
\end{bytefield}
\caption{DMR1}
\end{figure}
Single-stepping activates single-stepping mode, meaning the core traps to the
debugger after one instruction has been executed.
\subsection{Debug Register: DSR}
\textbf{CSR Address:} \texttt{0x3014} \\
\textbf{Reset Value:} \texttt{0x0000\_0000} \\
\begin{figure}[H]
\centering
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,8,7,6,0} \\
\bitbox{24}{ Unused }
\bitbox{1}{\rotatebox{90}{\tiny INTE }}
\bitbox{1}{\rotatebox{90}{\tiny IIE }}
\bitbox{6}{ Unused }
\end{bytefield}
\caption{DMR1}
\end{figure}
\signal{IIE} stands for illegal instruction exception enabled. A value of
\signal{1} means trap to the debugger when an illegal instruction is
encountered.
\signal{INTE} stands for interrupt enabled. A value of \signal{1} means trap to
the debugger when an interrupt is encountered.

View file

@ -1,66 +0,0 @@
\chapter{Exceptions and Interrupts}
\label{chap:exceptions}
\rvcore supports vectorized interrupts, exceptions on illegal instructions and
exceptions on load and store instructions to invalid addresses.
\begin{table}[H]
\caption{Interrupt/exception offset vector table}
\label{tab:exc_table}
\centering\begin{tabular}{@{}ll@{}} \toprule
\textbf{Address} & \textbf{Description} \\ \toprule
\signal{0x00} - \signal{0x0000\_007C} & Interrupts 0 - 31 \\ \hline
\signal{0x80} & Reset \\ \hline
\signal{0x84} & Illegal Instruction \\ \hline
\signal{0x88} & \instr{ECALL} instruction executed \\ \hline
\signal{0x8C} & LSU error (invalid memory access) \\ \bottomrule
\end{tabular}
\end{table}
The instruction addresses in Table~\ref{tab:exc_table} are considered as an
offset to the boot address given to the core. Specifically the core jumps to
address \signal{$\{$boot\_addr[31:8], offset[7:0]$\}$} when encountering an
exception/interrupt.
\section{Interrupts}
\rvcore uses vectorized interrupts, specifically it provides 32 separate
interrupt lines. Interrupts can only be enabled/disabled on a global basis and
not individually. It is assumed that there is an event/interrupt controller
outside of the core that performs masking and buffering of the interrupt lines.
The global interrupt enable is done via the CSR register \signal{MSTATUS}.
If multiple interrupts arrive in the same cycle, the interrupt with the lowest
number will be executed first. As soon as IRQs are re-enabled, either after an
\signal{eret} or an explicit enable, the interrupt with lowest number will be
executed.
This means that it is important to clear the interrupt line before re-enabling
interrupts, as otherwise the same interrupt handler could be called over and
over again.
\section{Exceptions}
The illegal instruction exception, the load and store invalid memory access
exceptions and ecall instruction exceptions can not be disabled and are always
active.
The illegal instruction exception and the load and store invalid memory access
exceptions are precise exceptions, i.e. the value of \signal{MEPC} will be the
instruction address that caused it.
\section{Handling}
\rvcore does support nested interrupt/exception handling. Exceptions inside
interrupt/exception handlers cause another exception, thus exceptions during the
critical part of your exception handlers, i.e. before having saved the
\signal{MEPC} and \signal{MESTATUS} registers, will cause those register to be
overwritten.
Interrupts during interrupt/exception handlers are disabled by default, but can
be explicitely enabled if desired.
Upon executing an \instr{eret} instruction, the core jumps to the program
counter saved in the CSR register \signal{MEPC} and restores the value of
register \signal{MESTATUS} to \signal{MSTATUS}. When entering an
interrupt/exception handler, the core sets \signal{MEPC} to the current program
counter and saves the current value of \signal{MSTATUS} in \signal{MESTATUS}.

View file

@ -1,191 +0,0 @@
\chapter{PULP Hardware Loop Extensions}
\label{chap:hwloop}
For increased efficiency of small loops, RI5CY supports hardware loops.
Hardware loops make it possible to execute a piece of code multiple times,
without the overhead of branches or updating a counter. Hardware loops involve
zero stall cycles for jumping to the first instruction of a loop.
A hardware loop is defined by its start address (pointing to the first
instruction in the loop), its end address (pointing to the instruction that
will be executed last in the loop) and a counter that is decremented every time
the loop body is executed. RI5CY contains two hardware loop register sets, each
of them can store these three values.
If the end address of the two hardware loops is identical, loop 0 has higher
priority and only the loop counter for hardware loop 0 is decremented.
As soon as the counter of loop 0 reaches 1 at an end address, meaning it is
decremented to 0 now, loop 1 gets active too. In this case, both counters will
be decremented and the core jumps to the start of loop 1.
The instructions described below are used to setup the hardware loop registers.
Note that the minimum loop size is two instructions.
For debugging and context switches the hardware loop registers are mapped into
the CSR address space and thus it is possible to read and write them via
\instr{csrr} and \instr{csrw} instructions.
\section{Instructions}
\subsection{lp.starti L, uimmL}
Sets the start address of a hardware loop.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ uimmL[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{4}{ 0000 }
\bitbox{1}{ L }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ uimmL[11:0] }
\bitbox[]{5}{ 00000 }
\bitbox[]{3}{ 000 }
\bitbox[]{4}{ 0000 }
\bitbox[]{1}{ L }
\bitbox[]{7}{ 111 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{lpstart[L] = pc + (Zext(uimmL[11:0]) << 1)}
\subsection{lp.endi L, uimmL}
Sets the end address of a hardware loop.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ uimmL[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{4}{ 0000 }
\bitbox{1}{ L }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ uimmL[11:0] }
\bitbox[]{5}{ 00000 }
\bitbox[]{3}{ 001 }
\bitbox[]{4}{ 0000 }
\bitbox[]{1}{ L }
\bitbox[]{7}{ 111 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{lpend[L] = pc + (Zext(uimmL[11:0]) << 1)}
\subsection{lp.count L, rs1}
Sets the number of iterations of a hardware loop.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ uimmL[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{4}{ 0000 }
\bitbox{1}{ L }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ 0000 0000 0000}
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 010 }
\bitbox[]{4}{ 0000 }
\bitbox[]{1}{ L }
\bitbox[]{7}{ 111 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{lpcount[L] = rs1}
\subsection{lp.counti L, uimmL}
Sets the number of iterations of a hardware loop.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ uimmL[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{4}{ 0000 }
\bitbox{1}{ L }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ uimmL[11:0] }
\bitbox[]{5}{ 00000 }
\bitbox[]{3}{ 011 }
\bitbox[]{4}{ 0000 }
\bitbox[]{1}{ L }
\bitbox[]{7}{ 111 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{lpcount[L] = Zext(uimmL[11:0])}
\subsection{lp.setup L, rs1, uimmL}
Sets up a hardware loop in one instruction. This instruction assumes that the
next instruction is the start address of the loop.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ uimmL[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{4}{ 0000 }
\bitbox{1}{ L }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ uimmL[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 100 }
\bitbox[]{4}{ 0000 }
\bitbox[]{1}{ L }
\bitbox[]{7}{ 111 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{lpstart[L] = pc + 4; lpend[L] = pc + Zext(uimmL[11:0]); lpcount[L] = rs1}
\subsection{lp.setupi L, uimmS, uimmL}
Sets up a hardware loop in one instruction. This instruction assumes that the
next instruction is the start address of the loop. The number of iterations is
given as an immediate.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ uimmL[11:0] }
\bitbox{5}{ uimmS }
\bitbox{3}{ funct3 }
\bitbox{4}{ 0000 }
\bitbox{1}{ L }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ uimmL[11:0] }
\bitbox[]{5}{ uimmS }
\bitbox[]{3}{ 101 }
\bitbox[]{4}{ 0000 }
\bitbox[]{1}{ L }
\bitbox[]{7}{ 111 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{lpstart[L] = pc + 4; lpend[L] = pc + Zext(uimmL[11:0]); lpcount[L] = Zext(uimmS)}
\section{CSR Mapping}
\begin{table}[H]
\caption{Control and Status Register Map}
\centering\begin{tabularx}{\linewidth}{@{}|cc|c|l|l|X|@{}} \toprule
\multicolumn{2}{|c|}{\textbf{CSR Address}} & \textbf{Hex} & \textbf{Name} & \textbf{Access} & \textbf{Description} \\ \hline
\textbf{[11:6]} & \textbf{[5:0]} & & & & \\ \toprule
011110 & 110000 & 0x7B0 & lpstart[0] & R/W & Hardware Loop 0 Start \\ \hline
011110 & 110001 & 0x7B1 & lpend[0] & R/W & Hardware Loop 0 End \\ \hline
011110 & 110010 & 0x7B2 & lpcount[0] & R/W & Hardware Loop 0 Counter \\ \hline
011110 & 110100 & 0x7B4 & lpstart[1] & R/W & Hardware Loop 1 Start \\ \hline
011110 & 110101 & 0x7B5 & lpend[1] & R/W & Hardware Loop 1 End \\ \hline
011110 & 110110 & 0x7B6 & lpcount[1] & R/W & Hardware Loop 1 Counter \\ \bottomrule
\end{tabularx}
\end{table}

View file

@ -1,41 +0,0 @@
\chapter{Instruction Fetch}
\label{chap:if}
The instruction fetcher of the core is able to supply one instruction to the ID
stage per cycle if the instruction cache or the instruction memory is able to
serve one instruction after one cycle.
The instruction address must be half-word-aligned. It is not possible to jump to
instruction addresses that have the LSB bit set.
For optimal performance and timing closure reasons, a prefetcher is used to
fetch instructions. There are two prefetch flavors available:
\begin{itemize}
\item 32-Bit Word prefetcher. It stores the fetched words in a FIFO with three
entries.
\item 128-Bit Cache line prefetcher. It stores one 128-bit wide cache line
plus 32-bit to allow for cross-cache line misaligned instructions.
\end{itemize}
Table~\ref{tab:instr_signals} describes the signals that are used to fetch
instructions. This interface is a simplified version that is used by the
LSU that is described in Chapter~\ref{chap:lsu}. The difference is that no
writes are possible and thus it needs less signals.
\begin{table}[H]
\caption{Instruction Fetch Signals}
\label{tab:instr_signals}
\begin{tabularx}{\textwidth}{@{}llX@{}} \toprule
\textbf{Signal} & \textbf{Direction} & \textbf{Description} \\ \toprule
\signal{instr\_req\_o} & \textbf{output} & Request ready, must stay high until \signal{instr\_gnt\_i} is high for one cycle \\ \hline
\signal{instr\_addr\_o[31:0]} & \textbf{output} & Address \\ \hline
\signal{instr\_rdata\_i[31:0]} & \textbf{input} & Data read from memory \\ \hline
\signal{instr\_rvalid\_i} & \textbf{input} & \signal{instr\_rdata\_i} is valid now for this cycle. When \signal{instr\_rvalid\_i} is high, another request can be sent. \\ \hline
\signal{instr\_gnt\_i} & \textbf{input} & The instruction cache accepted the request. The \signal{instr\_addr\_o} may be change in the next cylce. \\ \bottomrule
\end{tabularx}
\end{table}
\section{Protocol}
The protocol used to communicate with the instruction cache or the instruction
memory is the same as the protocl used by the LSU. See the description of the
LSU in Chapter~\ref{sec:lsu_protocol} for details about the protocol.

View file

@ -1,543 +0,0 @@
\chapter{Load-Store-Unit (LSU)}
\label{chap:lsu}
The LSU of the core takes care of accessing the data memory. Load and stores on
words (32 bit), half words (16 bit) and bytes (8 bit) are supported.
Table~\ref{tab:lsu_signals} describes the signals that are used by the LSU.
\begin{table}[H]
\caption{LSU Signals}
\label{tab:lsu_signals}
\begin{tabularx}{\textwidth}{@{}llX@{}} \toprule
\textbf{Signal} & \textbf{Direction} & \textbf{Description} \\ \toprule
\signal{data\_req\_o} & \textbf{output} & Request ready, must stay high until \signal{data\_gnt\_i} is high for one cycle \\ \hline
\signal{data\_addr\_o[31:0]} & \textbf{output} & Address, sent together with \signal{data\_req\_o} \\ \hline
\signal{data\_we\_o} & \textbf{output} & Write Enable, high for writes, low for reads, sent together with \signal{data\_req\_o} \\ \hline
\signal{data\_be\_o[3:0]} & \textbf{output} & Byte Enable, is set for the bytes to write/read, sent together with \signal{data\_req\_o} \\ \hline
\signal{data\_wdata\_o[31:0]} & \textbf{output} & Data to be written to memory, sent together with \signal{data\_req\_o} \\ \hline
\signal{data\_rdata\_i[31:0]} & \textbf{input} & Data read from memory, valid when \signal{data\_rvalid\_i} is set \\ \hline
\signal{data\_rvalid\_i} & \textbf{input} & \signal{data\_rdata\_i} is valid. \\ \hline
\signal{data\_gnt\_i} & \textbf{input} & The memory accepted the request, another request can be sent in the next cycle \\ \bottomrule
\end{tabularx}
\end{table}
\section{Misaligned Accesses}
The LSU is able to perform misaligned accesses, meaning accesses that are not
aligned on natural word boundaries. However it needs to perform two separate
word-aligned accesses internally.
This means that at least two cycles are needed for misaligned loads and stores.
\section{Protocol}
\label{sec:lsu_protocol}
The protocol that is used by the LSU to communicate with a memory works as
follows:
The LSU provides a valid address in \signal{data\_addr\_o} and sets
\signal{data\_req\_o} high. The memory then answers with a \signal{data\_gnt\_i}
set high as soon as it is ready to serve the request. This may happen in the
same cycle as the request was sent or any number of cycles later. After a grant
was received, the address may be changed in the next cycle by the LSU. Also the
\signal{data\_wdata\_o}, \signal{data\_we\_o} and \signal{data\_be\_o} signals
may be changed as it is assumed that the memory has already processed and stored that
information. After the grant, the memory answers with a
\signal{data\_rvalid\_i} set high when \signal{data\_rdata\_i} is valid. This
may happen one cycle after the grant was received, but may take any number of
cycles after the grant was received.
Note that \signal{data\_rvalid\_i} must also be set when a write was performed,
although the \signal{data\_rdata\_i} has no meaning in this case.
Figure~\ref{fig:lsu_trans_basic}, Figure~\ref{fig:lsu_trans_b2b} and
Figure~\ref{fig:lsu_trans_slow} show example timing diagrams of the protocol.
\begin{figure}[H]
\centering
\begin{tikztimingtable}
[timing/d/background/.style={fill=white},
timing/lslope=0.1,
xscale=3]
clk & 13{C} \\
data\_addr\_o & UUU 4D{Address} UU UU UU \\
data\_wdata\_o & UUU 4D{WData} UU UU UU \\
data\_req\_o & LLL HH HH LL LL LL \\
data\_gnt\_i & LLL LL HH LL LL LL \\
data\_rvalid\_i & LLL LL LL HH LL LL \\
data\_rdata\_i & UUU UU UU 2D{RData} UU UU \\
data\_we\_o & UUU 4D{WE} UU UU UU \\
data\_be\_o & UUU 4D{BE} UU UU UU \\
\end{tikztimingtable}
\caption{Basic Memory Transaction}
\label{fig:lsu_trans_basic}
\end{figure}
\begin{figure}[H]
\centering
\begin{tikztimingtable}
[timing/d/background/.style={fill=white},
timing/lslope=0.1,
xscale=3]
clk & 13{C} \\
data\_addr\_o & U 2D{Addr1} 2D{Addr2} UU UU UU UU \\
data\_wdata\_o & U 2D{WData1} 2D{Wdata2} UU UU UU UU \\
data\_req\_o & L HH HH LL LL LL LL \\
data\_gnt\_i & L HH HH LL LL LL LL \\
data\_rvalid\_i & L LL HH HH LL LL LL \\
data\_rdata\_i & U UU 2D{RData1} 2D{RData2} UU UU UU\\
data\_we\_o & U 2D{WE1} 2D{WE2} UU UU UU UU \\
data\_be\_o & U 2D{BE1} 2D{BE2} UU UU UU UU \\
\end{tikztimingtable}
\caption{Back to Back Memory Transaction}
\label{fig:lsu_trans_b2b}
\end{figure}
\begin{figure}[H]
\centering
\begin{tikztimingtable}
[timing/d/background/.style={fill=white},
timing/lslope=0.1,
xscale=3]
clk & 13{C} \\
data\_addr\_o & U 6D{Address} UU UU UU \\
data\_wdata\_o & U 6D{WData} UU UU UU \\
data\_req\_o & L HH HH HH LL LL LL \\
data\_gnt\_i & LLL LL HH LL LL LL \\
data\_rvalid\_i & LLL LL LL LL HH UU \\
data\_rdata\_i & UUU UU UU UU 2D{RData} UU \\
data\_we\_o & U 6D{WE} UU UU UU \\
data\_be\_o & U 6D{BE} UU UU UU \\
\end{tikztimingtable}
\caption{Slow Answer Memory Transaction}
\label{fig:lsu_trans_slow}
\end{figure}
\section{Post-Incrementing Load and Store Instructions}
Post-incrementing load and store instructions perform a load/store operation
from/to the data memory while at the same time increasing the base address by
the specified offset. For the memory access the base address without offset is
used.
Post-incrementing load and stores reduce the number of instructions necessary to
execute when running in a loop, i.e. the address increment can be embedded in
the post-increment instructions. Coupled with the hardware loop extension a
significant reduction in the number of instructions necessary to execute small
loops can be achieved.
A description of the individual instructions that were added can be found below.
\subsection{lb rD, imm(rs1!)}
Loads a byte from data memory on the address \texttt{rs1} and saves \texttt{(rs1
+ I)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 000 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Sext(mem[rs1]); rs1 += Sext(imm)}
\subsection{lh rD, imm(rs1!)}
Loads a half-word from data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + I)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 001 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Sext(mem[rs1]); rs1 += Sext(imm)}
\subsection{lw rD, imm(rs1!)}
Loads a word from data memory on the address \texttt{rs1} and saves \texttt{(rs1
+ I)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 010 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = mem[rs1]; rs1 += Sext(imm)}
\subsection{lbu rD, imm(rs1!)}
Loads a byte from data memory on the address \texttt{rs1} and saves \texttt{(rs1
+ I)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 100 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Zext(mem[rs1]); rs1 += Sext(imm)}
\subsection{lhu rD, imm(rs1!)}
Loads a half-word from data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + I)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 101 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Zext(mem[rs1]); rs1 += Sext(imm)}
\subsection{lb rD, rs2(rs1!)}
Loads a byte from data memory on the address \texttt{rs1} and saves \texttt{(rs1
+ rs2)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0000}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 111 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Sext(mem[rs1]); rs1 += rs2}
\subsection{lh rD, rs2(rs1!)}
Loads a half-word from data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + rs2)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 1000}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 111 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Sext(mem[rs1]); rs1 += rs2}
\subsection{lw rD, rs2(rs1!)}
Loads a word from data memory on the address \texttt{rs1} and saves \texttt{(rs1
+ I)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 001 0000}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 111 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = mem[rs1]; rs1 += rs2}
\subsection{lbu rD, rs2(rs1!)}
Loads a byte from data memory on the address \texttt{rs1} and saves \texttt{(rs1
+ rs2)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 010 0000}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 111 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Zext(mem[rs1]); rs1 += rs2}
\subsection{lhu rD, rs2(rs1!)}
Loads a half-word from data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + rs2)} in register \texttt{rs1} after the load has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 010 1000}
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 111 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = Zext(mem[rs1]); rs1 += rs2}
\subsection{sb rs2, imm(rs1!)}
Store a byte to data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + imm)} in register \texttt{rs1} after the store has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 000 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 010 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{mem[rs1] = rs2[7:0]; rs1 += Sext(imm)}
\subsection{sh rs2, imm(rs1!)}
Store a half-word to data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + imm)} in register \texttt{rs1} after the store has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 001 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 010 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{mem[rs1] = rs2[15:0]; rs1 += Sext(imm)}
\subsection{sw rs2, imm(rs1!)}
Store a word to data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + imm)} in register \texttt{rs1} after the store has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{12}{ imm[11:0] }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{12}{ imm[11:0] }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 010 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 010 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{mem[rs1] = rs2[31:0]; rs1 += Sext(imm)}
\subsection{sb rs2, rs3(rs1!)}
Store a byte to data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + rs3)} in register \texttt{rs1} after the store has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{2}{ 00 }
\bitbox{5}{ rs3 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ 00000 }
\bitbox{7}{ opcode } \\
\bitbox[]{2}{ 00 }
\bitbox[]{5}{ src3 }
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 100 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{mem[rs1] = rs2[7:0]; rs1 += rs3}
\subsection{sh rs2, rs3(rs1!)}
Store a half-word to data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + rs3)} in register \texttt{rs1} after the store has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{2}{ 00 }
\bitbox{5}{ rs3 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ 00000 }
\bitbox{7}{ opcode } \\
\bitbox[]{2}{ 00 }
\bitbox[]{5}{ src3 }
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 101 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{mem[rs1] = rs2[15:0]; rs1 += rs3}
\subsection{sw rs2, rs3(rs1!)}
Store a word to data memory on the address \texttt{rs1} and saves
\texttt{(rs1 + rs3)} in register \texttt{rs1} after the store has completed.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{2}{ 00 }
\bitbox{5}{ rs3 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ 00000 }
\bitbox{7}{ opcode } \\
\bitbox[]{2}{ 00 }
\bitbox[]{5}{ src3 }
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 110 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 000 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{mem[rs1] = rs2[31:0]; rs1 += rs3}

View file

@ -1,141 +0,0 @@
\chapter{Multiply-Accumulate}
\label{chap:mac}
\rvcore uses a single-cycle 32-bit $\times$ 32-bit multiplier with a 32-bit
result. Only a subset of the standard M extension is implemented, i.e. the
\instr{mul} instruction. Divisions and multiplications that return the upper
32-bit of the result are not supported.
Specifically the following instruction is supported:
\begin{itemize}
\item \instr{mul}
\end{itemize}
The following instructions are \textbf{not} supported:
\begin{itemize}
\item \instr{mulh}
\item \instr{mulhs}
\item \instr{mulhu}
\item \instr{div}
\item \instr{divu}
\item \instr{rem}
\item \instr{remu}
\end{itemize}
Instead \rvcore supports non-standard extensions for multiply-accumulate and
half-word multiplications.
\section{Instructions}
\subsection{p.mul rD, rs1, rs2}
Multiply on 32-bit $\times$ 32-bit with a 32-bit result.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,30,29,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0001 }
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 000 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = rs1 * rs2}
\subsection{p.mac rD, rs1, rs2}
Multiply-Accumulate on 32-bit $\times$ 32-bit with a 32-bit result.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,30,29,25,24,20,19,15,14,12,11,7,6,0} \\
\bitbox{7}{ funct7 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{3}{ funct3 }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{7}{ 000 0001 }
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{3}{ 001 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 011 0011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD += rs1 * rs2}
\subsection{p.mul\{s,hhs,u,hhu\} rD, rs1, rs2}
Multiply-Accumulate on 16-bit $\times$ 16-bit with a 32-bit result. The
half-word and sign-mode that is used for the multiplication can be selected.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,30,29,25,24,20,19,15,14,13,12,11,7,6,0} \\
\bitbox{1}{ S }
\bitbox{1}{ P }
\bitbox{5}{ imm5 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{1}{ R }
\bitbox{2}{ subop }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{1}{ S }
\bitbox[]{1}{ P }
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{1}{ 0 }
\bitbox[]{2}{ 00 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 101 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD = rs1[P*16+15:P*16] * rs2[P*16+15:P*16]}
S determines the zero/sign-extension of rs1 and rs2. A value of \texttt{1} means
sign-extension.
\subsection{p.mac\{s,hhs,u,hhu\} rD, rs1, rs2}
Multiply-Accumulate on 16-bit $\times$ 16-bit with a 32-bit result. The
half-word and sign-mode that is used for the multiplication can be selected.
\begin{center}
\begin{bytefield}[endianness=big,bitwidth=1.3em]{32}
\bitheader{31,30,29,25,24,20,19,15,14,13,12,11,7,6,0} \\
\bitbox{1}{ S }
\bitbox{1}{ P }
\bitbox{5}{ imm5 }
\bitbox{5}{ rs2 }
\bitbox{5}{ rs1 }
\bitbox{1}{ R }
\bitbox{2}{ subop }
\bitbox{5}{ rd }
\bitbox{7}{ opcode } \\
\bitbox[]{1}{ S }
\bitbox[]{1}{ P }
\bitbox[]{5}{ 00000 }
\bitbox[]{5}{ src2 }
\bitbox[]{5}{ src1 }
\bitbox[]{1}{ 0 }
\bitbox[]{2}{ 01 }
\bitbox[]{5}{ dest }
\bitbox[]{7}{ 101 1011 }
\end{bytefield}
\end{center}
\textbf{Operation:} \texttt{rD += rs1[P*16+15:P*16] * rs2[P*16+15:P*16]}
S determines the zero/sign-extension of rs1 and rs2. A value of \texttt{1} means
sign-extension.

View file

@ -1,47 +0,0 @@
\chapter{Overview}
\rvcore is a 4-stage in-order \riscv CPU. The ISA of \rvcore was extended to
also support multiple additional instructions including hardware loops,
post-increment load and store instructions and additional ALUinstructions that
are not part of the standard \riscv ISA.
Figure~\ref{fig:ri5cy_overview} shows a block diagram of the core.
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{./figures/ri5cy_overview}
\caption{\rvcore Overview.}
\label{fig:ri5cy_overview}
\end{figure}
\section{Supported Instruction Set}
\rvcore supports the following instructions:
\begin{itemize}
\item Full support for RV32I Base Integer Instruction Set
\item Full support for RV32C Standard Extension for Compressed Instructions
\item Partial support for RV32M Standard Extension for Integer Multiplication
and Division \\
Only the \instr{mul} instruction is supported.
\item PULP specific extensions \\
\begin{itemize}
\item Post-Incrementing load and stores, see Chapter~\ref{chap:lsu}
\item Multiply-Accumulate extensions, see Chapter~\ref{chap:mac}
\item ALU extensions, see Chapter~\ref{chap:aluext}
\item Hardware Loops, see Chapter~\ref{chap:hwloop}
\end{itemize}
\end{itemize}
\section{ASIC Synthesis}
ASIC synthesis is supported for \rvcore. The whole design is completely
synchronous and uses positive-edge triggered flip-flops, except for the register
file, where there is an option to use latches instead of flip-flops. See
Chapter~\ref{chap:rf} for more details about the register file. The core
occupies an area of about 35~kGE when the latch based register file is used.
\section{FPGA Synthesis}
FPGA synthesis is supported for \rvcore when the flip-flop based register file
is used. Since latches are not well supported on FPGAs, it is crucial to select
the flip-flop based register file.

View file

@ -1,119 +0,0 @@
\chapter{Performance Counters}
\label{chap:perf_count}
Performance Counters in \rvcore are placed inside the Control and Status
Registers and can be accessed with \instr{csrr} and \instr{csrw} instructions.
See Table~\ref{tab:csr_map} for the address map of the performance counter
registers.
\section{Performance Counter Mode Register (PCMR)}
\csrDesc{0x7A1}{0x0000\_0003}{PCMR}{
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,1,0} \\
\bitbox{30}{ Unused }
\bitbox{1}{\rotatebox{90}{\tiny Saturation }}
\bitbox{1}{\rotatebox{90}{\tiny Global Enable }}
\end{bytefield}
}
The \instr{Global Enable} bit controls all performance counters, i.e. if it is
set to \instr{0}, all performance counters are deactivated. After reset, the
\instr{Global Enable} bit is set.
The \instr{Saturation} bit controls saturation behaviour of the performance
counters. If it is set, saturating arithmetic is used. After reset, the
\instr{Saturation} bit is set.
\section{Performance Counter Event Register (PCER)}
\csrDesc{0x7A0}{0x0000\_0000}{PCER}{
\begin{bytefield}[endianness=big,bitheight=60pt]{32}
\bitheader{31,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0} \\
\bitbox{1}{\rotatebox{90}{\tiny (ALL) }}
\bitbox{14}{ Unused }
\bitbox{1}{\rotatebox{90}{\tiny TCDM CONT }}
\bitbox{1}{\rotatebox{90}{\tiny ST\_EXT\_CYC }}
\bitbox{1}{\rotatebox{90}{\tiny LD\_EXT\_CYC }}
\bitbox{1}{\rotatebox{90}{\tiny ST\_EXT }}
\bitbox{1}{\rotatebox{90}{\tiny LD\_EXT }}
\bitbox{1}{\rotatebox{90}{\tiny DELAY\_SLOT }}
\bitbox{1}{\rotatebox{90}{\tiny BRANCH }}
\bitbox{1}{\rotatebox{90}{\tiny JUMP }}
\bitbox{1}{\rotatebox{90}{\tiny ST }}
\bitbox{1}{\rotatebox{90}{\tiny LD }}
\bitbox{1}{\rotatebox{90}{\tiny WBRANCH\_CYC }}
\bitbox{1}{\rotatebox{90}{\tiny WBRANCH }}
\bitbox{1}{\rotatebox{90}{\tiny IMISS }}
\bitbox{1}{\rotatebox{90}{\tiny JMP\_STALL }}
\bitbox{1}{\rotatebox{90}{\tiny LD\_STALL }}
\bitbox{1}{\rotatebox{90}{\tiny INSTR }}
\bitbox{1}{\rotatebox{90}{\tiny CYCLES }}
\end{bytefield}
}
Each bit in the PCER register controls one performance counter. If the bit is
1, the counter is enabled and starts counting events. If it is 0, the counter
is disabled and its value won't change.
In the ASIC there is only one counter register, thus all counter events are
masked by PCER are ORed together, i.e. if one of the enabled event happens,
the counter will be increased. If multiple non-masked events happen at the same
time, the counter will only be increased by one.
In the FPGA or Simulation version each event has its own counter and can be
accesses separately.
\section{Performance Counter Counter Registers (PCCR0-31)}
\csrDesc{0x780 - 0x79F}{0x0000\_0000}{PCCR0-31}{
\begin{bytefield}[endianness=big]{32}
\bitheader{31,0} \\
\bitbox{32}{Unsigned integer counter value}
\end{bytefield}
}
PCCR registers support both saturating and wrap-around arithmetic. This is
controlled by the \instr{saturation} bit in PCMR.
\begin{table}[H]
\begin{tabularx}{\textwidth}{@{}llX@{}} \toprule
\textbf{Reg Name} & \textbf{Name} & Description \\ \toprule
\textbf{PCCR0} & \textbf{CYCLES} & Count the number of cycles the core was running \\ \hline
\textbf{PCCR1} & \textbf{INSTR} & Count the number of instructions executed \\ \hline
\textbf{PCCR2} & \textbf{LD\_STALL} & Number of load data hazards \\ \hline
\textbf{PCCR3} & \textbf{JR\_STALL} & Number of jump register data hazards \\ \hline
\textbf{PCCR4} & \textbf{IMISS} & Cycles waiting for instruction fetches. i.e. the number of instructions wasted due to non-ideal caches \\ \hline
\textbf{PCCR5} & \textbf{LD} & Number of memory loads executed. Misaligned accesses are counted twice \\ \hline
\textbf{PCCR6} & \textbf{ST} & Number of memory stores executed. Misaligned accesses are counted twice \\ \hline
\textbf{PCCR7} & \textbf{JUMP} & Number of jumps (j, jal, jr, jalr)\\ \hline
\textbf{PCCR8} & \textbf{BRANCH} & Number of branches, counts taken and not taken branches\\ \hline
\textbf{PCCR9} & \textbf{BTAKEN} & Number of taken branches \\ \hline
\textbf{PCCR10} & \textbf{RVC} & Number of compressed instructions executed \\ \hline
\textbf{PCCR11} & \textbf{LD\_EXT} & Number of memory loads to EXT executed. Misaligned accesses are counted twice. Every non-TCDM access is considered external (PULP only) \\ \hline
\textbf{PCCR12} & \textbf{ST\_EXT} & Number of memory stores to EXT executed. Misaligned accesses are counted twice. Every non-TCDM access is considered external (PULP only) \\ \hline
\textbf{PCCR13} & \textbf{LD\_EXT\_CYC} & Cycles used for memory loads to EXT. Every non-TCDM access is considered external (PULPY only) \\ \hline
\textbf{PCCR14} & \textbf{ST\_EXT\_CYC} & Cycles used for memory stores to EXT. Every non-TCDM access is considered external (PULPY only) \\ \hline
\textbf{PCCR15} & \textbf{TCDM\_CONT} & Cycles wasted due to TCDM/log-interconnect contention (PULPY only) \\ \hline
\textbf{PCCR31} & \textbf{ALL} & Special Register, a write to this register will set all counters to the supplied value\\ \bottomrule
\end{tabularx}
\end{table}
In the FPGA, RTL simulation and Virtual-Platform there are individual counters
for each event type, i.e. PCCR0-30 each represent a separate register.
To save area in the ASIC, there is only one counter and one counter register.
Accessing PCCR0-30 will access the same counter register in the ASIC.
Reading/writing from/to PCCR31 in the ASIC will access the same register as
PCCR0-30.
Figure~\ref{fig:events} shows how events are first masked with the PCER register
and then ORed together to increase the one performance counter PCCR.
\begin{figure}[H]
\centering
\includegraphics[width=0.5\textwidth]{./figures/events}
\caption{Events and PCCR, PCMR and PCER on the ASIC.}
\label{fig:events}
\end{figure}

View file

@ -1,44 +0,0 @@
\chapter{Pipeline}
\label{chap:pipeline}
\rvcore has a fully independent pipeline, meaning that whenever possible data
will propagate through the pipeline and therefor does not suffer from any
unneeded stalls.
The pipeline design is easily extendable to incorporate out-of-order
completion. E.g. it would be possible to complete an instruction that only
needs the EX stage before the WB stage, that is currently blocked waiting for
an rvalid, is ready.
Currently this is not done in \rvcore, but might be added in the future.
Figure~\ref{fig:pipeline} shows the control signals relevant for the pipeline
operation. Running from right to left are the main control signals, the
\signal{ready} signals of each pipeline stage.
Each pipeline stage has two control inputs: an enable and a clear. The enable
activates the pipeline stage and the core moves forward by one instruction. The
clear removes the instruction from the pipeline stage as it is completed.
At every pipeline stage, when the \signal{ready} coming from the stage to the
right is high, but the valid signal of the stage is low, the stage is cleared.
If the valid signal is high, it is enabled.
Going from right to left every stage is independent, no stage depends on the
stage on its left. Going from left to right every stage depends on its right
neighbor and can only continue when it is ready.
This means that in addition that a single stage has to be ready, also the stage
on its right has to be ready to move on.
\begin{figure}[H]
\centering
\includegraphics[width=0.9\textwidth]{./figures/pipeline}
\caption{\rvcore Pipeline.}
\label{fig:pipeline}
\end{figure}
\begin{boxnote}
In contrast to \orion there is no global stall controller any more, instead
every stage manages its own dependencies. The main controller of \rvcore is now
only responsible for control flow operations, i.e. flushing the pipe, branches,
jumps and exceptions.
\end{boxnote}

View file

@ -1,34 +0,0 @@
\chapter{Register File}
\label{chap:rf}
\rvcore has 31 $\times$ 32-bit wide registers which form registers \signal{x1} to
\signal{x31}. Register \signal{x0} is statically bound \signal{0} and can only be
read and not written, it does not contain any sequential logic.
There are two flavors of register file available:
\begin{enumerate}
\item Latch-based
\item Flip-flop based
\end{enumerate}
While the latch-based register file is recommended for ASICs, the flip-flop
based register file is recommended for FPGA synthesis, although both are
compatible with either synthesis target.
Note the flip-flop based register file is significantly larger than the
latch-based register-file for an ASIC implementation.
\section{Latch-based Register File}
The latch based register file contains manually instantiated clock gating cells
to keep the clock inactive when the latches are not written.
It is assumed that there is a clock gating cell for the target technology that
is wrapped in a module called \signal{cluster\_clock\_gating} and has the following
ports:
\begin{itemize}
\item \signal{clk\_i}: Clock Input
\item \signal{en\_i}: Clock Enable Input
\item \signal{test\_en\_i}: Test Enable Input (activates the clock even though
\signal{en\_i} is not set)
\item \signal{clk\_o}: Gated Clock Output
\end{itemize}

View file

@ -1,28 +0,0 @@
\makeatletter
\begin{titlepage}
% Remove the page number in the footer.
\thispagestyle{empty}
\begin{center}
\begin{spacing}{2.0}
{\Huge\textbf{\@title}}
\end{spacing}
\vspace{0.2cm}
\vfill
\includegraphics[height = 8cm]{figures/ri5cy_overview}
\vfill
{\Large \@author}\\
{atraber@iis.ee.ethz.ch}
\vfill
\@date
\end{center}
\end{titlepage}
\makeatother

View file

@ -1,48 +0,0 @@
\documentclass[%
oneside, % Use the same margins for odd and even pages (cannot
% be used with the 'twoside' option).
% twoside, % Use different margins for odd and even pages (cannot
% be used with the 'oneside' option).
openany, % Open chapters on odd and even pages.
halfparskip, % Create small spaces for new paragraphs but no indents.
]{scrbook}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% %
%%%%% Preamble %
%%%%% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Load the preamble from another file.
\input{./preamble/preamble}
%%%%% Mandatory title page settings.
\title{RI5CY Core: Datasheet}
\author{Andreas Traber}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% %
%%%%% Document starts here %
%%%%% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{document}
\input{./content/title.tex}
\tableofcontents
\input{./content/overview.tex}
\input{./content/if.tex}
\input{./content/lsu.tex}
\input{./content/mac.tex}
\input{./content/aluext.tex}
\input{./content/hwloop.tex}
\input{./content/pipeline.tex}
\input{./content/rf.tex}
\input{./content/csr.tex}
\input{./content/perfcounters.tex}
\input{./content/exceptions.tex}
\input{./content/debug.tex}
\end{document}

View file

View file

@ -1,477 +0,0 @@
%TGIF 4.2.5-QPL
state(0,37,100.000,0,0,0,64,1,0,2,2,0,0,0,0,1,1,'Courier',0,57600,0,0,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1050,1485,1,0,5760,0).
%
% @(#)$Header$
% %W%
%
unit("1 pixel/pixel").
color_info(51,65535,0,[
"black", 0, 0, 0, 0, 0, 0, 1,
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
"#F0F0F0", 61680, 61680, 61680, 61440, 61440, 61440, 1,
"#C8C8C8", 51400, 51400, 51400, 51200, 51200, 51200, 1,
"#505050", 20560, 20560, 20560, 20480, 20480, 20480, 1,
"#282828", 10280, 10280, 10280, 10240, 10240, 10240, 1,
"#FF0000", 65535, 0, 0, 65280, 0, 0, 1,
"#0000FF", 0, 0, 65535, 0, 0, 65280, 1,
"#00FF00", 0, 65535, 0, 0, 65280, 0, 1,
"#009000", 0, 37008, 0, 0, 36864, 0, 1,
"#1F407A", 7967, 16448, 31354, 7936, 16384, 31232, 1,
"#3C5A0F", 15420, 23130, 3855, 15360, 23040, 3840, 1,
"#0069B4", 0, 26985, 46260, 0, 26880, 46080, 1,
"#71791C", 29041, 31097, 7196, 28928, 30976, 7168, 1,
"#91056A", 37265, 1285, 27242, 37120, 1280, 27136, 1,
"#6F6F6E", 28527, 28527, 28270, 28416, 28416, 28160, 1,
"#A8322D", 43176, 12850, 11565, 43008, 12800, 11520, 1,
"#007A92", 0, 31354, 37522, 0, 31232, 37376, 1,
"#956013", 38293, 24672, 4883, 38144, 24576, 4864, 1,
"#82BE1E", 33410, 48830, 7710, 33280, 48640, 7680, 1,
"#758fbd", 30069, 36751, 48573, 29952, 36608, 48384, 1,
"#8eab63", 36494, 43947, 25443, 36352, 43776, 25344, 1,
"#6cacd9", 27756, 44204, 55769, 27648, 44032, 55552, 1,
"#b4ba72", 46260, 47802, 29298, 46080, 47616, 29184, 1,
"#c967ae", 51657, 26471, 44718, 51456, 26368, 44544, 1,
"#b8b8b6", 47288, 47288, 46774, 47104, 47104, 46592, 1,
"#d48985", 54484, 35209, 34181, 54272, 35072, 34048, 1,
"#65b9c9", 25957, 47545, 51657, 25856, 47360, 51456, 1,
"#c9a571", 51657, 42405, 29041, 51456, 42240, 28928, 1,
"#bbde81", 48059, 57054, 33153, 47872, 56832, 33024, 1,
"#a5b7d6", 42405, 47031, 54998, 42240, 46848, 54784, 1,
"#b8cc99", 47288, 52428, 39321, 47104, 52224, 39168, 1,
"#a2cbe8", 41634, 52171, 59624, 41472, 51968, 59392, 1,
"#d2d6a5", 53970, 54998, 42405, 53760, 54784, 42240, 1,
"#de9ecc", 57054, 40606, 52428, 56832, 40448, 52224, 1,
"#d4d4d2", 54484, 54484, 53970, 54272, 54272, 53760, 1,
"#e6b5b3", 59110, 46517, 46003, 58880, 46336, 45824, 1,
"#9bd3de", 39835, 54227, 57054, 39680, 54016, 56832, 1,
"#dec6a4", 57054, 50886, 42148, 56832, 50688, 41984, 1,
"#d5ebb0", 54741, 60395, 45232, 54528, 60160, 45056, 1,
"#b3cde3", 46003, 52685, 58339, 45824, 52480, 58112, 1,
"#bae4bc", 47802, 58596, 48316, 47616, 58368, 48128, 1,
"#edf8fb", 60909, 63736, 64507, 60672, 63488, 64256, 1,
"#ffffcc", 65535, 65535, 52428, 65280, 65280, 52224, 1,
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
"#f0f9e8", 61680, 63993, 59624, 61440, 63744, 59392, 1,
"#feebe2", 65278, 60395, 58082, 65024, 60160, 57856, 1,
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
"#fecc5c", 65278, 52428, 23644, 65024, 52224, 23552, 1,
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
"#CCCCCC", 52428, 52428, 52428, 52224, 52224, 52224, 1
]).
script_frac("0.6").
fg_bg_colors('black','white').
dont_reencode("FFDingbests:ZapfDingbats").
objshadow_info('#c0c0c0',2,2).
rotate_pivot(0,0,0,0).
spline_tightness(1).
page(1,"",1,'').
poly('black','',2,[
356,160,356,96],0,1,1,257919,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
box('white','',328,160,368,224,1,1,0,257908,0,0,0,0,0,'1',0,[
]).
poly('black','',2,[
440,160,440,96],0,1,1,257755,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
396,160,396,96],0,1,1,257753,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
group([
poly('#F0F0F0','',6,[
118,74,90,60,150,52,197,53,225,56,256,64],0,1,0,257805,1,1,0,0,0,0,0,'1',0,0,
"78","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('#F0F0F0','',11,[
366,71,375,64,450,65,481,77,481,93,467,100,450,106,416,114,
399,118,352,116,321,109],0,1,0,257804,1,1,0,0,0,0,0,'1',0,0,
"7fc","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('#F0F0F0','',5,[
321,109,312,122,284,130,225,125,214,111],0,1,0,257803,1,1,0,0,0,0,0,'1',0,0,
"70","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('#F0F0F0','',6,[
214,111,205,123,150,133,87,124,62,110,109,96],0,1,0,257802,1,1,0,0,0,0,0,'1',0,0,
"78","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('#F0F0F0','',5,[
113,96,40,94,31,80,62,68,123,74],0,1,0,257801,1,1,0,0,0,0,0,'1',0,0,
"70","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('#F0F0F0','',6,[
256,64,270,57,298,48,352,48,389,63,366,71],0,1,0,257800,1,1,0,0,0,0,0,'1',0,0,
"78","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
box('#F0F0F0','',118,64,312,111,1,1,0,257799,0,0,0,0,0,'1',0,[
]),
box('#F0F0F0','',109,81,164,101,1,1,0,257798,0,0,0,0,0,'1',0,[
]),
box('#F0F0F0','',307,65,371,110,1,1,0,257797,0,0,0,0,0,'1',0,[
])
],
257796,0,0,[
]).
box('white','',408,160,448,224,1,1,0,257762,0,0,0,0,0,'1',0,[
]).
box('white','',368,160,408,224,1,1,0,257756,0,0,0,0,0,'1',0,[
]).
box('black','',64,160,448,224,0,1,1,257660,0,0,0,0,0,'1',0,[
]).
text('black',256,173,1,1,1,92,38,257662,31,7,0,0,0,0,-65534,92,38,0,0,"",0,0,0,0,204,'',[
minilines(92,38,0,0,1,0,0,[
mini_line(92,31,7,0,0,0,[
str_block(0,92,31,7,0,-2,0,0,0,[
str_seg('black','Helvetica',0,195840,92,31,7,0,-2,0,0,0,0,0,
"PCER")])
])
])]).
text('black',448,145,1,1,1,6,13,257665,11,2,0,0,0,0,-65534,6,13,0,0,"",0,0,0,0,156,'',[
minilines(6,13,0,0,1,0,0,[
mini_line(6,11,2,0,0,0,[
str_block(0,6,11,2,0,-1,0,0,0,[
str_seg('black','Helvetica',0,57600,6,11,2,0,-1,0,0,0,0,0,
"0")])
])
])]).
poly('black','',2,[
408,160,408,224],0,1,1,257669,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
368,160,368,224],0,1,1,257670,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',64,145,1,1,1,12,13,257675,11,2,0,0,0,0,-65534,12,13,0,0,"",0,0,0,0,156,'',[
minilines(12,13,0,0,1,0,0,[
mini_line(12,11,2,0,0,0,[
str_block(0,12,11,2,0,-3,0,0,0,[
str_seg('black','Helvetica',0,57600,12,11,2,0,-3,0,0,0,0,0,
"31")])
])
])]).
group([
poly('black','',4,[
416,256,416,240,448,240,448,256],0,1,1,257731,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
424,240,424,224],0,1,1,257730,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
440,240,440,224],0,1,1,257729,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
432,288,432,272],0,1,1,257728,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
arc('black','',0,1,1,0,416,240,432,256,448,256,416,256,1,32,32,0,-11520,257727,0,0,8,3,0,0,0,'1','8','3',0,[
])
],
257726,0,0,[
]).
group([
poly('black','',4,[
372,256,372,240,404,240,404,256],0,1,1,257749,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
380,240,380,224],0,1,1,257748,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
396,240,396,224],0,1,1,257747,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
388,288,388,272],0,1,1,257746,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
arc('black','',0,1,1,0,372,240,388,256,404,256,372,256,1,32,32,0,-11520,257745,0,0,8,3,0,0,0,'1','8','3',0,[
])
],
257744,0,0,[
]).
poly('black','',2,[
380,240,380,224],0,1,1,257750,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
424,240,424,224],0,1,1,257752,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
group([
poly('black','',6,[
119,74,91,60,149,52,196,53,224,56,256,64],0,1,1,257772,1,0,0,0,0,0,0,'1',0,0,
"78","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',11,[
367,71,374,64,449,65,481,77,481,93,467,100,449,106,416,114,
397,118,353,116,321,109],0,1,1,257771,1,0,0,0,0,0,0,'1',0,0,
"7fc","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',5,[
321,109,312,122,284,130,224,125,214,111],0,1,1,257770,1,0,0,0,0,0,0,'1',0,0,
"70","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',6,[
214,111,205,123,149,133,87,124,63,110,110,96],0,1,1,257769,1,0,0,0,0,0,0,'1',0,0,
"78","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',5,[
115,96,41,94,31,80,63,68,124,74],0,1,1,257768,1,0,0,0,0,0,0,'1',0,0,
"70","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',6,[
256,64,270,57,298,48,353,48,388,63,367,71],0,1,1,257767,1,0,0,0,0,0,0,'1',0,0,
"78","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
])
],
257766,0,0,[
]).
text('black',256,71,1,1,1,211,38,257895,31,7,0,0,0,0,-65534,211,38,0,0,"",0,0,0,0,102,'',[
minilines(211,38,0,0,1,0,0,[
mini_line(211,31,7,0,0,0,[
str_block(0,211,31,7,0,-1,0,0,0,[
str_seg('black','Helvetica',0,195840,211,31,7,0,-1,0,0,0,0,0,
"Event Sources")])
])
])]).
poly('black','',2,[
368,160,368,224],0,1,1,257909,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
328,160,328,224],0,1,1,257910,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
group([
poly('black','',4,[
332,256,332,240,364,240,364,256],0,1,1,257916,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
340,240,340,224],0,1,1,257915,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
356,240,356,224],0,1,1,257914,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
348,288,348,272],0,1,1,257913,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
arc('black','',0,1,1,0,332,240,348,256,364,256,332,256,1,32,32,0,-11520,257912,0,0,8,3,0,0,0,'1','8','3',0,[
])
],
257911,0,0,[
]).
poly('black','',2,[
340,240,340,224],0,1,1,257917,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
388,280,388,303],0,1,1,257970,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
440,224,440,160],0,1,1,257990,0,0,1,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
396,224,396,160],0,1,1,257994,0,0,1,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
356,224,356,160],0,1,1,257996,0,0,1,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
group([
poly('black','',2,[
256,352,256,336],0,1,1,258015,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
440,300,440,308],0,1,1,258014,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
72,300,72,308],0,1,1,258013,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',3,[
440,300,256,312,72,300],0,1,1,258012,1,0,0,0,0,0,0,'1',0,0,
"4","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',3,[
440,308,440,328,256,336],0,1,1,258011,1,0,0,0,0,0,0,'1',0,0,
"4","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',3,[
72,308,72,328,256,336],0,1,1,258010,1,0,0,0,0,0,0,'1',0,0,
"4","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
])
],
258033,0,0,[
]).
poly('black','',2,[
432,288,432,300],0,1,1,258063,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
348,288,348,304],0,1,1,258065,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
oval('black','',252,252,256,256,1,1,0,258082,0,0,0,0,0,'1',0,[
]).
oval('black','',236,252,240,256,1,1,0,258087,0,0,0,0,0,'1',0,[
]).
oval('black','',220,252,224,256,1,1,0,258088,0,0,0,0,0,'1',0,[
]).
group([
polygon('black','',8,[
224,416,272,416,280,428,288,416,336,416,304,464,256,464,224,416],0,1,1,0,258093,0,0,0,0,0,'1',0,
"00",[
]),
group([
poly('black','',2,[
280,440,280,448],0,1,1,258092,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
276,444,284,444],0,1,1,258091,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
])
],
258090,0,0,[
])
],
258089,0,0,[
]).
poly('black','',3,[
64,184,80,192,64,200],0,1,1,258094,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
group([
box('black','',296,496,328,560,0,1,1,258101,0,0,0,0,0,'1',0,[
]),
poly('black','',3,[
308,560,312,552,316,560],0,1,1,258100,0,2,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
])
],
258099,0,0,[
]).
poly('black','',3,[
280,464,280,512,296,512],0,1,1,258102,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',5,[
328,512,360,512,360,400,312,400,312,416],0,1,1,258103,0,0,0,0,0,0,0,'1',0,0,
"00","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',408,594,1,1,1,17,43,258110,14,3,0,0,0,0,-65534,43,17,0,0,"",0,1,0,0,608,'',[
408,594,387,594,430,611,-1.83697e-13,-1000,1000,-1.83697e-13,-104,-66,386,593,431,612],[
minilines(43,17,0,0,1,0,0,[
mini_line(43,14,3,0,0,0,[
str_block(0,43,14,3,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,80640,43,14,3,0,-1,0,0,0,0,0,
"PCCR")])
])
])]).
group([
poly('black','',4,[
232,384,232,368,264,368,264,384],0,1,1,258128,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
240,368,240,352],0,1,1,258127,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
256,368,256,352],0,1,1,258126,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
248,416,248,400],0,1,1,258125,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
arc('black','',0,1,1,0,232,368,248,384,264,384,232,384,1,32,32,0,-11520,258124,0,0,8,3,0,0,0,'1','8','3',0,[
])
],
258123,0,0,[
]).
poly('black','',2,[
240,352,192,352],0,1,1,258130,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',212,339,1,1,1,42,11,258131,9,2,0,0,0,0,-65534,42,11,0,0,"",0,0,0,0,348,'',[
minilines(42,11,0,0,1,0,0,[
mini_line(42,9,2,0,0,0,[
str_block(0,42,9,2,0,-2,0,0,0,[
str_seg('black','Courier',0,57600,42,9,2,0,-2,0,0,0,0,0,
"PCMR[0]")])
])
])]).

View file

@ -1,641 +0,0 @@
%TGIF 4.2.5-QPL
state(0,37,100.000,0,0,0,32,1,16,2,2,1,0,0,0,1,1,'Helvetica-Bold',1,97920,0,0,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,5760,0).
%
% @(#)$Header$
% %W%
%
unit("1 pixel/pixel").
color_info(66,65535,0,[
"black", 0, 0, 0, 0, 0, 0, 1,
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
"#F0F0F0", 61680, 61680, 61680, 61440, 61440, 61440, 1,
"#C8C8C8", 51400, 51400, 51400, 51200, 51200, 51200, 1,
"#505050", 20560, 20560, 20560, 20480, 20480, 20480, 1,
"#282828", 10280, 10280, 10280, 10240, 10240, 10240, 1,
"#FF0000", 65535, 0, 0, 65280, 0, 0, 1,
"#0000FF", 0, 0, 65535, 0, 0, 65280, 1,
"#00FF00", 0, 65535, 0, 0, 65280, 0, 1,
"#009000", 0, 37008, 0, 0, 36864, 0, 1,
"#1F407A", 7967, 16448, 31354, 7936, 16384, 31232, 1,
"#3C5A0F", 15420, 23130, 3855, 15360, 23040, 3840, 1,
"#0069B4", 0, 26985, 46260, 0, 26880, 46080, 1,
"#71791C", 29041, 31097, 7196, 28928, 30976, 7168, 1,
"#91056A", 37265, 1285, 27242, 37120, 1280, 27136, 1,
"#6F6F6E", 28527, 28527, 28270, 28416, 28416, 28160, 1,
"#A8322D", 43176, 12850, 11565, 43008, 12800, 11520, 1,
"#007A92", 0, 31354, 37522, 0, 31232, 37376, 1,
"#956013", 38293, 24672, 4883, 38144, 24576, 4864, 1,
"#82BE1E", 33410, 48830, 7710, 33280, 48640, 7680, 1,
"#758fbd", 30069, 36751, 48573, 29952, 36608, 48384, 1,
"#8eab63", 36494, 43947, 25443, 36352, 43776, 25344, 1,
"#6cacd9", 27756, 44204, 55769, 27648, 44032, 55552, 1,
"#b4ba72", 46260, 47802, 29298, 46080, 47616, 29184, 1,
"#c967ae", 51657, 26471, 44718, 51456, 26368, 44544, 1,
"#b8b8b6", 47288, 47288, 46774, 47104, 47104, 46592, 1,
"#d48985", 54484, 35209, 34181, 54272, 35072, 34048, 1,
"#65b9c9", 25957, 47545, 51657, 25856, 47360, 51456, 1,
"#c9a571", 51657, 42405, 29041, 51456, 42240, 28928, 1,
"#bbde81", 48059, 57054, 33153, 47872, 56832, 33024, 1,
"#a5b7d6", 42405, 47031, 54998, 42240, 46848, 54784, 1,
"#b8cc99", 47288, 52428, 39321, 47104, 52224, 39168, 1,
"#a2cbe8", 41634, 52171, 59624, 41472, 51968, 59392, 1,
"#d2d6a5", 53970, 54998, 42405, 53760, 54784, 42240, 1,
"#de9ecc", 57054, 40606, 52428, 56832, 40448, 52224, 1,
"#d4d4d2", 54484, 54484, 53970, 54272, 54272, 53760, 1,
"#e6b5b3", 59110, 46517, 46003, 58880, 46336, 45824, 1,
"#9bd3de", 39835, 54227, 57054, 39680, 54016, 56832, 1,
"#dec6a4", 57054, 50886, 42148, 56832, 50688, 41984, 1,
"#d5ebb0", 54741, 60395, 45232, 54528, 60160, 45056, 1,
"#b3cde3", 46003, 52685, 58339, 45824, 52480, 58112, 1,
"#bae4bc", 47802, 58596, 48316, 47616, 58368, 48128, 1,
"#edf8fb", 60909, 63736, 64507, 60672, 63488, 64256, 1,
"#ffffcc", 65535, 65535, 52428, 65280, 65280, 52224, 1,
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
"#f0f9e8", 61680, 63993, 59624, 61440, 63744, 59392, 1,
"#feebe2", 65278, 60395, 58082, 65024, 60160, 57856, 1,
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
"#fecc5c", 65278, 52428, 23644, 65024, 52224, 23552, 1,
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
"red", 65535, 0, 0, 65535, 0, 0, 1,
"green", 0, 65535, 0, 0, 65535, 0, 1,
"blue", 0, 0, 65535, 0, 0, 65535, 1,
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1,
"#FF4D08", 65535, 19789, 2056, 65280, 19712, 2048, 1,
"#FF6437", 65535, 25700, 14135, 65280, 25600, 14080, 1,
"#7F321B", 32639, 12850, 6939, 32512, 12800, 6912, 1,
"#FF8080", 65535, 32896, 32896, 65280, 32768, 32768, 1,
"#FF8A7E", 65535, 35466, 32382, 65280, 35328, 32256, 1,
"#FFC37C", 65535, 50115, 31868, 65280, 49920, 31744, 1,
"#7F4A0D", 32639, 19018, 3341, 32512, 18944, 3328, 1,
"#DE82FF", 57054, 33410, 65535, 56832, 33280, 65280, 1,
"#EFB8FF", 61423, 47288, 65535, 61184, 47104, 65280, 1,
"#6F367F", 28527, 13878, 32639, 28416, 13824, 32512, 1
]).
script_frac("0.6").
fg_bg_colors('#A8322D','white').
dont_reencode("FFDingbests:ZapfDingbats").
objshadow_info('#c0c0c0',2,2).
rotate_pivot(0,0,0,0).
spline_tightness(1).
page(1,"",1,'').
box('#EFB8FF','',288,256,320,560,1,2,0,288070,0,0,0,0,0,'2',0,[
]).
box('#EFB8FF','',592,256,624,560,1,2,0,288062,0,0,0,0,0,'2',0,[
]).
box('#EFB8FF','',888,400,920,560,1,2,0,288031,0,0,0,0,0,'2',0,[
]).
rcbox('#f0f9e8','',332,256,580,616,1,1,0,0,16,287695,0,0,0,0,'1',0,[
]).
rcbox('#f0f9e8','',636,256,876,616,1,1,0,0,16,287722,0,0,0,0,'1',0,[
]).
rcbox('#f0f9e8','',932,256,1052,616,1,1,0,0,16,287742,0,0,0,0,'1',0,[
]).
rcbox('#f0f9e8','',24,256,276,616,1,1,0,0,16,287635,0,0,0,0,'1',0,[
]).
rcbox('#d4d4d2','',24,256,276,616,0,1,1,0,16,287685,0,0,0,0,'1',0,[
]).
poly('black','',2,[
820,280,820,192],1,1,1,286345,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',816,170,1,1,1,40,17,286346,14,3,0,0,0,0,2,40,17,0,0,"",0,0,0,0,184,'',[
minilines(40,17,0,0,1,0,0,[
mini_line(40,14,3,0,0,0,[
str_block(0,40,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,40,14,3,0,-1,0,0,0,0,0,
"addr")])
])
])]).
text('black',960,170,1,1,1,60,17,286404,14,3,0,0,0,0,2,60,17,0,0,"",0,0,0,0,184,'',[
minilines(60,17,0,0,1,0,0,[
mini_line(60,14,3,0,0,0,[
str_block(0,60,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0,
"rvalid")])
])
])]).
text('black',872,170,1,1,1,50,17,286468,14,3,0,0,0,0,2,50,17,0,0,"",0,0,0,0,184,'',[
minilines(50,17,0,0,1,0,0,[
mini_line(50,14,3,0,0,0,[
str_block(0,50,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,50,14,3,0,-1,0,0,0,0,0,
"grant")])
])
])]).
rcbox('#0069B4','',784,136,1024,192,0,1,1,0,16,286710,0,0,0,0,'1',0,[
]).
text('black',888,142,1,1,1,127,23,286718,18,5,0,0,0,0,2,127,23,0,0,"",0,0,0,0,160,'',[
minilines(127,23,0,0,1,0,0,[
mini_line(127,18,5,0,0,0,[
str_block(0,127,18,5,0,-1,0,0,0,[
str_seg('#0069B4','Helvetica-Bold',1,115200,127,18,5,0,-1,0,0,0,0,0,
"Data Interface")])
])
])]).
box('black','',12,224,1064,664,0,1,1,286736,0,0,0,0,0,'1',0,[
]).
text('black',184,170,1,1,1,40,17,286355,14,3,0,0,0,0,2,40,17,0,0,"",0,0,0,0,184,'',[
minilines(40,17,0,0,1,0,0,[
mini_line(40,14,3,0,0,0,[
str_block(0,40,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,40,14,3,0,-1,0,0,0,0,0,
"addr")])
])
])]).
text('black',120,170,1,1,1,60,17,286569,14,3,0,0,0,0,2,60,17,0,0,"",0,0,0,0,184,'',[
minilines(60,17,0,0,1,0,0,[
mini_line(60,14,3,0,0,0,[
str_block(0,60,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0,
"rvalid")])
])
])]).
rcbox('#0069B4','',56,136,264,192,0,1,1,0,16,286711,0,0,0,0,'1',0,[
]).
text('black',160,142,1,1,1,181,23,286715,18,5,0,0,0,0,2,181,23,0,0,"",0,0,0,0,160,'',[
minilines(181,23,0,0,1,0,0,[
mini_line(181,18,5,0,0,0,[
str_block(0,181,18,5,0,-1,0,0,0,[
str_seg('#0069B4','Helvetica-Bold',1,115200,181,18,5,0,-1,0,0,0,0,0,
"Instruction Interface")])
])
])]).
box('#6F367F','',288,256,320,560,0,2,1,283037,0,0,0,0,0,'2',0,[
]).
text('black',294,415,2,0,1,20,35,283038,14,3,0,0,0,0,2,20,34,0,0,"",0,1,0,0,429,'',[
294,415,294,415,314,449,1000,0,0,1022.73,0,4,293,414,315,450],[
minilines(20,34,0,0,0,0,0,[
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"IF")])
]),
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"ID")])
])
])]).
box('#6F367F','',592,256,624,560,0,2,1,283031,0,0,0,0,0,'2',0,[
]).
text('black',598,415,2,0,1,20,34,283032,14,3,0,0,0,0,2,20,34,0,0,"",0,0,0,0,429,'',[
minilines(20,34,0,0,0,0,0,[
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"ID")])
]),
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,0,0,0,0,0,0,
"EX")])
])
])]).
box('#6F367F','',888,400,920,560,0,2,1,283042,0,0,0,0,0,'2',0,[
]).
text('black',894,415,2,0,1,20,34,283043,14,3,0,0,0,0,2,20,34,0,0,"",0,0,0,0,429,'',[
minilines(20,34,0,0,0,0,0,[
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,0,0,0,0,0,0,
"EX")])
]),
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"WB")])
])
])]).
poly('black','',2,[
172,280,172,192],1,1,1,287533,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
116,192,116,280],1,1,1,287631,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
rcbox('#d4d4d2','',332,256,580,616,0,1,1,0,16,287693,0,0,0,0,'1',0,[
]).
rcbox('#d4d4d2','',636,256,876,616,0,1,1,0,16,287738,0,0,0,0,'1',0,[
]).
rcbox('#d4d4d2','',932,256,1052,616,0,1,1,0,16,287749,0,0,0,0,'1',0,[
]).
poly('#6F367F','',3,[
296,560,304,548,312,560],0,2,1,288021,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#6F367F','',3,[
600,560,608,548,616,560],0,2,1,288025,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#6F367F','',3,[
896,560,904,548,912,560],0,2,1,288028,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('#6F367F',376,554,1,1,1,80,17,288303,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,568,'',[
minilines(80,17,0,0,1,0,0,[
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0,
"id_ready")])
])
])]).
text('#6F367F',680,554,1,1,1,80,17,288352,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,568,'',[
minilines(80,17,0,0,1,0,0,[
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0,
"ex_ready")])
])
])]).
text('#6F367F',980,554,1,1,1,80,17,288361,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,568,'',[
minilines(80,17,0,0,1,0,0,[
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0,
"wb_ready")])
])
])]).
poly('black','',3,[
496,384,496,560,472,560],1,2,1,288369,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',2,[
728,576,472,576],1,2,1,288370,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('#6F367F',456,410,1,1,1,60,17,288372,14,3,0,0,0,0,-65534,60,17,0,0,"",0,0,0,0,424,'',[
minilines(60,17,0,0,1,0,0,[
mini_line(60,14,3,0,0,0,[
str_block(0,60,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0,
"!stall")])
])
])]).
text('#6F367F',744,402,1,1,1,70,17,288380,14,3,0,0,0,0,-65534,70,17,0,0,"",0,0,0,0,416,'',[
minilines(70,17,0,0,1,0,0,[
mini_line(70,14,3,0,0,0,[
str_block(0,70,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,70,14,3,0,-1,0,0,0,0,0,
"granted")])
])
])]).
text('#6F367F',988,402,1,1,1,60,17,288385,14,3,0,0,0,0,-65534,60,17,0,0,"",0,0,0,0,416,'',[
minilines(60,17,0,0,1,0,0,[
mini_line(60,14,3,0,0,0,[
str_block(0,60,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,60,14,3,0,-1,0,0,0,0,0,
"rvalid")])
])
])]).
poly('black','',2,[
1028,576,776,576],1,2,1,288388,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#3C5A0F','',3,[
424,576,424,608,464,608],0,2,1,288395,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#3C5A0F','',4,[
448,608,568,608,568,520,592,520],1,2,1,288396,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('#6F367F',520,586,1,1,1,80,17,288398,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,600,'',[
minilines(80,17,0,0,1,0,0,[
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,80,14,3,0,-1,0,0,0,0,0,
"id_valid")])
])
])]).
poly('#3C5A0F','',3,[
728,576,728,608,752,608],0,2,1,288403,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#3C5A0F','',4,[
736,608,864,608,864,520,888,520],1,2,1,288404,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('#6F367F',816,586,1,1,1,80,17,288405,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,600,'',[
minilines(80,17,0,0,1,0,0,[
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,80,14,3,0,-1,0,0,0,0,0,
"ex_valid")])
])
])]).
poly('#3C5A0F','',3,[
40,568,40,608,168,608],0,2,1,288407,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#3C5A0F','',4,[
160,608,256,608,256,520,288,520],1,2,1,288408,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('#6F367F',208,586,1,1,1,80,17,288409,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,600,'',[
minilines(80,17,0,0,1,0,0,[
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,80,14,3,0,-1,0,0,0,0,0,
"if_valid")])
])
])]).
text('#6F367F',80,546,1,1,1,80,17,288418,14,3,0,0,0,0,-65534,80,17,0,0,"",0,0,0,0,560,'',[
minilines(80,17,0,0,1,0,0,[
mini_line(80,14,3,0,0,0,[
str_block(0,80,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,80,14,3,0,0,0,0,0,0,0,
"if_ready")])
])
])]).
rcbox('#bbde81','',80,280,208,432,1,2,0,0,10,288422,0,0,0,0,'2',0,[
]).
poly('#009000','',3,[
136,432,144,420,152,432],0,2,1,288423,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('black',144,296,2,1,1,101,58,288424,24,5,0,0,0,0,2,101,58,0,0,"",0,0,0,0,320,'',[
minilines(101,58,0,0,1,0,0,[
mini_line(101,24,5,0,0,0,[
str_block(0,101,24,5,0,-2,0,0,0,[
str_seg('black','Helvetica-Bold',1,138240,101,24,5,0,-2,0,0,0,0,0,
"Prefetch")])
]),
mini_line(75,24,5,0,0,0,[
str_block(0,75,24,5,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,138240,75,24,5,0,-1,0,0,0,0,0,
"Buffer")])
])
])]).
rcbox('#009000','',80,280,208,432,0,2,1,0,10,288425,0,0,0,0,'2',0,[
]).
text('#6F367F',152,458,1,1,1,50,17,288428,14,3,0,0,0,0,-65534,50,17,0,0,"",0,0,0,0,472,'',[
minilines(50,17,0,0,1,0,0,[
mini_line(50,14,3,0,0,0,[
str_block(0,50,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,50,14,3,0,-1,0,0,0,0,0,
"valid")])
])
])]).
rcbox('#b8cc99','',432,328,560,384,1,2,1,0,10,288430,0,0,0,0,'2',0,[
]).
rcbox('#3C5A0F','',432,328,560,384,0,2,1,0,10,288431,0,0,0,0,'2',0,[
]).
text('black',496,337,2,1,1,104,46,288432,18,5,0,0,0,0,2,104,46,0,0,"",0,0,0,0,355,'',[
minilines(104,46,0,0,1,0,0,[
mini_line(104,18,5,0,0,0,[
str_block(0,104,18,5,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,115200,104,18,5,0,-1,0,0,0,0,0,
"Forwarding")])
]),
mini_line(67,18,5,0,0,0,[
str_block(0,67,18,5,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,115200,67,18,5,0,-1,0,0,0,0,0,
"Control")])
])
])]).
poly('black','',2,[
964,192,964,280],1,1,1,288438,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
rcbox('#a5b7d6','',768,280,1040,384,1,2,0,0,10,287905,0,0,0,0,'2',0,[
]).
rcbox('#1F407A','',768,280,1040,384,0,2,1,0,10,286743,0,0,0,0,'2',0,[
]).
text('black',824,288,1,1,1,51,29,286745,24,5,0,0,0,0,2,51,29,0,0,"",0,0,0,0,312,'',[
minilines(51,29,0,0,1,0,0,[
mini_line(51,24,5,0,0,0,[
str_block(0,51,24,5,0,-2,0,0,0,[
str_seg('black','Helvetica-Bold',1,138240,51,24,5,0,-2,0,0,0,0,0,
"LSU")])
])
])]).
poly('black','',2,[
904,280,904,384],0,2,1,288448,0,0,5,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',2,[
868,192,868,280],1,1,1,288459,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',896,508,1,1,1,10,20,288462,16,4,0,0,0,0,-65534,10,20,0,0,"",0,0,0,0,524,'',[
minilines(10,20,0,0,1,0,0,[
mini_line(10,16,4,0,0,0,[
str_block(0,10,16,4,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,97920,10,16,4,0,-1,0,0,0,0,0,
"E")])
])
])]).
text('black',600,508,1,1,1,10,20,288494,16,4,0,0,0,0,-65534,10,20,0,0,"",0,0,0,0,524,'',[
minilines(10,20,0,0,1,0,0,[
mini_line(10,16,4,0,0,0,[
str_block(0,10,16,4,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,97920,10,16,4,0,-1,0,0,0,0,0,
"E")])
])
])]).
text('black',296,508,1,1,1,10,20,288498,16,4,0,0,0,0,-65534,10,20,0,0,"",0,0,0,0,524,'',[
minilines(10,20,0,0,1,0,0,[
mini_line(10,16,4,0,0,0,[
str_block(0,10,16,4,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,97920,10,16,4,0,-1,0,0,0,0,0,
"E")])
])
])]).
group([
arc('black','',0,2,1,0,744,552,760,568,760,552,760,584,0,32,32,5760,11520,288353,0,0,10,4,0,0,0,'2','10','4',0,[
]),
poly('black','',4,[
760,552,776,552,776,584,760,584],0,2,1,288354,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
])
],
288516,0,0,[
]).
poly('black','',3,[
744,568,728,568,728,576],0,2,1,288522,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',3,[
792,384,792,560,776,560],1,2,1,288531,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',4,[
1028,384,1028,520,1028,520,1028,576],0,2,1,288539,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
group([
arc('black','',0,2,1,0,440,552,456,568,456,552,456,584,0,32,32,5760,11520,288315,0,0,10,4,0,0,0,'2','10','4',0,[
]),
poly('black','',4,[
456,552,472,552,472,584,456,584],0,2,1,288314,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
])
],
288544,0,0,[
]).
poly('black','',2,[
424,576,160,576],1,2,1,288560,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',3,[
440,568,424,568,424,576],0,2,1,288561,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
group([
arc('black','',0,2,1,0,128,552,144,568,144,552,144,584,0,32,32,5760,11520,288574,0,0,10,4,0,0,0,'2','10','4',0,[
]),
poly('black','',4,[
144,552,160,552,160,584,144,584],0,2,1,288573,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
])
],
288572,0,0,[
]).
poly('black','',3,[
184,432,184,560,160,560],1,2,1,288581,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('black','',2,[
128,568,40,568],0,2,1,288588,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('black',600,476,1,1,1,12,20,288598,16,4,0,0,0,0,-65534,12,20,0,0,"",0,0,0,0,492,'',[
minilines(12,20,0,0,1,0,0,[
mini_line(12,16,4,0,0,0,[
str_block(0,12,16,4,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,97920,12,16,4,0,-1,0,0,0,0,0,
"C")])
])
])]).
oval('#A8322D','',536,492,544,500,0,2,1,288611,0,0,0,0,0,'2',0,[
]).
group([
arc('#A8322D','',0,2,1,0,544,472,560,488,560,472,560,504,1,32,32,5760,-11520,288605,0,0,10,4,0,0,0,'2','10','4',0,[
]),
poly('#A8322D','',4,[
560,472,544,472,544,504,560,504],0,2,1,288604,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
])
],
288603,0,0,[
]).
poly('#A8322D','',3,[
512,576,512,480,544,480],0,2,1,288629,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#3C5A0F','',4,[
568,520,528,520,528,496,536,496],0,2,1,288632,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#A8322D','',2,[
576,488,592,488],0,2,1,288639,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
oval('#A8322D','',832,492,840,500,0,2,1,288653,0,0,0,0,0,'2',0,[
]).
group([
arc('#A8322D','',0,2,1,0,840,472,856,488,856,472,856,504,1,32,32,5760,-11520,288656,0,0,10,4,0,0,0,'2','10','4',0,[
]),
poly('#A8322D','',4,[
856,472,840,472,840,504,856,504],0,2,1,288655,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
])
],
288654,0,0,[
]).
poly('#A8322D','',3,[
808,576,808,480,840,480],0,2,1,288657,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#A8322D','',2,[
872,488,888,488],0,2,1,288658,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#3C5A0F','',4,[
864,520,824,520,824,496,832,496],0,2,1,288668,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
oval('#A8322D','',232,492,240,500,0,2,1,288675,0,0,0,0,0,'2',0,[
]).
group([
arc('#A8322D','',0,2,1,0,240,472,256,488,256,472,256,504,1,32,32,5760,-11520,288678,0,0,10,4,0,0,0,'2','10','4',0,[
]),
poly('#A8322D','',4,[
256,472,240,472,240,504,256,504],0,2,1,288677,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
])
],
288676,0,0,[
]).
poly('#A8322D','',3,[
208,576,208,480,240,480],0,2,1,288679,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#A8322D','',2,[
272,488,288,488],0,2,1,288680,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#3C5A0F','',4,[
256,520,224,520,224,496,232,496],0,2,1,288682,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('black',296,476,1,1,1,12,20,288685,16,4,0,0,0,0,-65534,12,20,0,0,"",0,0,0,0,492,'',[
minilines(12,20,0,0,1,0,0,[
mini_line(12,16,4,0,0,0,[
str_block(0,12,16,4,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,97920,12,16,4,0,-1,0,0,0,0,0,
"C")])
])
])]).
text('black',896,476,1,1,1,12,20,288687,16,4,0,0,0,0,-65534,12,20,0,0,"",0,0,0,0,492,'',[
minilines(12,20,0,0,1,0,0,[
mini_line(12,16,4,0,0,0,[
str_block(0,12,16,4,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,97920,12,16,4,0,-1,0,0,0,0,0,
"C")])
])
])]).

View file

@ -1,707 +0,0 @@
%TGIF 4.2.5-QPL
state(0,37,100.000,0,0,0,8,1,65,2,2,1,0,1,1,0,1,'Courier-Bold',1,138240,0,0,0,10,0,0,1,1,0,16,0,0,1,1,1,1,1088,1408,1,0,5760,0).
%
% @(#)$Header$
% %W%
%
unit("1 pixel/pixel").
color_info(66,65535,0,[
"black", 0, 0, 0, 0, 0, 0, 1,
"white", 65535, 65535, 65535, 65535, 65535, 65535, 1,
"#F0F0F0", 61680, 61680, 61680, 61440, 61440, 61440, 1,
"#C8C8C8", 51400, 51400, 51400, 51200, 51200, 51200, 1,
"#505050", 20560, 20560, 20560, 20480, 20480, 20480, 1,
"#282828", 10280, 10280, 10280, 10240, 10240, 10240, 1,
"#FF0000", 65535, 0, 0, 65280, 0, 0, 1,
"#0000FF", 0, 0, 65535, 0, 0, 65280, 1,
"#00FF00", 0, 65535, 0, 0, 65280, 0, 1,
"#009000", 0, 37008, 0, 0, 36864, 0, 1,
"#1F407A", 7967, 16448, 31354, 7936, 16384, 31232, 1,
"#3C5A0F", 15420, 23130, 3855, 15360, 23040, 3840, 1,
"#0069B4", 0, 26985, 46260, 0, 26880, 46080, 1,
"#71791C", 29041, 31097, 7196, 28928, 30976, 7168, 1,
"#91056A", 37265, 1285, 27242, 37120, 1280, 27136, 1,
"#6F6F6E", 28527, 28527, 28270, 28416, 28416, 28160, 1,
"#A8322D", 43176, 12850, 11565, 43008, 12800, 11520, 1,
"#007A92", 0, 31354, 37522, 0, 31232, 37376, 1,
"#956013", 38293, 24672, 4883, 38144, 24576, 4864, 1,
"#82BE1E", 33410, 48830, 7710, 33280, 48640, 7680, 1,
"#758fbd", 30069, 36751, 48573, 29952, 36608, 48384, 1,
"#8eab63", 36494, 43947, 25443, 36352, 43776, 25344, 1,
"#6cacd9", 27756, 44204, 55769, 27648, 44032, 55552, 1,
"#b4ba72", 46260, 47802, 29298, 46080, 47616, 29184, 1,
"#c967ae", 51657, 26471, 44718, 51456, 26368, 44544, 1,
"#b8b8b6", 47288, 47288, 46774, 47104, 47104, 46592, 1,
"#d48985", 54484, 35209, 34181, 54272, 35072, 34048, 1,
"#65b9c9", 25957, 47545, 51657, 25856, 47360, 51456, 1,
"#c9a571", 51657, 42405, 29041, 51456, 42240, 28928, 1,
"#bbde81", 48059, 57054, 33153, 47872, 56832, 33024, 1,
"#a5b7d6", 42405, 47031, 54998, 42240, 46848, 54784, 1,
"#b8cc99", 47288, 52428, 39321, 47104, 52224, 39168, 1,
"#a2cbe8", 41634, 52171, 59624, 41472, 51968, 59392, 1,
"#d2d6a5", 53970, 54998, 42405, 53760, 54784, 42240, 1,
"#de9ecc", 57054, 40606, 52428, 56832, 40448, 52224, 1,
"#d4d4d2", 54484, 54484, 53970, 54272, 54272, 53760, 1,
"#e6b5b3", 59110, 46517, 46003, 58880, 46336, 45824, 1,
"#9bd3de", 39835, 54227, 57054, 39680, 54016, 56832, 1,
"#dec6a4", 57054, 50886, 42148, 56832, 50688, 41984, 1,
"#d5ebb0", 54741, 60395, 45232, 54528, 60160, 45056, 1,
"#b3cde3", 46003, 52685, 58339, 45824, 52480, 58112, 1,
"#bae4bc", 47802, 58596, 48316, 47616, 58368, 48128, 1,
"#edf8fb", 60909, 63736, 64507, 60672, 63488, 64256, 1,
"#ffffcc", 65535, 65535, 52428, 65280, 65280, 52224, 1,
"magenta", 65535, 0, 65535, 65535, 0, 65535, 1,
"#f0f9e8", 61680, 63993, 59624, 61440, 63744, 59392, 1,
"#feebe2", 65278, 60395, 58082, 65024, 60160, 57856, 1,
"cyan", 0, 65535, 65535, 0, 65535, 65535, 1,
"#fecc5c", 65278, 52428, 23644, 65024, 52224, 23552, 1,
"yellow", 65535, 65535, 0, 65535, 65535, 0, 1,
"red", 65535, 0, 0, 65535, 0, 0, 1,
"green", 0, 65535, 0, 0, 65535, 0, 1,
"blue", 0, 0, 65535, 0, 0, 65535, 1,
"pink", 65535, 49344, 52171, 65535, 49344, 52171, 1,
"CadetBlue", 24415, 40606, 41120, 24415, 40606, 41120, 1,
"DarkSlateGray", 12079, 20303, 20303, 12079, 20303, 20303, 1,
"#FF4D08", 65535, 19789, 2056, 65280, 19712, 2048, 1,
"#FF6437", 65535, 25700, 14135, 65280, 25600, 14080, 1,
"#7F321B", 32639, 12850, 6939, 32512, 12800, 6912, 1,
"#FF8080", 65535, 32896, 32896, 65280, 32768, 32768, 1,
"#FF8A7E", 65535, 35466, 32382, 65280, 35328, 32256, 1,
"#FFC37C", 65535, 50115, 31868, 65280, 49920, 31744, 1,
"#7F4A0D", 32639, 19018, 3341, 32512, 18944, 3328, 1,
"#DE82FF", 57054, 33410, 65535, 56832, 33280, 65280, 1,
"#EFB8FF", 61423, 47288, 65535, 61184, 47104, 65280, 1,
"#6F367F", 28527, 13878, 32639, 28416, 13824, 32512, 1
]).
script_frac("0.6").
fg_bg_colors('#6F367F','white').
dont_reencode("FFDingbests:ZapfDingbats").
objshadow_info('#c0c0c0',2,2).
rotate_pivot(0,0,0,0).
spline_tightness(1).
page(1,"",1,'').
box('#EFB8FF','',256,256,288,616,1,2,0,288070,0,0,0,0,0,'2',0,[
]).
box('#EFB8FF','',592,256,624,616,1,2,0,288062,0,0,0,0,0,'2',0,[
]).
box('#EFB8FF','',888,256,920,616,1,2,0,288031,0,0,0,0,0,'2',0,[
]).
rcbox('#f0f9e8','',300,256,580,616,1,1,0,0,16,287695,0,0,0,0,'1',0,[
]).
rcbox('#FFC37C','',344,448,440,576,1,2,0,0,10,288000,0,0,0,0,'2',0,[
]).
rcbox('#f0f9e8','',636,256,876,616,1,1,0,0,16,287722,0,0,0,0,'1',0,[
]).
rcbox('#FFC37C','',688,416,784,480,1,2,0,0,10,287972,0,0,0,0,'2',0,[
]).
rcbox('#FF8A7E','',688,520,784,584,1,2,0,0,10,287963,0,0,0,0,'2',0,[
]).
rcbox('#FF8A7E','',688,336,784,400,1,2,0,0,10,287944,0,0,0,0,'2',0,[
]).
rcbox('#f0f9e8','',932,256,1052,616,1,1,0,0,16,287742,0,0,0,0,'1',0,[
]).
rcbox('#a5b7d6','',960,296,1024,400,1,2,0,0,10,287905,0,0,0,0,'2',0,[
]).
rcbox('#b8cc99','',344,312,440,368,1,2,1,0,10,287877,0,0,0,0,'2',0,[
]).
rcbox('#f0f9e8','',24,256,244,616,1,1,0,0,16,287635,0,0,0,0,'1',0,[
]).
rcbox('#bbde81','',48,280,176,464,1,2,0,0,10,287856,0,0,0,0,'2',0,[
]).
rcbox('#d4d4d2','',24,256,244,616,0,1,1,0,16,287685,0,0,0,0,'1',0,[
]).
poly('#7F4A0D','',3,[
384,576,392,564,400,576],0,2,1,283046,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('black',392,456,1,1,1,53,29,283047,24,5,0,0,0,0,2,53,29,0,0,"",0,0,0,0,480,'',[
minilines(53,29,0,0,1,0,0,[
mini_line(53,24,5,0,0,0,[
str_block(0,53,24,5,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,144000,53,24,5,0,-1,0,0,0,0,0,
"GPR")])
])
])]).
polygon('black','',5,[
544,296,560,312,560,376,544,392,544,296],0,1,1,0,286311,0,0,0,0,0,'1',1,
"00",[
]).
poly('black','',2,[
624,352,688,352],1,1,1,286322,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
624,384,688,384],1,1,1,286323,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',3,[
672,360,672,536,688,536],1,1,1,286324,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',3,[
656,384,656,552,688,552],1,1,1,286325,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
oval('black','',654,382,658,386,1,1,1,286326,0,0,0,0,0,'1',0,[
]).
oval('black','',670,350,674,354,1,1,1,286327,0,0,0,0,0,'1',0,[
]).
poly('black','',4,[
672,360,672,304,808,304,808,288],1,1,1,286341,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
820,272,820,192],1,1,1,286345,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',816,170,1,1,1,40,17,286346,14,3,0,0,0,0,2,40,17,0,0,"",0,0,0,0,184,'',[
minilines(40,17,0,0,1,0,0,[
mini_line(40,14,3,0,0,0,[
str_block(0,40,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,40,14,3,0,-1,0,0,0,0,0,
"addr")])
])
])]).
polygon('black','',5,[
544,400,560,416,560,448,544,464,544,400],0,1,1,0,286360,0,0,0,0,0,'1',1,
"00",[
]).
poly('black','',2,[
560,352,592,352],1,1,1,286361,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',4,[
592,384,572,384,572,432,560,432],2,1,1,286362,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
560,568,592,568],1,1,1,286374,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',3,[
944,192,944,352,960,352],1,1,1,286380,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',6,[
1024,352,1040,352,1040,648,312,648,312,504,344,504],1,1,1,286388,0,0,0,0,0,0,0,'1',0,0,
"00","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
polygon('black','',5,[
840,600,856,616,856,648,840,664,840,600],0,1,1,0,286390,0,0,0,1,0,'1',1,
"00",[
840,600,840,600,856,664,6.12323e-14,1000,-1000,6.12323e-14,8,-8],[
]).
poly('black','',3,[
784,552,800,552,800,592],1,1,1,286395,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
832,504,832,592],1,1,1,286396,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',944,170,1,1,1,50,17,286404,14,3,0,0,0,0,2,50,17,0,0,"",0,0,0,0,184,'',[
minilines(50,17,0,0,1,0,0,[
mini_line(50,14,3,0,0,0,[
str_block(0,50,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,50,14,3,0,-1,0,0,0,0,0,
"rdata")])
])
])]).
oval('black','',830,366,834,370,1,1,1,286407,0,0,0,0,0,'1',0,[
]).
poly('black','',5,[
816,608,816,632,328,632,328,528,344,528],1,1,1,286409,0,0,0,0,0,0,0,'1',0,0,
"00","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',4,[
440,464,480,464,480,352,544,352],1,1,1,286410,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',4,[
440,488,496,488,496,424,544,424],1,1,1,286411,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
440,552,544,552],1,1,1,286412,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('DarkSlateGray','',2,[
440,336,544,336],1,1,1,286429,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('DarkSlateGray','',4,[
440,352,464,352,464,408,544,408],1,1,1,286430,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',3,[
528,632,528,368,544,368],1,1,1,286450,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',2,[
528,440,544,440],1,1,1,286451,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',2,[
528,568,544,568],1,1,1,286452,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',3,[
512,648,512,384,544,384],1,1,1,286453,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',2,[
512,456,544,456],1,1,1,286454,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',2,[
512,584,544,584],1,1,1,286455,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',872,170,1,1,1,50,17,286468,14,3,0,0,0,0,2,50,17,0,0,"",0,0,0,0,184,'',[
minilines(50,17,0,0,1,0,0,[
mini_line(50,14,3,0,0,0,[
str_block(0,50,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,50,14,3,0,-1,0,0,0,0,0,
"wdata")])
])
])]).
oval('CadetBlue','',510,454,514,458,1,1,1,286512,0,0,0,0,0,'1',0,[
]).
oval('CadetBlue','',510,582,514,586,1,1,1,286513,0,0,0,0,0,'1',0,[
]).
oval('CadetBlue','',526,438,530,442,1,1,1,286514,0,0,0,0,0,'1',0,[
]).
oval('CadetBlue','',526,566,530,570,1,1,1,286515,0,0,0,0,0,'1',0,[
]).
oval('CadetBlue','',526,630,530,634,1,1,1,286517,0,0,0,0,0,'1',0,[
]).
oval('CadetBlue','',510,646,514,650,1,1,1,286518,0,0,0,0,0,'1',0,[
]).
polygon('black','',5,[
544,480,560,496,560,512,544,528,544,480],0,1,1,0,286520,0,0,0,0,0,'1',1,
"00",[
]).
poly('black','',2,[
496,488,544,488],1,1,1,286530,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',2,[
528,504,544,504],1,1,1,286531,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('CadetBlue','',2,[
512,520,544,520],1,1,1,286532,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
polygon('black','',5,[
544,544,560,560,560,576,544,592,544,544],0,1,1,0,286537,0,0,0,0,0,'1',1,
"00",[
]).
oval('CadetBlue','',526,502,530,506,1,1,1,286539,0,0,0,0,0,'1',0,[
]).
oval('CadetBlue','',510,518,514,522,1,1,1,286540,0,0,0,0,0,'1',0,[
]).
oval('black','',494,486,498,490,1,1,1,286541,0,0,0,0,0,'1',0,[
]).
poly('black','',4,[
624,568,656,568,656,568,688,568],1,1,1,286550,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
832,368,832,288],1,1,1,286555,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',3,[
784,368,832,368,832,504],0,1,1,286561,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',4,[
288,288,480,288,480,320,544,320],1,1,1,286587,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
288,344,344,344],1,1,1,286592,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
oval('DarkSlateGray','',462,390,466,394,1,1,1,286664,0,0,0,0,0,'1',0,[
]).
oval('black','',462,486,466,490,1,1,1,286668,0,0,0,0,0,'1',0,[
]).
rcbox('#0069B4','',784,136,992,192,0,1,1,0,16,286710,0,0,0,0,'1',0,[
]).
text('black',888,142,1,1,1,127,23,286718,18,5,0,0,0,0,2,127,23,0,0,"",0,0,0,0,160,'',[
minilines(127,23,0,0,1,0,0,[
mini_line(127,18,5,0,0,0,[
str_block(0,127,18,5,0,-1,0,0,0,[
str_seg('#0069B4','Helvetica-Bold',1,115200,127,18,5,0,-1,0,0,0,0,0,
"Data Interface")])
])
])]).
poly('black','',4,[
592,504,576,504,576,504,560,504],2,1,1,286728,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
box('black','',12,224,1064,664,0,1,1,286736,0,0,0,0,0,'1',0,[
]).
group([
polygon('black','',8,[
208,416,232,428,232,408,224,404,232,400,232,380,208,392,208,416],0,1,1,0,286804,0,0,0,0,0,'1',0,
"00",[
]),
group([
poly('black','',2,[
216,400,216,408],0,1,1,286803,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
212,404,220,404],0,1,1,286802,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
])
],
286801,0,0,[
])
],
286800,0,0,[
]).
rcbox('#7F4A0D','',344,448,440,576,0,2,1,0,10,283045,0,0,0,0,'2',0,[
]).
rcbox('#1F407A','',960,296,1024,400,0,2,1,0,10,286743,0,0,0,0,'2',0,[
]).
text('black',992,304,1,1,1,51,29,286745,24,5,0,0,0,0,2,51,29,0,0,"",0,0,0,0,328,'',[
minilines(51,29,0,0,1,0,0,[
mini_line(51,24,5,0,0,0,[
str_block(0,51,24,5,0,-2,0,0,0,[
str_seg('black','Helvetica-Bold',1,138240,51,24,5,0,-2,0,0,0,0,0,
"LSU")])
])
])]).
rcbox('#7F321B','',688,336,784,400,0,2,1,0,10,283054,0,0,0,0,'2',0,[
]).
text('black',736,354,1,1,1,52,29,283056,24,5,0,0,0,0,2,52,29,0,0,"",0,0,0,0,378,'',[
minilines(52,29,0,0,1,0,0,[
mini_line(52,24,5,0,0,0,[
str_block(0,52,24,5,0,-2,0,0,0,[
str_seg('black','Helvetica-Bold',1,144000,52,24,5,0,-2,0,0,0,0,0,
"ALU")])
])
])]).
rcbox('#7F321B','',688,520,784,584,0,2,1,0,10,283062,0,0,0,0,'2',0,[
]).
text('black',772,539,1,2,1,72,29,283063,24,5,0,0,0,0,2,72,29,0,0,"",0,0,0,0,563,'',[
minilines(72,29,0,0,2,0,0,[
mini_line(72,24,5,0,0,0,[
str_block(0,72,24,5,0,0,0,0,0,[
str_seg('black','Helvetica-Bold',1,144000,72,24,5,0,0,0,0,0,0,0,
"MULT")])
])
])]).
poly('#7F4A0D','',3,[
728,480,736,468,744,480],0,2,1,287150,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
rcbox('#7F4A0D','',688,416,784,480,0,2,1,0,10,283068,0,0,0,0,'2',0,[
]).
text('black',736,430,1,1,1,52,29,283070,24,5,0,0,0,0,2,52,29,0,0,"",0,0,0,0,454,'',[
minilines(52,29,0,0,1,0,0,[
mini_line(52,24,5,0,0,0,[
str_block(0,52,24,5,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,138240,52,24,5,0,-1,0,0,0,0,0,
"CSR")])
])
])]).
poly('black','',2,[
672,432,688,432],1,1,1,287253,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
656,464,688,464],1,1,1,287254,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
oval('black','',654,462,658,466,1,1,1,287257,0,0,0,0,0,'1',0,[
]).
oval('black','',670,430,674,434,1,1,1,287258,0,0,0,0,0,'1',0,[
]).
poly('black','',3,[
624,504,864,504,864,192],1,1,1,287272,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',3,[
784,448,816,448,816,592],1,1,1,287273,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',152,170,1,1,1,40,17,286355,14,3,0,0,0,0,2,40,17,0,0,"",0,0,0,0,184,'',[
minilines(40,17,0,0,1,0,0,[
mini_line(40,14,3,0,0,0,[
str_block(0,40,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,40,14,3,0,-1,0,0,0,0,0,
"addr")])
])
])]).
text('black',88,170,1,1,1,50,17,286569,14,3,0,0,0,0,2,50,17,0,0,"",0,0,0,0,184,'',[
minilines(50,17,0,0,1,0,0,[
mini_line(50,14,3,0,0,0,[
str_block(0,50,14,3,0,-1,0,0,0,[
str_seg('#0069B4','Courier-Bold',1,97920,50,14,3,0,-1,0,0,0,0,0,
"rdata")])
])
])]).
rcbox('#0069B4','',24,136,232,192,0,1,1,0,16,286711,0,0,0,0,'1',0,[
]).
text('black',128,142,1,1,1,181,23,286715,18,5,0,0,0,0,2,181,23,0,0,"",0,0,0,0,160,'',[
minilines(181,23,0,0,1,0,0,[
mini_line(181,18,5,0,0,0,[
str_block(0,181,18,5,0,-1,0,0,0,[
str_seg('#0069B4','Helvetica-Bold',1,115200,181,18,5,0,-1,0,0,0,0,0,
"Instruction Interface")])
])
])]).
box('#6F367F','',256,256,288,616,0,2,1,283037,0,0,0,0,0,'2',0,[
]).
text('black',262,415,2,0,1,20,35,283038,14,3,0,0,0,0,2,20,34,0,0,"",0,1,0,0,429,'',[
262,415,262,415,282,449,1000,0,0,1022.73,0,4,261,414,283,450],[
minilines(20,34,0,0,0,0,0,[
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"IF")])
]),
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"ID")])
])
])]).
box('#6F367F','',592,256,624,616,0,2,1,283031,0,0,0,0,0,'2',0,[
]).
text('black',598,415,2,0,1,20,34,283032,14,3,0,0,0,0,2,20,34,0,0,"",0,0,0,0,429,'',[
minilines(20,34,0,0,0,0,0,[
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"ID")])
]),
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,0,0,0,0,0,0,
"EX")])
])
])]).
box('#6F367F','',888,256,920,616,0,2,1,283042,0,0,0,0,0,'2',0,[
]).
text('black',894,415,2,0,1,20,34,283043,14,3,0,0,0,0,2,20,34,0,0,"",0,0,0,0,429,'',[
minilines(20,34,0,0,0,0,0,[
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,0,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,0,0,0,0,0,0,
"EX")])
]),
mini_line(20,14,3,0,0,0,[
str_block(0,20,14,3,0,-1,0,0,0,[
str_seg('black','Courier-Bold',1,97920,20,14,3,0,-1,0,0,0,0,0,
"WB")])
])
])]).
group([
polygon('black','',8,[
232,300,208,312,208,292,216,288,208,284,208,264,232,276,232,300],0,1,1,0,287341,0,0,0,0,0,'1',0,
"00",[
]),
group([
poly('black','',2,[
224,284,224,292],0,1,1,287340,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
poly('black','',2,[
228,288,220,288],0,1,1,287339,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
])
],
287338,0,0,[
])
],
287337,0,0,[
]).
group([
poly('black','',2,[
544,304,532,304],2,1,1,287319,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]),
text('black',524,296,1,1,1,13,15,287320,12,3,0,0,0,0,2,13,15,0,0,"",0,0,0,0,308,'',[
minilines(13,15,0,0,1,0,0,[
mini_line(13,12,3,0,0,0,[
str_block(0,13,12,3,0,-1,0,0,0,[
str_seg('black','Helvetica',0,69120,13,12,3,0,-1,0,0,0,0,0,
"'0'")])
])
])])
],
287352,0,0,[
]).
poly('black','',2,[
208,272,196,272],2,1,1,287358,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
text('black',188,264,1,1,1,13,15,287357,12,3,0,0,0,0,2,13,15,0,0,"",0,0,0,0,276,'',[
minilines(13,15,0,0,1,0,0,[
mini_line(13,12,3,0,0,0,[
str_block(0,13,12,3,0,-1,0,0,0,[
str_seg('black','Helvetica',0,69120,13,12,3,0,-1,0,0,0,0,0,
"'2'")])
])
])]).
poly('black','',2,[
232,288,256,288],1,1,1,287363,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',3,[
464,488,464,416,232,416],1,1,1,287446,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
rcbox('#3C5A0F','',344,312,440,368,0,2,1,0,10,286419,0,0,0,0,'2',0,[
]).
text('black',392,321,1,1,1,78,23,286420,18,5,0,0,0,0,2,78,23,0,0,"",0,0,0,0,339,'',[
minilines(78,23,0,0,1,0,0,[
mini_line(78,18,5,0,0,0,[
str_block(0,78,18,5,0,0,0,0,0,[
str_seg('black','Helvetica-Bold',1,115200,78,18,5,0,0,0,0,0,0,0,
"Decoder")])
])
])]).
poly('black','',2,[
464,392,232,392],1,1,1,287500,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
polygon('black','',5,[
208,320,224,336,224,352,208,368,208,320],0,1,1,0,287518,0,0,0,0,0,'1',1,
"00",[
]).
poly('black','',2,[
140,280,140,192],1,1,1,287533,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
224,344,256,344],1,1,1,287562,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('#009000','',3,[
104,464,112,452,120,464],0,2,1,287566,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
text('black',112,296,2,1,1,101,58,287567,24,5,0,0,0,0,2,101,58,0,0,"",0,0,0,0,320,'',[
minilines(101,58,0,0,1,0,0,[
mini_line(101,24,5,0,0,0,[
str_block(0,101,24,5,0,-2,0,0,0,[
str_seg('black','Helvetica-Bold',1,138240,101,24,5,0,-2,0,0,0,0,0,
"Prefetch")])
]),
mini_line(75,24,5,0,0,0,[
str_block(0,75,24,5,0,-1,0,0,0,[
str_seg('black','Helvetica-Bold',1,138240,75,24,5,0,-1,0,0,0,0,0,
"Buffer")])
])
])]).
rcbox('#009000','',48,280,176,464,0,2,1,0,10,287568,0,0,0,0,'2',0,[
]).
poly('black','',2,[
176,328,208,328],1,1,1,287573,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
176,360,208,360],1,1,1,287574,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
176,304,208,304],1,1,1,287585,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
poly('black','',2,[
84,192,84,280],1,1,1,287631,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
rcbox('#d4d4d2','',300,256,580,616,0,1,1,0,16,287693,0,0,0,0,'1',0,[
]).
rcbox('#d4d4d2','',636,256,876,616,0,1,1,0,16,287738,0,0,0,0,'1',0,[
]).
rcbox('#d4d4d2','',932,256,1052,616,0,1,1,0,16,287749,0,0,0,0,'1',0,[
]).
poly('black','',2,[
208,404,176,404],1,1,1,287830,0,0,0,0,0,0,0,'1',0,0,
"0","",[
0,8,3,0,'8','3','0'],[0,8,3,0,'8','3','0'],[
]).
polygon('black','',5,[
868,312,884,328,884,344,868,360,868,312],0,1,1,0,287928,0,0,0,1,0,'1',1,
"00",[
868,312,868,312,884,360,-1.83697e-13,-1000,1000,-1.83697e-13,-72,-24],[
]).
poly('#6F367F','',3,[
264,616,272,604,280,616],0,2,1,288021,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#6F367F','',3,[
600,616,608,604,616,616],0,2,1,288025,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).
poly('#6F367F','',3,[
896,616,904,604,912,616],0,2,1,288028,0,0,0,0,0,0,0,'2',0,0,
"0","",[
0,10,4,0,'10','4','0'],[0,10,4,0,'10','4','0'],[
]).

View file

@ -1,126 +0,0 @@
% Determines the input encoding.
\usepackage[%
utf8,
% latin1
]{inputenc}
% ---------------------------------------------------------------------
% Determines the output encoding.
\usepackage[T1]{fontenc}
% ---------------------------------------------------------------------
% Determines language settings.
\usepackage[%
english % You may change this to 'ngerman' in order to write a
% german report.
]{babel}
% Provides stretchable tables.
\usepackage{tabularx}
% Provides image loading.
\usepackage{graphicx}
% ---------------------------------------------------------------------
% Provides the algorithm environment
\usepackage[ruled,%
linesnumbered]{algorithm2e}
% ---------------------------------------------------------------------
% Provides simple line spacings.
\usepackage{setspace}
% ---------------------------------------------------------------------
% Provides colors in LaTeX.
\usepackage{xcolor}
% ---------------------------------------------------------------------
% Provides nicer tables than the standard tables.
\usepackage{booktabs}
\usepackage{float}
\usepackage{listings}
\usepackage{amsmath}
%\usepackage{caption}
\usepackage{bytefield}
\usepackage{fullpage}
\usepackage{enumitem}
\usepackage{tcolorbox}
\usepackage{pdflscape}
\usepackage{tikz-timing}[2009/05/15]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% %
%%%%% Custom Macros %
%%%%% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Create an inline command for shell commands.
\newcommand{\shell}[1]{\texttt{#1}}
% Create an environment for a shell commands.
\newenvironment{shellenv}%
{\VerbatimEnvironment%
\begin{Sbox}\begin{minipage}{0.97\textwidth}\begin{Verbatim}%
}%
{\end{Verbatim}\end{minipage}\end{Sbox}%
\setlength{\fboxsep}{6pt}\shadowbox{\TheSbox}}%
% Create an inline command for files.
\newcommand{\file}[1]{\texttt{#1}}
% Create a command for command parameters.
\newcommand{\parameter}[1]{$<$#1$>$}
\newcommand{\instr}[1]{\texttt{#1}}
\definecolor{lightGray}{RGB}{240,240,240}
\lstnewenvironment{instrenv}{\lstset{backgroundcolor=\color{lightGray},frame=single,basicstyle=\ttfamily}}{}
\newcommand{\orion}{\textsc{Or10n}\xspace}
\newcommand{\riscv}{\mbox{RISC-V}\xspace}
\newcommand{\rvcore}{\textsc{RI5CY}\xspace}
\newcommand{\pulpino}{\textsc{PULPino}\xspace}
\newcommand{\pulp}{\textsc{PULP}\xspace}
\newcommand\signal[1]{{\ttfamily\bfseries #1}}
\newcommand\csrDesc[4]{%
\textbf{CSR Address:} \texttt{#1}\\%
\textbf{Reset Value:} \texttt{#2}\\%
\begin{figure}[H]
\centering
#4
\caption{#3}
\end{figure}}
\newcommand\instrDesc[3]{%
\subsection{#1}
\begin{center}
#3
\end{center}
\textbf{Operation:} \texttt{#2}%
}
\newenvironment{boxnote}%
{%
\begin{tcolorbox}[colback=red!5!white,colframe=red!75!black,title=Note]%
}%
{%
\end{tcolorbox}%
}%

View file

@ -33,12 +33,7 @@ import riscv_defines::*;
module riscv_ex_stage
#(
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter REG_ADDR_WIDTH = 4
`else
parameter REG_ADDR_WIDTH = 5
`endif // RV32E
)
(
input logic clk,
@ -49,62 +44,20 @@ module riscv_ex_stage
input logic [31:0] alu_operand_a_i,
input logic [31:0] alu_operand_b_i,
input logic [31:0] alu_operand_c_i,
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
input logic [ 4:0] bmask_a_i,
input logic [ 4:0] bmask_b_i,
`endif // BIT_SUPPORT
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
input logic [ 1:0] imm_vec_ext_i,
input logic [ 1:0] alu_vec_mode_i,
`endif // VEC_SUPPORT
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// Multiplier signals
input logic [ 2:0] mult_operator_i,
input logic [31:0] mult_operand_a_i,
input logic [31:0] mult_operand_b_i,
input logic [31:0] mult_operand_c_i,
input logic mult_en_i,
input logic mult_sel_subword_i,
input logic [ 1:0] mult_signed_mode_i,
input logic [ 4:0] mult_imm_i,
input logic [31:0] mult_dot_op_a_i,
input logic [31:0] mult_dot_op_b_i,
input logic [31:0] mult_dot_op_c_i,
input logic [ 1:0] mult_dot_signed_i,
output logic mult_multicycle_o,
`endif // MUL_SUPPORT
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
output logic [31:0] alu_adder_result_ex_o,
`endif // LSU_ADDER_SUPPORT
// input from ID stage
input logic branch_in_ex_i,
input logic [(REG_ADDR_WIDTH-1):0] regfile_alu_waddr_i,
input logic regfile_alu_we_i,
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
input logic jal_in_ex_i,
`endif
// directly passed through to WB stage, not used in EX
input logic regfile_we_i,
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
input logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_i,
`endif // THREE_PORT_REG_FILE
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
input logic alu_req_ex_i,
`endif
// CSR access
input logic csr_access_i,
@ -126,10 +79,7 @@ module riscv_ex_stage
// Stall Control
input logic lsu_ready_ex_i, // EX part of LSU is done
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
output logic alu_ready_o,
`endif
output logic ex_ready_o, // EX stage ready for new data
@ -137,40 +87,19 @@ module riscv_ex_stage
input logic wb_ready_i // WB stage ready for new data
);
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifndef THREE_PORT_REG_FILE
logic regfile_we_conflict; // Tests for a conflict when WB and EX want to write to a register at the same cycle.
assign regfile_we_conflict = regfile_we_wb_o && regfile_alu_we_fw_o;
`endif // THREE_PORT_REG_FILE
logic [31:0] alu_result;
logic [31:0] alu_csr_result;
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
logic [31:0] mult_result;
`endif // MUL_SUPPORT
logic alu_cmp_result;
logic alu_ready;
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
logic mult_ready;
`endif // MUL_SUPPORT
// EX stage result mux (ALU, MAC unit, CSR)
assign alu_csr_result = csr_access_i ? csr_rdata_i : alu_result;
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
assign regfile_alu_wdata_fw_o = mult_en_i ? mult_result : alu_csr_result;
`else
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
assign regfile_alu_wdata_fw_o = jal_in_ex_i ? alu_operand_c_i : alu_csr_result; // Select return address
`else
assign regfile_alu_wdata_fw_o = alu_csr_result;
`endif
`endif // MUL_SUPPORT
assign regfile_alu_we_fw_o = regfile_alu_we_i;
@ -179,12 +108,7 @@ module riscv_ex_stage
// branch handling
assign branch_decision_o = alu_cmp_result;
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
assign jump_target_o = alu_adder_result_ex_o;
`else
assign jump_target_o = alu_operand_c_i;
`endif
@ -198,33 +122,6 @@ module riscv_ex_stage
////////////////////////////
// CONFIG_REGION: SIMPLE_ALU
`ifdef SIMPLE_ALU
// CONFIG_REGION: SPLITTED
`ifdef SPLITTED_ADDER
riscv_alu_simplified_splitted alu_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.operator_i ( alu_operator_i ),
.operand_a_i ( alu_operand_a_i ),
.operand_b_i ( alu_operand_b_i ),
.req_i ( alu_req_ex_i ),
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
.adder_result_o ( alu_adder_result_ex_o ),
`endif // LSU_ADDER_SUPPORT
.ready_o ( alu_ready ),
.result_o ( alu_result ),
.comparison_result_o ( alu_cmp_result )
);
`else
riscv_alu_simplified alu_i
(
@ -235,10 +132,7 @@ module riscv_ex_stage
.operand_a_i ( alu_operand_a_i ),
.operand_b_i ( alu_operand_b_i ),
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
.adder_result_o (alu_adder_result_ex_o ),
`endif // LSU_ADDER_SUPPORT
.result_o ( alu_result ),
.comparison_result_o ( alu_cmp_result )
@ -246,91 +140,10 @@ module riscv_ex_stage
assign alu_ready = 1'b1; // As there is no divider, ALU always takes only one cycle
`endif // SPLITTED_ADDER
`else // SIMPLE_ALU
riscv_alu alu_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.operator_i ( alu_operator_i ),
.operand_a_i ( alu_operand_a_i ),
.operand_b_i ( alu_operand_b_i ),
.operand_c_i ( alu_operand_c_i ),
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
.vector_mode_i ( alu_vec_mode_i ),
`endif // VEC_SUPPORT
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
.bmask_a_i ( bmask_a_i ),
.bmask_b_i ( bmask_b_i ),
`endif // BIT_SUPPORT
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
.imm_vec_ext_i ( imm_vec_ext_i ),
`endif // VEC_SUPPORT
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
.adder_result_o (alu_adder_result_ex_o ),
`endif // LSU_ADDER_SUPPORT
.result_o ( alu_result ),
.comparison_result_o ( alu_cmp_result ),
.ready_o ( alu_ready ),
.ex_ready_i ( ex_ready_o )
);
`endif // SIMPLE_ALU
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
////////////////////////////////////////////////////////////////
// __ __ _ _ _ _____ ___ ____ _ ___ _____ ____ //
// | \/ | | | | | |_ _|_ _| _ \| | |_ _| ____| _ \ //
// | |\/| | | | | | | | | || |_) | | | || _| | |_) | //
// | | | | |_| | |___| | | || __/| |___ | || |___| _ < //
// |_| |_|\___/|_____|_| |___|_| |_____|___|_____|_| \_\ //
// //
////////////////////////////////////////////////////////////////
riscv_mult mult_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.enable_i ( mult_en_i ),
.operator_i ( mult_operator_i ),
.short_subword_i ( mult_sel_subword_i ),
.short_signed_i ( mult_signed_mode_i ),
.op_a_i ( mult_operand_a_i ),
.op_b_i ( mult_operand_b_i ),
.op_c_i ( mult_operand_c_i ),
.imm_i ( mult_imm_i ),
.dot_op_a_i ( mult_dot_op_a_i ),
.dot_op_b_i ( mult_dot_op_b_i ),
.dot_op_c_i ( mult_dot_op_c_i ),
.dot_signed_i ( mult_dot_signed_i ),
.result_o ( mult_result ),
.multicycle_o ( mult_multicycle_o ),
.ready_o ( mult_ready ),
.ex_ready_i ( ex_ready_o )
);
`endif
///////////////////////////////////////
// EX/WB Pipeline Register //
@ -348,12 +161,7 @@ module riscv_ex_stage
begin
regfile_we_wb_o <= regfile_we_i;
if (regfile_we_i) begin
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
regfile_waddr_wb_o <= regfile_waddr_i;
`else
regfile_waddr_wb_o <= regfile_alu_waddr_i;
`endif // THREE_PORT_REG_FILE
end
end else if (wb_ready_i) begin
// we are ready for a new instruction, but there is none available,
@ -367,31 +175,9 @@ module riscv_ex_stage
// to finish branches without going to the WB stage, ex_valid does not
// depend on ex_ready.
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
assign ex_ready_o = (alu_ready & mult_ready & lsu_ready_ex_i & wb_ready_i) | branch_in_ex_i;
assign ex_valid_o = (alu_ready & mult_ready & lsu_ready_ex_i & wb_ready_i);
`else
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
assign ex_ready_o = (alu_ready & lsu_ready_ex_i & wb_ready_i) | branch_in_ex_i;
assign ex_valid_o = (alu_ready & lsu_ready_ex_i & wb_ready_i);
`else // THREE_PORT_REG_FILE
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
assign ex_ready_o = (alu_ready & lsu_ready_ex_i & wb_ready_i & ~regfile_we_conflict);
assign ex_valid_o = (alu_ready & lsu_ready_ex_i & wb_ready_i);
`else
assign ex_ready_o = (alu_ready & lsu_ready_ex_i & wb_ready_i & ~regfile_we_conflict) | branch_in_ex_i;
assign ex_valid_o = (alu_ready & lsu_ready_ex_i & wb_ready_i);
`endif // SPLITTED_ADDER
`endif // THREE_PORT_REG_FILE
`endif // MUL_SUPPORT
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef SPLITTED_ADDER
assign alu_ready_o = alu_ready;
`endif
endmodule

File diff suppressed because it is too large Load diff

View file

@ -30,10 +30,6 @@
import riscv_defines::*;
module riscv_if_stage #(
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
parameter N_HWLP = 2,
`endif
parameter RDATA_WIDTH = 32
)
(
@ -50,11 +46,6 @@ module riscv_if_stage #(
input logic instr_rvalid_i,
input logic [RDATA_WIDTH-1:0] instr_rdata_i,
// Output of IF Pipeline stage
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
output logic [N_HWLP-1:0] hwlp_dec_cnt_id_o, // currently served instruction was the target of a hwlp
output logic is_hwlp_id_o, // currently served instruction was the target of a hwlp
`endif // HWLP_SUPPORT
output logic instr_valid_id_o, // instruction in IF/ID pipeline is valid
output logic [31:0] instr_rdata_id_o, // read instruction is sampled and sent to ID stage for decoding
output logic is_compressed_id_o, // compressed decoder thinks this is a compressed instruction
@ -70,21 +61,8 @@ module riscv_if_stage #(
input logic [4:0] exc_vec_pc_mux_i, // selects ISR address for vectorized interrupt lines
// jump and branch target and decision
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
input logic [31:0] jump_target_id_i, // jump target address
`endif
`endif
input logic [31:0] jump_target_ex_i, // jump target address
// from hwloop controller
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
input logic [N_HWLP-1:0] [31:0] hwlp_start_i, // hardware loop start addresses
input logic [N_HWLP-1:0] [31:0] hwlp_end_i, // hardware loop end addresses
input logic [N_HWLP-1:0] [31:0] hwlp_cnt_i, // hardware loop counters
`endif // HWLP_SUPPORT
// from debug unit
input logic [31:0] dbg_jump_addr_i,
input logic dbg_jump_req_i,
@ -112,24 +90,13 @@ module riscv_if_stage #(
logic fetch_ready;
logic [31:0] fetch_rdata;
logic [31:0] fetch_addr;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic is_hwlp_id_q, fetch_is_hwlp;
`endif // HWLP_SUPPORT
// CONFIG_REGION: ONLY_ALIGNED
`ifdef ONLY_ALIGNED
logic illegal_fetch;
`endif
logic [31:0] exc_pc;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// hardware loop related signals
logic hwlp_jump;
logic [31:0] hwlp_target;
logic [N_HWLP-1:0] hwlp_dec_cnt, hwlp_dec_cnt_if;
`endif // HWLP_SUPPORT
// exception PC selection mux
@ -155,17 +122,8 @@ module riscv_if_stage #(
unique case (pc_mux_i)
PC_BOOT: fetch_addr_n = {boot_addr_i[31:8], EXC_OFF_RST};
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
PC_JUMP: fetch_addr_n = jump_target_id_i;
`else
PC_JUMP: fetch_addr_n = jump_target_ex_i;
`endif
`else
PC_JUMP: fetch_addr_n = jump_target_ex_i;
`endif // JUMP_IN_ID
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
@ -176,67 +134,7 @@ module riscv_if_stage #(
end
// CONFIG_REGION: ONLY_ALIGNED
`ifdef ONLY_ALIGNED
// prefetch buffer, caches a fixed number of instructions
riscv_prefetch_buffer_only_aligned prefetch_buffer_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.req_i ( req_i ),
.branch_i ( branch_req ),
.addr_i ( {fetch_addr_n[31:1], 1'b0} ),
.ready_i ( fetch_ready ),
.valid_o ( fetch_valid ),
.rdata_o ( fetch_rdata ),
.addr_o ( fetch_addr ),
// goes to instruction memory / instruction cache
.instr_req_o ( instr_req_o ),
.instr_addr_o ( instr_addr_o ),
.instr_gnt_i ( instr_gnt_i ),
.instr_rvalid_i ( instr_rvalid_i ),
.instr_rdata_i ( instr_rdata_i ),
// Prefetch Buffer Status
.illegal_fetch_o ( illegal_fetch ),
.busy_o ( prefetch_busy )
);
`else
// CONFIG_REGION: SMALL_IF
`ifdef SMALL_IF
// prefetch buffer, caches a fixed number of instructions
riscv_prefetch_buffer_small prefetch_buffer_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.req_i ( req_i ),
.branch_i ( branch_req ),
.addr_i ( {fetch_addr_n[31:1], 1'b0} ),
.ready_i ( fetch_ready ),
.valid_o ( fetch_valid ),
.rdata_o ( fetch_rdata ),
.addr_o ( fetch_addr ),
// goes to instruction memory / instruction cache
.instr_req_o ( instr_req_o ),
.instr_addr_o ( instr_addr_o ),
.instr_gnt_i ( instr_gnt_i ),
.instr_rvalid_i ( instr_rvalid_i ),
.instr_rdata_i ( instr_rdata_i ),
// Prefetch Buffer Status
.busy_o ( prefetch_busy )
);
`else // SMALL_IF
generate
if (RDATA_WIDTH == 32) begin : prefetch_32
@ -251,20 +149,11 @@ module riscv_if_stage #(
.branch_i ( branch_req ),
.addr_i ( {fetch_addr_n[31:1], 1'b0} ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.hwloop_i ( hwlp_jump ),
.hwloop_target_i ( hwlp_target ),
`endif // HWLP_SUPPORT
.ready_i ( fetch_ready ),
.valid_o ( fetch_valid ),
.rdata_o ( fetch_rdata ),
.addr_o ( fetch_addr ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.is_hwlp_o ( fetch_is_hwlp ),
`endif // HWLP_SUPPORT
// goes to instruction memory / instruction cache
.instr_req_o ( instr_req_o ),
@ -288,20 +177,11 @@ module riscv_if_stage #(
.branch_i ( branch_req ),
.addr_i ( {fetch_addr_n[31:1], 1'b0} ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.hwloop_i ( hwlp_jump ),
.hwloop_target_i ( hwlp_target ),
`endif // HWLP_SUPPORT
.ready_i ( fetch_ready ),
.valid_o ( fetch_valid ),
.rdata_o ( fetch_rdata ),
.addr_o ( fetch_addr ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.is_hwlp_o ( fetch_is_hwlp ),
`endif // HWLP_SUPPORT
// goes to instruction memory / instruction cache
.instr_req_o ( instr_req_o ),
@ -315,8 +195,6 @@ module riscv_if_stage #(
);
end
endgenerate
`endif // SMALL_IF
`endif // ONLY_ALIGNED
// offset FSM state
@ -376,30 +254,6 @@ module riscv_if_stage #(
end
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// Hardware Loops
riscv_hwloop_controller
#(
.N_REGS ( N_HWLP )
)
hwloop_controller_i
(
.current_pc_i ( fetch_addr ),
.hwlp_jump_o ( hwlp_jump ),
.hwlp_targ_addr_o ( hwlp_target ),
// from hwloop_regs
.hwlp_start_addr_i ( hwlp_start_i ),
.hwlp_end_addr_i ( hwlp_end_i ),
.hwlp_counter_i ( hwlp_cnt_i ),
// to hwloop_regs
.hwlp_dec_cnt_o ( hwlp_dec_cnt ),
.hwlp_dec_cnt_id_i ( hwlp_dec_cnt_id_o & {N_HWLP{is_hwlp_id_o}} )
);
`endif // HWLP_SUPPORT
@ -432,18 +286,9 @@ module riscv_if_stage #(
begin
if (rst_n == 1'b0)
begin
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
hwlp_dec_cnt_if <= '0;
`endif // HWLP_SUPPORT
end
else
begin
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (hwlp_jump)
hwlp_dec_cnt_if <= hwlp_dec_cnt;
`endif // HWLP_SUPPORT
end
end
@ -457,11 +302,6 @@ module riscv_if_stage #(
illegal_c_insn_id_o <= 1'b0;
is_compressed_id_o <= 1'b0;
pc_id_o <= '0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_id_q <= 1'b0;
hwlp_dec_cnt_id_o <= '0;
`endif // HWLP_SUPPORT
end
else
begin
@ -470,21 +310,9 @@ module riscv_if_stage #(
begin
instr_valid_id_o <= 1'b1;
instr_rdata_id_o <= instr_decompressed;
// CONFIG_REGION: ONLY_ALIGNED
`ifdef ONLY_ALIGNED
illegal_c_insn_id_o <= illegal_c_insn | illegal_fetch;
`else
illegal_c_insn_id_o <= illegal_c_insn;
`endif
is_compressed_id_o <= instr_compressed_int;
pc_id_o <= pc_if_o;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_id_q <= fetch_is_hwlp;
if (fetch_is_hwlp)
hwlp_dec_cnt_id_o <= hwlp_dec_cnt_if;
`endif // HWLP_SUPPORT
end else if (clear_instr_valid_i) begin
instr_valid_id_o <= 1'b0;
@ -493,10 +321,6 @@ module riscv_if_stage #(
end
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign is_hwlp_id_o = is_hwlp_id_q & instr_valid_id_o;
`endif // HWLP_SUPPORT
assign if_ready_o = valid & id_ready_i;
assign if_valid_o = (~halt_if_i) & if_ready_o;

View file

@ -47,38 +47,19 @@ module riscv_load_store_unit
input logic data_we_ex_i, // write enable -> from ex stage
input logic [1:0] data_type_ex_i, // Data type word, halfword, byte -> from ex stage
input logic [31:0] data_wdata_ex_i, // data to write to memory -> from ex stage
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
input logic [1:0] data_reg_offset_ex_i, // offset inside register for stores -> from ex stage
`endif // ONLY_ALIGNED
input logic data_sign_ext_ex_i, // sign extension -> from ex stage
output logic [31:0] data_rdata_ex_o, // requested data -> to ex stage
input logic data_req_ex_i, // data request -> from ex stage
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
input logic [31:0] operand_a_ex_i, // operand a from RF for address -> from ex stage
input logic [31:0] operand_b_ex_i, // operand b from RF for address -> from ex stage
`else
input logic [31:0] adder_result_ex_i,
`endif // LSU_ADDER_SUPPORT
// CONFIG_REGION: PREPOST_SUPPORT
`ifdef PREPOST_SUPPORT
input logic addr_useincr_ex_i, // use a + b or just a for address -> from ex stage
`endif // PREPOST_SUPPORT
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
input logic data_misaligned_ex_i, // misaligned access in last ld/st -> from ID/EX pipeline
output logic data_misaligned_o, // misaligned access was detected -> to controller
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
output logic first_cycle_misaligned_o,
output logic [31:0] misaligned_addr_o,
`endif
`endif // ONLY_ALIGNED
// exception signals
output logic load_err_o,
@ -88,10 +69,7 @@ module riscv_load_store_unit
output logic lsu_ready_ex_o, // LSU ready for new data in EX stage
output logic lsu_ready_wb_o, // LSU ready for new data in WB stage
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
input logic alu_ready_i,
`endif
input logic ex_valid_i,
@ -111,11 +89,8 @@ module riscv_load_store_unit
logic [3:0] data_be;
logic [31:0] data_wdata;
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
logic misaligned_st; // high if we are currently performing the second part of a misaligned store
logic data_misaligned;
`endif // ONLY_ALIGNED
enum logic [1:0] { IDLE, WAIT_RVALID, WAIT_RVALID_EX_STALL, IDLE_EX_STALL } CS, NS;
@ -127,8 +102,6 @@ module riscv_load_store_unit
case (data_type_ex_i) // Data type 00 Word, 01 Half word, 11,10 byte
2'b00:
begin // Writing a word
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
if (misaligned_st == 1'b0)
begin // non-misaligned case
case (data_addr_int[1:0])
@ -147,15 +120,10 @@ module riscv_load_store_unit
2'b11: data_be = 4'b0111;
endcase; // case (data_addr_int[1:0])
end
`else
data_be = 4'b1111;
`endif // ONLY_ALIGNED
end
2'b01:
begin // Writing a half word
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
if (misaligned_st == 1'b0)
begin // non-misaligned case
case (data_addr_int[1:0])
@ -169,12 +137,6 @@ module riscv_load_store_unit
begin // misaligned case
data_be = 4'b0001;
end
`else
case (data_addr_int[1])
1'b0: data_be = 4'b0011;
1'b1: data_be = 4'b1100;
endcase; // case (data_addr_int[1])
`endif // ONLY_ALIGNED
end
2'b10,
@ -192,12 +154,7 @@ module riscv_load_store_unit
// prepare data to be written to the memory
// we handle misaligned accesses, half word and byte accesses and
// register offsets here
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
assign wdata_offset = data_addr_int[1:0] - data_reg_offset_ex_i[1:0];
`else
assign wdata_offset = data_addr_int[1:0];
`endif // ONLY_ALIGNED
always_comb
begin
case (wdata_offset)
@ -247,24 +204,17 @@ module riscv_load_store_unit
// take care of misaligned words
always_comb
begin
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
case (rdata_offset_q)
2'b00: rdata_w_ext = data_rdata_i[31:0];
2'b01: rdata_w_ext = {data_rdata_i[ 7:0], rdata_q[31:8]};
2'b10: rdata_w_ext = {data_rdata_i[15:0], rdata_q[31:16]};
2'b11: rdata_w_ext = {data_rdata_i[23:0], rdata_q[31:24]};
endcase
`else
rdata_w_ext = data_rdata_i[31:0];
`endif // ONLY_ALIGNED
end
// sign extension for half words
always_comb
begin
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
case (rdata_offset_q)
2'b00:
begin
@ -298,25 +248,6 @@ module riscv_load_store_unit
rdata_h_ext = {{16{data_rdata_i[7]}}, data_rdata_i[7:0], rdata_q[31:24]};
end
endcase // case (rdata_offset_q)
`else
case (rdata_offset_q[1])
1'b0:
begin
if (data_sign_ext_q == 1'b0)
rdata_h_ext = {16'h0000, data_rdata_i[15:0]};
else
rdata_h_ext = {{16{data_rdata_i[15]}}, data_rdata_i[15:0]};
end
1'b1:
begin
if (data_sign_ext_q == 1'b0)
rdata_h_ext = {16'h0000, data_rdata_i[31:16]};
else
rdata_h_ext = {{16{data_rdata_i[31]}}, data_rdata_i[31:16]};
end
endcase // case (rdata_offset_q[1])
`endif // ONLY_ALIGNED
end
// sign extension for bytes
@ -374,27 +305,15 @@ module riscv_load_store_unit
begin
CS <= IDLE;
rdata_q <= '0;
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
data_misaligned_o <= '0;
misaligned_addr_o <= 32'b0;
`endif
`endif
end
else
begin
CS <= NS;
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
if (ex_valid_i)
data_misaligned_o <= data_misaligned;
misaligned_addr_o <= data_addr_int;
`endif
`endif
if (data_rvalid_i && (~data_we_q))
begin
@ -404,15 +323,10 @@ module riscv_load_store_unit
// In all other cases, rdata_q gets the value that we are
// writing to the register file
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
if ((data_misaligned_ex_i == 1'b1) || (data_misaligned == 1'b1))
rdata_q <= data_rdata_i;
else
rdata_q <= data_rdata_ext;
`else
rdata_q <= data_rdata_ext;
`endif // ONLY_ALIGNED
end
end
end
@ -426,15 +340,9 @@ module riscv_load_store_unit
assign data_we_o = data_we_ex_i;
assign data_be_o = data_be;
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
assign misaligned_st = data_misaligned_ex_i;
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
assign first_cycle_misaligned_o = data_misaligned; // Directly forward signal to
`endif
`endif // ONLY_ALIGNED
@ -455,12 +363,7 @@ module riscv_load_store_unit
// starts from not active and stays in IDLE until request was granted
IDLE:
begin
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
if (data_req_ex_i & alu_ready_i) begin
`else
if (data_req_ex_i) begin
`endif
data_req_o = data_req_ex_i;
lsu_ready_ex_o = 1'b0;
@ -485,12 +388,7 @@ module riscv_load_store_unit
// source for the WB stage
lsu_ready_wb_o = 1'b1;
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
if (data_req_ex_i & alu_ready_i) begin
`else
if (data_req_ex_i) begin
`endif
data_req_o = data_req_ex_i;
lsu_ready_ex_o = 1'b0;
@ -550,8 +448,6 @@ module riscv_load_store_unit
endcase
end
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
// check for misaligned accesses that need a second memory access
// If one is detected, this is signaled with data_misaligned_o to
// the controller which selectively stalls the pipeline
@ -576,30 +472,11 @@ module riscv_load_store_unit
end
end
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
assign data_misaligned_o = data_misaligned;
`endif
`endif // ONLY_ALIGNED
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// generate address from operands
// CONFIG_REGION: PREPOST_SUPPORT
`ifdef PREPOST_SUPPORT
assign data_addr_int = (addr_useincr_ex_i) ? (operand_a_ex_i + operand_b_ex_i) : operand_a_ex_i;
`else
assign data_addr_int = (operand_a_ex_i + operand_b_ex_i);
`endif // PREPOST_SUPPORT
`else // LSU_ADDER_SUPPORT
assign data_addr_int = adder_result_ex_i;
`endif // LSU_ADDER_SUPPORT
assign busy_o = (CS == WAIT_RVALID) || (CS == WAIT_RVALID_EX_STALL) || (CS == IDLE_EX_STALL) || (data_req_o == 1'b1);

View file

@ -39,20 +39,11 @@ module riscv_prefetch_L0_buffer
input logic branch_i,
input logic [31:0] addr_i,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
input logic hwloop_i,
input logic [31:0] hwloop_target_i,
`endif // HWLP_SUPPORT
input logic ready_i,
output logic valid_o,
output logic [31:0] rdata_o,
output logic [31:0] addr_o,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
output logic is_hwlp_o, // is set when the currently served data is from a hwloop
`endif // HWLP_SUPPORT
// goes to instruction memory / instruction cache
output logic instr_req_o,
@ -67,36 +58,15 @@ module riscv_prefetch_L0_buffer
logic busy_L0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
enum logic [3:0] { IDLE, BRANCHED,
HWLP_WAIT_GNT, HWLP_GRANTED, HWLP_GRANTED_WAIT, HWLP_FETCH_DONE,
NOT_VALID, NOT_VALID_GRANTED, NOT_VALID_CROSS, NOT_VALID_CROSS_GRANTED,
VALID, VALID_CROSS, VALID_GRANTED, VALID_FETCH_DONE } CS, NS;
`else
enum logic [3:0] { IDLE, BRANCHED,
NOT_VALID, NOT_VALID_GRANTED, NOT_VALID_CROSS, NOT_VALID_CROSS_GRANTED,
VALID, VALID_CROSS, VALID_GRANTED, VALID_FETCH_DONE } CS, NS;
`endif // HWLP_SUPPORT
logic do_fetch;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic do_hwlp, do_hwlp_int;
`endif // HWLP_SUPPORT
logic use_last;
logic save_rdata_last;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic use_hwlp;
logic save_rdata_hwlp;
`endif // HWLP_SUPPORT
logic valid;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic hwlp_is_crossword;
`endif // HWLP_SUPPORT
logic is_crossword;
logic next_is_crossword;
logic next_valid;
@ -105,10 +75,6 @@ module riscv_prefetch_L0_buffer
logic upper_is_compressed;
logic [31:0] addr_q, addr_n, addr_int, addr_aligned_next, addr_real_next;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic is_hwlp_q, is_hwlp_n;
`endif // HWLP_SUPPORT
logic [31:0] rdata_last_q;
@ -123,10 +89,6 @@ module riscv_prefetch_L0_buffer
logic [31:0] rdata, rdata_unaligned;
logic aligned_is_compressed, unaligned_is_compressed;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic hwlp_aligned_is_compressed, hwlp_unaligned_is_compressed;
`endif // HWLP_SUPPORT
prefetch_L0_buffer_L0
@ -144,11 +106,6 @@ module riscv_prefetch_L0_buffer
.branch_i ( branch_i ),
.branch_addr_i ( addr_i ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.hwlp_i ( do_hwlp | do_hwlp_int ),
.hwlp_addr_i ( hwloop_target_i ),
`endif // HWLP_SUPPORT
.fetch_gnt_o ( fetch_gnt ),
.fetch_valid_o ( fetch_valid ),
@ -167,12 +124,7 @@ module riscv_prefetch_L0_buffer
);
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign rdata = (use_last || use_hwlp) ? rdata_last_q : rdata_L0[addr_o[3:2]];
`else
assign rdata = use_last ? rdata_last_q : rdata_L0[addr_o[3:2]];
`endif // HWLP_SUPPORT
// the lower part of rdata_unaligned is always the higher part of rdata
assign rdata_unaligned[15:0] = rdata[31:16];
@ -204,12 +156,6 @@ module riscv_prefetch_L0_buffer
assign addr_aligned_next = { addr_o[31:2], 2'b00 } + 32'h4;
assign addr_real_next = (next_is_crossword) ? { addr_o[31:4], 4'b0000 } + 32'h16 : { addr_o[31:2], 2'b00 } + 32'h4;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign hwlp_unaligned_is_compressed = rdata_L0[2][17:16] != 2'b11;
assign hwlp_aligned_is_compressed = rdata_L0[3][1:0] != 2'b11;
assign hwlp_is_crossword = (hwloop_target_i[3:1] == 3'b111) && (~upper_is_compressed);
`endif // HWLP_SUPPORT
always_comb
begin
@ -247,30 +193,10 @@ module riscv_prefetch_L0_buffer
begin
NS = CS;
do_fetch = 1'b0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
do_hwlp = 1'b0;
do_hwlp_int = 1'b0;
`endif // HWLP_SUPPORT
use_last = 1'b0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
use_hwlp = 1'b0;
`endif // HWLP_SUPPORT
save_rdata_last = 1'b0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
save_rdata_hwlp = 1'b0;
`endif // HWLP_SUPPORT
valid = 1'b0;
addr_n = addr_int;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_n = is_hwlp_q;
if (ready_i)
is_hwlp_n = 1'b0;
`endif // HWLP_SUPPORT
case (CS)
IDLE: begin
@ -285,16 +211,7 @@ module riscv_prefetch_L0_buffer
valid = 1'b1;
if (ready_i) begin
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (hwloop_i) begin
addr_n = addr_o; // keep the old address for now
NS = HWLP_WAIT_GNT;
end
else begin
`else
begin
`endif // HWLP_SUPPORT
if (next_valid) begin
if (fetch_gnt) begin
@ -344,10 +261,6 @@ module riscv_prefetch_L0_buffer
NOT_VALID_GRANTED: begin
valid = fetch_valid;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
do_hwlp = hwloop_i;
`endif // HWLP_SUPPORT
if (fetch_valid)
NS = VALID;
@ -368,10 +281,6 @@ module riscv_prefetch_L0_buffer
begin
valid = fetch_valid;
use_last = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
do_hwlp = hwloop_i;
`endif // HWLP_SUPPORT
if (fetch_valid)
begin
@ -385,10 +294,6 @@ module riscv_prefetch_L0_buffer
VALID: begin
valid = 1'b1;
do_fetch = fetch_possible; // fetch_possible = addr_o[3:2] == 2'b11;//
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
do_hwlp = hwloop_i;
`endif // HWLP_SUPPORT
if (ready_i)
begin
@ -439,10 +344,6 @@ module riscv_prefetch_L0_buffer
VALID_CROSS: begin
valid = 1'b1;
use_last = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
do_hwlp = hwloop_i;
`endif // HWLP_SUPPORT
if (ready_i)
NS = VALID;
@ -451,10 +352,6 @@ module riscv_prefetch_L0_buffer
VALID_GRANTED: begin
valid = 1'b1;
use_last = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
do_hwlp = hwloop_i;
`endif // HWLP_SUPPORT
if (ready_i) begin
@ -482,10 +379,6 @@ module riscv_prefetch_L0_buffer
VALID_FETCH_DONE: begin
valid = 1'b1;
use_last = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
do_hwlp = hwloop_i;
`endif // HWLP_SUPPORT
if (ready_i) begin
if (next_is_crossword)
@ -497,106 +390,14 @@ module riscv_prefetch_L0_buffer
end
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
HWLP_WAIT_GNT: begin
do_hwlp_int = 1'b1;
if (fetch_gnt) begin
is_hwlp_n = 1'b1;
addr_n = hwloop_target_i;
NS = BRANCHED;
end
end
HWLP_GRANTED: begin
valid = 1'b1;
use_hwlp = 1'b1;
if (ready_i) begin
addr_n = hwloop_target_i;
if (fetch_valid) begin
is_hwlp_n = 1'b1;
if (hwlp_is_crossword) begin
NS = NOT_VALID_CROSS;
end else begin
NS = VALID;
end
end else begin
NS = HWLP_GRANTED_WAIT;
end
end else begin
if (fetch_valid)
NS = HWLP_FETCH_DONE;
end
end
HWLP_GRANTED_WAIT: begin
use_hwlp = 1'b1;
if (fetch_valid) begin
is_hwlp_n = 1'b1;
if (hwlp_is_crossword) begin
NS = NOT_VALID_CROSS;
end else begin
NS = VALID;
end
end
end
HWLP_FETCH_DONE: begin
valid = 1'b1;
use_hwlp = 1'b1;
if (ready_i) begin
is_hwlp_n = 1'b1;
addr_n = hwloop_target_i;
if (hwlp_is_crossword) begin
NS = NOT_VALID_CROSS;
end else begin
NS = VALID;
end
end
end
`endif // HWLP_SUPPORT
endcase
// branches always have priority
if (branch_i) begin
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_n = 1'b0;
`endif // HWLP_SUPPORT
addr_n = addr_i;
NS = BRANCHED;
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwloop_i) begin
if (do_hwlp) begin
if (ready_i) begin
if (fetch_gnt) begin
is_hwlp_n = 1'b1;
addr_n = hwloop_target_i;
NS = BRANCHED;
end else begin
addr_n = addr_o; // keep the old address for now
NS = HWLP_WAIT_GNT;
end
end else begin
if (fetch_gnt) begin
save_rdata_hwlp = 1'b1;
NS = HWLP_GRANTED;
end
end
end
end
`endif // HWLP_SUPPORT
end
@ -609,31 +410,16 @@ module riscv_prefetch_L0_buffer
if (~rst_n)
begin
addr_q <= '0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_q <= 1'b0;
`endif // HWLP_SUPPORT
CS <= IDLE;
rdata_last_q <= '0;
end
else
begin
addr_q <= addr_n;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_q <= is_hwlp_n;
`endif // HWLP_SUPPORT
CS <= NS;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (save_rdata_hwlp)
rdata_last_q <= rdata_o;
else if(save_rdata_last)
`else
if(save_rdata_last)
`endif // HWLP_SUPPORT
begin
//rdata_last_q <= rdata_L0[3];
if(ready_i)
@ -653,21 +439,12 @@ module riscv_prefetch_L0_buffer
//////////////////////////////////////////////////////////////////////////////
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign rdata_o = ((~addr_o[1]) || use_hwlp) ? rdata : rdata_unaligned;
`else
assign rdata_o = (~addr_o[1]) ? rdata : rdata_unaligned;
`endif // HWLP_SUPPORT
assign valid_o = valid & (~branch_i);
assign addr_o = addr_q;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign is_hwlp_o = is_hwlp_q & (~branch_i);
`endif // HWLP_SUPPORT
assign busy_o = busy_L0;
@ -703,11 +480,6 @@ module prefetch_L0_buffer_L0
input logic branch_i,
input logic [31:0] branch_addr_i,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
input logic hwlp_i,
input logic [31:0] hwlp_addr_i,
`endif // HWLP_SUPPORT
output logic fetch_gnt_o,
output logic fetch_valid_o,
@ -726,12 +498,7 @@ module prefetch_L0_buffer_L0
output logic busy_o
);
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
enum logic [2:0] { EMPTY, VALID_L0, WAIT_GNT, WAIT_RVALID, ABORTED_BRANCH, WAIT_HWLOOP } CS, NS;
`else
enum logic [2:0] { EMPTY, VALID_L0, WAIT_GNT, WAIT_RVALID, ABORTED_BRANCH} CS, NS;
`endif // HWLP_SUPPORT
logic [3:0][31:0] L0_buffer;
logic [31:0] addr_q, instr_addr_int;
@ -757,20 +524,10 @@ module prefetch_L0_buffer_L0
begin
if (branch_i)
instr_addr_int = branch_addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwlp_i)
instr_addr_int = hwlp_addr_i;
`endif // HWLP_SUPPORT
else
instr_addr_int = prefetch_addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (branch_i | hwlp_i | prefetch_i) // make the request to icache
`else
if (branch_i | prefetch_i) // make the request to icache
`endif // HWLP_SUPPORT
begin
instr_req_o = 1'b1;
@ -785,11 +542,6 @@ module prefetch_L0_buffer_L0
begin
if (branch_i)
instr_addr_int = branch_addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwlp_i)
instr_addr_int = hwlp_addr_i;
`endif // HWLP_SUPPORT
else
instr_addr_int = addr_q;
@ -821,11 +573,6 @@ module prefetch_L0_buffer_L0
if (branch_i)
instr_addr_int = branch_addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwlp_i)
instr_addr_int = hwlp_addr_i;
`endif // HWLP_SUPPORT
else
instr_addr_int = prefetch_addr_i;
@ -852,12 +599,7 @@ module prefetch_L0_buffer_L0
begin
fetch_valid_o = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (prefetch_i | hwlp_i) // we are receiving the last packet, then prefetch the next one
`else
if (prefetch_i) // we are receiving the last packet, then prefetch the next one
`endif // HWLP_SUPPORT
begin
instr_req_o = 1'b1;
@ -880,20 +622,10 @@ module prefetch_L0_buffer_L0
if (branch_i)
instr_addr_int = branch_addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwlp_i)
instr_addr_int = hwlp_addr_i;
`endif // HWLP_SUPPORT
else
instr_addr_int = prefetch_addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (branch_i | hwlp_i | prefetch_i)
`else
if (branch_i | prefetch_i)
`endif // HWLP_SUPPORT
begin
instr_req_o = 1'b1;
@ -954,12 +686,7 @@ module prefetch_L0_buffer_L0
L0_buffer <= instr_rdata_i;
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (branch_i | hwlp_i | prefetch_i)
`else
if (branch_i | prefetch_i)
`endif // HWLP_SUPPORT
addr_q <= instr_addr_int;
end
end

View file

@ -40,11 +40,6 @@ module riscv_fetch_fifo
input logic in_valid_i,
output logic in_ready_o,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
input logic in_replace2_i, // replaces second entry if there is one: "to be served after this instr"
input logic in_is_hwlp_i,
`endif // HWL_LOOP
// output port
output logic out_valid_o,
@ -52,14 +47,7 @@ module riscv_fetch_fifo
output logic [31:0] out_rdata_o,
output logic [31:0] out_addr_o,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
output logic out_valid_stored_o, // same as out_valid_o, except that if something is incoming now it is not included. This signal is available immediately as it comes directly out of FFs
output logic out_is_hwlp_o
`else
output logic out_valid_stored_o // same as out_valid_o, except that if something is incoming now it is not included. This signal is available immediately as it comes directly out of FFs
`endif // HWLP_SUPPORT
);
localparam DEPTH = 3; // must be 3 or greater
@ -68,10 +56,6 @@ module riscv_fetch_fifo
logic [0:DEPTH-1] [31:0] addr_n, addr_int, addr_Q;
logic [0:DEPTH-1] [31:0] rdata_n, rdata_int, rdata_Q;
logic [0:DEPTH-1] valid_n, valid_int, valid_Q;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic [0:1 ] is_hwlp_n, is_hwlp_int, is_hwlp_Q;
`endif // HWLP_SUPPORT
logic [31:0] addr_next;
logic [31:0] rdata, rdata_unaligned;
@ -86,12 +70,7 @@ module riscv_fetch_fifo
assign rdata = (valid_Q[0]) ? rdata_Q[0] : in_rdata_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign valid = valid_Q[0] || in_valid_i || is_hwlp_Q[1];
`else
assign valid = valid_Q[0] || in_valid_i;
`endif // HWLP_SUPPORT
assign rdata_unaligned = (valid_Q[1]) ? {rdata_Q[1][15:0], rdata[31:16]} : {in_rdata_i[15:0], rdata[31:16]};
// it is implied that rdata_valid_Q[0] is set
@ -111,12 +90,7 @@ module riscv_fetch_fifo
// serve the aligned case even though the output address is unaligned when
// the next instruction will be from a hardware loop target
// in this case the current instruction is already prealigned in element 0
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (out_addr_o[1] && (~is_hwlp_Q[1])) begin
`else
if (out_addr_o[1]) begin
`endif // HWLP_SUPPORT
// unaligned case
out_rdata_o = rdata_unaligned;
@ -132,22 +106,13 @@ module riscv_fetch_fifo
end
assign out_addr_o = (valid_Q[0]) ? addr_Q[0] : in_addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
assign out_is_hwlp_o = (valid_Q[0]) ? is_hwlp_Q[0] : in_is_hwlp_i;
`endif // HWLP_SUPPORT
// this valid signal must not depend on signals from outside!
always_comb
begin
out_valid_stored_o = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (out_addr_o[1] && (~is_hwlp_Q[1])) begin
`else
if (out_addr_o[1]) begin
`endif // HWLP_SUPPORT
if (unaligned_is_compressed_st)
out_valid_stored_o = 1'b1;
else
@ -179,10 +144,6 @@ module riscv_fetch_fifo
rdata_int = rdata_Q;
valid_int = valid_Q;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_int = is_hwlp_Q;
`endif // HWLP_SUPPORT
if (in_valid_i) begin
for(j = 0; j < DEPTH; j++) begin
@ -195,33 +156,6 @@ module riscv_fetch_fifo
end
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// replace 2nd entry
if (in_replace2_i) begin
if (valid_Q[0]) begin
addr_int[1] = in_addr_i;
// if we replace the 2nd entry, let's cache the output word in case we
// still need it and it would span two words in the FIFO
rdata_int[0] = out_rdata_o;
rdata_int[1] = in_rdata_i;
valid_int[1] = 1'b1;
valid_int[2:DEPTH-1] = '0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// hardware loop incoming?
is_hwlp_int[1] = in_is_hwlp_i;
`endif // HWLP_SUPPORT
end else begin
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_int[0] = in_is_hwlp_i;
`endif // HWLP_SUPPORT
end
end
`endif // HWLP_SUPPORT
end
end
@ -233,24 +167,9 @@ module riscv_fetch_fifo
addr_n = addr_int;
rdata_n = rdata_int;
valid_n = valid_int;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_n = is_hwlp_int;
`endif // HWLP_SUPPORT
if (out_ready_i && out_valid_o) begin
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_n = {is_hwlp_int[1], 1'b0};
if (is_hwlp_int[1]) begin
addr_n[0] = addr_int[1][31:0];
rdata_n = {rdata_int[1:DEPTH-1], 32'b0};
valid_n = {valid_int[1:DEPTH-1], 1'b0};
end else begin
`else
begin
`endif // HWLP_SUPPORT
if (addr_int[0][1]) begin
// unaligned case
if (unaligned_is_compressed) begin
@ -288,10 +207,6 @@ module riscv_fetch_fifo
addr_Q <= '{default: '0};
rdata_Q <= '{default: '0};
valid_Q <= '0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_Q <= '0;
`endif // HWLP_SUPPORT
end
else
begin
@ -299,18 +214,10 @@ module riscv_fetch_fifo
// completely and start from an empty state
if (clear_i) begin
valid_Q <= '0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_Q <= '0;
`endif // HWLP_SUPPORT
end else begin
addr_Q <= addr_n;
rdata_Q <= rdata_n;
valid_Q <= valid_n;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
is_hwlp_Q <= is_hwlp_n;
`endif // HWLP_SUPPORT
end
end
end
@ -319,15 +226,8 @@ module riscv_fetch_fifo
// Assertions
//----------------------------------------------------------------------------
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// check for FIFO overflows
assert property (
@(posedge clk) (in_valid_i) |-> ((valid_Q[DEPTH-1] == 1'b0) || (clear_i == 1'b1) || (in_replace2_i == 1'b1)) );
`else
assert property (
@(posedge clk) (in_valid_i) |-> ((valid_Q[DEPTH-1] == 1'b0) || (clear_i == 1'b1)) );
`endif
endmodule
@ -342,21 +242,12 @@ module riscv_prefetch_buffer
input logic branch_i,
input logic [31:0] addr_i,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
input logic hwloop_i,
input logic [31:0] hwloop_target_i,
`endif // HWLP_SUPPORT
input logic ready_i,
output logic valid_o,
output logic [31:0] rdata_o,
output logic [31:0] addr_o,
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
output logic is_hwlp_o, // is set when the currently served data is from a hwloop
`endif // HWLP_SUPPORT
// goes to instruction memory / instruction cache
output logic instr_req_o,
@ -370,31 +261,15 @@ module riscv_prefetch_buffer
);
enum logic [1:0] {IDLE, WAIT_GNT, WAIT_RVALID, WAIT_ABORTED } CS, NS;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
enum logic [1:0] {HWLP_NONE, HWLP_IN, HWLP_FETCHING, HWLP_DONE } hwlp_CS, hwlp_NS;
`endif // HWLP_SUPPORT
logic [31:0] instr_addr_q, fetch_addr;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic fetch_is_hwlp;
`endif // HWLP_SUPPORT
logic addr_valid;
logic fifo_valid;
logic fifo_ready;
logic fifo_clear;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic fifo_hwlp;
`endif // HWLP_SUPPORT
logic valid_stored;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic hwlp_masked;
`endif // HWLP_SUPPORT
//////////////////////////////////////////////////////////////////////////////
@ -420,25 +295,13 @@ module riscv_prefetch_buffer
.in_valid_i ( fifo_valid ),
.in_ready_o ( fifo_ready ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.in_replace2_i ( fifo_hwlp ),
.in_is_hwlp_i ( fifo_hwlp ),
`endif // HWLP_SUPPORT
.out_valid_o ( valid_o ),
.out_ready_i ( ready_i ),
.out_rdata_o ( rdata_o ),
.out_addr_o ( addr_o ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.out_valid_stored_o ( valid_stored ),
.out_is_hwlp_o ( is_hwlp_o )
`else
.out_valid_stored_o ( valid_stored )
`endif // HWLP_SUPPORT
);
@ -450,70 +313,7 @@ module riscv_prefetch_buffer
always_comb
begin
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
hwlp_NS = hwlp_CS;
fifo_hwlp = 1'b0;
hwlp_masked = 1'b0;
fifo_clear = 1'b0;
unique case (hwlp_CS)
HWLP_NONE: begin
if (hwloop_i) begin
hwlp_masked = 1'b1;
if (fetch_is_hwlp)
hwlp_NS = HWLP_FETCHING;
else
hwlp_NS = HWLP_IN;
if (ready_i)
fifo_clear = 1'b1;
end
end
HWLP_IN: begin
hwlp_masked = 1'b1;
if (fetch_is_hwlp)
hwlp_NS = HWLP_FETCHING;
if (ready_i)
fifo_clear = 1'b1;
end
// just waiting for rvalid really
HWLP_FETCHING: begin
fifo_hwlp = 1'b1;
if (instr_rvalid_i & (CS != WAIT_ABORTED)) begin
if (valid_o & is_hwlp_o)
hwlp_NS = HWLP_NONE;
else
hwlp_NS = HWLP_DONE;
end else begin
if (ready_i)
fifo_clear = 1'b1;
end
end
HWLP_DONE: begin
if (valid_o & is_hwlp_o)
hwlp_NS = HWLP_NONE;
end
default: begin
hwlp_NS = HWLP_NONE;
end
endcase
if (branch_i) begin
hwlp_NS = HWLP_NONE;
fifo_clear = 1'b1;
end
`else
fifo_clear = branch_i;
`endif // HWLP_SUPPORT
end
//////////////////////////////////////////////////////////////////////////////
@ -527,10 +327,6 @@ module riscv_prefetch_buffer
instr_addr_o = fetch_addr;
fifo_valid = 1'b0;
addr_valid = 1'b0;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
fetch_is_hwlp = 1'b0;
`endif // HWLP_SUPPORT
NS = CS;
unique case(CS)
@ -542,27 +338,11 @@ module riscv_prefetch_buffer
if (branch_i)
instr_addr_o = addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if(hwlp_masked & valid_stored)
instr_addr_o = hwloop_target_i;
`endif // HWLP_SUPPORT
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (req_i & (fifo_ready | branch_i | (hwlp_masked & valid_stored))) begin
`else
if (req_i & (fifo_ready | branch_i )) begin
`endif // HWLP_SUPPORT
instr_req_o = 1'b1;
addr_valid = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (hwlp_masked & valid_stored) begin
fetch_is_hwlp = 1'b1;
end
`endif // HWLP_SUPPORT
if(instr_gnt_i) //~> granted request
NS = WAIT_RVALID;
@ -582,14 +362,6 @@ module riscv_prefetch_buffer
instr_addr_o = addr_i;
addr_valid = 1'b1;
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwlp_masked & valid_stored) begin
instr_addr_o = hwloop_target_i;
addr_valid = 1'b1;
fetch_is_hwlp = 1'b1;
end
`endif // HWLP_SUPPORT
if(instr_gnt_i)
NS = WAIT_RVALID;
@ -604,18 +376,8 @@ module riscv_prefetch_buffer
if (branch_i)
instr_addr_o = addr_i;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwlp_masked)
instr_addr_o = hwloop_target_i;
`endif // HWLP_SUPPORT
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (req_i & (fifo_ready | branch_i | hwlp_masked)) begin
`else
if (req_i & (fifo_ready | branch_i)) begin
`endif // HWLP_SUPPORT
// prepare for next request
if (instr_rvalid_i) begin
@ -623,12 +385,6 @@ module riscv_prefetch_buffer
fifo_valid = 1'b1;
addr_valid = 1'b1;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
if (hwlp_masked) begin
fetch_is_hwlp = 1'b1;
end
`endif // HWLP_SUPPORT
if (instr_gnt_i) begin
NS = WAIT_RVALID;
@ -642,14 +398,6 @@ module riscv_prefetch_buffer
addr_valid = 1'b1;
NS = WAIT_ABORTED;
end
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
else if (hwlp_masked & valid_o) begin
addr_valid = 1'b1;
fetch_is_hwlp = 1'b1;
NS = WAIT_ABORTED;
end
`endif // HWLP_SUPPORT
end
end else begin
// just wait for rvalid and go back to IDLE, no new request
@ -701,19 +449,11 @@ module riscv_prefetch_buffer
if(rst_n == 1'b0)
begin
CS <= IDLE;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
hwlp_CS <= HWLP_NONE;
`endif // HWLP_SUPPORT
instr_addr_q <= '0;
end
else
begin
CS <= NS;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
hwlp_CS <= hwlp_NS;
`endif // HWLP_SUPPORT
if (addr_valid) begin
instr_addr_q <= instr_addr_o;

View file

@ -214,11 +214,8 @@ module riscv_prefetch_buffer_small
instr_req_o = 1'b1;
instr_addr_o = {fetch_addr_Q[31:2], 2'b00};
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
if (is_second_fetch_n)
addr_o = last_fetch_addr_Q;
`endif
if (~branch_i) begin
if (instr_gnt_i)
@ -248,11 +245,8 @@ module riscv_prefetch_buffer_small
WAIT_RVALID: begin
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
if (is_second_fetch_n)
addr_o = last_fetch_addr_Q;
`endif
if (~branch_i) begin

View file

@ -29,12 +29,7 @@
module riscv_register_file
#(
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter ADDR_WIDTH = 4,
`else
parameter ADDR_WIDTH = 5,
`endif // CONFIG_REGION: RV32E
parameter DATA_WIDTH = 32
)
(
@ -52,27 +47,12 @@ module riscv_register_file
input logic [ADDR_WIDTH-1:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
//Read port R3
input logic [ADDR_WIDTH-1:0] raddr_c_i,
output logic [DATA_WIDTH-1:0] rdata_c_o,
`endif // THREE_PORT_REG_FILE
// Write port W1
input logic [ADDR_WIDTH-1:0] waddr_a_i,
input logic [DATA_WIDTH-1:0] wdata_a_i,
input logic we_a_i
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
,
// Write port W2
input logic [ADDR_WIDTH-1:0] waddr_b_i,
input logic [DATA_WIDTH-1:0] wdata_b_i,
input logic we_b_i
`endif // THREE_PORT_REG_FILE
);
localparam NUM_WORDS = 2**ADDR_WIDTH;
@ -80,17 +60,9 @@ module riscv_register_file
logic [DATA_WIDTH-1:0] mem[NUM_WORDS];
logic [NUM_WORDS-1:1] waddr_onehot_a;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [NUM_WORDS-1:1] waddr_onehot_b, waddr_onehot_b_q;
`endif // THREE_PORT_REG_FILE
logic [NUM_WORDS-1:1] mem_clocks;
logic [DATA_WIDTH-1:0] wdata_a_q;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [DATA_WIDTH-1:0] wdata_b_q;
`endif // THREE_PORT_REG_FILE
logic clk_int;
@ -105,10 +77,6 @@ module riscv_register_file
//-----------------------------------------------------------------------------
assign rdata_a_o = mem[raddr_a_i];
assign rdata_b_o = mem[raddr_b_i];
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
assign rdata_c_o = mem[raddr_c_i];
`endif // THREE_PORT_REG_FILE
//-----------------------------------------------------------------------------
// WRITE : SAMPLE INPUT DATA
@ -117,12 +85,7 @@ module riscv_register_file
cluster_clock_gating CG_WE_GLOBAL
(
.clk_i ( clk ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.en_i ( we_a_i | we_b_i ),
`else
.en_i ( we_a_i ),
`endif // THREE_PORT_REG_FILE
.test_en_i ( test_en_i ),
.clk_o ( clk_int )
);
@ -132,21 +95,9 @@ module riscv_register_file
begin : sample_waddr
if (~rst_n) begin
wdata_a_q <= '0;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
wdata_b_q <= '0;
waddr_onehot_b_q <= '0;
`endif // THREE_PORT_REG_FILE
end else begin
if(we_a_i)
wdata_a_q <= wdata_a_i;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if(we_b_i)
wdata_b_q <= wdata_b_i;
waddr_onehot_b_q <= waddr_onehot_b;
`endif // THREE_PORT_REG_FILE
end
end
@ -164,19 +115,6 @@ module riscv_register_file
end
end
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
always_comb
begin : p_WADb
for(j = 1; j < NUM_WORDS; j++)
begin : p_WordIterb
if ( (we_b_i == 1'b1 ) && (waddr_b_i == j) )
waddr_onehot_b[j] = 1'b1;
else
waddr_onehot_b[j] = 1'b0;
end
end
`endif // THREE_PORT_REG_FILE
//-----------------------------------------------------------------------------
//-- WRITE : Clock gating (if integrated clock-gating cells are available)
@ -187,12 +125,7 @@ module riscv_register_file
cluster_clock_gating CG_Inst
(
.clk_i ( clk_int ),
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.en_i ( waddr_onehot_a[x] | waddr_onehot_b[x] ),
`else
.en_i ( waddr_onehot_a[x] ),
`endif // THREE_PORT_REG_FILE
.test_en_i ( test_en_i ),
.clk_o ( mem_clocks[x] )
);
@ -216,12 +149,7 @@ module riscv_register_file
for(k = 1; k < NUM_WORDS; k++)
begin : w_WordIter
if(mem_clocks[k] == 1'b1)
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
mem[k] = waddr_onehot_b_q[k] ? wdata_b_q : wdata_a_q;
`else
mem[k] = wdata_a_q;
`endif // THREE_PORT_REG_FILE
end
end

View file

@ -1,146 +1,98 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Francesco Conti - f.conti@unibo.it //
// //
// Additional contributions by: //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V register file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Register file with 31x 32 bit wide registers. Register 0 //
// is fixed to 0. This register file is based on flip-flops. //
// //
////////////////////////////////////////////////////////////////////////////////
`include "riscv_config.sv"
module riscv_register_file
#(
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter ADDR_WIDTH = 4,
`else
parameter ADDR_WIDTH = 5,
`endif // CONFIG_REGION: RV32E
parameter DATA_WIDTH = 32
)
(
// Clock and Reset
input logic clk,
input logic rst_n,
input logic test_en_i,
//Read port R1
input logic [ADDR_WIDTH-1:0] raddr_a_i,
output logic [DATA_WIDTH-1:0] rdata_a_o,
//Read port R2
input logic [ADDR_WIDTH-1:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
//Read port R3
input logic [ADDR_WIDTH-1:0] raddr_c_i,
output logic [DATA_WIDTH-1:0] rdata_c_o,
`endif // THREE_PORT_REG_FILE
// Write port W1
input logic [ADDR_WIDTH-1:0] waddr_a_i,
input logic [DATA_WIDTH-1:0] wdata_a_i,
input logic we_a_i
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
,
// Write port W2
input logic [ADDR_WIDTH-1:0] waddr_b_i,
input logic [DATA_WIDTH-1:0] wdata_b_i,
input logic we_b_i
`endif // THREE_PORT_REG_FILE
);
localparam NUM_WORDS = 2**ADDR_WIDTH;
logic [NUM_WORDS-1:0][DATA_WIDTH-1:0] rf_reg;
logic [NUM_WORDS-1:0] we_a_dec;
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [NUM_WORDS-1:0] we_b_dec;
`endif // THREE_PORT_REG_FILE
always_comb
begin : we_a_decoder
for (int i = 0; i < NUM_WORDS; i++) begin
if (waddr_a_i == i)
we_a_dec[i] = we_a_i;
else
we_a_dec[i] = 1'b0;
end
end
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
always_comb
begin : we_b_decoder
for (int i=0; i<NUM_WORDS; i++) begin
if (waddr_b_i == i)
we_b_dec[i] = we_b_i;
else
we_b_dec[i] = 1'b0;
end
end
`endif // THREE_PORT_REG_FILE
genvar i;
generate
// loop from 1 to NUM_WORDS-1 as R0 is nil
for (i = 1; i < NUM_WORDS; i++)
begin : rf_gen
always_ff @(posedge clk, negedge rst_n)
begin : register_write_behavioral
if (rst_n==1'b0) begin
rf_reg[i] <= 'b0;
end else begin
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
if(we_b_dec[i] == 1'b1)
rf_reg[i] <= wdata_b_i;
else if(we_a_dec[i] == 1'b1)
rf_reg[i] <= wdata_a_i;
`else
rf_reg[i] <= wdata_a_i;
`endif // THREE_PORT_REG_FILE
end
end
end
// R0 is nil
assign rf_reg[0] = '0;
endgenerate
assign rdata_a_o = rf_reg[raddr_a_i];
assign rdata_b_o = rf_reg[raddr_b_i];
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
assign rdata_c_o = rf_reg[raddr_c_i];
`endif // THREE_PORT_REG_FILE
endmodule
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Francesco Conti - f.conti@unibo.it //
// //
// Additional contributions by: //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V register file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Register file with 31x 32 bit wide registers. Register 0 //
// is fixed to 0. This register file is based on flip-flops. //
// //
////////////////////////////////////////////////////////////////////////////////
`include "riscv_config.sv"
module riscv_register_file
#(
parameter ADDR_WIDTH = 5,
parameter DATA_WIDTH = 32
)
(
// Clock and Reset
input logic clk,
input logic rst_n,
input logic test_en_i,
//Read port R1
input logic [ADDR_WIDTH-1:0] raddr_a_i,
output logic [DATA_WIDTH-1:0] rdata_a_o,
//Read port R2
input logic [ADDR_WIDTH-1:0] raddr_b_i,
output logic [DATA_WIDTH-1:0] rdata_b_o,
// Write port W1
input logic [ADDR_WIDTH-1:0] waddr_a_i,
input logic [DATA_WIDTH-1:0] wdata_a_i,
input logic we_a_i
);
localparam NUM_WORDS = 2**ADDR_WIDTH;
logic [NUM_WORDS-1:0][DATA_WIDTH-1:0] rf_reg;
logic [NUM_WORDS-1:0] we_a_dec;
always_comb
begin : we_a_decoder
for (int i = 0; i < NUM_WORDS; i++) begin
if (waddr_a_i == i)
we_a_dec[i] = we_a_i;
else
we_a_dec[i] = 1'b0;
end
end
genvar i;
generate
// loop from 1 to NUM_WORDS-1 as R0 is nil
for (i = 1; i < NUM_WORDS; i++)
begin : rf_gen
always_ff @(posedge clk, negedge rst_n)
begin : register_write_behavioral
if (rst_n==1'b0) begin
rf_reg[i] <= 'b0;
end else begin
rf_reg[i] <= wdata_a_i;
end
end
end
// R0 is nil
assign rf_reg[0] = '0;
endgenerate
assign rdata_a_o = rf_reg[raddr_a_i];
assign rdata_b_o = rf_reg[raddr_b_i];
endmodule

View file

@ -33,12 +33,7 @@ module riscv_core
#(
parameter N_EXT_PERF_COUNTERS = 0,
parameter INSTR_RDATA_WIDTH = 32,
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter REG_ADDR_WIDTH = 4
`else
parameter REG_ADDR_WIDTH = 5
`endif // RV32E
)
(
// Clock and Reset
@ -97,11 +92,6 @@ module riscv_core
localparam N_HWLP_BITS = $clog2(N_HWLP);
// IF/ID signals
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
logic is_hwlp_id;
logic [N_HWLP-1:0] hwlp_dec_cnt_id;
`endif // HWLP_SUPPORT
logic instr_valid_id;
logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
logic is_compressed_id;
@ -121,38 +111,15 @@ module riscv_core
// ID performance counter signals
logic is_decoding;
// CONFIG_REGION: PREPOST_SUPPORT
`ifdef PREPOST_SUPPORT
logic useincr_addr_ex; // Active when post increment
`endif // PREPOST_SUPPORT
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
logic data_misaligned;
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
logic [31:0] misaligned_addr;
logic first_cycle_misaligned;
`endif
`endif // ONLY_ALIGNED
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
logic mult_multicycle;
`endif // MUL_SUPPORT
// Jump and branch target and decision (EX->IF)
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
logic [31:0] jump_target_id, jump_target_ex;
`else
logic [31:0] jump_target_ex;
`endif
`else
logic [31:0] jump_target_ex;
`endif
logic branch_in_ex;
logic branch_decision;
@ -160,64 +127,21 @@ module riscv_core
logic if_busy;
logic lsu_busy;
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
logic [31:0] pc_ex; // PC of last executed branch or p.elw
`endif
// 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;
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
logic jal_in_ex;
`endif
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
logic alu_req_ex;
`endif
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
logic [31:0] alu_adder_result_ex; // Used to forward computed address to LSU
`endif // LSU_ADDER_SUPPORT
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
logic [ 4:0] bmask_a_ex;
logic [ 4:0] bmask_b_ex;
`endif // BIT_SUPPORT
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
logic [ 1:0] imm_vec_ext_ex;
logic [ 1:0] alu_vec_mode_ex;
`endif // VEC_SUPPORT
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// Multiplier Control
logic [ 2:0] mult_operator_ex;
logic [31:0] mult_operand_a_ex;
logic [31:0] mult_operand_b_ex;
logic [31:0] mult_operand_c_ex;
logic mult_en_ex;
logic mult_sel_subword_ex;
logic [ 1:0] mult_signed_mode_ex;
logic [ 4:0] mult_imm_ex;
logic [31:0] mult_dot_op_a_ex;
logic [31:0] mult_dot_op_b_ex;
logic [31:0] mult_dot_op_c_ex;
logic [ 1:0] mult_dot_signed_ex;
`endif // MUL_SUPPORT
// Register Write Control
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_ex;
`endif // THREE_PORT_REG_FILE
logic regfile_we_ex;
logic [(REG_ADDR_WIDTH-1):0] regfile_waddr_fw_wb_o; // From WB to ID
logic regfile_we_wb;
@ -245,17 +169,11 @@ module riscv_core
logic data_we_ex;
logic [1:0] data_type_ex;
logic data_sign_ext_ex;
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
logic [1:0] data_reg_offset_ex;
`endif // ONLY_ALIGNED
logic data_req_ex;
logic [31:0] data_pc_ex;
logic data_load_event_ex;
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
logic data_misaligned_ex;
`endif // ONLY_ALIGNED
// stall control
logic halt_if;
@ -271,10 +189,7 @@ module riscv_core
logic lsu_ready_ex;
logic lsu_ready_wb;
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
logic alu_ready;
`endif
// Signals between instruction core interface and pipe (if and id stages)
logic instr_req_int; // Id stage asserts a req to instruction core interface
@ -291,18 +206,6 @@ module riscv_core
logic exc_restore_id;
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// Hardware loop controller signals
logic [N_HWLP-1:0] [31:0] hwlp_start;
logic [N_HWLP-1:0] [31:0] hwlp_end;
logic [N_HWLP-1:0] [31:0] hwlp_cnt;
// used to write from CS registers to hardware loop registers
logic [N_HWLP_BITS-1:0] csr_hwlp_regid;
logic [2:0] csr_hwlp_we;
logic [31:0] csr_hwlp_data;
`endif // HWLP_SUPPORT
// Debug Unit
@ -386,10 +289,6 @@ module riscv_core
//////////////////////////////////////////////////
riscv_if_stage
#(
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.N_HWLP ( N_HWLP ),
`endif // HWLP_SUPPORT
.RDATA_WIDTH ( INSTR_RDATA_WIDTH )
)
if_stage_i
@ -411,11 +310,6 @@ module riscv_core
.instr_rdata_i ( instr_rdata_i ),
// outputs to ID stage
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.hwlp_dec_cnt_id_o ( hwlp_dec_cnt_id ),
.is_hwlp_id_o ( is_hwlp_id ),
`endif // HWLP_SUPPORT
.instr_valid_id_o ( instr_valid_id ),
.instr_rdata_id_o ( instr_rdata_id ),
.is_compressed_id_o ( is_compressed_id ),
@ -431,26 +325,12 @@ module riscv_core
.exc_pc_mux_i ( exc_pc_mux_id ),
.exc_vec_pc_mux_i ( exc_vec_pc_mux_id ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// from hwloop registers
.hwlp_start_i ( hwlp_start ),
.hwlp_end_i ( hwlp_end ),
.hwlp_cnt_i ( hwlp_cnt ),
`endif // HWLP_SUPPORT
// from debug unit
.dbg_jump_addr_i ( dbg_jump_addr ),
.dbg_jump_req_i ( dbg_jump_req ),
// Jump targets
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
.jump_target_id_i ( jump_target_id ),
`endif
`endif // JUMP_IN_ID
.jump_target_ex_i ( jump_target_ex ),
// pipeline stalls
@ -474,10 +354,6 @@ module riscv_core
/////////////////////////////////////////////////
riscv_id_stage
#(
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.N_HWLP ( N_HWLP )
`endif // HWLP_SUPPORT
)
id_stage_i
(
@ -492,11 +368,6 @@ module riscv_core
.is_decoding_o ( is_decoding ),
// Interface to instruction memory
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
.hwlp_dec_cnt_i ( hwlp_dec_cnt_id ),
.is_hwlp_i ( is_hwlp_id ),
`endif // HWLP_SUPPORT
.instr_valid_i ( instr_valid_id ),
.instr_rdata_i ( instr_rdata_id ),
.instr_req_o ( instr_req_int ),
@ -504,13 +375,6 @@ module riscv_core
// Jumps and branches
.branch_in_ex_o ( branch_in_ex ),
.branch_decision_i ( branch_decision ),
// CONFIG_REGION: JUMP_IN_ID
`ifdef JUMP_IN_ID
// CONFIG_REGION: NO_JUMP_ADDER
`ifndef NO_JUMP_ADDER
.jump_target_o ( jump_target_id ),
`endif
`endif
// IF and ID control signals
.clear_instr_valid_o ( clear_instr_valid ),
@ -531,10 +395,7 @@ module riscv_core
.if_ready_i ( if_ready ),
.id_ready_o ( id_ready ),
.ex_ready_i ( ex_ready ),
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
.wb_ready_i ( lsu_ready_wb ),
`endif // MERGE_ID_EX
.if_valid_i ( if_valid ),
.id_valid_o ( id_valid ),
@ -542,111 +403,42 @@ module riscv_core
.wb_valid_i ( wb_valid ),
// From the Pipeline ID/EX
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
.pc_ex_o ( pc_ex ),
`endif
.alu_operator_ex_o ( alu_operator_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 ), // Still needed if 2r1w reg file used
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
.alu_req_ex_o ( alu_req_ex ),
`endif
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
.jal_in_ex_o ( jal_in_ex ),
`endif
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
.bmask_a_ex_o ( bmask_a_ex ),
.bmask_b_ex_o ( bmask_b_ex ),
`endif // BIT_SUPPORT
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
.imm_vec_ext_ex_o ( imm_vec_ext_ex ),
.alu_vec_mode_ex_o ( alu_vec_mode_ex ),
`endif // VEC_SUPPORT
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.regfile_waddr_ex_o ( regfile_waddr_ex ),
`endif // THREE_PORT_REG_FILE
.regfile_we_ex_o ( regfile_we_ex ),
.regfile_alu_we_ex_o ( regfile_alu_we_ex ),
.regfile_alu_waddr_ex_o ( regfile_alu_waddr_ex ),
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// MUL
.mult_operator_ex_o ( mult_operator_ex ), // from ID to EX stage
.mult_en_ex_o ( mult_en_ex ), // from ID to EX stage
.mult_sel_subword_ex_o ( mult_sel_subword_ex ), // from ID to EX stage
.mult_signed_mode_ex_o ( mult_signed_mode_ex ), // from ID to EX stage
.mult_operand_a_ex_o ( mult_operand_a_ex ), // from ID to EX stage
.mult_operand_b_ex_o ( mult_operand_b_ex ), // from ID to EX stage
.mult_operand_c_ex_o ( mult_operand_c_ex ), // from ID to EX stage
.mult_imm_ex_o ( mult_imm_ex ), // from ID to EX stage
.mult_dot_op_a_ex_o ( mult_dot_op_a_ex ), // from ID to EX stage
.mult_dot_op_b_ex_o ( mult_dot_op_b_ex ), // from ID to EX stage
.mult_dot_op_c_ex_o ( mult_dot_op_c_ex ), // from ID to EX stage
.mult_dot_signed_ex_o ( mult_dot_signed_ex ), // from ID to EX stage
`endif // MUL_SUPPORT
// CSR ID/EX
.csr_access_ex_o ( csr_access_ex ),
.csr_op_ex_o ( csr_op_ex ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// hardware loop signals to IF hwlp controller
.hwlp_start_o ( hwlp_start ),
.hwlp_end_o ( hwlp_end ),
.hwlp_cnt_o ( hwlp_cnt ),
// hardware loop signals from CSR
.csr_hwlp_regid_i ( csr_hwlp_regid ),
.csr_hwlp_we_i ( csr_hwlp_we ),
.csr_hwlp_data_i ( csr_hwlp_data ),
`endif // HWLP_SUPPORT
// LSU
.data_req_ex_o ( data_req_ex ), // to load store unit
.data_we_ex_o ( data_we_ex ), // to load store unit
.data_type_ex_o ( data_type_ex ), // to load store unit
.data_sign_ext_ex_o ( data_sign_ext_ex ), // to load store unit
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
.data_reg_offset_ex_o ( data_reg_offset_ex ), // to load store unit
`endif // ONLY_ALIGNED
.data_load_event_ex_o ( data_load_event_ex ), // to load store unit
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
.data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit
`endif // ONLY_ALIGNED
// CONFIG_REGION: PREPOST_SUPPORT
`ifdef PREPOST_SUPPORT
.prepost_useincr_ex_o ( useincr_addr_ex ),
`endif // PREPOST_SUPPORT
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
.data_misaligned_i ( data_misaligned ),
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
.misaligned_addr_i ( misaligned_addr ),
.first_cycle_misaligned_i ( first_cycle_misaligned),
`endif
`endif // ONLY_ALIGNED
// Interrupt Signals
.irq_i ( irq_i ), // incoming interrupts
@ -686,11 +478,6 @@ module riscv_core
.regfile_alu_we_fw_i ( regfile_alu_we_fw ),
.regfile_alu_wdata_fw_i ( regfile_alu_wdata_fw ),
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// from ALU
.mult_multicycle_i ( mult_multicycle ),
`endif // MUL_SUPPORT
// Performance Counters
.perf_jump_o ( perf_jump ),
@ -718,45 +505,11 @@ module riscv_core
.alu_operand_a_i ( alu_operand_a_ex ), // from ID/EX pipe registers
.alu_operand_b_i ( alu_operand_b_ex ), // from ID/EX pipe registers
.alu_operand_c_i ( alu_operand_c_ex ), // from ID/EX pipe registers
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
.alu_req_ex_i ( alu_req_ex ),
`endif
// CONFIG_REGION: BIT_SUPPORT
`ifdef BIT_SUPPORT
.bmask_a_i ( bmask_a_ex ), // from ID/EX pipe registers
.bmask_b_i ( bmask_b_ex ), // from ID/EX pipe registers
`endif // BIT_SUPPORT
// CONFIG_REGION: VEC_SUPPORT
`ifdef VEC_SUPPORT
.imm_vec_ext_i ( imm_vec_ext_ex ), // from ID/EX pipe registers
.alu_vec_mode_i ( alu_vec_mode_ex ), // from ID/EX pipe registers
`endif // VEC_SUPPORT
// CONFIG_REGION: MUL_SUPPORT
`ifdef MUL_SUPPORT
// Multipler
.mult_operator_i ( mult_operator_ex ), // from ID/EX pipe registers
.mult_operand_a_i ( mult_operand_a_ex ), // from ID/EX pipe registers
.mult_operand_b_i ( mult_operand_b_ex ), // from ID/EX pipe registers
.mult_operand_c_i ( mult_operand_c_ex ), // from ID/EX pipe registers
.mult_en_i ( mult_en_ex ), // from ID/EX pipe registers
.mult_sel_subword_i ( mult_sel_subword_ex ), // from ID/EX pipe registers
.mult_signed_mode_i ( mult_signed_mode_ex ), // from ID/EX pipe registers
.mult_imm_i ( mult_imm_ex ), // from ID/EX pipe registers
.mult_dot_op_a_i ( mult_dot_op_a_ex ), // from ID/EX pipe registers
.mult_dot_op_b_i ( mult_dot_op_b_ex ), // from ID/EX pipe registers
.mult_dot_op_c_i ( mult_dot_op_c_ex ), // from ID/EX pipe registers
.mult_dot_signed_i ( mult_dot_signed_ex ), // from ID/EX pipe registers
.mult_multicycle_o ( mult_multicycle ), // to ID/EX pipe registers
`endif // MUL_SUPPORT
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifndef LSU_ADDER_SUPPORT
.alu_adder_result_ex_o ( alu_adder_result_ex ), // from ALU to LSU
`endif // LSU_ADDER_SUPPORT
// interface with CSRs
.csr_access_i ( csr_access_ex ),
@ -766,15 +519,8 @@ module riscv_core
.branch_in_ex_i ( branch_in_ex ),
.regfile_alu_waddr_i ( regfile_alu_waddr_ex ),
.regfile_alu_we_i ( regfile_alu_we_ex ),
// CONFIG_REGION: NO_JUMP_ADDER
`ifdef NO_JUMP_ADDER
.jal_in_ex_i ( jal_in_ex ),
`endif
// CONFIG_REGION: THREE_PORT_REG_FILE
`ifdef THREE_PORT_REG_FILE
.regfile_waddr_i ( regfile_waddr_ex ),
`endif // THREE_PORT_REG_FILE
.regfile_we_i ( regfile_we_ex ),
// Output of ex stage pipeline
@ -793,10 +539,6 @@ module riscv_core
// stall control
.lsu_ready_ex_i ( lsu_ready_ex ),
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
.alu_ready_o ( alu_ready ),
`endif
.ex_ready_o ( ex_ready ),
.ex_valid_o ( ex_valid ),
@ -834,38 +576,19 @@ module riscv_core
.data_we_ex_i ( data_we_ex ),
.data_type_ex_i ( data_type_ex ),
.data_wdata_ex_i ( alu_operand_c_ex ),
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
.data_reg_offset_ex_i ( data_reg_offset_ex ),
`endif // ONLY_ALIGNED
.data_sign_ext_ex_i ( data_sign_ext_ex ), // sign extension
.data_rdata_ex_o ( regfile_wdata ),
.data_req_ex_i ( data_req_ex ),
// CONFIG_REGION: LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
.operand_a_ex_i ( alu_operand_a_ex ),
.operand_b_ex_i ( alu_operand_b_ex ),
`else
.adder_result_ex_i ( alu_adder_result_ex),
`endif // LSU_ADDER_SUPPORT
// CONFIG_REGION: PREPOST_SUPPORT
`ifdef PREPOST_SUPPORT
.addr_useincr_ex_i ( useincr_addr_ex ),
`endif // PREPOST_SUPPORT
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
.data_misaligned_ex_i ( data_misaligned_ex ), // from ID/EX pipeline
.data_misaligned_o ( data_misaligned ),
// CONFIG_REGION: MERGE_ID_EX
`ifdef MERGE_ID_EX
.misaligned_addr_o ( misaligned_addr ),
.first_cycle_misaligned_o( first_cycle_misaligned),
`endif
`endif // ONLY_ALIGNED
// exception signals
.load_err_o ( lsu_load_err ),
@ -875,10 +598,7 @@ module riscv_core
.lsu_ready_ex_o ( lsu_ready_ex ),
.lsu_ready_wb_o ( lsu_ready_wb ),
// CONFIG_REGION: SPLITTED_ADDER
`ifdef SPLITTED_ADDER
.alu_ready_i ( alu_ready ),
`endif
.ex_valid_i ( ex_valid ),
.busy_o ( lsu_busy )
@ -923,10 +643,6 @@ module riscv_core
.pc_if_i ( pc_if ),
.pc_id_i ( pc_id ), // from IF stage
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
.pc_ex_i ( pc_ex ), // from ID/EX pipeline
`endif
.branch_target_i ( jump_target_ex ), // from ID/EX pipeline
.data_load_event_ex_i ( data_load_event_ex ), // from ID/EX pipeline
.exc_save_if_i ( exc_save_if ),
@ -937,17 +653,6 @@ module riscv_core
.exc_cause_i ( exc_cause ),
.save_exc_cause_i ( save_exc_cause ),
// CONFIG_REGION: HWLP_SUPPORT
`ifdef HWLP_SUPPORT
// from hwloop registers
.hwlp_start_i ( hwlp_start ),
.hwlp_end_i ( hwlp_end ),
.hwlp_cnt_i ( hwlp_cnt ),
.hwlp_regid_o ( csr_hwlp_regid ),
.hwlp_we_o ( csr_hwlp_we ),
.hwlp_data_o ( csr_hwlp_data ),
`endif // HWLP_SUPPORT
// performance counter related signals
.id_valid_i ( id_valid ),
@ -1032,10 +737,6 @@ module riscv_core
// signals for PPC and NPC
.pc_if_i ( pc_if ), // from IF stage
.pc_id_i ( pc_id ), // from IF stage
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
.pc_ex_i ( pc_ex ), // PC of last executed branch (in EX stage) or p.elw
`endif
.data_load_event_i ( data_load_event_ex ),
.instr_valid_id_i ( instr_valid_id ),
@ -1145,10 +846,7 @@ module riscv_core
.ex_data_wdata ( data_wdata_o ),
.wb_bypass ( ex_stage_i.branch_in_ex_i ),
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
.lsu_misaligned ( data_misaligned ),
`endif // ONLY_ALIGNED
.wb_valid ( wb_valid ),
.wb_reg_addr ( id_stage_i.registers_i.waddr_a_i ),

View file

@ -37,12 +37,7 @@ import "DPI-C" function void riscv_checker_reg_access(input chandle cpu, inpu
module riscv_simchecker
#(
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter REG_ADDR_WIDTH = 4
`else
parameter REG_ADDR_WIDTH = 5
`endif // RV32E
)
(
// Clock and Reset
@ -79,10 +74,7 @@ module riscv_simchecker
input logic [31:0] ex_data_addr,
input logic [31:0] ex_data_wdata,
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
input logic lsu_misaligned,
`endif // ONLY_ALIGNED
input logic wb_bypass,
input logic wb_valid,
@ -184,12 +176,7 @@ module riscv_simchecker
trace.mem_access.push_back(mem_acc);
end
// CONFIG_REGION: ONLY_ALIGNED
`ifndef ONLY_ALIGNED
end while ((!ex_valid || lsu_misaligned) && (!wb_bypass));
`else
end while ((!ex_valid) && (!wb_bypass));
`endif // ONLY_ALIGNED
trace.wb_bypass = wb_bypass;

View file

@ -27,30 +27,16 @@ import riscv_defines::*;
import riscv_tracer_defines::*;
// CONFIG_REGION: RV32E
`ifdef RV32E
// Source/Destination register instruction index
`define REG_S1 18:15
`define REG_S2 23:20
`define REG_S3 28:25
`define REG_D 10:07
`else
// 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
`endif // RV32E
module riscv_tracer
#(
// CONFIG_REGION: RV32E
`ifdef RV32E
parameter REG_ADDR_WIDTH = 4
`else
parameter REG_ADDR_WIDTH = 5
`endif // RV32E
)
(
// Clock and Reset
@ -616,12 +602,6 @@ module riscv_tracer
while(1) begin
instr_ex.get(trace);
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
// wait until we are going to the next stage
do begin
@(negedge clk);
`endif
// replace register written back
foreach(trace.regs_write[i])
@ -640,10 +620,6 @@ module riscv_tracer
trace.mem_access.push_back(mem_acc);
end
// CONFIG_REGION: MERGE_ID_EX
`ifndef MERGE_ID_EX
end while (!ex_valid && !wb_bypass); // ex branches bypass the WB stage
`endif
instr_wb.put(trace);
end

4
scripts/.gitignore vendored
View file

@ -1,4 +0,0 @@
build/
.idea/
synthesis_results/
gmon.out

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
`define BIT_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,140 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
`define BIT_SUPPORT
// CONFIG: JUMP_IN_ID_SUPPORT
// will enable jump capability in ID stage.
`define JUMP_IN_ID_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,137 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
//`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,137 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
//`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
//`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,139 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
//`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef SMALL_IF
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,137 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,136 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
//`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,141 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
//`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
//`define NO_JUMP_ADDER
`endif
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,135 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,135 +0,0 @@
// Copyright 2015 ETH Zurich and University of Bologna.
// Copyright and related rights are licensed under the Solderpad Hardware
// License, Version 0.51 (the “License”); you may not use this file except in
// compliance with the License. You may obtain a copy of the License at
// http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
// or agreed to in writing, software, hardware and materials distributed under
// this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
////////////////////////////////////////////////////////////////////////////////
// Engineer: Michael Gautschi - gautschi@iis.ee.ethz.ch //
// //
// Additional contributions by: //
// //
// Markus Wegmann - markus.wegmann@technokrat.ch //
// //
// Design Name: RISC-V config file //
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Configure optional simulation modules //
// //
////////////////////////////////////////////////////////////////////////////////
// no traces for synthesis, they are not synthesizable
`ifndef SYNTHESIS
`ifndef PULP_FPGA_EMUL
`define TRACE_EXECUTION
`endif
//`define SIMCHECKER
`endif
// littleRISCV configuration.
// Decomment to enable.
// The format should be strictly followed so the ri5cly-manage tool can parse the configuration
// A CONFIG section declares a config definition, a CONFIG_REGION enables the tool to remove disabled code
// for export. See the ri5cly-manage.py tool help and source code in the /scripts folder for more information.
// CONFIG: MUL_SUPPORT
// will enable RISCV32M support for multiplication, division, MAC operations. Uses a lot of multiplications
//`define MUL_SUPPORT
// CONFIG: VEC_SUPPORT
// will enable RISCV32V support for vector operations.
//`define VEC_SUPPORT
// CONFIG: HWLP_SUPPORT
// will enable hardware loop support.
//`define HWLP_SUPPORT
// CONFIG: BIT_SUPPORT
// will enable bit manipulation and counting support.
//`define BIT_SUPPORT
// CONFIG: LSU_ADDER_SUPPORT
// will enable an additional adder in the LSU for better timings.
//`define LSU_ADDER_SUPPORT
`ifdef LSU_ADDER_SUPPORT
// CONFIG: PREPOST_SUPPORT
// will enable pre/post increment load/store support support.
//`define PREPOST_SUPPORT
`endif // LSU_ADDER_SUPPORT
// CONFIG: MATH_SPECIAL_SUPPORT
// will enable clip, min and max operations support.
//`define MATH_SPECIAL_SUPPORT
// CONFIG: JUMP_IN_ID
// will enable direct jump in ID. Might increase critical path of jump target.
`define JUMP_IN_ID
// Dependent definitions
// CONFIG: THREE_PORT_REG_FILE
// enables 3r2w reg file (rather than 2r1w)
//`define THREE_PORT_REG_FILE
`ifndef MUL_SUPPORT
`ifndef VEC_SUPPORT
`ifndef BIT_SUPPORT
`ifndef LSU_ADDER_SUPPORT
`ifndef PREPOST_SUPPORT
`ifndef MATH_SPECIAL_SUPPORT
// CONFIG: SIMPLE_ALU
// will enable simplified ALU for less gates. It does not support vectors, shuffling, nor bit operations.
`define SIMPLE_ALU
// CONFIG: SMALL_IF
// will disable large FIFO in IF stage and use a more simple one.
//`define SMALL_IF
// CONFIG: RV32E
// will reduce the register file to 16 words
`define RV32E
// CONFIG: ONLY_ALIGNED
// will only allow aligned memory accesses and therefore overlapping mustn't occur
`define ONLY_ALIGNED
// CONFIG: SPLITTED_ADDER
// will split ALU Adder in half and use two cycles to add operands
//`define SPLITTED_ADDER
`ifndef SPLITTED_ADDER
`ifdef JUMP_IN_ID
// CONFIG: MERGE_ID_EX
// will merge/fuse the ID and EX stage
`define MERGE_ID_EX
`ifdef MERGE_ID_EX
// CONFIG: NO_JUMP_ADDER
// will use ALU adder to calculate target and get return address from prefetcher
`define NO_JUMP_ADDER
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif
`endif

View file

@ -1,481 +0,0 @@
#!/bin/env python3
# Copyright 2016 ETH Zurich and University of Bologna.
# Copyright and related rights are licensed under the Solderpad Hardware
# License, Version 0.51 (the “License”); you may not use this file except in
# compliance with the License. You may obtain a copy of the License at
# http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law
# or agreed to in writing, software, hardware and materials distributed under
# this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR
# CONDITIONS OF ANY KIND, either express or implied. See the License for the
# specific language governing permissions and limitations under the License.
################################################################################
## Engineer: Markus Wegmann - markus.wegmann@technokrat.ch ##
## ##
## Project Name: littleRISCV ##
## Language: Python 3.6 ##
## ##
## Description: This program can overwrite the littleRISCV config and ##
## export a clean version of the core. The macro switches ##
## and all unnecessary code is removed in the root .sv files. ##
## ##
################################################################################
import sys
if sys.version_info[0] < 3:
raise "Must be using Python 3"
import os
import shutil
import argparse
import re
import zipfile
import subprocess
class bcolors:
HEADER = '\033[95m'
OKBLUE = '\033[94m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
ENDC = '\033[0m'
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
def zipdir(path, ziph):
# ziph is zipfile handle
for root, dirs, files in os.walk(path):
for file in files:
ziph.write(os.path.relpath(os.path.join(root, file), os.path.join(path, '..')))
def main():
littleRISCV_path = os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/..") # Path to littleRISCV folder
print(littleRISCV_path)
parser = argparse.ArgumentParser(description="ri5cly-manage.py can overwrite the config and export a clean version of littleRISCV core.")
parser.add_argument('-i', dest="new_riscv_config", metavar='.../new_riscv_config.sv',
help='path to a new config file to overwrite littleRISCV config')
parser.add_argument('-o', dest='export_folder_path', metavar='.../export_folder_path',
help='path to a folder to export clean version of littleRISCV without preprocessor switches')
parser.add_argument('-z', dest='zip', action='store_true',
help='zip the export into a tar.gz')
parser.add_argument('--synthesize', dest='synthesize', action='store_true',
help='will synthesize the current or new configuration')
parser.add_argument('--report', dest='report', action='store_true',
help='will report custom synthesized design')
parser.add_argument('--test', dest='test', action='store_true',
help='will run some basic RTL simulations test, like helloworld')
parser.add_argument('--synthesize_all', dest='synthesize_all', action='store_true',
help='will synthesize all sample configs in the scripts/example_configs folder with Synopsys')
parser.add_argument('--report_all', dest='report_all', action='store_true',
help='will report all sample configs which have been synthesized')
parser.add_argument('--test_all', dest='test_all', action='store_true',
help='will run some basic RTL simulations test, like helloworld on all sample configs in the scripts/example_configs folder')
parser.add_argument('--setup_script', dest='setup_script', metavar='.../new_setup.tcl',
help='will overwrite setup script in Synopsys (imperio/synopsys/scripts/setup/setup.tcl) with given file')
parser.add_argument('--vsim', dest='vsim_test',
help='will start ModelSim for the given test')
args = parser.parse_args()
action_taken = False
if args.new_riscv_config is not None:
overwriteConfig(args.new_riscv_config, littleRISCV_path)
action_taken = True
if args.export_folder_path is not None:
exportCleanVersion(args.export_folder_path, littleRISCV_path, zip=args.zip)
action_taken = True
if args.synthesize == True:
synthesize(littleRISCV_path)
report(littleRISCV_path)
action_taken = True
elif args.report == True:
report(littleRISCV_path)
action_taken = True
if args.synthesize_all == True:
synthesizeAll(littleRISCV_path)
reportAll(littleRISCV_path)
action_taken = True
elif args.report_all == True:
reportAll(littleRISCV_path)
action_taken = True
if args.test_all == True:
testAll(littleRISCV_path)
action_taken = True
if args.test == True:
test(littleRISCV_path)
action_taken = True
if args.setup_script is not None:
synopsysSetSetupScript(args.setup_script, littleRISCV_path)
action_taken = True
if args.vsim_test is not None:
vsimTest(args.vsim_test, littleRISCV_path)
action_taken = True
if action_taken == False:
print("No action taken. Please see the help below for more information:")
parser.print_help()
def backupConfig(littleRISCV_path):
print("Backing up current config (include/riscv_config.sv) to (include/riscv_config.sv.bak)")
shutil.copy(os.path.abspath(littleRISCV_path + "/include/riscv_config.sv"), os.path.abspath(littleRISCV_path + "/include/riscv_config.sv.bak")) # Backup
def restoreConfig(littleRISCV_path):
print("Restoring backup config from (include/riscv_config.sv.bak).")
shutil.copy(os.path.abspath(littleRISCV_path + "/include/riscv_config.sv"), os.path.abspath(littleRISCV_path + "/include/riscv_config.sv.bak")) # Backup
def overwriteConfig(new_config_path, littleRISCV_path, backup=True):
print("Overwriting current config (include/riscv_config.sv) with new one ({})".format(new_config_path))
if backup:
backupConfig(littleRISCV_path)
shutil.copy(os.path.abspath(new_config_path), os.path.abspath(littleRISCV_path + "/include/riscv_config.sv")) # Copy new config to littleRISCV
def parseConfig(littleRISCV_path):
print("Trying to parse configuration.")
definitions = []
config = os.path.abspath(littleRISCV_path + "/include/riscv_config.sv")
with open(config, encoding="utf8") as f:
nesting_counter = 0 # If we enter a not-enabled section, keep track when we leave the section again
content = f.readlines()
while len(content) > 0:
line = content.pop(0)
config_pattern = re.compile("^//.*CONFIG:\s(\w*)$") # Test for config declaration
m = config_pattern.match(line)
if m is not None and nesting_counter == 0:
content.pop(0) # Pop description
line = content.pop(0)
config_value_pattern = re.compile("^`define\s(\w*)$") # Check if config enabled and extract name
m = config_value_pattern.match(line)
if m is not None:
definitions.append(m.group(1))
else:
ifdef_pattern = re.compile("^`ifdef\s(\w*)$") # Check if we have a dependant config
m = ifdef_pattern.match(line)
if m is not None:
if m.group(1) in definitions:
pass
else:
nesting_counter += 1
ifndef_pattern = re.compile("^`ifndef\s(\w*)$") # Check if we have a dependant config
m = ifndef_pattern.match(line)
if m is not None:
if not (m.group(1) in definitions):
pass
else:
nesting_counter += 1
endif_pattern = re.compile("^`endif.*$") # Check if we ended a block
m = endif_pattern.match(line)
if m is not None:
nesting_counter -= 1
if nesting_counter < 0:
nesting_counter = 0
print("Enabled CONFIG definitions: {}".format(definitions))
return definitions
def processSystemVerilog(filename, folderpath, definitions):
print("Processing: {}".format(filename))
content = []
new_content = []
with open(os.path.abspath(folderpath+"/"+filename), encoding="utf8") as f:
content = f.readlines()
nesting_counter = 0 # If we enter a not-enabled section, keep track when we leave the section again
level_counter = 0
is_else_true = False # at first occurence of missing declarations
while len(content) > 0:
is_codeline = True
line = content.pop(0)
config_pattern = re.compile("^\s*//.*CONFIG_REGION:\s(\w*)$") # Test for config region declaration
m = config_pattern.match(line)
if m is not None:
level_counter += 1
is_codeline = False
line = content.pop(0)
ifdef_pattern = re.compile("^\s*`ifdef\s(\w*)$") # Check if we have an ifdef
m = ifdef_pattern.match(line)
if m is not None:
if m.group(1) in definitions:
if nesting_counter == 0:
is_else_true = False
else:
nesting_counter += 1
else:
if nesting_counter == 0:
is_else_true = True
nesting_counter += 1
ifndef_pattern = re.compile("^\s*`ifndef\s(\w*)$") # Check if we have an ifndef
m = ifndef_pattern.match(line)
if m is not None:
if not (m.group(1) in definitions):
if nesting_counter == 0:
is_else_true = False
else:
nesting_counter += 1
else:
if nesting_counter == 0:
is_else_true = True
nesting_counter += 1
else_pattern = re.compile("^\s*`else.*$") # Check if we have an else
m = else_pattern.match(line)
if m is not None:
if level_counter > 0:
is_codeline = False
if nesting_counter == 1 and is_else_true:
nesting_counter -= 1
if (not is_else_true) and nesting_counter == 0:
nesting_counter += 1
endif_pattern = re.compile("^\s*`endif.*$") # Check if we have an endif
m = endif_pattern.match(line)
if m is not None:
if level_counter > 0:
is_codeline = False
level_counter -= 1
nesting_counter -= 1
if nesting_counter < 0:
nesting_counter = 0
if is_codeline and nesting_counter == 0:
new_content.append(line)
os.remove(os.path.abspath(folderpath+"/"+filename))
with open(os.path.abspath(folderpath+"/"+filename), 'w', encoding="utf8") as f:
f.writelines(new_content)
def exportCleanVersion(build_path, littleRISCV_path, zip=False):
print("Exporting clean version of littleRISCV without preprocessor switches to defined output folder.")
definitions = parseConfig(littleRISCV_path)
shutil.rmtree(os.path.abspath(build_path), ignore_errors=True)
shutil.copytree(os.path.abspath(littleRISCV_path), os.path.abspath(build_path), ignore=shutil.ignore_patterns("*.git", "scripts", "docs"))
for filename in os.listdir(os.path.abspath(build_path)):
sv_p = re.compile("^.*\.sv")
m = sv_p.match(filename)
if m is not None:
processSystemVerilog(filename, build_path, definitions)
with open(os.path.abspath(build_path+"/THIS_CORE_IS_AUTOMATICALLY_GENERATATED!!!.txt"), 'w', encoding="utf8") as f:
f.write("This core export was automatically generated by ri5cly-manage.py\n\n")
f.write("Following settings were enabled: {}".format(definitions))
if zip is True:
print("Zip exported version.")
zipf = zipfile.ZipFile(os.path.abspath(build_path)+".zip", 'w', zipfile.ZIP_DEFLATED)
zipdir(os.path.abspath(build_path), zipf)
zipf.close()
shutil.rmtree(os.path.abspath(build_path), ignore_errors=True)
def synopsysSetSetupScript(setup_script, littleRISCV_path):
if not os.path.exists(os.path.abspath(littleRISCV_path+"/../../../synopsys/start_synopsys.py")):
print("littleRISCV repository not contained in Imperio/Pulpino project! Canceling.")
return
print("Changing setup script in Synopsys (imperio/synopsys/scripts/setup/setup.tcl) to given setup file.")
shutil.copy(os.path.abspath(setup_script), os.path.abspath(littleRISCV_path + "/../../../synopsys/scripts/setup/setup.tcl"))
def synthesizeAll(littleRISCV_path):
if not os.path.exists(os.path.abspath(littleRISCV_path+"/../../../synopsys/start_synopsys_synth.py")):
print("littleRISCV repository not contained in Imperio/Pulpino project! Canceling.")
return
if not os.path.isdir(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/")):
os.mkdir(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/"))
backupConfig(littleRISCV_path)
print("Synthsizing all configs in (/scripts/example_configs/).")
for filename in os.listdir(os.path.abspath(littleRISCV_path + "/scripts/example_configs")):
print("Synthesizing {}".format(filename))
overwriteConfig(os.path.abspath(littleRISCV_path + "/scripts/example_configs/" + filename), littleRISCV_path, backup=False)
p = subprocess.Popen([os.path.abspath(littleRISCV_path+"/../../../synopsys/start_synopsys_synth.py")], cwd=os.path.abspath(littleRISCV_path+"/../../../synopsys/"))
p.wait()
content = ""
# Get clock of synopsys setup configuration
with open(os.path.abspath(littleRISCV_path+"/../../../synopsys/scripts/setup/setup.tcl"), encoding="utf8") as f:
content = f.read()
clock_p = re.compile("set\sCLOCK_SLOW\s(\d+\.?\d*);")
m = clock_p.search(content)
if m is not None:
clock = m.group(1)
else:
clock = "undefined"
shutil.rmtree(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/" + filename + "_{}".format(clock)), ignore_errors=True)
shutil.copytree(os.path.abspath(littleRISCV_path + "/../../../synopsys"), os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/" + filename + "_{}".format(clock)))
print("Synthesized {}".format(filename + "_{}".format(clock)))
restoreConfig(littleRISCV_path)
print("Synthesized all configurations! Bye.")
def synthesize(littleRISCV_path):
if not os.path.exists(os.path.abspath(littleRISCV_path+"/../../../synopsys/start_synopsys_synth.py")):
print("littleRISCV repository not contained in Imperio/Pulpino project! Canceling.")
if not os.path.isdir(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/")):
os.mkdir(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/"))
p = subprocess.Popen([os.path.abspath(littleRISCV_path+"/../../../synopsys/start_synopsys_synth.py")], cwd=os.path.abspath(littleRISCV_path+"/../../../synopsys/"))
p.wait()
content = ""
# Get clock of synopsys setup configuration
with open(os.path.abspath(littleRISCV_path+"/../../../synopsys/scripts/setup/setup.tcl"), encoding="utf8") as f:
content = f.read()
clock_p = re.compile("set\sCLOCK_SLOW\s(\d+\.?\d*);")
m = clock_p.search(content)
if m is not None:
clock = str(m.group(1))
else:
clock = "undefined"
shutil.rmtree(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/custom" + "_{}".format(clock)), ignore_errors=True)
shutil.copytree(os.path.abspath(littleRISCV_path + "/../../../synopsys"), os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/custom" + "_{}".format(clock)))
print("Synthesized Imperio! Results are in little-riscv/scripts/synthesis_results/custom_{}. Bye.".format(clock))
def report_specific(config_name, littleRISCV_path):
clock_p = re.compile("^.*_(\d+\.?\d*)$")
m = clock_p.match(config_name)
if m is not None:
period = m.group(1)
clock = float(m.group(1))
clock = 1000/clock # [MHz]
else:
period = "*"
clock = "undefined"
process = os.popen("cat " + os.path.abspath(littleRISCV_path + "/scripts/synthesis_results/" + config_name + "/reports/imperio_" + period +"_area.rpt | grep 'pulpino_i/core_region_i/RISCV_CORE' "))
area = process.read()
process.close()
area_pattern = re.compile("pulpino_i/core_region_i/RISCV_CORE\s*(\d+\.?\d*)\s*.*")
m = area_pattern.match(area)
if m is not None:
area = m.group(1)
area = float(area)
area /= 1.44 * 1000.0 # 1k GE (gate equivalent)
else:
area = "undefined"
number_p = re.compile("^(\d+)_.*$")
m = number_p.match(config_name)
if m is not None:
config_number = m.group(1)
else:
config_number = ""
return "{},{},{},{}".format(config_name,config_number,area,clock)
def report(littleRISCV_path):
print("Config,Config Nr.,Area (kGE),Frequency (MHz)")
for filename in os.listdir(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results")):
custom_p = re.compile("^custom.*$")
m = custom_p.match(filename)
if m is not None:
print(report_specific(filename, littleRISCV_path))
def reportAll(littleRISCV_path):
print("Config,Config Nr.,Area (kGE),Frequency (MHz)")
for filename in os.listdir(os.path.abspath(littleRISCV_path + "/scripts/synthesis_results")):
print(report_specific(filename, littleRISCV_path))
def testAll(littleRISCV_path):
backupConfig(littleRISCV_path)
for filename in os.listdir(os.path.abspath(littleRISCV_path + "/scripts/example_configs")):
print("Testing RTL of {}".format(filename))
overwriteConfig(os.path.abspath(littleRISCV_path + "/scripts/example_configs/" + filename), littleRISCV_path, backup=False)
test(littleRISCV_path)
restoreConfig(littleRISCV_path)
print("Tested all configurations! Bye.")
def test(littleRISCV_path):
if not os.path.exists(os.path.abspath(littleRISCV_path+"/../../sw/build")):
print("littleRISCV repository not contained in Imperio/Pulpino project, or you did not generate make files with CMake in pulpino/sw/build. Canceling.")
return
print("Testing current configuration.")
print("Compiling design")
p = subprocess.Popen(["make", "vcompile"], cwd=os.path.abspath(littleRISCV_path+"/../../sw/build"))
p.wait()
print("Running helloworld")
p = subprocess.Popen(["make", "helloworld.vsimc"], cwd=os.path.abspath(littleRISCV_path+"/../../sw/build"))
p.wait()
print("Running compressed")
p = subprocess.Popen(["make", "compressed.vsimc"], cwd=os.path.abspath(littleRISCV_path+"/../../sw/build"))
p.wait()
print("Testing finished.")
def vsimTest(vsim_test, littleRISCV_path):
if not os.path.exists(os.path.abspath(littleRISCV_path+"/../../sw/build")):
print("littleRISCV repository not contained in Imperio/Pulpino project, or you did not generate make files with CMake in pulpino/sw/build. Canceling.")
return
print("Opening VSIM test")
print("Running helloworld")
p = subprocess.Popen(["make", vsim_test + ".vsim"], cwd=os.path.abspath(littleRISCV_path+"/../../sw/build"))
p.wait()
print("ModelSim was quit.")
if __name__ == "__main__":
main()

View file

@ -1,38 +0,0 @@
set NUM_CORES 16;
set CLOCK_SLOW 10; # 100 MHz
set DESIGN_NAME imperio_${CLOCK_SLOW}
set USE_CORNER "SLOW" ;# "SLOW | NOMINAL"
set USE_CORE "LITTLE_RISCV" ;# "RISCV | OR10N | LITTLE_RISCV"
set RI5CY_LATCH_RF "TRUE" ;# "TRUE | FALSE"
set UNGROUP_CORE "FALSE" ;# "TRUE | FALSE"
set ASIC_PATH ../rtl
set RTL_PATH ../pulpino/rtl
set IPS_PATH ../pulpino/ips
set search_path [ join "$IPS_PATH/axi/wb2axi
$IPS_PATH/axi/per2axi
$IPS_PATH/axi/axi2per
$IPS_PATH/axi/axi2mem
$IPS_PATH/axi/axi_node
$IPS_PATH/apb/apb_i2c
$IPS_PATH/apb/apb_event_unit/include
$RTL_PATH/includes
$search_path"
]
set RISCV_PATH $IPS_PATH/riscv
set OR10N_PATH $IPS_PATH/or10n
set LITTLE_RISCV_PATH $IPS_PATH/little-riscv
set AXI_PATH $IPS_PATH/axi
set SCM_PATH $IPS_PATH/scm
set APB_PATH $IPS_PATH/apb
set PULPINO_PATH $RTL_PATH
set ADV_DEBUG_IF_PATH $IPS_PATH/adv_dbg_if/rtl
# supress port can become inout port (for interfaces crossing hierarchy)
suppress_message {VER-735}
# suppress 'assert property not supported'
suppress_message {VER-708}

View file

@ -1,38 +0,0 @@
set NUM_CORES 16;
set CLOCK_SLOW 3; # 333 MHz
set DESIGN_NAME imperio_${CLOCK_SLOW}
set USE_CORNER "SLOW" ;# "SLOW | NOMINAL"
set USE_CORE "LITTLE_RISCV" ;# "RISCV | OR10N | LITTLE_RISCV"
set RI5CY_LATCH_RF "TRUE" ;# "TRUE | FALSE"
set UNGROUP_CORE "FALSE" ;# "TRUE | FALSE"
set ASIC_PATH ../rtl
set RTL_PATH ../pulpino/rtl
set IPS_PATH ../pulpino/ips
set search_path [ join "$IPS_PATH/axi/wb2axi
$IPS_PATH/axi/per2axi
$IPS_PATH/axi/axi2per
$IPS_PATH/axi/axi2mem
$IPS_PATH/axi/axi_node
$IPS_PATH/apb/apb_i2c
$IPS_PATH/apb/apb_event_unit/include
$RTL_PATH/includes
$search_path"
]
set RISCV_PATH $IPS_PATH/riscv
set OR10N_PATH $IPS_PATH/or10n
set LITTLE_RISCV_PATH $IPS_PATH/little-riscv
set AXI_PATH $IPS_PATH/axi
set SCM_PATH $IPS_PATH/scm
set APB_PATH $IPS_PATH/apb
set PULPINO_PATH $RTL_PATH
set ADV_DEBUG_IF_PATH $IPS_PATH/adv_dbg_if/rtl
# supress port can become inout port (for interfaces crossing hierarchy)
suppress_message {VER-735}
# suppress 'assert property not supported'
suppress_message {VER-708}

View file

@ -1,38 +0,0 @@
set NUM_CORES 16;
set CLOCK_SLOW 5; # 200 MHz
set DESIGN_NAME imperio_${CLOCK_SLOW}
set USE_CORNER "SLOW" ;# "SLOW | NOMINAL"
set USE_CORE "LITTLE_RISCV" ;# "RISCV | OR10N | LITTLE_RISCV"
set RI5CY_LATCH_RF "TRUE" ;# "TRUE | FALSE"
set UNGROUP_CORE "FALSE" ;# "TRUE | FALSE"
set ASIC_PATH ../rtl
set RTL_PATH ../pulpino/rtl
set IPS_PATH ../pulpino/ips
set search_path [ join "$IPS_PATH/axi/wb2axi
$IPS_PATH/axi/per2axi
$IPS_PATH/axi/axi2per
$IPS_PATH/axi/axi2mem
$IPS_PATH/axi/axi_node
$IPS_PATH/apb/apb_i2c
$IPS_PATH/apb/apb_event_unit/include
$RTL_PATH/includes
$search_path"
]
set RISCV_PATH $IPS_PATH/riscv
set OR10N_PATH $IPS_PATH/or10n
set LITTLE_RISCV_PATH $IPS_PATH/little-riscv
set AXI_PATH $IPS_PATH/axi
set SCM_PATH $IPS_PATH/scm
set APB_PATH $IPS_PATH/apb
set PULPINO_PATH $RTL_PATH
set ADV_DEBUG_IF_PATH $IPS_PATH/adv_dbg_if/rtl
# supress port can become inout port (for interfaces crossing hierarchy)
suppress_message {VER-735}
# suppress 'assert property not supported'
suppress_message {VER-708}

View file

@ -1,18 +0,0 @@
#!/bin/csh
# Test all defined clock setups scripts with all configurations. This might take some time!
#rm -r ./synthesis_results;
python3 ./ri5cly-manage.py --setup_script ./synopsys_setup_scripts/setup_10.tcl;
python3 ./ri5cly-manage.py --synthesize_all;
python3 ./ri5cly-manage.py --setup_script ./synopsys_setup_scripts/setup_5.tcl;
python3 ./ri5cly-manage.py --synthesize_all;
python3 ./ri5cly-manage.py --setup_script ./synopsys_setup_scripts/setup_3.tcl;
python3 ./ri5cly-manage.py --synthesize_all;
python3 ./ri5cly-manage.py --report_all;

View file

@ -1,6 +0,0 @@
#!/bin/bash
vlib ./work
vlog -sv ../../../alu_div.sv || exit 1
vlog -sv +incdir+../ ../tb.sv || exit 1

View file

@ -1,53 +0,0 @@
#!/bin/bash
#default no batch mode
BATCHMODE=0
######################
# helper function
LIGHT_GREEN_COL="\033[1;32m"
LIGHT_RED_COL="\033[1;31m"
NO_COL="\033[0m"
function check_exitcode() {
if [ $1 -ne 0 ] ; then
echo -en "$LIGHT_RED_COL$2 [ FAILED ]$NO_COL \n";
exit 1;
else
echo -en "$LIGHT_GREEN_COL$2 [ OK ]$NO_COL \n";
fi
}
######################
######################
# check args,
# otherwise use default
######################
if [ $1 -eq 0 ]; then
BATCHMODE=1
fi
######################
#compile sourcefiles
######################
./compile.sh
check_exitcode $? "compile sources"
######################
######################
#start modelsim in batch mode
######################
if [ ${BATCHMODE} -eq 1 ] ; then
vsim -c -t ps -do tb_nogui.do
else
######################
#start modelsim normally
######################
vsim -t 1ps -do tb.do
fi

View file

@ -1,30 +0,0 @@
###############################################################################
## Title : testbench starter script (with GUI)
## Project : Approximate Cholesky Solver
## Purpose : compiles all sources and generates the testvectors
## Author : Michael Schaffner (schaffner@iis.ee.ethz.ch)
###############################################################################
## File ID : $Id: tb.do 756 2014-06-20 12:41:06Z michscha $
## SVN Rev. : $Revision: 756 $
## Date: : $Date: 2014-06-20 14:41:06 +0200 (Fri, 20 Jun 2014) $
## Modified by : $Author: michscha $
###############################################################################
## Major Changes:
## Date | Author | Description
## 2014/01/18 | schaffner | created
###############################################################################
## Description:
##
##
###############################################################################
## Copyright (c) 2014 Disney Research Zurich, Integrated Systems Lab ETH Zurich
###############################################################################
#vsim -sva -assertdebug -t ps tb
vsim -voptargs="+acc" -t ps tb
#turn off disturbing warnings...
#set NumericStdNoWarnings 1
do wave.do
run -all

View file

@ -1,33 +0,0 @@
###############################################################################
## Title : testbench starter script (no GUI)
## Project : Approximate Cholesky Solver
## Purpose : compiles all sources and generates the testvectors
## Author : Michael Schaffner (schaffner@iis.ee.ethz.ch)
###############################################################################
## File ID : $Id: tb_nogui.do 756 2014-06-20 12:41:06Z michscha $
## SVN Rev. : $Revision: 756 $
## Date: : $Date: 2014-06-20 14:41:06 +0200 (Fri, 20 Jun 2014) $
## Modified by : $Author: michscha $
###############################################################################
## Major Changes:
## Date | Author | Description
## 2014/01/18 | schaffner | created
###############################################################################
## Description:
##
##
###############################################################################
## Copyright (c) 2014 Disney Research Zurich, Integrated Systems Lab ETH Zurich
###############################################################################
vsim -t ps \
tb
#turn off disturbing warnings...
set StdArithNoWarnings 1
set StdNumNoWarnings 1
set NumericStdNoWarnings 1
run -all
exit -f

View file

@ -1,95 +0,0 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /tb/AcqTrig_T
add wave -noupdate /tb/C_ACQ_DEL
add wave -noupdate /tb/C_APPL_DEL
add wave -noupdate /tb/C_CLK_HI
add wave -noupdate /tb/C_CLK_LO
add wave -noupdate /tb/C_LOG_WIDTH
add wave -noupdate /tb/C_WIDTH
add wave -noupdate /tb/Clk_CI
add wave -noupdate /tb/EndOfSim_T
add wave -noupdate /tb/InRdy_SO
add wave -noupdate /tb/InVld_SI
add wave -noupdate /tb/NumStim_T
add wave -noupdate /tb/OpA_DI
add wave -noupdate /tb/OpA_T
add wave -noupdate /tb/OpBShift_DI
add wave -noupdate /tb/OpBSign_SI
add wave -noupdate /tb/OpB_DI
add wave -noupdate /tb/OpB_T
add wave -noupdate /tb/OpCode_SI
add wave -noupdate /tb/OutRdy_SI
add wave -noupdate /tb/OutVld_SO
add wave -noupdate /tb/Res_DO
add wave -noupdate /tb/Rst_RBI
add wave -noupdate /tb/StimEnd_T
add wave -noupdate /tb/StimStart_T
add wave -noupdate /tb/TestName_T
add wave -noupdate -divider internal
add wave -noupdate /tb/i_mut/Clk_CI
add wave -noupdate /tb/i_mut/Rst_RBI
add wave -noupdate /tb/i_mut/OpA_DI
add wave -noupdate /tb/i_mut/OpB_DI
add wave -noupdate -radix unsigned /tb/i_mut/OpBShift_DI
add wave -noupdate /tb/i_mut/OpBSign_SI
add wave -noupdate /tb/OpBIsZero_SI
add wave -noupdate /tb/i_mut/OpCode_SI
add wave -noupdate /tb/i_mut/InVld_SI
add wave -noupdate /tb/i_mut/InRdy_SO
add wave -noupdate /tb/i_mut/OutRdy_SI
add wave -noupdate /tb/i_mut/OutVld_SO
add wave -noupdate -radix decimal /tb/i_mut/Res_DO
add wave -noupdate /tb/i_mut/ResReg_DN
add wave -noupdate /tb/i_mut/ResReg_DP
add wave -noupdate /tb/i_mut/AReg_DN
add wave -noupdate -radix decimal /tb/i_mut/AReg_DP
add wave -noupdate /tb/i_mut/BReg_DN
add wave -noupdate -radix decimal /tb/i_mut/BReg_DP
add wave -noupdate /tb/i_mut/RemSel_SN
add wave -noupdate /tb/i_mut/RemSel_SP
add wave -noupdate /tb/i_mut/CompInv_SN
add wave -noupdate /tb/i_mut/CompInv_SP
add wave -noupdate /tb/i_mut/ResInv_SN
add wave -noupdate /tb/i_mut/ResInv_SP
add wave -noupdate /tb/i_mut/AddMux_D
add wave -noupdate /tb/i_mut/AddOut_D
add wave -noupdate /tb/i_mut/BMux_D
add wave -noupdate /tb/i_mut/OutMux_D
add wave -noupdate /tb/i_mut/Cnt_DN
add wave -noupdate /tb/i_mut/Cnt_DP
add wave -noupdate /tb/i_mut/CntZero_S
add wave -noupdate /tb/i_mut/ARegEn_S
add wave -noupdate /tb/i_mut/BRegEn_S
add wave -noupdate /tb/i_mut/ResRegEn_S
add wave -noupdate /tb/i_mut/ABComp_S
add wave -noupdate /tb/i_mut/PmSel_S
add wave -noupdate /tb/i_mut/State_SN
add wave -noupdate /tb/i_mut/State_SP
add wave -noupdate /tb/OpA_DI
add wave -noupdate /tb/OpB_DI
add wave -noupdate /tb/Res_DO
add wave -noupdate /tb/Clk_CI
add wave -noupdate /tb/Rst_RBI
add wave -noupdate /tb/StimStart_T
add wave -noupdate /tb/StimEnd_T
add wave -noupdate /tb/EndOfSim_T
add wave -noupdate /tb/NumStim_T
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {89306315 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 348
configure wave -valuecolwidth 194
configure wave -justifyvalue left
configure wave -signalnamewidth 1
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {186977012 ps} {187704368 ps}