Wire up hwloops correctly, other small fixes

This commit is contained in:
Sven Stucki 2015-09-05 03:37:50 +02:00
parent 87e2eec128
commit a6dc8271e9
5 changed files with 112 additions and 132 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
@ -192,13 +194,15 @@ module controller
always_comb
begin
jump_in_id = `BRANCH_NONE;
jump_target_mux_sel_o = `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;
@ -215,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;
@ -251,7 +255,7 @@ module controller
//////////////////////////////////////
`OPCODE_JAL: begin // Jump and Link
jump_target_mux_sel_o = `BRANCH_JAL;
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;
@ -264,7 +268,7 @@ module controller
end
`OPCODE_JALR: begin // Jump and Link Register
jump_target_mux_sel_o = `BRANCH_JALR;
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;
@ -284,7 +288,7 @@ module controller
end
`OPCODE_BRANCH: begin // Branch
jump_target_mux_sel_o = `BRANCH_COND;
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;
@ -831,65 +835,54 @@ module controller
// //
///////////////////////////////////////////////
`OPCODE_HWLOOP: begin // hardware loop instructions
jump_target_mux_sel_o = `BRANCH_JALR; // reuse jump target adder to calculate PC + I imm
`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;
// 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;
// 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 rs1
hwloop_cnt_mux_sel_o = 2'b11;
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 I-type immediate
hwloop_cnt_mux_sel_o = 2'b01;
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: initialize counter from rs1, set start address to
// next instruction and end address to PC + I-type immediate
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;
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: initialize counter from I-type immediate, set start
// address to next instruction and end address to PC + shifted
// z-type immediate
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;
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
@ -936,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("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

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

@ -93,12 +93,7 @@ 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 csr_access_ex_o,
output logic [1:0] csr_op_ex_o,
@ -119,12 +114,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,
@ -237,11 +226,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;
@ -326,22 +325,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 = imm_i_type;
2'b01: hwloop_cnt = { imm_z_type[30:0], 1'b0 };
2'b11: hwloop_cnt = operand_a_fw_id;
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
//////////////////////////////////////////////////////////////////
// _ _____ _ //
// _ _____ _ //
// | |_ _ _ __ ___ _ __ |_ _|_ _ _ __ __ _ ___| |_ //
// _ | | | | | '_ ` _ \| '_ \ | |/ _` | '__/ _` |/ _ \ __| //
// | |_| | |_| | | | | | | |_) | | | (_| | | | (_| | __/ |_ //
@ -352,10 +368,10 @@ module id_stage
always_comb
begin : jump_target_mux
unique case (jump_target_mux_sel)
`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
`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
@ -375,11 +391,11 @@ module id_stage
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;
default: alu_operand_a = operand_a_fw_id;
endcase; // case (alu_op_a_mux_sel)
end
@ -420,10 +436,10 @@ module id_stage
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;
default: operand_b = operand_b_fw_id;
endcase // case (alu_op_b_mux_sel)
end
@ -578,7 +594,8 @@ module id_stage
// hwloop signals
.hwloop_we_o ( hwloop_we ),
.hwloop_wb_mux_sel_o ( hwloop_wb_mux_sel ),
.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 ),
@ -615,6 +632,7 @@ module id_stage
.operand_c_fw_mux_sel_o ( operand_c_fw_mux_sel ),
// 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 ),
@ -669,12 +687,11 @@ module id_stage
// CSR
.save_pc_if_o ( save_pc_if_o ),
.save_pc_id_o ( save_pc_id_o ),
.save_sr_o ( save_sr_o ),
// Controller
.core_busy_i ( core_busy_o ),
.jump_in_id_i ( jump_in_id_o ),
.jump_in_ex_i ( jump_in_ex_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 ),
@ -703,23 +720,23 @@ module id_stage
hwloop_controller hwloop_controller_i
(
// from ID stage
.enable_i ( hwloop_enable ),
.enable_i ( hwloop_enable ),
.current_pc_i ( current_pc_if_i ),
.current_pc_i ( current_pc_if_i ),
// to ID controller
.hwloop_jump_o ( hwloop_jump ),
// to controller
.hwloop_jump_o ( hwloop_jump ),
// to if stage
.hwloop_targ_addr_o ( hwloop_targ_addr_o ),
.hwloop_targ_addr_o ( hwloop_targ_addr_o ),
// 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 ),
.hwloop_start_addr_i ( hwloop_start_addr ),
.hwloop_end_addr_i ( hwloop_end_addr ),
.hwloop_counter_i ( hwloop_counter ),
// to hwloop_regs
.hwloop_dec_cnt_o ( hwloop_dec_cnt_o )
.hwloop_dec_cnt_o ( hwloop_dec_cnt )
);
hwloop_regs hwloop_regs_i
@ -727,23 +744,23 @@ module id_stage
.clk ( clk ),
.rst_n ( rst_n ),
// from ex stage
.hwloop_start_data_i ( hwlp_start_data_ex ),
.hwloop_end_data_i ( hwlp_end_data_ex ),
.hwloop_cnt_data_i ( hwlp_cnt_data_ex ),
.hwloop_we_i ( hwlp_we_ex ),
.hwloop_regid_i ( hwlp_regid_ex ),
// 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 ),
.stall_id_i ( stall_id_o ),
// to hwloop controller
.hwloop_start_addr_o ( hwlp_start_addr ),
.hwloop_end_addr_o ( hwlp_end_addr ),
.hwloop_counter_o ( hwlp_counter ),
.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 ( hwlp_dec_cnt )
.hwloop_dec_cnt_i ( hwloop_dec_cnt )
);
@ -793,11 +810,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
@ -856,13 +868,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

@ -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

@ -180,21 +180,8 @@ module riscv_core
logic save_pc_id;
// Hardware loop 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
// Hardware loop 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
logic [31:0] hwlp_targ_addr; // from hwloop controller to if stage
// Debug Unit
@ -357,11 +344,6 @@ module riscv_core
.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 ),
.prepost_useincr_ex_o ( useincr_addr_ex ),
@ -383,11 +365,6 @@ module riscv_core
.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 ),
// Debug Unit Signals
.dbg_flush_pipe_i ( dbg_flush_pipe ),
.dbg_st_en_i ( dbg_st_en ),