Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Moved two instructions from predecoder to decoder #510

Merged
merged 1 commit into from
Apr 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions rtl/cv32e40x_compressed_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
input logic instr_is_ptr_i,
output inst_resp_t instr_o,
output logic is_compressed_o,
output logic use_merged_dec_o, // todo: remove this temporary signal once done merging decoder
output logic illegal_instr_o
);

Expand All @@ -51,6 +52,7 @@ module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
begin
illegal_instr_o = 1'b0;
instr_o = instr_i;
use_merged_dec_o = 1'b0;

if (instr_is_ptr_i) begin
is_compressed_o = 1'b0;
Expand All @@ -62,12 +64,14 @@ module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
unique case (instr[15:13])
3'b000: begin
// c.addi4spn -> addi rd', x2, imm
use_merged_dec_o = 1'b1;
instr_o.bus_resp.rdata = {2'b0, instr[10:7], instr[12:11], instr[5], instr[6], 2'b00, 5'h02, 3'b000, 2'b01, instr[4:2], OPCODE_OPIMM};
if (instr[12:5] == 8'b0) illegal_instr_o = 1'b1;
end

3'b010: begin
// c.lw -> lw rd', imm(rs1')
use_merged_dec_o = 1'b1;
instr_o.bus_resp.rdata = {5'b0, instr[5], instr[12:10], instr[6], 2'b00, 2'b01, instr[9:7], 3'b010, 2'b01, instr[4:2], OPCODE_LOAD};
end

Expand Down
39 changes: 36 additions & 3 deletions rtl/cv32e40x_i_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
// Project Name: RI5CY //
// Language: SystemVerilog //
// //
// Description: Decoder for the RV32I Base Instruction set //
// Description: Decoder for the RV32I Base Instruction set + C //
// //
////////////////////////////////////////////////////////////////////////////////

Expand All @@ -46,20 +46,44 @@ module cv32e40x_i_decoder import cv32e40x_pkg::*;
decoder_ctrl_o.illegal_insn = 1'b0;

unique case (instr_rdata_i[1:0])

//////////////////////////////////////////////////////////////////////////////////////////////////////
// ____ _ ____ _ //
// / ___|___ _ __ ___ _ __ _ __ ___ ___ ___ ___ __| | | _ \ ___ ___ ___ __| | ___ _ __ //
// | | / _ \| '_ ` _ \| '_ \| '__/ _ \/ __/ __|/ _ \/ _` | | | | |/ _ \/ __/ _ \ / _` |/ _ \ '__| //
// | |__| (_) | | | | | | |_) | | | __/\__ \__ \ __/ (_| | | |_| | __/ (_| (_) | (_| | __/ | //
// \____\___/|_| |_| |_| .__/|_| \___||___/___/\___|\__,_| |____/ \___|\___\___/ \__,_|\___|_| //
// |_| //
//////////////////////////////////////////////////////////////////////////////////////////////////////

// C0
2'b00: begin
unique case (instr_rdata_i[15:13])
3'b000: begin
// c.addi4spn -> addi rd', x2, imm
// todo instr_o.bus_resp.rdata = {2'b0, instr[10:7], instr[12:11], instr[5], instr[6], 2'b00, 5'h02, 3'b000, 2'b01, instr[4:2], OPCODE_OPIMM};
decoder_ctrl_o.alu_en = 1'b1;
decoder_ctrl_o.alu_op_a_mux_sel = OP_A_REGA_OR_FWD;
decoder_ctrl_o.alu_op_b_mux_sel = OP_B_IMM;
decoder_ctrl_o.imm_b_mux_sel = IMMB_CIW;
decoder_ctrl_o.rf_we = 1'b1;
decoder_ctrl_o.rf_re[0] = 1'b1;
decoder_ctrl_o.alu_operator = ALU_ADD; // Add Immediate
if (instr_rdata_i[12:5] == 8'b0) begin
decoder_ctrl_o.illegal_insn = 1'b1;
end
end

3'b010: begin
// c.lw -> lw rd', imm(rs1')
// todo instr_o.bus_resp.rdata = {5'b0, instr[5], instr[12:10], instr[6], 2'b00, 2'b01, instr[9:7], 3'b010, 2'b01, instr[4:2], OPCODE_LOAD};
decoder_ctrl_o.lsu_en = 1'b1;
decoder_ctrl_o.rf_we = 1'b1;
decoder_ctrl_o.rf_re[0] = 1'b1;
decoder_ctrl_o.alu_op_a_mux_sel = OP_A_REGA_OR_FWD;
decoder_ctrl_o.alu_op_b_mux_sel = OP_B_IMM;
decoder_ctrl_o.op_c_mux_sel = OP_C_NONE;
decoder_ctrl_o.imm_b_mux_sel = IMMB_CL;
decoder_ctrl_o.lsu_sext = 1'b0;
decoder_ctrl_o.lsu_size = 2'b10;
end

3'b110: begin
Expand Down Expand Up @@ -274,6 +298,15 @@ module cv32e40x_i_decoder import cv32e40x_pkg::*;
endcase
end

////////////////////////////////////////////////
// _ ____ _ //
// | | | _ \ ___ ___ ___ __| | ___ _ __ //
// | | | | | |/ _ \/ __/ _ \ / _` |/ _ \ '__| //
// | | | |_| | __/ (_| (_) | (_| | __/ | //
// |_| |____/ \___|\___\___/ \__,_|\___|_| //
// //
////////////////////////////////////////////////

default: begin
// 32 bit (or more) instruction

Expand Down
42 changes: 36 additions & 6 deletions rtl/cv32e40x_id_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
localparam REG_D_LSB = 7;

logic [31:0] instr;
logic [15:0] c_instr; // Compressed instruction

// Register Read/Write Control
logic [1:0] rf_re; // Decoder only supports rs1, rs2
Expand Down Expand Up @@ -173,6 +174,8 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
logic [31:0] imm_u_type;
logic [31:0] imm_uj_type;
logic [31:0] imm_z_type;
logic [31:0] imm_ciw_type;
logic [31:0] imm_cl_type;

// Branch target address
logic [31:0] bch_target;
Expand Down Expand Up @@ -201,13 +204,35 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
assign sys_mret_insn_o = sys_mret_insn;

assign instr = if_id_pipe_i.instr.bus_resp.rdata;
assign c_instr = if_id_pipe_i.compressed_instr;

// Immediate extraction and sign extension
assign imm_i_type = { {20 {instr[31]}}, instr[31:20] };
assign imm_s_type = { {20 {instr[31]}}, instr[31:25], instr[11:7] };
assign imm_sb_type = { {19 {instr[31]}}, instr[31], instr[7], instr[30:25], instr[11:8], 1'b0 };
assign imm_u_type = { instr[31:12], 12'b0 };
assign imm_uj_type = { {12 {instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0 };
assign imm_i_type = { {20 {instr[31]}}, instr[31:20] };
assign imm_s_type = { {20 {instr[31]}}, instr[31:25], instr[11:7] };
assign imm_sb_type = { {19 {instr[31]}}, instr[31], instr[7], instr[30:25], instr[11:8], 1'b0 };
assign imm_u_type = { instr[31:12], 12'b0 };
assign imm_uj_type = { {12 {instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0 };

// Immediate extraction and sign extension (compressed instructions)
assign imm_ciw_type = { 22'b0, c_instr[10:7], c_instr[12:11], c_instr[5], c_instr[6], 2'b0 };
assign imm_cl_type = { 25'b0, c_instr[5], c_instr[12:10], c_instr[6], 2'b0 };

/*
assign imm_cfldsp_type = {22'b0, c_instr[4:2], c_instr[12], c_instr[6:5], 3'b0};
assign imm_caddi_type = {{22{c_instr[12]}}, c_instr[12:12], c_instr[4:3], c_instr[5:5], c_instr[2:2], c_instr[6:6], 4'b0};
assign imm_clwsp_type = {24'b0, c_instr[3:2], c_instr[12:12], c_instr[6:4], 2'b0};
assign imm_cld_type = {24'b0, c_instr[6:5], c_instr[12:10], 3'b0};
assign imm_cswsp_type = {24'b0, c_instr[8:7], c_instr[12:9], 2'b0};
assign imm_fsdp_type = {24'b0, c_instr[9:7], c_instr[12:10], 2'b0};
assign imm_csrli_type = {26'b0, c_instr[12:12], c_instr[6:2]};
assign imm_candi_type = {{26{c_instr[12]}}, c_instr[12:12], c_instr[6:2]};
assign imm_cbeq_type = {{23{c_instr[12]}}, c_instr[12:12], c_instr[6:5], c_instr[2:2], c_instr[11:10], c_instr[4:3], 1'b0};
assign imm_clui_type = {{14{c_instr[12]}}, c_instr[12:12], c_instr[6:2], 12'b0};
assign imm_clsb_type = {28'd0, c_instr[10], c_instr[6:5], c_instr[11]};
assign imm_clsh_type = {27'd0, c_instr[11:10], c_instr[6:5], 1'b0};
*/



// Immediate for CSR manipulation (zero extended)
assign imm_z_type = { 27'b0, instr[REG_S1_MSB:REG_S1_LSB] };
Expand Down Expand Up @@ -311,6 +336,8 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
IMMB_S: imm_b = imm_s_type;
IMMB_U: imm_b = imm_u_type;
IMMB_PCINCR: imm_b = if_id_pipe_i.instr_meta.compressed ? 32'h2 : 32'h4;
IMMB_CIW: imm_b = imm_ciw_type;
IMMB_CL: imm_b = imm_cl_type;
default: imm_b = imm_i_type;
endcase
end
Expand Down Expand Up @@ -362,6 +389,9 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
// //
///////////////////////////////////////////////

logic [31:0] instr_merged;
assign instr_merged = if_id_pipe_i.use_merged_dec ? {16'b0, c_instr} : instr; // todo: temporary hack while merging decoder

cv32e40x_decoder
#(
.A_EXT ( A_EXT ),
Expand All @@ -385,7 +415,7 @@ module cv32e40x_id_stage import cv32e40x_pkg::*;
.sys_fencei_insn_o ( sys_fencei_insn ),

// from IF/ID pipeline
.instr_rdata_i ( instr ),
.instr_rdata_i ( instr_merged ), // todo: temporary hack while merging decoders
.illegal_c_insn_i ( if_id_pipe_i.illegal_c_insn ),

// ALU
Expand Down
4 changes: 4 additions & 0 deletions rtl/cv32e40x_if_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;

inst_resp_t instr_decompressed;
logic instr_compressed_int;
logic use_merged_dec;

// Transaction signals to/from obi interface
logic prefetch_resp_valid;
Expand Down Expand Up @@ -263,6 +264,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
if (rst_n == 1'b0) begin
if_id_pipe_o.instr_valid <= 1'b0;
if_id_pipe_o.instr <= INST_RESP_RESET_VAL;
if_id_pipe_o.use_merged_dec <= 1'b0;
if_id_pipe_o.instr_meta <= '0;
if_id_pipe_o.pc <= '0;
if_id_pipe_o.illegal_c_insn <= 1'b0;
Expand All @@ -276,6 +278,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
if_id_pipe_o.instr_valid <= 1'b1;
// instr_decompressed may be a pointer in case of CLIC or Zc, handled within the compressed decoder.
if_id_pipe_o.instr <= instr_decompressed;
if_id_pipe_o.use_merged_dec <= use_merged_dec;
if_id_pipe_o.instr_meta <= instr_meta_n;
if_id_pipe_o.illegal_c_insn <= illegal_c_insn;
if_id_pipe_o.pc <= pc_if_o;
Expand All @@ -295,6 +298,7 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
.instr_is_ptr_i ( prefetch_is_ptr ),
.instr_o ( instr_decompressed ),
.is_compressed_o ( instr_compressed_int ),
.use_merged_dec_o ( use_merged_dec ),
.illegal_instr_o ( illegal_c_insn )
);

Expand Down
13 changes: 8 additions & 5 deletions rtl/include/cv32e40x_pkg.sv
Original file line number Diff line number Diff line change
Expand Up @@ -711,11 +711,13 @@ typedef enum logic[1:0] {
} alu_op_b_mux_e;

// Immediate b selection
typedef enum logic[1:0] {
IMMB_I = 2'b00,
IMMB_S = 2'b01,
IMMB_U = 2'b10,
IMMB_PCINCR = 2'b11
typedef enum logic[2:0] {
IMMB_I = 3'b000,
IMMB_S = 3'b001,
IMMB_U = 3'b010,
IMMB_PCINCR = 3'b011,
IMMB_CIW = 3'b100,
IMMB_CL = 3'b101
} imm_b_mux_e;

// Operand c selection
Expand Down Expand Up @@ -1031,6 +1033,7 @@ typedef struct packed
typedef struct packed {
logic instr_valid;
inst_resp_t instr;
logic use_merged_dec; // todo: remove once done with decoder merge
instr_meta_t instr_meta;
logic [31:0] pc;
logic [15:0] compressed_instr;
Expand Down