JAL working

This commit is contained in:
Sven Stucki 2015-04-09 16:09:37 +02:00
parent 6d8d6287b4
commit c9a0ffdc7d
8 changed files with 277 additions and 207 deletions

29
alu.sv
View file

@ -36,6 +36,7 @@ module alu
input logic [`ALU_OP_WIDTH-1:0] operator_i,
input logic [31:0] operand_a_i,
input logic [31:0] operand_b_i,
input logic [31:0] operand_c_i, // for jump target calculation
input logic carry_i,
input logic flag_i,
@ -44,12 +45,15 @@ module alu
input logic [1:0] vec_ext_i,
output logic [31:0] result_o,
output logic [31:0] jump_target_o,
output logic overflow_o,
output logic carry_o,
output logic flag_o
);
logic [31:0] pc_after_jal;
logic [31:0] operand_a_rev; // bit reversed signal of operand_a_i
// bit reverse operand_a for left shifts
@ -140,6 +144,9 @@ module alu
assign {carry_out[2], adder_result[23:16]} = adder_op_a[23:16] + adder_op_b[23:16] + carry_in[2];
assign {carry_out[3], adder_result[31:24]} = adder_op_a[31:24] + adder_op_b[31:24] + carry_in[3];
// additional 32 bit adder for PC after JAL(R) instruction
assign pc_after_jal = operand_c_i + 32'd4;
// averaging by right shifting of one bit
logic [31:0] result_avg;
@ -539,18 +546,19 @@ module alu
always_comb
begin
shift_left = 1'b0;
shift_amt = operand_b_i;
result_o = 'x;
carry_o = 1'b0;
overflow_o = 1'b0;
flag_o = 1'b0;
shift_left = 1'b0;
shift_amt = operand_b_i;
result_o = 'x;
jump_target_o = 1'b0;
carry_o = 1'b0;
overflow_o = 1'b0;
flag_o = 1'b0;
unique case (operator_i)
// Standard Operations
`ALU_ADD, `ALU_ADDC, `ALU_SUB:
begin // Addition defined above
result_o = adder_result[31:0];
result_o = adder_result;
carry_o = carry_out[3];
overflow_o = (adder_op_a[31] ^ adder_result[31]) & (adder_op_b[31] ^ adder_result[31]); // ++ => - and -- => +
end
@ -559,6 +567,13 @@ module alu
`ALU_OR: result_o = operand_a_i | operand_b_i;
`ALU_XOR: result_o = operand_a_i ^ operand_b_i;
// Jump Target Calculation
`ALU_JAL:
begin
result_o = pc_after_jal;
jump_target_o = adder_result;
end
// Shift Operations
`ALU_MOVHI:
begin

View file

@ -53,6 +53,7 @@ module controller
output logic extend_immediate_o, // Extend a 16 bit immediate to 32 bit
output logic [1:0] alu_op_a_mux_sel_o, // Operator a is selected between reg value, PC or immediate
output logic [1:0] alu_op_b_mux_sel_o, // Operator b is selected between reg value or immediate
output logic alu_op_c_mux_sel_o, // Operator c is selected between reg value or PC
output logic alu_pc_mux_sel_o, // selects IF or ID PC for ALU computations
output logic [3:0] immediate_mux_sel_o,
@ -134,6 +135,9 @@ module controller
output logic [1:0] operand_b_fw_mux_sel_o, // regfile rb data selector form ID stage
output logic [1:0] operand_c_fw_mux_sel_o, // regfile rc data selector form ID stage
// Jump target calcuation done detection
input logic jump_in_ex_i, // jump is being calculated in ALU
output logic drop_instruction_o, // prevent instruction to enter ID stage
`ifdef BRANCH_PREDICTION
output logic wrong_branch_taken_o, // 1 if the wrong branch was selected
@ -175,7 +179,7 @@ module controller
logic mfspr_stall;
logic instr_ack_stall;
logic load_stall;
logic jr_stall;
logic j_stall;
logic set_npc;
`ifdef BRANCH_PREDICTION
@ -207,6 +211,7 @@ module controller
extend_immediate_o = 1'b0;
alu_op_a_mux_sel_o = `OP_A_REGA_OR_FWD;
alu_op_b_mux_sel_o = `OP_B_REGB_OR_FWD;
alu_op_c_mux_sel_o = `OP_C_REGC_OR_FWD;
alu_pc_mux_sel_o = 1'b1;
vector_mode_o = `VEC_MODE32;
@ -318,6 +323,7 @@ module controller
pc_mux_sel_o = `PC_FROM_ALU;
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
alu_op_c_mux_sel_o = `OP_C_CURRPC;
immediate_mux_sel_o = `IMM_UJ;
alu_operator = `ALU_JAL;
regfile_alu_we = 1'b1;
@ -330,6 +336,7 @@ module controller
if (instr_rdata_i ==? `INSTR_JALR) begin
pc_mux_sel_o = `PC_FROM_ALU;
alu_op_b_mux_sel_o = `OP_B_IMM;
alu_op_c_mux_sel_o = `OP_C_CURRPC;
immediate_mux_sel_o = `IMM_I;
alu_operator = `ALU_JAL;
regfile_alu_we = 1'b1;
@ -1141,13 +1148,13 @@ module controller
endcase; // case (instr_rdata_i[6:0])
// synopsys translate_off
if (illegal_insn_o == 1'b1) begin
// synopsys translate_off
$display("%t: Illegal instruction:", $time, instr_rdata_i);
prettyPrintInstruction(instr_rdata_i);
$display("%t: Illegal instruction:", $time);
prettyPrintInstruction(instr_rdata_i, id_stage.current_pc_id_i);
$stop;
// synopsys translate_on
end
// synopsys translate_on
// misaligned access was detected by the LSU
if (data_misaligned_i == 1'b1)
@ -1196,7 +1203,7 @@ module controller
mfspr_stall = 1'b0;
mtspr_stall = 1'b0;
load_stall = 1'b0;
jr_stall = 1'b0;
j_stall = 1'b0;
deassert_we = 1'b0;
@ -1230,16 +1237,24 @@ module controller
// Stall because of jr path
// - Load results cannot directly be forwarded to PC
// - Multiplication results cannot be forwarded to PC
if (((instr_rdata_i[6:0] == `OPCODE_JALR) || (instr_rdata_i[6:0] == `OPCODE_JAL)) &&
if ((instr_rdata_i[6:0] == `OPCODE_JALR) &&
(((regfile_we_wb_i == 1'b1) && (reg_d_wb_is_reg_b_id == 1'b1) && (data_rvalid_i == 1'b1)) ||
((regfile_we_ex_i == 1'b1) && (reg_d_ex_is_reg_b_id == 1'b1)) ||
((regfile_alu_we_fw_i == 1'b1) && (reg_d_alu_is_reg_b_id == 1'b1) && (mult_is_running_ex_i == 1'b1))) )
begin
jr_stall = 1'b1;
j_stall = 1'b1;
deassert_we = 1'b1;
end
/*
// Stall because of JAL/JALR
// Stall until jump target is calculated in EX (1 cycle, then fetch instruction)
if ( (instr_rdata_i[6:0] == `OPCODE_JAL || instr_rdata_i[6:0] == `OPCODE_JALR) &&
(jump_in_ex_i == 1'b0) )
begin
j_stall = 1'b1;
//deassert_we = 1'b1;
end
`ifdef BRANCH_PREDICTION
// Stall because of set_flag path
if (wrong_branch_taken)
@ -1247,14 +1262,13 @@ module controller
deassert_we = 1'b1;
end
`endif
*/
end
`ifdef BRANCH_PREDICTION
assign drop_instruction_o = wrong_branch_taken;
assign drop_instruction_o = wrong_branch_taken | j_stall;
`else
assign drop_instruction_o = 1'b0;
assign drop_instruction_o = j_stall;
`endif
// Stall because of IF miss
@ -1285,8 +1299,8 @@ module controller
// we unstall the if_stage if the debug unit wants to set a new
// pc, so that the new value gets written into current_pc_if and is
// used by the instr_core_interface
stall_if_o = (instr_ack_stall | mfspr_stall | mtspr_stall | load_stall | jr_stall | lsu_stall | misalign_stall | dbg_stall_i | (~pc_valid_i));
stall_id_o = instr_ack_stall | mfspr_stall | mtspr_stall | load_stall | jr_stall | lsu_stall | misalign_stall | dbg_stall_i;
stall_if_o = (instr_ack_stall | mfspr_stall | mtspr_stall | load_stall | j_stall | lsu_stall | misalign_stall | dbg_stall_i | (~pc_valid_i));
stall_id_o = instr_ack_stall | mfspr_stall | mtspr_stall | load_stall | j_stall | lsu_stall | misalign_stall | dbg_stall_i;
stall_ex_o = instr_ack_stall | lsu_stall | dbg_stall_i;
stall_wb_o = lsu_stall | dbg_stall_i;
end
@ -1297,14 +1311,14 @@ module controller
// RiscV register encoding: rs1 is [19:15], rs2 is [24:20], rd is [11:7] //
// Or10n register encoding: ra is [20:16], rb is [15:11], rd is [25:21] //
////////////////////////////////////////////////////////////////////////////////////////////
assign reg_d_ex_is_reg_a_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_RS1]) && (rega_used == 1'b1);
assign reg_d_ex_is_reg_b_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_RS2]) && (regb_used == 1'b1);
assign reg_d_ex_is_reg_c_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_RD]) && (regc_used == 1'b1);
assign reg_d_wb_is_reg_a_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_RS1]) && (rega_used == 1'b1);
assign reg_d_wb_is_reg_b_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_RS2]) && (regb_used == 1'b1);
assign reg_d_wb_is_reg_c_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_RD]) && (regc_used == 1'b1);
assign reg_d_alu_is_reg_a_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_RS1]) && (rega_used == 1'b1);
assign reg_d_alu_is_reg_b_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_RS2]) && (regb_used == 1'b1);
assign reg_d_ex_is_reg_a_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_S1]) && (rega_used == 1'b1);
assign reg_d_ex_is_reg_b_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_S2]) && (regb_used == 1'b1);
assign reg_d_ex_is_reg_c_id = (regfile_waddr_ex_i == instr_rdata_i[`REG_D]) && (regc_used == 1'b1);
assign reg_d_wb_is_reg_a_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_S1]) && (rega_used == 1'b1);
assign reg_d_wb_is_reg_b_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_S2]) && (regb_used == 1'b1);
assign reg_d_wb_is_reg_c_id = (regfile_waddr_wb_i == instr_rdata_i[`REG_D]) && (regc_used == 1'b1);
assign reg_d_alu_is_reg_a_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_S1]) && (rega_used == 1'b1);
assign reg_d_alu_is_reg_b_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_S2]) && (regb_used == 1'b1);
//assign reg_d_alu_is_reg_c_id = (regfile_alu_waddr_fw_i == instr_rdata_i[`REG_RD]) && (regc_used == 1'b1);
always_comb

View file

@ -119,7 +119,10 @@ module ex_stage
output logic [4:0] regfile_alu_waddr_fw_o,
output logic regfile_alu_we_fw_o,
output logic [31:0] regfile_alu_wdata_fw_o, // forward to RF and ID/EX pipe, ALU & MUL
output logic [31:0] regfile_alu_wdata_fw_pc_o // forward to PC, no multiplication
output logic [31:0] regfile_alu_wdata_fw_pc_o, // forward to PC, no multiplication
// JAL/JALR jumpt target calculation (to IF)
output logic [31:0] jump_target_o
`ifdef TCDM_ADDR_PRECAL
,
@ -134,6 +137,7 @@ module ex_stage
// Internal output of the LU
logic [31:0] alu_result;
logic [31:0] alu_jump_target_int;
logic [31:0] alu_adder_lsu_int; // to LS unit
@ -182,6 +186,10 @@ module ex_stage
assign data_addr_ex_o = (prepost_useincr_i == 1'b1) ? alu_adder_lsu_int : alu_operand_a_i;
// PC calculation for JAL/JALR
assign jump_target_o = alu_jump_target_int;
////////////////////////////
// _ _ _ _ //
// / \ | | | | | | //
@ -192,21 +200,22 @@ module ex_stage
////////////////////////////
alu alu_i
(
.operator_i ( alu_operator_i ),
.operand_a_i ( alu_operand_a_i ),
.operand_b_i ( alu_operand_b_i ),
.carry_i ( alu_carry_i ),
.flag_i ( alu_flag_i ),
.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 ),
.carry_i ( alu_carry_i ),
.flag_i ( alu_flag_i ),
.vector_mode_i ( vector_mode_i ),
.cmp_mode_i ( alu_cmp_mode_i ),
.vec_ext_i ( alu_vec_ext_i ),
.vector_mode_i ( vector_mode_i ),
.cmp_mode_i ( alu_cmp_mode_i ),
.vec_ext_i ( alu_vec_ext_i ),
.adder_lsu_o ( alu_adder_lsu_int ),
.result_o ( alu_result ),
.overflow_o ( alu_overflow_int ), // Internal signal
.carry_o ( alu_carry_int ), // Internal signal
.flag_o ( alu_flag_o )
.result_o ( alu_result ),
.jump_target_o ( alu_jump_target_int ),
.overflow_o ( alu_overflow_int ), // Internal signal
.carry_o ( alu_carry_int ), // Internal signal
.flag_o ( alu_flag_o )
);

View file

@ -177,111 +177,113 @@ module id_stage
// Immediate decoding and sign extension
logic [31:0] imm_i_type;
logic [31:0] imm_s_type;
logic [31:0] imm_sb_type;
logic [31:0] imm_u_type;
logic [31:0] imm_uj_type;
logic [31:0] imm_i_type;
logic [31:0] imm_s_type;
logic [31:0] imm_sb_type;
logic [31:0] imm_u_type;
logic [31:0] imm_uj_type;
logic [31:0] immediate_b; // contains the immediate for operand b
logic [31:0] immediate_b; // contains the immediate for operand b
logic [31:0] current_pc; // PC to be used in ALU (either IF or ID)
logic [31:0] current_pc; // PC to be used in ALU (either IF or ID)
logic exc_pc_sel;
logic [2:0] pc_mux_sel_int; // selects next PC in if stage
logic pc_from_immediate_mux_sel = 1'b0; // TODO: FIXME
logic exc_pc_sel;
logic [2:0] pc_mux_sel_int; // selects next PC in if stage
//logic pc_from_immediate_mux_sel = 1'b0; // TODO: FIXME (remove)
logic irq_present;
logic irq_present;
// Signals running between controller and exception controller
logic jump_in_id;
logic jump_in_ex; // registered copy of jump_in_id
logic illegal_insn;
logic trap_insn;
logic pipe_flush;
logic pc_valid;
logic clear_isr_running;
logic jump_in_id;
logic jump_in_ex; // registered copy of jump_in_id
logic illegal_insn;
logic trap_insn;
logic pipe_flush;
logic pc_valid;
logic clear_isr_running;
logic [4:0] regfile_addr_ra_id;
logic [4:0] regfile_addr_rb_id;
logic [4:0] regfile_addr_rc_id;
logic [4:0] regfile_addr_ra_id;
logic [4:0] regfile_addr_rb_id;
logic [4:0] regfile_addr_rc_id;
logic [4:0] regfile_waddr_id;
logic [4:0] regfile_alu_waddr_id;
logic regfile_alu_we_id;
logic [4:0] regfile_waddr_id;
logic [4:0] regfile_alu_waddr_id;
logic regfile_alu_we_id;
logic [31:0] regfile_data_ra_id;
logic [31:0] regfile_data_rb_id;
logic [31:0] regfile_data_rc_id;
logic [31:0] regfile_data_ra_id;
logic [31:0] regfile_data_rb_id;
logic [31:0] regfile_data_rc_id;
logic imm_sign_ext_sel;
logic imm_sign_ext_sel;
// ALU Control
logic [`ALU_OP_WIDTH-1:0] alu_operator;
logic [1:0] alu_op_a_mux_sel;
logic [1:0] alu_op_b_mux_sel;
logic scalar_replication;
logic [`ALU_OP_WIDTH-1:0] alu_operator;
logic [1:0] alu_op_a_mux_sel;
logic [1:0] alu_op_b_mux_sel;
logic alu_op_c_mux_sel;
logic scalar_replication;
logic [1:0] vector_mode;
logic [1:0] alu_cmp_mode;
logic [1:0] alu_vec_ext;
logic [1:0] vector_mode;
logic [1:0] alu_cmp_mode;
logic [1:0] alu_vec_ext;
logic alu_pc_mux_sel;
logic [3:0] immediate_mux_sel;
logic alu_pc_mux_sel;
logic [3:0] immediate_mux_sel;
// Multiplier Control
logic mult_is_running; // output of the controller (1 if the opcode is a multiplication)
logic [1:0] mult_sel_subword; // Select a subword when doing multiplications
logic [1:0] mult_signed_mode; // Signed mode multiplication at the output of the controller, and before the pipe registers
logic mult_use_carry; // Enables carry in for the MAC
logic mult_mac_en; // Enables the use of the accumulator
logic mult_is_running; // output of the controller (1 if the opcode is a multiplication)
logic [1:0] mult_sel_subword; // Select a subword when doing multiplications
logic [1:0] mult_signed_mode; // Signed mode multiplication at the output of the controller, and before the pipe registers
logic mult_use_carry; // Enables carry in for the MAC
logic mult_mac_en; // Enables the use of the accumulator
logic eoc; // End of computation generated from the controller
logic eoc; // End of computation generated from the controller
// Register Write Control
logic regfile_wdata_mux_sel;
logic regfile_we_id;
logic [1:0] regfile_alu_waddr_mux_sel; // TODO: FixMe -> 1bit
logic regfile_wdata_mux_sel;
logic regfile_we_id;
logic [1:0] regfile_alu_waddr_mux_sel; // TODO: FixMe -> 1bit
// Special-Purpose Register Write Control
logic sp_we_id;
logic sp_we_id;
// Data Memory Control
logic data_we_id;
logic [1:0] data_type_id;
logic data_sign_ext_id;
logic [1:0] data_reg_offset_id;
logic data_req_id;
logic data_we_id;
logic [1:0] data_type_id;
logic data_sign_ext_id;
logic [1:0] data_reg_offset_id;
logic data_req_id;
// hwloop signals
logic [1:0] hwloop_regid;
logic [2:0] hwloop_we;
logic hwloop_wb_mux_sel;
logic [1:0] hwloop_cnt_mux_sel;
logic [31:0] hwloop_cnt;
logic hwloop_jump;
logic hwloop_enable;
logic [1:0] hwloop_regid;
logic [2:0] hwloop_we;
logic hwloop_wb_mux_sel;
logic [1:0] hwloop_cnt_mux_sel;
logic [31:0] hwloop_cnt;
logic hwloop_jump;
logic hwloop_enable;
// Supervision Register
logic set_flag;
logic set_carry;
logic set_overflow;
logic set_flag;
logic set_carry;
logic set_overflow;
logic prepost_useincr;
logic prepost_useincr;
// Forwarding
logic [1:0] operand_a_fw_mux_sel;
logic [1:0] operand_b_fw_mux_sel;
logic [1:0] operand_c_fw_mux_sel;
logic [31:0] operand_a_fw_id;
logic [31:0] operand_b_fw_id;
logic [1:0] operand_a_fw_mux_sel;
logic [1:0] operand_b_fw_mux_sel;
logic [1:0] operand_c_fw_mux_sel;
logic [31:0] operand_a_fw_id;
logic [31:0] operand_b_fw_id;
logic [31:0] alu_operand_a;
logic [31:0] alu_operand_b;
logic [31:0] alu_operand_c;
logic [31:0] operand_b; // before going through the scalar replication mux
logic [31:0] operand_b_vec; // scalar replication of operand_b for 8 and 16 bit
logic [31:0] alu_operand_a;
logic [31:0] alu_operand_b;
logic [31:0] alu_operand_c;
logic [31:0] operand_b; // before going through the scalar replication mux
logic [31:0] operand_b_vec; // scalar replication of operand_b for 8 and 16 bit
logic [31:0] operand_c;
// TODO: FIXME temporary assignments while not everything is implemented (e.g. exceptions)
@ -301,12 +303,13 @@ module id_stage
instr_rdata_i[20], instr_rdata_i[30:21], 1'b0 };
// source registers
assign regfile_addr_ra_id = instr_rdata_i[`REG_RS1];
assign regfile_addr_rb_id = instr_rdata_i[`REG_RS2];
assign regfile_addr_ra_id = instr_rdata_i[`REG_S1];
assign regfile_addr_rb_id = instr_rdata_i[`REG_S2];
//assign regfile_addr_rc_id = instr_rdata_i[25:21];
assign regfile_addr_rc_id = 32'd0;
// destination registers
assign regfile_waddr_id = instr_rdata_i[`REG_RD];
assign regfile_waddr_id = instr_rdata_i[`REG_D];
//assign alu_vec_ext = instr_rdata_i[9:8];
@ -333,14 +336,14 @@ module id_stage
///////////////////////////////////////////////////////////////////////////////////////
// PC offset for `PC_FROM_IMM PC mux
//assign pc_from_immediate_o = imm_uj_type;
always_comb
begin : pc_from_immediate_mux
case (pc_from_immediate_mux_sel)
1'b0: pc_from_immediate_o = imm_uj_type; // JAL
1'b1: pc_from_immediate_o = imm_i_type; // JALR
endcase // case (pc_from_immediate_mux_sel)
end
//assign pc_from_immediate_o = imm_uj_type; // riscv no longer used
//always_comb
//begin : pc_from_immediate_mux
// case (pc_from_immediate_mux_sel)
// 1'b0: pc_from_immediate_o = imm_uj_type; // JAL
// 1'b1: pc_from_immediate_o = imm_i_type; // JALR
// endcase // case (pc_from_immediate_mux_sel)
//end
// PC Mux
always_comb
@ -472,14 +475,23 @@ module id_stage
// |_| //
//////////////////////////////////////////////////////
// ALU OP C Mux
always_comb
begin : alu_operand_c_mux
case (alu_op_c_mux_sel)
`OP_C_CURRPC: operand_c = current_pc;
default: operand_c = regfile_data_rc_id;
endcase // case (alu_op_c_mux_sel)
end
// Operand c forwarding mux
always_comb
begin : operand_c_fw_mux
case (operand_c_fw_mux_sel)
`SEL_FW_EX: alu_operand_c = regfile_alu_wdata_fw_i;
`SEL_FW_WB: alu_operand_c = regfile_wdata_wb_i;
`SEL_REGFILE: alu_operand_c = regfile_data_rc_id;
default: alu_operand_c = regfile_data_rc_id;
`SEL_REGFILE: alu_operand_c = operand_c;
default: alu_operand_c = operand_c;
endcase; // case (operand_b_fw_mux_sel)
end
@ -551,6 +563,7 @@ module id_stage
.extend_immediate_o ( imm_sign_ext_sel ),
.alu_op_a_mux_sel_o ( alu_op_a_mux_sel ),
.alu_op_b_mux_sel_o ( alu_op_b_mux_sel ),
.alu_op_c_mux_sel_o ( alu_op_c_mux_sel ),
.alu_pc_mux_sel_o ( alu_pc_mux_sel ),
.immediate_mux_sel_o ( immediate_mux_sel ),
@ -638,11 +651,13 @@ module id_stage
.operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ),
.operand_c_fw_mux_sel_o ( operand_c_fw_mux_sel ),
.jump_in_ex_i ( jump_in_ex ),
// branch prediction
.drop_instruction_o ( drop_instruction_o ),
.drop_instruction_o ( drop_instruction_o ),
`ifdef BRANCH_PREDICTION
.wrong_branch_taken_o ( wrong_branch_taken_o ),
.take_branch_o ( take_branch_o ),
.wrong_branch_taken_o ( wrong_branch_taken_o ),
.take_branch_o ( take_branch_o ),
`endif
// Stall signals
.stall_if_o ( stall_if_o ),

View file

@ -52,7 +52,8 @@ module if_stage
input logic force_nop_i, // insert a NOP in the pipe
input logic [31:0] exception_pc_reg_i, // address used to restore the program counter when the interrupt/exception is served
input logic [31:0] pc_from_regfile_i, // pc from reg file
input logic [31:0] pc_from_immediate_i, // pc from immediate
input logic [31:0] pc_from_alu_i, // calculated jump target form ALU
//input logic [31:0] pc_from_immediate_i, // pc from immediate
input logic [31:0] pc_from_hwloop_i, // pc from hwloop start addr
input logic [2:0] pc_mux_sel_i, // sel for pc multiplexer
input logic pc_mux_boot_i, // load boot address as PC
@ -93,8 +94,8 @@ module if_stage
// Address to fetch the instruction
assign instr_addr_o = next_pc;
assign branch_taken = current_pc_id_o + pc_from_immediate_i;
assign branch_not_taken = current_pc_if_o + 32'd4;
//assign branch_taken = current_pc_id_o + pc_from_immediate_i;
//assign branch_not_taken = current_pc_if_o + 32'd4;
// Next PC Selection: pc_mux_sel_i comes from id_stage.controller
always_comb
@ -103,7 +104,8 @@ module if_stage
`INCR_PC: begin next_pc = current_pc_if_o + 32'd4; end // PC is incremented and points the next instruction
`NO_INCR: begin next_pc = current_pc_if_o; end // PC is not incremented
`PC_FROM_REGFILE: begin next_pc = pc_from_regfile_i; end // PC is taken from the regfile
`PC_FROM_IMM: begin next_pc = branch_taken; end // PC is taken from current PC in id + the immediate displacement
`PC_FROM_ALU: begin next_pc = pc_from_alu_i; end // use calculated jump target from ALU
//`PC_FROM_IMM: begin next_pc = branch_taken; end // PC is taken from current PC in id + the immediate displacement
`PC_EXCEPTION: begin next_pc = exc_pc; end // PC that points to the exception
`EXC_PC_REG: begin next_pc = exception_pc_reg_i; end // restore the PC when exiting from interr/ecpetions
`HWLOOP_ADDR: begin next_pc = pc_from_hwloop_i; end // PC is taken from hwloop start addr

View file

@ -164,13 +164,13 @@
*/
// Source/Destination register instruction index
`define REG_RS1 19:15
`define REG_RS2 24:20
`define REG_RD 11:07
`define REG_S1 19:15
`define REG_S2 24:20
`define REG_D 11:07
// synopsis translate off
function void prettyPrintInstruction(input [31:0] instr);
function void prettyPrintInstruction(input [31:0] instr, input [31:0] pc);
string opcode;
begin
unique case (instr[6:0])
@ -188,10 +188,10 @@ function void prettyPrintInstruction(input [31:0] instr);
default: opcode = "Unknown";
endcase // unique case (instr[6:0])
$display("%t: %s Instruction 0x%h.", $time, opcode, instr[31:0]);
$display("%t: %s Instruction 0x%h at 0x%h.", $time, opcode, instr[31:0], pc[31:0]);
$display("%t: | fct7 | rs2 | rs1 | | rd | opc. |", $time);
$display("%t: 0b %b %b %b %b %b %b", $time, instr[31:25], instr[`REG_RS2],
instr[`REG_RS1], instr[14:12], instr[`REG_RD], instr[6:0]);
$display("%t: 0b %b %b %b %b %b %b", $time, instr[31:25], instr[`REG_S2],
instr[`REG_S1], instr[14:12], instr[`REG_D], instr[6:0]);
$display();
end
endfunction // prettyPrintInstruction
@ -268,6 +268,9 @@ endfunction // prettyPrintInstruction
`define ALU_FL1 6'b11_0011
`define ALU_CLB 6'b11_0001
// next PC and PC+4 computation for JAL/JALR in RiscV
`define ALU_JAL 6'b11_1000
// Vector Mode
`define VEC_MODE32 2'b00
@ -321,20 +324,24 @@ endfunction // prettyPrintInstruction
`define SR_DSX 5'd13
// forwarding operand mux
`define SEL_REGFILE 2'b00
`define SEL_FW_EX 2'b01
`define SEL_FW_WB 2'b10
`define SEL_REGFILE 2'b00
`define SEL_FW_EX 2'b01
`define SEL_FW_WB 2'b10
// operand a selection
`define OP_A_REGA_OR_FWD 2'b00
`define OP_A_CURRPC 2'b10
`define OP_A_IMM16 2'b11
`define OP_A_ZERO 2'b11
`define OP_A_REGA_OR_FWD 2'b00
`define OP_A_CURRPC 2'b10
`define OP_A_IMM16 2'b11
`define OP_A_ZERO 2'b11
// operand b selection
`define OP_B_REGB_OR_FWD 2'b00
`define OP_B_REGC_OR_FWD 2'b01
`define OP_B_IMM 2'b10
`define OP_B_REGB_OR_FWD 2'b00
`define OP_B_REGC_OR_FWD 2'b01
`define OP_B_IMM 2'b10
// operand c selection
`define OP_C_REGC_OR_FWD 1'b0
`define OP_C_CURRPC 1'b1
// immediate selection
// - `define IMM_5N11 4'b0000
@ -357,7 +364,8 @@ endfunction // prettyPrintInstruction
`define INCR_PC 3'b000
`define NO_INCR 3'b001
`define PC_FROM_REGFILE 3'b010
`define PC_FROM_IMM 3'b011
//`define PC_FROM_IMM 3'b011 Replaced in RiscV
`define PC_FROM_ALU 3'b011
`define PC_EXCEPTION 3'b100
`define EXC_PC_REG 3'b101
`define HWLOOP_ADDR 3'b110

View file

@ -7,8 +7,8 @@
// Additional contributions by: //
// //
// //
// Create Date: 06/08/2014 //
// Design Name: Instruction Fetch interface //
// Create Date: 06/08/2014 //
// Design Name: Instruction Fetch interface //
// Module Name: instr_core_interface.sv //
// Project Name: OR10N //
// Language: SystemVerilog //
@ -31,20 +31,20 @@ module instr_core_interface
(
input logic clk,
input logic rst_n,
input logic req_i,
input logic [31:0] addr_i,
output logic ack_o,
output logic [31:0] rdata_o,
output logic instr_req_o,
output logic [31:0] instr_addr_o,
input logic instr_gnt_i,
input logic instr_r_valid_i,
input logic [31:0] instr_r_rdata_i,
input logic stall_if_i,
input logic drop_request_i
@ -58,7 +58,7 @@ module instr_core_interface
logic wait_gnt;
logic [31:0] addr_Q;
always_ff @(posedge clk, negedge rst_n)
begin
if(rst_n == 1'b0)
@ -70,19 +70,19 @@ module instr_core_interface
else
begin
CS <= NS;
if(wait_gnt)
addr_Q <= addr_i;
if(save_rdata)
rdata_Q <= instr_r_rdata_i;
end
end
always_comb
begin
instr_req_o = 1'b0;
ack_o = 1'b0;
save_rdata = 1'b0;
@ -90,16 +90,16 @@ module instr_core_interface
instr_addr_o = addr_i;
wait_gnt = 1'b0;
case(CS)
IDLE :
IDLE :
begin
instr_req_o = req_i;
ack_o = 1'b0;
rdata_o = rdata_Q;
if(req_i)
begin
if(instr_gnt_i) //~> granted request
@ -115,10 +115,10 @@ module instr_core_interface
end
end // case: IDLE
WAIT_GNT :
begin
instr_addr_o = addr_Q;
instr_req_o = 1'b1;
@ -131,17 +131,17 @@ module instr_core_interface
// else
NS = WAIT_GNT;
end
end // case: WAIT_GNT
PENDING :
PENDING :
begin
if(instr_r_valid_i)
begin
save_rdata = 1'b1;
ack_o = 1'b1;
if(stall_if_i)
begin
@ -165,7 +165,7 @@ module instr_core_interface
end
else
NS = IDLE;
end
end
end
else
begin
@ -174,23 +174,23 @@ module instr_core_interface
ack_o = 1'b0;
end
end // case: PENDING
WAIT_RVALID :
WAIT_RVALID :
begin
if(instr_r_valid_i)
begin
ack_o = 1'b1;
save_rdata = 1'b1;
if(stall_if_i)
begin
instr_req_o = 1'b0;
NS = WAIT_IF_STALL;
end
else
begin
@ -205,7 +205,7 @@ module instr_core_interface
else
NS = IDLE;
end
end
else
begin
@ -214,14 +214,14 @@ module instr_core_interface
instr_req_o = 1'b0;
end
end // case: WAIT_RVALID
WAIT_IF_STALL :
begin
ack_o = 1'b1;
rdata_o = rdata_Q;
if(stall_if_i)
begin
instr_req_o = 1'b0;
@ -229,7 +229,7 @@ module instr_core_interface
end
else
begin
instr_req_o = req_i;
if(req_i)
if(instr_gnt_i)
@ -241,11 +241,11 @@ module instr_core_interface
else
NS = IDLE;
end
end // case: WAIT_IF_STALL
ABORT:
begin
ack_o = 1'b1;
@ -264,17 +264,17 @@ module instr_core_interface
NS = IDLE;
end
end // case: ABORT
default :
default :
begin
NS = IDLE;
instr_req_o = 1'b0;
end
endcase
end
endmodule

View file

@ -89,7 +89,10 @@ module riscv_core
// Forwarding
logic [31:0] pc_from_immediate_id; //take PC from immediate in case of Jump
//logic [31:0] pc_from_immediate_id; //take PC from immediate in case of Jump
// Jump handling
logic [31:0] jump_target;
// Stalling
logic stall_if; // Stall instruction fetch(deassert request)
@ -278,7 +281,8 @@ module riscv_core
.force_nop_i ( force_nop_id ), // select incoming instr or NOP
.exception_pc_reg_i ( epcr ), // Exception PC register
.pc_from_regfile_i ( pc_from_regfile_id ), // pc from reg file
.pc_from_immediate_i ( pc_from_immediate_id ), // pc from immediate
//.pc_from_immediate_i ( pc_from_immediate_id ), // pc from immediate
.pc_from_alu_i ( jump_target ), // calculated jump target from ALU (EX)
.pc_from_hwloop_i ( hwloop_targ_addr ), // pc from hwloop start address
.pc_mux_sel_i ( pc_mux_sel_id ), // sel for pc multiplexer
.pc_mux_boot_i ( pc_mux_boot ), // load boot address as PC
@ -362,7 +366,7 @@ module riscv_core
.pc_from_regfile_o ( pc_from_regfile_id ),
.current_pc_if_i ( current_pc_if ),
.current_pc_id_i ( current_pc_id ),
.pc_from_immediate_o ( pc_from_immediate_id ),
//.pc_from_immediate_o ( pc_from_immediate_id ),
.sr_flag_fw_i ( sr_flag_fw ),
.sr_flag_i ( sr_flag ),
@ -563,6 +567,9 @@ module riscv_core
.sp_we_wb_o ( sp_we_wb ),
.eoc_o ( eoc_wb ),
// Jump target address
.jump_target_o ( jump_target ),
// To ID stage: Forwarding signals
.regfile_alu_waddr_fw_o ( regfile_alu_waddr_fw ),
.regfile_alu_we_fw_o ( regfile_alu_we_fw ),