Merge branch 'hwloops'

This commit is contained in:
Sven Stucki 2015-09-07 03:41:28 +02:00
commit c2b519786b
9 changed files with 456 additions and 534 deletions

View file

@ -86,9 +86,11 @@ module controller
input logic data_rvalid_i, // rvalid from data memory
// hwloop signals
output logic [2:0] hwloop_we_o, // write enables for hwloop regs
output logic hwloop_wb_mux_sel_o, // select data to write to hwloop regs
output logic [1:0] hwloop_cnt_mux_sel_o, // selects hwloop counter input
output logic [2:0] hwloop_we_o, // write enable for hwloop regs
output logic hwloop_start_mux_sel_o, // selects hwloop start address input
output logic hwloop_end_mux_sel_o, // selects hwloop end address input
output logic hwloop_cnt_mux_sel_o, // selects hwloop counter input
input logic hwloop_jump_i, // modify pc_mux_sel to select the hwloop addr
// Interrupt signals
@ -120,6 +122,7 @@ module controller
output logic [1:0] operand_c_fw_mux_sel_o, // regfile rc data selector form ID stage
// Jump target calcuation done decision
output logic [1:0] jump_target_mux_sel_o, // jump target selection
input logic [1:0] jump_in_ex_i, // jump is being calculated in ALU
output logic [1:0] jump_in_id_o, // jump is being calculated in ALU
input logic branch_decision_i,
@ -191,12 +194,15 @@ module controller
always_comb
begin
jump_in_id = `BRANCH_NONE;
jump_target_mux_sel_o = `JT_JAL;
alu_operator = `ALU_NOP;
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;
immediate_mux_sel_o = `IMM_I;
vector_mode_o = `VEC_MODE32;
scalar_replication_o = 1'b0;
alu_cmp_mode_o = `ALU_CMP_FULL;
@ -213,9 +219,9 @@ module controller
prepost_useincr_o = 1'b1;
hwloop_we_o = 3'b0;
hwloop_wb_mux_sel_o = 1'b0;
hwloop_cnt_mux_sel_o = 2'b00;
immediate_mux_sel_o = `IMM_I;
hwloop_start_mux_sel_o = 1'b0;
hwloop_end_mux_sel_o = 1'b0;
hwloop_cnt_mux_sel_o = 1'b0;
csr_access_o = 1'b0;
csr_op = `CSR_OP_NONE;
@ -249,43 +255,44 @@ module controller
//////////////////////////////////////
`OPCODE_JAL: begin // Jump and Link
if (instr_rdata_i ==? `INSTR_JAL) begin
jump_in_id = `BRANCH_JAL;
// Calculate and store PC+4
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_PCINCR;
alu_operator = `ALU_ADD;
regfile_alu_we = 1'b1;
// Calculate jump target (= PC + UJ imm)
alu_op_c_mux_sel_o = `OP_C_JT;
end else begin
illegal_insn_int = 1'b1;
end
jump_target_mux_sel_o = `JT_JAL;
jump_in_id = `BRANCH_JAL;
// Calculate and store PC+4
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_PCINCR;
alu_operator = `ALU_ADD;
regfile_alu_we = 1'b1;
// Calculate jump target (= PC + UJ imm)
alu_op_c_mux_sel_o = `OP_C_JT;
end
`OPCODE_JALR: begin // Jump and Link Register
if (instr_rdata_i ==? `INSTR_JALR) begin
jump_in_id = `BRANCH_JALR;
// Calculate and store PC+4
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_PCINCR;
alu_operator = `ALU_ADD;
regfile_alu_we = 1'b1;
// Calculate jump target (= RS1 + I imm)
rega_used = 1'b1;
alu_op_c_mux_sel_o = `OP_C_JT;
end else begin
illegal_insn_int = 1'b1;
jump_target_mux_sel_o = `JT_JALR;
jump_in_id = `BRANCH_JALR;
// Calculate and store PC+4
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
immediate_mux_sel_o = `IMM_PCINCR;
alu_operator = `ALU_ADD;
regfile_alu_we = 1'b1;
// Calculate jump target (= RS1 + I imm)
rega_used = 1'b1;
alu_op_c_mux_sel_o = `OP_C_JT;
if (instr_rdata_i[14:12] != 3'b0) begin
jump_in_id = `BRANCH_NONE;
regfile_alu_we = 1'b0;
illegal_insn_int = 1'b0;
end
end
`OPCODE_BRANCH: begin // Branch
jump_in_id = `BRANCH_COND;
alu_op_c_mux_sel_o = `OP_C_JT;
rega_used = 1'b1;
regb_used = 1'b1;
jump_target_mux_sel_o = `JT_COND;
jump_in_id = `BRANCH_COND;
alu_op_c_mux_sel_o = `OP_C_JT;
rega_used = 1'b1;
regb_used = 1'b1;
unique case (instr_rdata_i[14:12])
3'b000: alu_operator = `ALU_EQ;
@ -828,54 +835,54 @@ module controller
// //
///////////////////////////////////////////////
`OPCODE_HWLOOP: begin // hardware loop instructions
`OPCODE_HWLOOP: begin
jump_target_mux_sel_o = `JT_HWLP; // get PC + I imm from jump target adder
unique case (instr_rdata_i[14:12])
3'b000: begin // lp.starti set start address
hwloop_wb_mux_sel_o = 1'b1;
hwloop_we_o[0] = 1'b1; // set we for start addr reg
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
alu_operator = `ALU_ADD;
3'b000: begin
// lp.starti: set start address to PC + I-type immediate
hwloop_we_o[0] = 1'b1;
hwloop_start_mux_sel_o = 1'b0;
// $display("%t: hwloop start address: %h", $time, instr_rdata_i);
end
3'b001: begin // lp.endi set end address
hwloop_wb_mux_sel_o = 1'b1;
hwloop_we_o[1] = 1'b1; // set we for end addr reg
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
alu_operator = `ALU_ADD;
3'b001: begin
// lp.endi: set end address to PC + I-type immediate
hwloop_we_o[1] = 1'b1;
hwloop_end_mux_sel_o = 1'b0; // jump target
// $display("%t: hwloop end address: %h", $time, instr_rdata_i);
end
3'b010: begin // lp.count initialize counter from register
hwloop_cnt_mux_sel_o = 2'b11;
hwloop_we_o[2] = 1'b1; // set we for counter reg
3'b010: begin
// lp.count initialize counter from rs1
hwloop_we_o[2] = 1'b1;
hwloop_cnt_mux_sel_o = 1'b1;
rega_used = 1'b1;
// $display("%t: hwloop counter: %h", $time, instr_rdata_i);
end
3'b011: begin // lp.counti initialize counter from immediate
hwloop_cnt_mux_sel_o = 2'b01;
hwloop_we_o[2] = 1'b1; // set we for counter reg
3'b011: begin
// lp.counti initialize counter from I-type immediate
hwloop_we_o[2] = 1'b1;
hwloop_cnt_mux_sel_o = 1'b0;
// $display("%t: hwloop counter imm: %h", $time, instr_rdata_i);
end
3'b100: begin // lp.setup
hwloop_wb_mux_sel_o = 1'b0;
hwloop_cnt_mux_sel_o = 2'b11;
hwloop_we_o = 3'b111; // set we for counter/start/end reg
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
alu_operator = `ALU_ADD;
// TODO: immediate_mux_sel_o = `IMM_16Z;
rega_used = 1'b1;
3'b100: begin
// lp.setup: initialize counter from rs1, set start address to
// next instruction and end address to PC + I-type immediate
hwloop_we_o = 3'b111;
hwloop_start_mux_sel_o = 1'b1;
hwloop_end_mux_sel_o = 1'b0;
hwloop_cnt_mux_sel_o = 1'b1;
rega_used = 1'b1;
// $display("%t: hwloop setup: %h", $time, instr_rdata_i);
end
3'b101: begin // lp.setupi
hwloop_wb_mux_sel_o = 1'b0;
hwloop_cnt_mux_sel_o = 2'b10;
hwloop_we_o = 3'b111; // set we for counter/start/end reg
alu_op_a_mux_sel_o = `OP_A_CURRPC;
alu_op_b_mux_sel_o = `OP_B_IMM;
alu_operator = `ALU_ADD;
// TODO: immediate_mux_sel_o = `IMM_8Z;
3'b101: begin
// lp.setupi: initialize counter from I-type immediate, set start
// address to next instruction and end address to PC + shifted
// z-type immediate
hwloop_we_o = 3'b111;
hwloop_start_mux_sel_o = 1'b1;
hwloop_end_mux_sel_o = 1'b1;
hwloop_cnt_mux_sel_o = 1'b0;
illegal_insn_int = 1'b1; // TODO: PC + z-imm currently not supported
// $display("%t: hwloop setup imm: %h", $time, instr_rdata_i);
end
default: begin
@ -922,10 +929,9 @@ module controller
always_ff @(negedge clk)
begin
// print warning in case of decoding errors
// note: this is done intentionally before checking RVC decoding, to
// suppress wrong (and annoying) messages during simulation
if (illegal_insn_o) begin
$warning("%t: Illegal instruction (core %0d) at PC 0x%h:", $time, riscv_core.core_id_i);
$display("%t: Illegal instruction (core %0d) at PC 0x%h:", $time, riscv_core.core_id_i,
id_stage.current_pc_id_i);
//prettyPrintInstruction(instr_rdata_i, id_stage.current_pc_id_i);
end
end
@ -1023,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

@ -96,7 +96,6 @@ module cs_registers
logic is_pcmr;
// Generic CSRs
int csr_index;
logic [31:0] csr [0:`CSR_MAX_IDX];
logic [31:0] csr_n [0:`CSR_MAX_IDX];

View file

@ -62,12 +62,6 @@ module ex_stage
input logic regfile_we_i,
input logic [4:0] regfile_waddr_i,
input logic [31:0] regfile_rb_data_i,
input logic hwloop_wb_mux_sel_i,
input logic [31:0] hwloop_pc_plus4_i,
input logic [31:0] hwloop_cnt_i,
// CSR access
input logic csr_access_i,
input logic [31:0] csr_rdata_i,
@ -75,11 +69,6 @@ module ex_stage
// Output of EX stage pipeline
output logic [4:0] regfile_waddr_wb_o,
output logic regfile_we_wb_o,
output logic [31:0] regfile_rb_data_wb_o,
output logic [31:0] hwloop_start_data_o,
output logic [31:0] hwloop_end_data_o,
output logic [31:0] hwloop_cnt_data_o,
// Forwarding ports : to ID stage
output logic [4:0] regfile_alu_waddr_fw_o,
@ -113,21 +102,6 @@ module ex_stage
regfile_alu_wdata_fw_o = csr_rdata_i;
end
// hwloop mux. selects the right data to be sent to the hwloop registers (start/end-address and counter)
always_comb
begin : hwloop_start_mux
case (hwloop_wb_mux_sel_i)
1'b0: hwloop_start_data_o = hwloop_pc_plus4_i;
1'b1: hwloop_start_data_o = alu_result;
endcase
end
// assign alu result to hwloop end data
assign hwloop_end_data_o = alu_result;
// assign hwloop mux. selects the right data to be sent to the hwloop registers (start/end-address and counter)
assign hwloop_cnt_data_o = hwloop_cnt_i;
// Branch is taken when result[0] == 1'b1
assign branch_decision_o = alu_flag;
assign jump_target_o = alu_operand_c_i;
@ -188,7 +162,6 @@ module ex_stage
begin
regfile_waddr_wb_o <= 5'b0_0000;
regfile_we_wb_o <= 1'b0;
regfile_rb_data_wb_o <= 32'h0000_0000;
end
else
begin
@ -196,7 +169,6 @@ module ex_stage
begin
regfile_we_wb_o <= regfile_we_i;
regfile_waddr_wb_o <= regfile_waddr_i;
regfile_rb_data_wb_o <= regfile_rb_data_i;
end
end
end

View file

@ -48,7 +48,6 @@ module exc_controller
// SPR
output logic save_pc_if_o, // saves current_pc_if before entering interrupt routine
output logic save_pc_id_o, // saves current_pc_id before entering interrupt routine
output logic save_sr_o, // saves status register
// Controller
input logic core_busy_i, // Is the controller currently in the IDLE state?
@ -146,14 +145,14 @@ module exc_controller
end
end
//////////////////////////////////////////////////////////////////////
// _____ _ _ ____ _ _ //
// | ____|_ _____ ___ _ __ | |_(_) ___ _ __ / ___| |_ _ __| | //
// | _| \ \/ / __/ _ \ '_ \| __| |/ _ \| '_ \ | | | __| '__| | //
// | |___ > < (_| __/ |_) | |_| | (_) | | | | | |___| |_| | | | //
// |_____/_/\_\___\___| .__/ \__|_|\___/|_| |_| \____|\__|_| |_| //
// |_| //
//////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////
// _____ _ _ ____ _ _ //
// | ____|_ _____ ___ _ __ | |_(_) ___ _ __ / ___| |_ _ __| | //
// | _| \ \/ / __/ _ \ '_ \| __| |/ _ \| '_ \ | | | __| '__| | //
// | |___ > < (_| __/ |_) | |_| | (_) | | | | | |___| |_| | | | //
// |_____/_/\_\___\___| .__/ \__|_|\___/|_| |_| \____|\__|_| |_| //
// |_| //
/////////////////////////////////////////////////////////////////////
// exception control FSM
always_comb begin
@ -163,7 +162,6 @@ module exc_controller
clear_exc_reason = 1'b0;
save_pc_if_o = 1'b0;
save_pc_id_o = 1'b0;
save_sr_o = 1'b0;
force_nop_o = 1'b0;
pc_valid_o = 1'b1;
exc_pc_sel_o = 1'b0;
@ -184,7 +182,6 @@ module exc_controller
force_nop_o = 1'b1;
exc_pc_sel_o = 1'b1;
save_pc_if_o = 1'b1; // save current PC
save_sr_o = 1'b1; // save Supervision Register
if (irq_nm_i == 1'b1) // emergency IRQ has higher priority
exc_pc_mux_o = `EXC_PC_IRQ_NM;
@ -208,7 +205,6 @@ module exc_controller
exc_pc_sel_o = 1'b1;
exc_pc_mux_o = `EXC_PC_ILLINSN;
save_pc_id_o = 1'b1; // save current PC
save_sr_o = 1'b1; // save Supervision Register
exc_running_n = 1'b1;
clear_exc_reason = 1'b1;
@ -224,7 +220,6 @@ module exc_controller
force_nop_o = 1'b1;
exc_pc_sel_o = 1'b1;
save_pc_if_o = 1'b1; // save current PC
save_sr_o = 1'b1; // save Supervision Register
if (irq_nm_i == 1'b1) // emergency IRQ has higher priority
exc_pc_mux_o = `EXC_PC_IRQ_NM;

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

@ -93,12 +93,8 @@ module id_stage
output logic prepost_useincr_ex_o,
input logic data_misaligned_i,
output logic [2:0] hwloop_we_ex_o,
output logic [1:0] hwloop_regid_ex_o,
output logic hwloop_wb_mux_sel_ex_o,
output logic [31:0] hwloop_cnt_o,
output logic [`HWLOOP_REGS-1:0] hwloop_dec_cnt_o,
output logic [31:0] hwloop_targ_addr_o,
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,
@ -119,12 +115,6 @@ module id_stage
input logic irq_enable_i,
output logic save_pc_if_o,
output logic save_pc_id_o,
output logic save_sr_o,
// from hwloop regs
input logic [`HWLOOP_REGS-1:0] [31:0] hwloop_start_addr_i,
input logic [`HWLOOP_REGS-1:0] [31:0] hwloop_end_addr_i,
input logic [`HWLOOP_REGS-1:0] [31:0] hwloop_counter_i,
// Debug Unit Signals
input logic dbg_flush_pipe_i,
@ -169,8 +159,6 @@ module id_stage
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] jump_target; // calculated jump target (-> EX -> IF)
logic exc_pc_sel;
@ -215,6 +203,8 @@ module id_stage
logic [2:0] immediate_mux_sel;
logic [1:0] jump_target_mux_sel;
// Multiplier Control
logic mult_en; // multiplication is used instead of ALU
logic [1:0] mult_sel_subword; // Select a subword when doing multiplications
@ -235,11 +225,21 @@ module id_stage
// 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 hwloop_start_mux_sel;
logic hwloop_end_mux_sel;
logic hwloop_cnt_mux_sel;
logic [31:0] hwloop_start;
logic [31:0] hwloop_end;
logic [31:0] hwloop_cnt;
// hwloop reg signals
logic [`HWLOOP_REGS-1:0] hwloop_dec_cnt;
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_start_addr;
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_end_addr;
logic [`HWLOOP_REGS-1:0] [31:0] hwloop_counter;
// CSR control
logic csr_access;
@ -296,25 +296,12 @@ module id_stage
//assign alu_vec_ext = instr[9:8]; TODO
assign alu_vec_ext = '0;
// Second Register Write Adress Selection
// Used for prepost load/store and multiplier
assign regfile_alu_waddr_id = regfile_alu_waddr_mux_sel ?
regfile_waddr_id : regfile_addr_ra_id;
///////////////////////////////////////////////////////////////////////////////////////
// ____ ____ _ //
// | _ \ _ __ ___ __ _ _ __ __ _ _ __ ___ / ___|___ _ _ _ __ | |_ ___ _ __ //
// | |_) | '__/ _ \ / _` | '__/ _` | '_ ` _ \ | | / _ \| | | | '_ \| __/ _ \ '__| //
// | __/| | | (_) | (_| | | | (_| | | | | | | | |__| (_) | |_| | | | | || __/ | //
// |_| |_| \___/ \__, |_| \__,_|_| |_| |_| \____\___/ \__,_|_| |_|\__\___|_| //
// |___/ //
///////////////////////////////////////////////////////////////////////////////////////
assign current_pc = current_pc_id_i;
///////////////////////////////////////////////
// _ ___ ___ ___ ___ ____ //
// | | | \ \ / / | / _ \ / _ \| _ \ //
@ -324,23 +311,39 @@ module id_stage
// //
///////////////////////////////////////////////
// hwloop_cnt_mux
// hwloop register id
assign hwloop_regid = instr[8:7]; // rd contains hwloop register id
// hwloop start mux
always_comb
begin
unique case (hwloop_start_mux_sel)
1'b0: hwloop_start = jump_target; // for PC + I imm
1'b1: hwloop_start = current_pc_if_i; // for next PC
endcase
end
// hwloop end mux
always_comb
begin
unique case (hwloop_end_mux_sel)
1'b0: hwloop_end = jump_target; // for PC + I imm
1'b1: hwloop_end = jump_target; // TODO: PC + (Z imm << 1) for lp.setupi
endcase
end
// hwloop cnt mux
always_comb
begin : hwloop_cnt_mux
unique case (hwloop_cnt_mux_sel)
2'b00: hwloop_cnt = 32'b0;
2'b01: hwloop_cnt = imm_i_type;
2'b10: hwloop_cnt = 32'b0;
2'b11: hwloop_cnt = operand_a_fw_id;
endcase; // case (hwloop_cnt_mux_sel)
1'b0: hwloop_cnt = imm_i_type;
1'b1: hwloop_cnt = operand_a_fw_id;
endcase;
end
// hwloop register id
assign hwloop_regid = instr[8:7]; // rd contains hwloop register id
//////////////////////////////////////////////////////////////////
// _ _____ _ //
// _ _____ _ //
// | |_ _ _ __ ___ _ __ |_ _|_ _ _ __ __ _ ___| |_ //
// _ | | | | | '_ ` _ \| '_ \ | |/ _` | '__/ _` |/ _ \ __| //
// | |_| | |_| | | | | | | |_) | | | (_| | | | (_| | __/ |_ //
@ -349,12 +352,12 @@ module id_stage
//////////////////////////////////////////////////////////////////
always_comb
begin
unique case (jump_in_id_o)
`BRANCH_JAL: jump_target = current_pc_id_i + imm_uj_type;
`BRANCH_JALR: jump_target = regfile_data_ra_id + imm_i_type; // cannot forward rs1 as path is too long
`BRANCH_COND: jump_target = current_pc_id_i + imm_sb_type;
default: jump_target = current_pc_id_i + imm_sb_type; // replicate this as default to avoid another case
begin : jump_target_mux
unique case (jump_target_mux_sel)
`JT_JAL: jump_target = current_pc_id_i + imm_uj_type;
`JT_JALR: jump_target = regfile_data_ra_id + imm_i_type; // cannot forward rs1 as path is too long
`JT_COND: jump_target = current_pc_id_i + imm_sb_type;
`JT_HWLP: jump_target = current_pc_id_i + imm_i_type;
endcase
end
@ -373,24 +376,24 @@ module id_stage
// ALU_Op_a Mux
always_comb
begin : alu_operand_a_mux
case (alu_op_a_mux_sel)
default: alu_operand_a = operand_a_fw_id;
`OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
`OP_A_CURRPC: alu_operand_a = current_pc;
`OP_A_ZIMM: alu_operand_a = imm_z_type;
`OP_A_ZERO: alu_operand_a = 32'b0;
endcase; // case (alu_op_a_mux_sel)
case (alu_op_a_mux_sel)
`OP_A_REGA_OR_FWD: alu_operand_a = operand_a_fw_id;
`OP_A_CURRPC: alu_operand_a = current_pc_id_i;
`OP_A_ZIMM: alu_operand_a = imm_z_type;
`OP_A_ZERO: alu_operand_a = 32'b0;
default: alu_operand_a = operand_a_fw_id;
endcase; // case (alu_op_a_mux_sel)
end
// Operand a forwarding mux
always_comb
begin : operand_a_fw_mux
case (operand_a_fw_mux_sel)
`SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i;
`SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i;
`SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id;
default: operand_a_fw_id = regfile_data_ra_id;
endcase; // case (operand_a_fw_mux_sel)
case (operand_a_fw_mux_sel)
`SEL_FW_EX: operand_a_fw_id = regfile_alu_wdata_fw_i;
`SEL_FW_WB: operand_a_fw_id = regfile_wdata_wb_i;
`SEL_REGFILE: operand_a_fw_id = regfile_data_ra_id;
default: operand_a_fw_id = regfile_data_ra_id;
endcase; // case (operand_a_fw_mux_sel)
end
//////////////////////////////////////////////////////
@ -405,25 +408,25 @@ module id_stage
// Immediate Mux for operand B
always_comb
begin : immediate_mux
unique case (immediate_mux_sel)
//`IMM_VEC: immediate_b = immediate_vec_id;
`IMM_I: immediate_b = imm_i_type;
`IMM_S: immediate_b = imm_s_type;
`IMM_U: immediate_b = imm_u_type;
`IMM_PCINCR: immediate_b = compressed_instr_o ? 32'h2 : 32'h4;
default: immediate_b = imm_i_type;
endcase; // case (immediate_mux_sel)
unique case (immediate_mux_sel)
//`IMM_VEC: immediate_b = immediate_vec_id;
`IMM_I: immediate_b = imm_i_type;
`IMM_S: immediate_b = imm_s_type;
`IMM_U: immediate_b = imm_u_type;
`IMM_PCINCR: immediate_b = compressed_instr_o ? 32'h2 : 32'h4;
default: immediate_b = imm_i_type;
endcase; // case (immediate_mux_sel)
end
// ALU_Op_b Mux
always_comb
begin : alu_operand_b_mux
case (alu_op_b_mux_sel)
default: operand_b = operand_b_fw_id;
`OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id;
`OP_B_REGC_OR_FWD: operand_b = alu_operand_c;
`OP_B_IMM: operand_b = immediate_b;
endcase // case (alu_op_b_mux_sel)
case (alu_op_b_mux_sel)
`OP_B_REGB_OR_FWD: operand_b = operand_b_fw_id;
`OP_B_REGC_OR_FWD: operand_b = alu_operand_c;
`OP_B_IMM: operand_b = immediate_b;
default: operand_b = operand_b_fw_id;
endcase // case (alu_op_b_mux_sel)
end
// scalar replication for operand B
@ -436,12 +439,12 @@ module id_stage
// Operand b forwarding mux
always_comb
begin : operand_b_fw_mux
case (operand_b_fw_mux_sel)
`SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
`SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i;
`SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id;
default: operand_b_fw_id = regfile_data_rb_id;
endcase; // case (operand_b_fw_mux_sel)
case (operand_b_fw_mux_sel)
`SEL_FW_EX: operand_b_fw_id = regfile_alu_wdata_fw_i;
`SEL_FW_WB: operand_b_fw_id = regfile_wdata_wb_i;
`SEL_REGFILE: operand_b_fw_id = regfile_data_rb_id;
default: operand_b_fw_id = regfile_data_rb_id;
endcase; // case (operand_b_fw_mux_sel)
end
@ -466,12 +469,12 @@ module id_stage
// 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 = operand_c;
default: alu_operand_c = operand_c;
endcase; // case (operand_b_fw_mux_sel)
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 = operand_c;
default: alu_operand_c = operand_c;
endcase; // case (operand_b_fw_mux_sel)
end
@ -523,115 +526,117 @@ module id_stage
////////////////////////////////////////////////////////////////////
controller controller_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.fetch_enable_i ( fetch_enable_i ),
.core_busy_o ( core_busy_o ),
.clk ( clk ),
.rst_n ( rst_n ),
.fetch_enable_i ( fetch_enable_i ),
.core_busy_o ( core_busy_o ),
// Signal from-to PC pipe (instr rdata) and instr mem system (req and ack)
.instr_rdata_i ( instr ),
.instr_req_o ( instr_req_o ),
.instr_gnt_i ( instr_gnt_i ),
.instr_ack_i ( instr_ack_i ),
.pc_mux_sel_o ( pc_mux_sel_int ),
// Signal from-to PC pipe (instr rdata) and instr mem system (req and ack)
.instr_rdata_i ( instr ),
.instr_req_o ( instr_req_o ),
.instr_gnt_i ( instr_gnt_i ),
.instr_ack_i ( instr_ack_i ),
.pc_mux_sel_o ( pc_mux_sel_int ),
// Alu signals
.alu_operator_o ( alu_operator ),
.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 ),
.immediate_mux_sel_o ( immediate_mux_sel ),
// Alu signals
.alu_operator_o ( alu_operator ),
.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 ),
.immediate_mux_sel_o ( immediate_mux_sel ),
.scalar_replication_o ( scalar_replication ),
.vector_mode_o ( vector_mode ),
.alu_cmp_mode_o ( alu_cmp_mode ),
.scalar_replication_o ( scalar_replication ),
.vector_mode_o ( vector_mode ),
.alu_cmp_mode_o ( alu_cmp_mode ),
// mult signals
.mult_en_o ( mult_en ),
.mult_sel_subword_o ( mult_sel_subword ),
.mult_signed_mode_o ( mult_signed_mode ),
.mult_mac_en_o ( mult_mac_en ),
// mult signals
.mult_en_o ( mult_en ),
.mult_sel_subword_o ( mult_sel_subword ),
.mult_signed_mode_o ( mult_signed_mode ),
.mult_mac_en_o ( mult_mac_en ),
// Register file control signals
.regfile_we_o ( regfile_we_id ),
// Register file control signals
.regfile_we_o ( regfile_we_id ),
.regfile_alu_we_o ( regfile_alu_we_id ),
.regfile_alu_waddr_mux_sel_o ( regfile_alu_waddr_mux_sel ),
.regfile_alu_we_o ( regfile_alu_we_id ),
.regfile_alu_waddr_mux_sel_o ( regfile_alu_waddr_mux_sel ),
.prepost_useincr_o ( prepost_useincr ),
.data_misaligned_i ( data_misaligned_i ),
.prepost_useincr_o ( prepost_useincr ),
.data_misaligned_i ( data_misaligned_i ),
// CSR control signals
.csr_access_o ( csr_access ),
.csr_op_o ( csr_op ),
// CSR control signals
.csr_access_o ( csr_access ),
.csr_op_o ( csr_op ),
// Data bus interface
.data_we_o ( data_we_id ),
.data_type_o ( data_type_id ),
.data_sign_extension_o ( data_sign_ext_id ),
.data_reg_offset_o ( data_reg_offset_id ),
.data_req_o ( data_req_id ),
.data_ack_i ( data_ack_i ),
.data_req_ex_i ( data_req_ex_o ),
.data_rvalid_i ( data_rvalid_i ),
// Data bus interface
.data_we_o ( data_we_id ),
.data_type_o ( data_type_id ),
.data_sign_extension_o ( data_sign_ext_id ),
.data_reg_offset_o ( data_reg_offset_id ),
.data_req_o ( data_req_id ),
.data_ack_i ( data_ack_i ),
.data_req_ex_i ( data_req_ex_o ),
.data_rvalid_i ( data_rvalid_i ),
// hwloop signals
.hwloop_we_o ( hwloop_we ),
.hwloop_wb_mux_sel_o ( hwloop_wb_mux_sel ),
.hwloop_cnt_mux_sel_o ( hwloop_cnt_mux_sel ),
.hwloop_jump_i ( hwloop_jump ),
// hwloop signals
.hwloop_we_o ( hwloop_we ),
.hwloop_start_mux_sel_o ( hwloop_start_mux_sel ),
.hwloop_end_mux_sel_o ( hwloop_end_mux_sel ),
.hwloop_cnt_mux_sel_o ( hwloop_cnt_mux_sel ),
.hwloop_jump_i ( hwloop_jump ),
// Interrupt signals
.irq_present_i ( irq_present ),
// Interrupt signals
.irq_present_i ( irq_present ),
// Exception Controller Signals
.illegal_c_insn_i ( illegal_c_insn ),
.illegal_insn_o ( illegal_insn ),
.trap_insn_o ( trap_insn ),
.pc_valid_i ( pc_valid ),
.clear_isr_running_o ( clear_isr_running ),
.trap_hit_i ( trap_hit ),
.exc_pipe_flush_i ( exc_pipe_flush ),
// Exception Controller Signals
.illegal_c_insn_i ( illegal_c_insn ),
.illegal_insn_o ( illegal_insn ),
.trap_insn_o ( trap_insn ),
.pc_valid_i ( pc_valid ),
.clear_isr_running_o ( clear_isr_running ),
.trap_hit_i ( trap_hit ),
.exc_pipe_flush_i ( exc_pipe_flush ),
// Debug Unit Signals
.dbg_stall_i ( dbg_stall_i ),
.dbg_set_npc_i ( dbg_set_npc_i ),
.dbg_trap_o ( dbg_trap_o ),
// Debug Unit Signals
.dbg_stall_i ( dbg_stall_i ),
.dbg_set_npc_i ( dbg_set_npc_i ),
.dbg_trap_o ( dbg_trap_o ),
// regfile port 1
.regfile_waddr_ex_i ( regfile_waddr_ex_o ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_ex_i ( regfile_we_ex_o ),
.regfile_waddr_wb_i ( regfile_waddr_wb_i ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_wb_i ( regfile_we_wb_i ),
// regfile port 1
.regfile_waddr_ex_i ( regfile_waddr_ex_o ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_ex_i ( regfile_we_ex_o ),
.regfile_waddr_wb_i ( regfile_waddr_wb_i ), // Write address for register file from ex-wb- pipeline registers
.regfile_we_wb_i ( regfile_we_wb_i ),
// regfile port 2
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw_i ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw_i ),
// regfile port 2
.regfile_alu_waddr_fw_i ( regfile_alu_waddr_fw_i ),
.regfile_alu_we_fw_i ( regfile_alu_we_fw_i ),
// Forwarding signals
.operand_a_fw_mux_sel_o ( operand_a_fw_mux_sel ),
.operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ),
.operand_c_fw_mux_sel_o ( operand_c_fw_mux_sel ),
// Forwarding signals
.operand_a_fw_mux_sel_o ( operand_a_fw_mux_sel ),
.operand_b_fw_mux_sel_o ( operand_b_fw_mux_sel ),
.operand_c_fw_mux_sel_o ( operand_c_fw_mux_sel ),
// To controller (TODO: Remove when control/decode separated and moved)
.jump_in_ex_i ( jump_in_ex_o ),
// To controller (TODO: Remove when control/decode separated and moved)
.jump_target_mux_sel_o ( jump_target_mux_sel ),
.jump_in_ex_i ( jump_in_ex_o ),
.branch_decision_i ( branch_decision_i ),
.branch_decision_i ( branch_decision_i ),
// To exception controller and EX: Jump/Branch indication
.jump_in_id_o ( jump_in_id_o ),
// To exception controller and EX: Jump/Branch indication
.jump_in_id_o ( jump_in_id_o ),
// Stall signals
.stall_if_o ( stall_if_o ),
.stall_id_o ( stall_id_o ),
.stall_ex_o ( stall_ex_o ),
.stall_wb_o ( stall_wb_o ),
// Stall signals
.stall_if_o ( stall_if_o ),
.stall_id_o ( stall_id_o ),
.stall_ex_o ( stall_ex_o ),
.stall_wb_o ( stall_wb_o ),
// Performance Counters
.perf_jump_o ( perf_jump_o ),
.perf_branch_o ( perf_branch_o ),
.perf_jr_stall_o ( perf_jr_stall_o ),
.perf_ld_stall_o ( perf_ld_stall_o )
// Performance Counters
.perf_jump_o ( perf_jump_o ),
.perf_branch_o ( perf_branch_o ),
.perf_jr_stall_o ( perf_jr_stall_o ),
.perf_ld_stall_o ( perf_ld_stall_o )
);
@ -646,48 +651,47 @@ module id_stage
exc_controller exc_controller_i
(
.clk ( clk ),
.rst_n ( rst_n ),
.clk ( clk ),
.rst_n ( rst_n ),
.fetch_enable_i ( fetch_enable_i ),
.fetch_enable_i ( fetch_enable_i ),
// to IF stage
.exc_pc_sel_o ( exc_pc_sel ),
.exc_pc_mux_o ( exc_pc_mux_o ),
.force_nop_o ( force_nop_exc ),
// to IF stage
.exc_pc_sel_o ( exc_pc_sel ),
.exc_pc_mux_o ( exc_pc_mux_o ),
.force_nop_o ( force_nop_exc ),
// hwloop signals
.hwloop_enable_o ( hwloop_enable ),
// hwloop signals
.hwloop_enable_o ( hwloop_enable ),
// Interrupt signals
.irq_i ( irq_i ),
.irq_nm_i ( irq_nm_i ),
.irq_enable_i ( irq_enable_i ),
.irq_present_o ( irq_present ),
// Interrupt signals
.irq_i ( irq_i ),
.irq_nm_i ( irq_nm_i ),
.irq_enable_i ( irq_enable_i ),
.irq_present_o ( irq_present ),
// CSR
.save_pc_if_o ( save_pc_if_o ),
.save_pc_id_o ( save_pc_id_o ),
.save_sr_o ( save_sr_o ),
// CSR
.save_pc_if_o ( save_pc_if_o ),
.save_pc_id_o ( save_pc_id_o ),
// Controller
.core_busy_i ( core_busy_o ),
.jump_in_id_i ( jump_in_id_o ),
.jump_in_ex_i ( jump_in_ex_o ),
.stall_id_i ( stall_id_o ),
.illegal_insn_i ( illegal_insn ),
.trap_insn_i ( trap_insn ),
.drop_instruction_i ( 1'b0 ),
.pc_valid_o ( pc_valid ),
.clear_isr_running_i ( clear_isr_running ),
.trap_hit_o ( trap_hit ),
.exc_pipe_flush_o ( exc_pipe_flush ),
// Controller
.core_busy_i ( core_busy_o ),
.jump_in_id_i ( jump_in_id_o ),
.jump_in_ex_i ( jump_in_ex_o ),
.stall_id_i ( stall_id_o ),
.illegal_insn_i ( illegal_insn ),
.trap_insn_i ( trap_insn ),
.drop_instruction_i ( 1'b0 ),
.pc_valid_o ( pc_valid ),
.clear_isr_running_i ( clear_isr_running ),
.trap_hit_o ( trap_hit ),
.exc_pipe_flush_o ( exc_pipe_flush ),
// Debug Unit Signals
.dbg_flush_pipe_i ( dbg_flush_pipe_i ),
.dbg_st_en_i ( dbg_st_en_i ),
.dbg_dsr_i ( dbg_dsr_i )
);
// Debug Unit Signals
.dbg_flush_pipe_i ( dbg_flush_pipe_i ),
.dbg_st_en_i ( dbg_st_en_i ),
.dbg_dsr_i ( dbg_dsr_i )
);
//////////////////////////////////////////////////////////////////////////
@ -700,25 +704,49 @@ module id_stage
//////////////////////////////////////////////////////////////////////////
hwloop_controller hwloop_controller_i
(
// from ID stage
.enable_i ( hwloop_enable ),
.current_pc_i ( current_pc_if_i ),
(
// from ID stage
.enable_i ( hwloop_enable ),
.current_pc_i ( current_pc_if_i ),
// to ID controller
.hwloop_jump_o ( hwloop_jump ),
// to IF stage/controller
.hwloop_jump_o ( hwloop_jump ),
.hwloop_targ_addr_o ( hwloop_targ_addr_o ),
// to if stage
.hwloop_targ_addr_o ( hwloop_targ_addr_o ),
// from hwloop_regs
.hwloop_start_addr_i ( hwloop_start_addr ),
.hwloop_end_addr_i ( hwloop_end_addr ),
.hwloop_counter_i ( hwloop_counter ),
// from hwloop_regs
.hwloop_start_addr_i ( hwloop_start_addr_i ),
.hwloop_end_addr_i ( hwloop_end_addr_i ),
.hwloop_counter_i ( hwloop_counter_i ),
// to hwloop_regs
.hwloop_dec_cnt_o ( hwloop_dec_cnt )
);
// to hwloop_regs
.hwloop_dec_cnt_o ( hwloop_dec_cnt_o )
);
assign hwloop_jump_o = hwloop_jump;
hwloop_regs hwloop_regs_i
(
.clk ( clk ),
.rst_n ( rst_n ),
// from ID
.hwloop_start_data_i ( hwloop_start ),
.hwloop_end_data_i ( hwloop_end ),
.hwloop_cnt_data_i ( hwloop_cnt ),
.hwloop_we_i ( hwloop_we ),
.hwloop_regid_i ( hwloop_regid ),
// from controller
.stall_id_i ( stall_id_o ),
// to hwloop controller
.hwloop_start_addr_o ( hwloop_start_addr ),
.hwloop_end_addr_o ( hwloop_end_addr ),
.hwloop_counter_o ( hwloop_counter ),
// from hwloop controller
.hwloop_dec_cnt_i ( hwloop_dec_cnt )
);
/////////////////////////////////////////////////////////////////////////////////
@ -767,11 +795,6 @@ module id_stage
data_misaligned_ex_o <= 1'b0;
hwloop_we_ex_o <= 3'b0;
hwloop_regid_ex_o <= 2'b0;
hwloop_wb_mux_sel_ex_o <= 1'b0;
hwloop_cnt_o <= 32'b0;
jump_in_ex_o <= 2'b0;
end
@ -830,13 +853,7 @@ module id_stage
data_misaligned_ex_o <= 1'b0;
hwloop_we_ex_o <= hwloop_we;
hwloop_regid_ex_o <= hwloop_regid;
hwloop_wb_mux_sel_ex_o <= hwloop_wb_mux_sel;
hwloop_cnt_o <= hwloop_cnt;
jump_in_ex_o <= jump_in_id_o;
end
end

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

@ -341,6 +341,12 @@ endfunction // prettyPrintInstruction
`define BRANCH_JALR 2'b10
`define BRANCH_COND 2'b11 // conditional branches
// jump target mux
`define JT_HWLP 2'b00
`define JT_JAL 2'b01
`define JT_JALR 2'b10
`define JT_COND 2'b11
///////////////////////////////////////////////
// ___ _____ ____ _ //

View file

@ -116,7 +116,6 @@ module riscv_core
// Register Data
logic [31:0] regfile_rb_data_ex; // from id stage to load/store unit and ex stage
logic [31:0] regfile_rb_data_wb; // from ex stage to sp register
// ALU Control
@ -165,7 +164,6 @@ module riscv_core
logic data_sign_ext_ex;
logic [1:0] data_reg_offset_ex;
logic data_req_ex;
logic [31:0] data_addr_ex;
logic data_misaligned_ex;
logic data_ack_int;
@ -180,28 +178,9 @@ module riscv_core
logic save_pc_id;
// hwloop data from ALU
logic [31:0] hwlp_cnt_ex; // from id to ex stage (hwloop_regs)
logic [2:0] hwlp_we_ex; // from id to ex stage (hwloop_regs)
logic [1:0] hwlp_regid_ex; // from id to ex stage (hwloop_regs)
logic hwlp_wb_mux_sel_ex; // from id to ex stage (hwloop_regs)
logic [31:0] hwlp_start_data_ex; // hwloop data to write to hwloop_regs
logic [31:0] hwlp_end_data_ex; // hwloop data to write to hwloop_regs
logic [31:0] hwlp_cnt_data_ex; // hwloop data to write to hwloop_regs
// Access to hwloop registers
logic [31:0] hwlp_start_data;
logic [31:0] hwlp_end_data;
logic [31:0] hwlp_cnt_data;
logic [2:0] hwlp_we;
logic [1:0] hwlp_regid;
// hwloop controller signals
logic [`HWLOOP_REGS-1:0] [31:0] hwlp_start_addr; // to hwloop controller
logic [`HWLOOP_REGS-1:0] [31:0] hwlp_end_addr; // to hwloop controller
logic [`HWLOOP_REGS-1:0] [31:0] hwlp_counter; // to hwloop controller
logic [`HWLOOP_REGS-1:0] hwlp_dec_cnt; // from hwloop controller to hwloop regs
logic [31:0] hwlp_targ_addr; // from hwloop controller to if stage
// Hardware loop controller signals
logic hwloop_jump;
logic [31:0] hwloop_target; // from hwloop controller to if stage
// Debug Unit
@ -268,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 ),
@ -301,126 +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_we_ex_o ( hwlp_we_ex ),
.hwloop_regid_ex_o ( hwlp_regid_ex ),
.hwloop_wb_mux_sel_ex_o ( hwlp_wb_mux_sel_ex ),
.hwloop_cnt_o ( hwlp_cnt_ex ),
.hwloop_dec_cnt_o ( hwlp_dec_cnt ),
.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
// from hwloop regs
.hwloop_start_addr_i ( hwlp_start_addr ),
.hwloop_end_addr_i ( hwlp_end_addr ),
.hwloop_counter_i ( hwlp_counter ),
.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 )
);
@ -468,23 +441,9 @@ module riscv_core
.regfile_alu_we_i ( regfile_alu_we_ex ),
.regfile_alu_waddr_i ( regfile_alu_waddr_ex ),
// From ID stage: hwloop wb reg signals
.hwloop_wb_mux_sel_i ( hwlp_wb_mux_sel_ex ),
.hwloop_pc_plus4_i ( current_pc_id ),
.hwloop_cnt_i ( hwlp_cnt_ex ),
//From ID stage.Controller
.regfile_rb_data_i ( regfile_rb_data_ex ),
// Output of ex stage pipeline
.regfile_waddr_wb_o ( regfile_waddr_fw_wb_o ),
.regfile_we_wb_o ( regfile_we_wb ),
.regfile_rb_data_wb_o ( regfile_rb_data_wb ),
// To hwloop regs
.hwloop_start_data_o ( hwlp_start_data_ex ),
.hwloop_end_data_o ( hwlp_end_data_ex ),
.hwloop_cnt_data_o ( hwlp_cnt_data_ex ),
// To IF: Jump and branch target and decision
.jump_target_o ( jump_target_ex ),
@ -603,40 +562,6 @@ module riscv_core
assign dbg_rdata = (dbg_sp_mux == 1'b0) ? dbg_reg_rdata : csr_rdata;
//////////////////////////////////////////////
// Hardware Loop Registers //
//////////////////////////////////////////////
hwloop_regs hwloop_regs_i
(
.clk ( clk ),
.rst_n ( rst_n ),
// from ex stage
.hwloop_start_data_i ( hwlp_start_data ),
.hwloop_end_data_i ( hwlp_end_data ),
.hwloop_cnt_data_i ( hwlp_cnt_data ),
.hwloop_we_i ( hwlp_we ),
.hwloop_regid_i ( hwlp_regid ),
// from controller
.stall_id_i ( stall_id ),
// to hwloop controller
.hwloop_start_addr_o ( hwlp_start_addr ),
.hwloop_end_addr_o ( hwlp_end_addr ),
.hwloop_counter_o ( hwlp_counter ),
// from hwloop controller
.hwloop_dec_cnt_i ( hwlp_dec_cnt )
);
assign hwlp_start_data = hwlp_start_data_ex;
assign hwlp_end_data = hwlp_end_data_ex;
assign hwlp_cnt_data = hwlp_cnt_data_ex;
assign hwlp_regid = hwlp_regid_ex;
assign hwlp_we = hwlp_we_ex;
/////////////////////////////////////////////////////////////
// ____ _____ ____ _ _ ____ _ _ _ _ ___ _____ //
// | _ \| ____| __ )| | | |/ ___| | | | | \ | |_ _|_ _| //