Fix bug with hardware loops

This commit is contained in:
Sven Stucki 2015-10-25 19:26:46 +01:00
parent d2c8159a2d
commit f8dbb7ed92
4 changed files with 39 additions and 12 deletions

View file

@ -76,7 +76,7 @@ module riscv_exc_controller
logic new_instr_id_q;
// disable hardware loops when nops are inserted or the controller is not active
assign hwloop_enable_o = (~core_busy_i);
assign hwloop_enable_o = 1'b1;
/////////////////////////////////////////////
// ____ _ //

View file

@ -46,6 +46,8 @@ module riscv_id_stage
input logic [31:0] instr_rdata_i, // comes from pipeline of IF stage
output logic instr_req_o,
input logic id_execute_i,
// Jumps and branches
output logic [1:0] jump_in_id_o,
output logic [1:0] jump_in_ex_o,
@ -53,6 +55,7 @@ module riscv_id_stage
output logic [31:0] jump_target_o,
// IF and ID stage signals
output logic clear_id_execute_o,
output logic pc_set_o,
output logic [2:0] pc_mux_sel_o,
output logic [1:0] exc_pc_mux_o,
@ -304,6 +307,14 @@ module riscv_id_stage
regfile_waddr_id : regfile_addr_ra_id;
// ID execute signal control
// This signal is used to detect when an instruction first enters the ID
// stage. Based on this hardware loops are decremented and it's also useful
// for exceptions, i.e. to suppress the illegal instruction signal during
// an if stall of a jump.
assign clear_id_execute_o = (~jr_stall) | (|hwloop_end_addr);
///////////////////////////////////////////////
// _ ___ ___ ___ ___ ____ //
// | | | \ \ / / | / _ \ / _ \| _ \ //
@ -786,7 +797,7 @@ module riscv_id_stage
.hwloop_regid_i ( hwloop_regid ),
// from controller
.stall_id_i ( ~id_valid_o ),
.stall_id_i ( id_execute_i ),
// to hwloop controller
.hwloop_start_addr_o ( hwloop_start_addr ),

View file

@ -55,6 +55,7 @@ module riscv_if_stage
input logic [RDATA_WIDTH-1:0] instr_rdata_i,
// Output of IF Pipeline stage
output logic id_execute_o, // execute current instruction in ID
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
output logic illegal_c_insn_id_o, // compressed decoder thinks this is an invalid instruction
@ -62,6 +63,7 @@ module riscv_if_stage
output logic [31:0] current_pc_id_o,
// Forwarding ports - control signals
input logic clear_id_execute_i, // clear execute bit
input logic pc_set_i, // set the program counter to a new value
input logic [31:0] exception_pc_reg_i, // address used to restore PC when the interrupt/exception is served
input logic [2:0] pc_mux_sel_i, // sel for pc multiplexer
@ -391,6 +393,7 @@ module riscv_if_stage
begin : IF_ID_PIPE_REGISTERS
if (rst_n == 1'b0)
begin
id_execute_o <= 1'b0;
instr_rdata_id_o <= '0;
illegal_c_insn_id_o <= 1'b0;
is_compressed_id_o <= 1'b0;
@ -398,12 +401,16 @@ module riscv_if_stage
end
else
begin
if (clear_id_execute_i)
id_execute_o <= 1'b0;
if (if_valid_o)
begin : ENABLED_PIPE
instr_rdata_id_o <= instr_decompressed;
illegal_c_insn_id_o <= illegal_c_insn;
is_compressed_id_o <= instr_compressed_int;
current_pc_id_o <= current_pc_if_o;
id_execute_o <= 1'b0;
instr_rdata_id_o <= instr_decompressed;
illegal_c_insn_id_o <= illegal_c_insn;
is_compressed_id_o <= instr_compressed_int;
current_pc_id_o <= current_pc_if_o;
end
end
end

View file

@ -83,11 +83,14 @@ module riscv_core
// IF/ID signals
logic id_execute;
logic [31:0] instr_rdata_id; // Instruction sampled inside IF stage
logic is_compressed_id;
logic illegal_c_insn_id; // Illegal compressed instruction sent to ID stage
logic [31:0] current_pc_if; // Current Program counter
logic [31:0] current_pc_id; // Current Program counter
logic clear_id_execute;
logic pc_set;
logic [2:0] pc_mux_sel_id; // Mux selector for next PC
logic [1:0] exc_pc_mux_id; // Mux selector for exception PC
@ -244,17 +247,19 @@ module riscv_core
.instr_rdata_i ( instr_rdata_i ),
// outputs to ID stage
.id_execute_o ( id_execute ),
.instr_rdata_id_o ( instr_rdata_id ),
.is_compressed_id_o ( is_compressed_id ),
.illegal_c_insn_id_o ( illegal_c_insn_id ),
.current_pc_if_o ( current_pc_if ), // current pc in IF stage
.current_pc_id_o ( current_pc_id ), // current pc in ID stage
.current_pc_if_o ( current_pc_if ),
.current_pc_id_o ( current_pc_id ),
// control signals
.pc_set_i ( pc_set ),
.exception_pc_reg_i ( epcr ), // exception return address
.pc_mux_sel_i ( pc_mux_sel_id ), // sel for pc multiplexer
.exc_pc_mux_i ( exc_pc_mux_id ), // selector for exception multiplexer
.clear_id_execute_i ( clear_id_execute ),
.pc_set_i ( pc_set ),
.exception_pc_reg_i ( epcr ), // exception return address
.pc_mux_sel_i ( pc_mux_sel_id ), // sel for pc multiplexer
.exc_pc_mux_i ( exc_pc_mux_id ), // selector for exception multiplexer
.branch_done_o ( branch_done ),
@ -305,12 +310,16 @@ module riscv_core
.instr_rdata_i ( instr_rdata_id ),
.instr_req_o ( instr_req_int ),
.id_execute_i ( id_execute ),
// Jumps and branches
.jump_in_id_o ( jump_in_id ),
.jump_in_ex_o ( jump_in_ex ),
.branch_decision_i ( branch_decision ),
.jump_target_o ( jump_target_id ),
// IF and ID control signals
.clear_id_execute_o ( clear_id_execute ),
.pc_set_o ( pc_set ),
.pc_mux_sel_o ( pc_mux_sel_id ),
.exc_pc_mux_o ( exc_pc_mux_id ),