Merge branch_pc_ex and data_pc_ex, allow debugging during p.elw

This commit is contained in:
Andreas Traber 2016-05-02 13:47:13 +02:00
parent 0b5f992952
commit 3b766501af
5 changed files with 77 additions and 75 deletions

View file

@ -59,6 +59,7 @@ module riscv_controller
// LSU
input logic data_req_ex_i, // data memory access is currently performed in EX stage
input logic data_misaligned_i,
input logic data_load_event_i,
// from ALU
input logic mult_multicycle_i, // multiplier is taken multiple cycles and uses op c as storage
@ -328,6 +329,13 @@ module riscv_controller
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

View file

@ -57,8 +57,8 @@ module riscv_cs_registers
output logic irq_enable_o,
output logic [31:0] mepc_o,
input logic [31:0] curr_pc_id_i,
input logic [31:0] data_pc_ex_i,
input logic [31:0] pc_id_i,
input logic [31:0] pc_ex_i,
input logic data_load_event_ex_i,
input logic exc_save_i,
input logic exc_restore_i,
@ -206,7 +206,7 @@ module riscv_cs_registers
// exception controller gets priority over other writes
if (exc_save_i) begin
mepc_n = data_load_event_ex_i ? data_pc_ex_i : curr_pc_id_i; // save EX PC if special event load
mepc_n = data_load_event_ex_i ? pc_ex_i : pc_id_i; // save EX PC if special event load
mestatus_n = mstatus_q;
mstatus_n = 1'b0;
end

View file

@ -65,9 +65,11 @@ module riscv_debug_unit
input logic [31:0] csr_rdata_i,
// Signals for PPC & NPC register
input logic [31:0] curr_pc_if_i,
input logic [31:0] curr_pc_id_i,
input logic [31:0] branch_pc_i,
input logic [31:0] pc_if_i,
input logic [31:0] pc_id_i,
input logic [31:0] pc_ex_i,
input logic data_load_event_i,
input logic branch_in_ex_i,
input logic branch_taken_i,
@ -407,24 +409,24 @@ module riscv_debug_unit
begin
pc_tracking_fsm_ns = pc_tracking_fsm_cs;
ppc_int = curr_pc_id_i;
npc_int = curr_pc_if_i;
ppc_int = pc_id_i;
npc_int = pc_if_i;
// PPC/NPC mux
unique case (pc_tracking_fsm_cs)
IFID: begin
ppc_int = curr_pc_id_i;
npc_int = curr_pc_if_i;
ppc_int = pc_id_i;
npc_int = pc_if_i;
end
IFEX: begin
ppc_int = branch_pc_i;
npc_int = curr_pc_if_i;
ppc_int = pc_ex_i;
npc_int = pc_if_i;
end
IDEX: begin
ppc_int = branch_pc_i;
npc_int = curr_pc_id_i;
ppc_int = pc_ex_i;
npc_int = pc_id_i;
if (jump_req_o)
pc_tracking_fsm_ns = IFEX;
@ -444,6 +446,9 @@ module riscv_debug_unit
pc_tracking_fsm_ns = IFEX;
else
pc_tracking_fsm_ns = IDEX;
end else if (data_load_event_i) begin
// for p.elw
pc_tracking_fsm_ns = IDEX;
end
end
end

View file

@ -82,7 +82,7 @@ module riscv_id_stage
input logic wb_valid_i, // WB stage is done
// Pipeline ID/EX
output logic [31:0] branch_pc_ex_o,
output logic [31:0] pc_ex_o,
output logic [31:0] alu_operand_a_ex_o,
output logic [31:0] alu_operand_b_ex_o,
@ -137,7 +137,6 @@ module riscv_id_stage
output logic [1:0] data_type_ex_o,
output logic data_sign_ext_ex_o,
output logic [1:0] data_reg_offset_ex_o,
output logic [31:0] data_pc_ex_o,
output logic data_load_event_ex_o,
output logic data_misaligned_ex_o,
@ -839,6 +838,7 @@ module riscv_id_stage
// LSU
.data_req_ex_i ( data_req_ex_o ),
.data_misaligned_i ( data_misaligned_i ),
.data_load_event_i ( data_load_event_ex_o ),
// ALU
.mult_multicycle_i ( mult_multicycle_i ),
@ -998,17 +998,6 @@ module riscv_id_stage
// |___|____/ |_____/_/\_\ |_| |___|_| |_____|_____|___|_| \_|_____| //
// //
/////////////////////////////////////////////////////////////////////////////////
always_ff @(posedge clk, negedge rst_n)
begin
if (rst_n == 1'b0)
begin
branch_pc_ex_o <= '0;
end
else begin
if (jump_in_id == `BRANCH_COND && id_valid_o)
branch_pc_ex_o <= pc_id_i;
end
end
always_ff @(posedge clk, negedge rst_n)
begin : ID_EX_PIPE_REGISTERS
@ -1052,11 +1041,12 @@ module riscv_id_stage
data_sign_ext_ex_o <= 1'b0;
data_reg_offset_ex_o <= 2'b0;
data_req_ex_o <= 1'b0;
data_pc_ex_o <= '0;
data_load_event_ex_o <= 1'b0;
data_misaligned_ex_o <= 1'b0;
pc_ex_o <= '0;
branch_in_ex_o <= 1'b0;
end
@ -1139,19 +1129,17 @@ module riscv_id_stage
data_type_ex_o <= data_type_id;
data_sign_ext_ex_o <= data_sign_ext_id;
data_reg_offset_ex_o <= data_reg_offset_id;
if (data_load_event_id) begin
data_pc_ex_o <= pc_id_i;
data_load_event_ex_o <= 1'b1;
end else begin
data_load_event_ex_o <= 1'b0;
end
data_load_event_ex_o <= data_load_event_id;;
end else begin
data_load_event_ex_o <= 1'b0;
end
data_misaligned_ex_o <= 1'b0;
if ((jump_in_id == `BRANCH_COND) || data_load_event_id) begin
pc_ex_o <= pc_id_i;
end
branch_in_ex_o <= jump_in_id == `BRANCH_COND;
end else if(ex_ready_i) begin
// EX stage is ready but we don't have a new instruction for it,

View file

@ -124,7 +124,7 @@ module riscv_core
logic lsu_busy;
logic [31:0] branch_pc_ex; // PC of last executed branch
logic [31:0] pc_ex; // PC of last executed branch or p.elw
// ALU Control
logic [`ALU_OP_WIDTH-1:0] alu_operator_ex;
@ -425,7 +425,7 @@ module riscv_core
.wb_valid_i ( wb_valid ),
// From the Pipeline ID/EX
.branch_pc_ex_o ( branch_pc_ex ),
.pc_ex_o ( pc_ex ),
.alu_operator_ex_o ( alu_operator_ex ),
.alu_operand_a_ex_o ( alu_operand_a_ex ),
@ -477,7 +477,6 @@ module riscv_core
.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_pc_ex_o ( data_pc_ex ), // to load store unit
.data_load_event_ex_o ( data_load_event_ex ), // to load store unit
.data_misaligned_ex_o ( data_misaligned_ex ), // to load store unit
@ -696,8 +695,8 @@ module riscv_core
.irq_enable_o ( irq_enable ),
.mepc_o ( mepc ),
.curr_pc_id_i ( pc_id ), // from IF stage
.data_pc_ex_i ( data_pc_ex ), // from ID/EX pipeline
.pc_id_i ( pc_id ), // from IF stage
.pc_ex_i ( pc_ex ), // from ID/EX pipeline
.data_load_event_ex_i ( data_load_event_ex ), // from ID/EX pipeline
.exc_save_i ( exc_save_id ),
.exc_restore_i ( exc_restore_id ),
@ -754,55 +753,57 @@ module riscv_core
riscv_debug_unit debug_unit_i
(
.clk ( clk_i ), // always-running clock for debug
.rst_n ( rst_ni ),
.clk ( clk_i ), // always-running clock for debug
.rst_n ( rst_ni ),
// Debug Interface
.debug_req_i ( debug_req_i ),
.debug_gnt_o ( debug_gnt_o ),
.debug_rvalid_o ( debug_rvalid_o ),
.debug_addr_i ( debug_addr_i ),
.debug_we_i ( debug_we_i ),
.debug_wdata_i ( debug_wdata_i ),
.debug_rdata_o ( debug_rdata_o ),
.debug_halt_i ( debug_halt_i ),
.debug_halted_o ( debug_halted_o ),
.debug_req_i ( debug_req_i ),
.debug_gnt_o ( debug_gnt_o ),
.debug_rvalid_o ( debug_rvalid_o ),
.debug_addr_i ( debug_addr_i ),
.debug_we_i ( debug_we_i ),
.debug_wdata_i ( debug_wdata_i ),
.debug_rdata_o ( debug_rdata_o ),
.debug_halt_i ( debug_halt_i ),
.debug_halted_o ( debug_halted_o ),
// To/From Core
.settings_o ( dbg_settings ),
.trap_i ( dbg_trap ),
.exc_cause_i ( exc_cause ),
.stall_o ( dbg_stall ),
.dbg_req_o ( dbg_req ),
.dbg_ack_i ( dbg_ack ),
.settings_o ( dbg_settings ),
.trap_i ( dbg_trap ),
.exc_cause_i ( exc_cause ),
.stall_o ( dbg_stall ),
.dbg_req_o ( dbg_req ),
.dbg_ack_i ( dbg_ack ),
// register file read port
.regfile_rreq_o ( dbg_reg_rreq ),
.regfile_raddr_o ( dbg_reg_raddr ),
.regfile_rdata_i ( dbg_reg_rdata ),
.regfile_rreq_o ( dbg_reg_rreq ),
.regfile_raddr_o ( dbg_reg_raddr ),
.regfile_rdata_i ( dbg_reg_rdata ),
// register file write port
.regfile_wreq_o ( dbg_reg_wreq ),
.regfile_waddr_o ( dbg_reg_waddr ),
.regfile_wdata_o ( dbg_reg_wdata ),
.regfile_wreq_o ( dbg_reg_wreq ),
.regfile_waddr_o ( dbg_reg_waddr ),
.regfile_wdata_o ( dbg_reg_wdata ),
// CSR read/write port
.csr_req_o ( dbg_csr_req ),
.csr_addr_o ( dbg_csr_addr ),
.csr_we_o ( dbg_csr_we ),
.csr_wdata_o ( dbg_csr_wdata ),
.csr_rdata_i ( csr_rdata ),
.csr_req_o ( dbg_csr_req ),
.csr_addr_o ( dbg_csr_addr ),
.csr_we_o ( dbg_csr_we ),
.csr_wdata_o ( dbg_csr_wdata ),
.csr_rdata_i ( csr_rdata ),
// signals for PPC and NPC
.curr_pc_if_i ( pc_if ), // from IF stage
.curr_pc_id_i ( pc_id ), // from IF stage
.branch_pc_i ( branch_pc_ex ), // PC of last executed branch (in EX stage)
.pc_if_i ( pc_if ), // from IF stage
.pc_id_i ( pc_id ), // from IF stage
.pc_ex_i ( pc_ex ), // PC of last executed branch (in EX stage) or p.elw
.branch_in_ex_i ( branch_in_ex ),
.branch_taken_i ( branch_decision ),
.data_load_event_i ( data_load_event_ex ),
.jump_addr_o ( dbg_jump_addr ), // PC from debug unit
.jump_req_o ( dbg_jump_req ) // set PC to new value
.branch_in_ex_i ( branch_in_ex ),
.branch_taken_i ( branch_decision ),
.jump_addr_o ( dbg_jump_addr ), // PC from debug unit
.jump_req_o ( dbg_jump_req ) // set PC to new value
);