Add hwloop decoding

This commit is contained in:
Sven Stucki 2015-08-31 03:13:14 +02:00
parent 5a38967a0c
commit 6aa40c336d
4 changed files with 56 additions and 71 deletions

View file

@ -869,80 +869,71 @@ module controller
end
/*
///////////////////////////////////////////////
// _ ___ ___ ___ ___ ____ //
// | | | \ \ / / | / _ \ / _ \| _ \ //
// | |_| |\ \ /\ / /| | | | | | | | | |_) | //
// | _ | \ V V / | |__| |_| | |_| | __/ //
// |_| |_| \_/\_/ |_____\___/ \___/|_| //
// //
///////////////////////////////////////////////
`OPCODE_HWLOOP: begin // hwloop instructions
hwloop_regid_o = instr_rdata_i[22:21]; // set hwloop register id
case (instr_rdata_i[25:23])
3'b000,3'b110,3'b111: begin // lp.start 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;
alu_pc_mux_sel_o = 1'b1;
immediate_mux_sel_o = `IMM_21S;
// $display("%t: hwloop start address: %h", $time, instr_rdata_i);
`OPCODE_HWLOOP: begin // hardware loop instructions
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;
// $display("%t: hwloop start address: %h", $time, instr_rdata_i);
end
3'b001: begin // lp.end 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;
alu_pc_mux_sel_o = 1'b1;
immediate_mux_sel_o = `IMM_21S;
// $display("%t: hwloop end address: %h", $time, instr_rdata_i);
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;
// $display("%t: hwloop end address: %h", $time, instr_rdata_i);
end
3'b010: 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
// $display("%t: hwloop counter imm: %h", $time, instr_rdata_i);
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
rega_used = 1'b1;
// $display("%t: hwloop counter: %h", $time, instr_rdata_i);
end
3'b011: 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
rega_used = 1'b1;
// $display("%t: hwloop counter: %h", $time, instr_rdata_i);
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
// $display("%t: hwloop counter imm: %h", $time, instr_rdata_i);
end
3'b100: 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;
alu_pc_mux_sel_o = 1'b1;
immediate_mux_sel_o = `IMM_8Z;
// $display("%t: hwloop setup imm: %h", $time, instr_rdata_i);
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;
// $display("%t: hwloop setup: %h", $time, instr_rdata_i);
end
3'b101: 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;
alu_pc_mux_sel_o = 1'b1;
immediate_mux_sel_o = `IMM_16Z;
rega_used = 1'b1;
// $display("%t: hwloop setup: %h", $time, instr_rdata_i);
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;
// $display("%t: hwloop setup imm: %h", $time, instr_rdata_i);
end
default: begin
illegal_insn_int = 1'b1;
end
endcase
end
*/
default: begin
illegal_insn_int = 1'b1;
end

View file

@ -712,7 +712,6 @@ module id_stage
// //
//////////////////////////////////////////////////////////////////////////
/*
hwloop_controller hwloop_controller_i
(
// from ID stage
@ -733,8 +732,6 @@ module id_stage
// to hwloop_regs
.hwloop_dec_cnt_o ( hwloop_dec_cnt_o )
);
*/
/////////////////////////////////////////////////////////////////////////////////

View file

@ -56,6 +56,7 @@
// PULP custom
`define OPCODE_STORE_POST 7'h27
`define OPCODE_LOAD_POST 7'h07
`define OPCODE_HWLOOP 7'h6b
// instruction masks (for tracer)

View file

@ -179,6 +179,7 @@ module riscv_core
logic save_pc_if;
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)
@ -188,7 +189,6 @@ module riscv_core
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;
@ -606,7 +606,7 @@ module riscv_core
.ext_counters_i ( ext_perf_counters_i )
);
// Mux for SPR access through Debug Unit
// Mux for CSR access through Debug Unit
assign csr_addr = (dbg_sp_mux == 1'b0) ? alu_operand_b_ex[11:0] : dbg_reg_addr;
assign csr_wdata = (dbg_sp_mux == 1'b0) ? alu_operand_a_ex : dbg_reg_wdata;
assign csr_op = (dbg_sp_mux == 1'b0) ? csr_op_ex
@ -614,8 +614,6 @@ module riscv_core
assign dbg_rdata = (dbg_sp_mux == 1'b0) ? dbg_reg_rdata : csr_rdata;
/*
//////////////////////////////////////////////
// Hardware Loop Registers //
//////////////////////////////////////////////
@ -643,13 +641,11 @@ module riscv_core
.hwloop_dec_cnt_i ( hwlp_dec_cnt )
);
// write to hwloop registers via SPR or instructions
assign hwlp_start_data = (hwlp_we_ex[0] == 1'b1) ? hwlp_start_data_ex : sp_hwlp_start;
assign hwlp_end_data = (hwlp_we_ex[1] == 1'b1) ? hwlp_end_data_ex : sp_hwlp_end;
assign hwlp_cnt_data = (hwlp_we_ex[2] == 1'b1) ? hwlp_cnt_data_ex : sp_hwlp_cnt;
assign hwlp_regid = (|hwlp_we_ex) ? hwlp_regid_ex : sp_hwlp_regid;
assign hwlp_we = hwlp_we_ex | sp_hwlp_we;
*/
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;
/////////////////////////////////////////////////////////////