Finish hwloops addition

This commit is contained in:
Sven Stucki 2015-09-07 03:40:28 +02:00
parent 82afb4c839
commit b5aea15659
5 changed files with 113 additions and 106 deletions

View file

@ -1029,6 +1029,11 @@ module controller
ctrl_fsm_ns = BRANCH_DELAY;
end
// handle hwloops
if (hwloop_jump_i) begin
pc_mux_sel_o = `PC_HWLOOP;
end
// handle illegal instructions
if (illegal_insn_int) begin
illegal_insn_o = 1'b1;

View file

@ -50,8 +50,11 @@ module hwloop_controller
logic [`HWLOOP_REGS-1:0] pc_is_end_addr;
// end address detection
integer j;
// generate comparators. check for end address and the loop counter
// generate comparators. check for end address and the loop counter
genvar i;
for (i = 0; i < `HWLOOP_REGS; i++) begin
assign pc_is_end_addr[i] = (
@ -65,30 +68,18 @@ module hwloop_controller
assign hwloop_jump_o = |pc_is_end_addr;
// select corresponding start address and decrement counter. give highest priority to register 0
// select corresponding start address and decrement counter
always_comb
begin
hwloop_targ_addr_o = 32'b0;
hwloop_dec_cnt_o = '0;
if (pc_is_end_addr[0]) begin
hwloop_targ_addr_o = hwloop_start_addr_i[0];
hwloop_dec_cnt_o[0] = 1'b1;
for (j = `HWLOOP_REGS-1; j >= 0; j--) begin
if (pc_is_end_addr[j]) begin
hwloop_targ_addr_o = hwloop_start_addr_i[j];
hwloop_dec_cnt_o[j] = 1'b1;
end
end
else if (pc_is_end_addr[1]) begin
hwloop_targ_addr_o = hwloop_start_addr_i[1];
hwloop_dec_cnt_o[1] = 1'b1;
end
/* -----\/----- EXCLUDED -----\/-----
else if (pc_is_end_addr[2]) begin
hwloop_targ_addr_o = hwloop_start_addr_i[2];
hwloop_dec_cnt_o[2] = 1'b1;
end
else if (pc_is_end_addr[3]) begin
hwloop_targ_addr_o = hwloop_start_addr_i[3];
hwloop_dec_cnt_o[3] = 1'b1;
end
-----/\----- EXCLUDED -----/\----- */
end
endmodule

View file

@ -94,6 +94,7 @@ module id_stage
input logic data_misaligned_i,
output logic [31:0] hwloop_targ_addr_o,
output logic hwloop_jump_o,
output logic csr_access_ex_o,
output logic [1:0] csr_op_ex_o,
@ -706,13 +707,10 @@ module id_stage
(
// from ID stage
.enable_i ( hwloop_enable ),
.current_pc_i ( current_pc_if_i ),
// to controller
// to IF stage/controller
.hwloop_jump_o ( hwloop_jump ),
// to if stage
.hwloop_targ_addr_o ( hwloop_targ_addr_o ),
// from hwloop_regs
@ -724,6 +722,8 @@ module id_stage
.hwloop_dec_cnt_o ( hwloop_dec_cnt )
);
assign hwloop_jump_o = hwloop_jump;
hwloop_regs hwloop_regs_i
(
.clk ( clk ),

View file

@ -61,7 +61,6 @@ module if_stage
// Forwarding ports - control signals
input logic force_nop_i, // insert a NOP in the pipe
input logic [31:0] exception_pc_reg_i, // address used to restore PC when the interrupt/exception is served
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 [1:0] exc_pc_mux_i, // select which exception to execute
@ -72,6 +71,10 @@ module if_stage
input logic [31:0] jump_target_ex_i, // jump target address
input logic branch_decision_i,
// from hwloop controller
input logic hwloop_jump_i,
input logic [31:0] hwloop_target_i, // pc from hwloop start addr
// from debug unit
input logic [31:0] dbg_npc_i,
input logic dbg_set_npc_i,
@ -160,7 +163,7 @@ module if_stage
`PC_INCR: fetch_addr_n = fetch_addr_Q + 32'd4; // incremented PC
`PC_EXCEPTION: fetch_addr_n = exc_pc; // set PC to exception handler
`PC_ERET: fetch_addr_n = exception_pc_reg_i; // PC is restored when returning from IRQ/exception
`PC_HWLOOP: fetch_addr_n = pc_from_hwloop_i; // PC is taken from hwloop start addr
`PC_HWLOOP: fetch_addr_n = hwloop_target_i; // PC is taken from hwloop start addr
`PC_DBG_NPC: fetch_addr_n = dbg_npc_i; // PC is taken from debug unit
default:
begin
@ -180,7 +183,7 @@ module if_stage
`PC_JUMP: unaligned_jump = jump_target_id_i[1];
`PC_BRANCH: unaligned_jump = jump_target_ex_i[1];
`PC_ERET: unaligned_jump = exception_pc_reg_i[1];
`PC_HWLOOP: unaligned_jump = pc_from_hwloop_i[1];
`PC_HWLOOP: unaligned_jump = hwloop_target_i[1];
`PC_DBG_NPC: unaligned_jump = dbg_npc_i[1];
endcase
end
@ -389,7 +392,10 @@ module if_stage
offset_fsm_ns = WAIT_JUMPED_ALIGNED;
end
end else if (jump_in_id_i == `BRANCH_JAL || jump_in_id_i == `BRANCH_JALR || dbg_set_npc_i) begin
end else if (jump_in_id_i == `BRANCH_JAL || jump_in_id_i == `BRANCH_JALR
|| dbg_set_npc_i
|| hwloop_jump_i) begin
// switch to new PC from ID stage
fetch_req = 1'b1;
if (unaligned_jump)
offset_fsm_ns = WAIT_JUMPED_UNALIGNED;

View file

@ -179,7 +179,8 @@ module riscv_core
// Hardware loop controller signals
logic [31:0] hwlp_targ_addr; // from hwloop controller to if stage
logic hwloop_jump;
logic [31:0] hwloop_target; // from hwloop controller to if stage
// Debug Unit
@ -246,10 +247,13 @@ module riscv_core
// Forwrding ports - control signals
.force_nop_i ( force_nop_id ), // select incoming instr or NOP
.exception_pc_reg_i ( epcr ), // Exception PC register
.pc_from_hwloop_i ( hwlp_targ_addr ), // pc from hwloop start 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
// from hwloop controller
.hwloop_jump_i ( hwloop_jump ),
.hwloop_target_i ( hwloop_target ), // pc from hwloop start address
// from debug unit
.dbg_npc_i ( dbg_npc ),
.dbg_set_npc_i ( dbg_set_npc ),
@ -279,116 +283,117 @@ module riscv_core
/////////////////////////////////////////////////
id_stage id_stage_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.clk ( clk ),
.rst_n ( rst_n ),
// Processor Enable
.fetch_enable_i ( fetch_enable_i ),
.fetch_enable_i ( fetch_enable_i ),
.jump_in_id_o ( jump_in_id ),
.jump_in_ex_o ( jump_in_ex ),
.branch_decision_i ( branch_decision ),
.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 ),
.jump_target_o ( jump_target_id ),
.core_busy_o ( core_busy ),
.core_busy_o ( core_busy ),
// Interface to instruction memory
.instr_rdata_i ( instr_rdata_id ),
.instr_req_o ( instr_req_int ),
.instr_gnt_i ( instr_grant_i ),
.instr_ack_i ( instr_ack_int ),
.instr_rdata_i ( instr_rdata_id ),
.instr_req_o ( instr_req_int ),
.instr_gnt_i ( instr_grant_i ),
.instr_ack_i ( instr_ack_int ),
.pc_mux_sel_o ( pc_mux_sel_id ),
.exc_pc_mux_o ( exc_pc_mux_id ),
.force_nop_o ( force_nop_id ),
.pc_mux_sel_o ( pc_mux_sel_id ),
.exc_pc_mux_o ( exc_pc_mux_id ),
.force_nop_o ( force_nop_id ),
.current_pc_if_i ( current_pc_if ),
.current_pc_id_i ( current_pc_id ),
.current_pc_if_i ( current_pc_if ),
.current_pc_id_i ( current_pc_id ),
.compressed_instr_o ( compressed_instr ),
.compressed_instr_o ( compressed_instr ),
// STALLS
.stall_if_o ( stall_if ),
.stall_id_o ( stall_id ),
.stall_ex_o ( stall_ex ),
.stall_wb_o ( stall_wb ),
.stall_if_o ( stall_if ),
.stall_id_o ( stall_id ),
.stall_ex_o ( stall_ex ),
.stall_wb_o ( stall_wb ),
// From the Pipeline ID/EX
.regfile_rb_data_ex_o ( regfile_rb_data_ex ),
.regfile_rb_data_ex_o ( regfile_rb_data_ex ),
.alu_operand_a_ex_o ( alu_operand_a_ex ),
.alu_operand_b_ex_o ( alu_operand_b_ex ),
.alu_operand_c_ex_o ( alu_operand_c_ex ),
.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 ),
.alu_operator_ex_o ( alu_operator_ex ),
.vector_mode_ex_o ( vector_mode_ex ), // from ID to EX stage
.alu_cmp_mode_ex_o ( alu_cmp_mode_ex ), // from ID to EX stage
.alu_vec_ext_ex_o ( alu_vec_ext_ex ), // from ID to EX stage
.vector_mode_ex_o ( vector_mode_ex ), // from ID to EX stage
.alu_cmp_mode_ex_o ( alu_cmp_mode_ex ), // from ID to EX stage
.alu_vec_ext_ex_o ( alu_vec_ext_ex ), // from ID to EX stage
.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_mac_en_ex_o ( mult_mac_en_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_mac_en_ex_o ( mult_mac_en_ex ), // from ID to EX stage
.regfile_waddr_ex_o ( regfile_waddr_ex ),
.regfile_we_ex_o ( regfile_we_ex ),
.regfile_waddr_ex_o ( regfile_waddr_ex ),
.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 ),
.regfile_alu_we_ex_o ( regfile_alu_we_ex ),
.regfile_alu_waddr_ex_o ( regfile_alu_waddr_ex ),
// CSR ID/EX
.csr_access_ex_o ( csr_access_ex ),
.csr_op_ex_o ( csr_op_ex ),
.csr_access_ex_o ( csr_access_ex ),
.csr_op_ex_o ( csr_op_ex ),
// hwloop signals
.hwloop_targ_addr_o ( hwlp_targ_addr ),
.hwloop_jump_o ( hwloop_jump ),
.hwloop_targ_addr_o ( hwloop_target ),
.prepost_useincr_ex_o ( useincr_addr_ex ),
.data_misaligned_i ( data_misaligned ),
.prepost_useincr_ex_o ( useincr_addr_ex ),
.data_misaligned_i ( data_misaligned ),
.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
.data_reg_offset_ex_o ( data_reg_offset_ex ), // to load store unit
.data_req_ex_o ( data_req_ex ), // to load store unit
.data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit
.data_ack_i ( data_ack_int ), // from load store unit
.data_rvalid_i ( data_r_valid_i ),
.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
.data_reg_offset_ex_o ( data_reg_offset_ex ), // to load store unit
.data_req_ex_o ( data_req_ex ), // to load store unit
.data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit
.data_ack_i ( data_ack_int ), // from load store unit
.data_rvalid_i ( data_r_valid_i ),
// Interrupt Signals
.irq_i ( irq_i ), // incoming interrupts
.irq_nm_i ( irq_nm_i ), // incoming interrupts
.irq_enable_i ( irq_enable ), // global interrupt enable
.save_pc_if_o ( save_pc_if ), // control signal to save pc
.save_pc_id_o ( save_pc_id ), // control signal to save pc
.irq_i ( irq_i ), // incoming interrupts
.irq_nm_i ( irq_nm_i ), // incoming interrupts
.irq_enable_i ( irq_enable ), // global interrupt enable
.save_pc_if_o ( save_pc_if ), // control signal to save pc
.save_pc_id_o ( save_pc_id ), // control signal to save pc
// Debug Unit Signals
.dbg_flush_pipe_i ( dbg_flush_pipe ),
.dbg_st_en_i ( dbg_st_en ),
.dbg_dsr_i ( dbg_dsr ),
.dbg_stall_i ( dbg_stall ),
.dbg_trap_o ( dbg_trap ),
.dbg_reg_mux_i ( dbg_reg_mux ),
.dbg_reg_we_i ( dbg_reg_we ),
.dbg_reg_addr_i ( dbg_reg_addr[4:0] ),
.dbg_reg_wdata_i ( dbg_reg_wdata ),
.dbg_reg_rdata_o ( dbg_reg_rdata ),
.dbg_set_npc_i ( dbg_set_npc ),
.dbg_flush_pipe_i ( dbg_flush_pipe ),
.dbg_st_en_i ( dbg_st_en ),
.dbg_dsr_i ( dbg_dsr ),
.dbg_stall_i ( dbg_stall ),
.dbg_trap_o ( dbg_trap ),
.dbg_reg_mux_i ( dbg_reg_mux ),
.dbg_reg_we_i ( dbg_reg_we ),
.dbg_reg_addr_i ( dbg_reg_addr[4:0] ),
.dbg_reg_wdata_i ( dbg_reg_wdata ),
.dbg_reg_rdata_o ( dbg_reg_rdata ),
.dbg_set_npc_i ( dbg_set_npc ),
// Forward Signals
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw ),
.regfile_alu_wdata_fw_i ( regfile_alu_wdata_fw ),
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw ),
.regfile_alu_wdata_fw_i ( regfile_alu_wdata_fw ),
.regfile_waddr_wb_i ( regfile_waddr_fw_wb_o ), // Write address ex-wb pipeline
.regfile_we_wb_i ( regfile_we_wb ), // write enable for the register file
.regfile_wdata_wb_i ( regfile_wdata ), // write data to commit in the register file
.regfile_waddr_wb_i ( regfile_waddr_fw_wb_o), // Write address ex-wb pipeline
.regfile_we_wb_i ( regfile_we_wb ), // write enable for the register file
.regfile_wdata_wb_i ( regfile_wdata ), // write data to commit in the register file
.perf_jump_o ( perf_jump ),
.perf_branch_o ( perf_branch ),
.perf_jr_stall_o ( perf_jr_stall ),
.perf_ld_stall_o ( perf_ld_stall )
.perf_jump_o ( perf_jump ),
.perf_branch_o ( perf_branch ),
.perf_jr_stall_o ( perf_jr_stall ),
.perf_ld_stall_o ( perf_ld_stall )
);