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

Speeding up decoder #516

Merged
merged 2 commits into from
Apr 27, 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
14 changes: 9 additions & 5 deletions rtl/cv32e40x_compressed_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
3'b001, 3'b101: begin
// 001: c.jal -> jal x1, imm
// 101: c.j -> jal x0, imm
instr_o.bus_resp.rdata = {instr[12], instr[8], instr[10:9], instr[6], instr[7], instr[2], instr[11], instr[5:3], {9 {instr[12]}}, 4'b0, ~instr[15], OPCODE_JAL};
instr_o.bus_resp.rdata = {instr[12], instr[8], instr[10:9], instr[6], instr[7], instr[2], instr[11], instr[5:3], {9 {instr[12]}}, 4'b0, !instr[15], OPCODE_JAL};
end

3'b010: begin
Expand Down Expand Up @@ -235,10 +235,14 @@ module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
3'b100: begin
if (instr[12] == 1'b0) begin
if (instr[6:2] == 5'b0) begin
// c.jr -> jalr x0, rd/rs1, 0
instr_o.bus_resp.rdata = {12'b0, instr[11:7], 3'b0, 5'b0, OPCODE_JALR};
// c.jr with rs1 = 0 is reserved
if (instr[11:7] == 5'b0) illegal_instr_o = 1'b1;
if (instr[11:7] == 5'b0) begin
// c.jr with rs1 = 0 is reserved
instr_o.bus_resp.rdata = {7'b0, instr[6:2], 5'b0, 3'b0, instr[11:7], OPCODE_OP}; // Not using OPCODE_JALR on purpose (to allow direct decoder_i_ctrl branch/jump usage)
illegal_instr_o = 1'b1;
end else begin
// c.jr -> jalr x0, rd/rs1, 0
instr_o.bus_resp.rdata = {12'b0, instr[11:7], 3'b0, 5'b0, OPCODE_JALR};
end
end else begin
if (instr[11:7] == 5'b0) begin
// Hint -> add x0, x0, rs2
Expand Down
54 changes: 27 additions & 27 deletions rtl/cv32e40x_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -193,47 +193,47 @@ module cv32e40x_decoder import cv32e40x_pkg::*;
end

assign alu_en = decoder_ctrl_mux.alu_en;
assign alu_bch_o = decoder_ctrl_mux.alu_bch;
assign alu_jmp_o = decoder_ctrl_mux.alu_jmp;
assign alu_jmpr_o = decoder_ctrl_mux.alu_jmpr;
assign alu_bch_o = decoder_i_ctrl.alu_bch; // Only I decoder handles branches/jumps
assign alu_jmp_o = decoder_i_ctrl.alu_jmp; // Only I decoder handles branches/jumps
assign alu_jmpr_o = decoder_i_ctrl.alu_jmpr; // Only I decoder handles branches/jumps
assign alu_operator_o = decoder_ctrl_mux.alu_operator;
assign alu_op_a_mux_sel_o = decoder_ctrl_mux.alu_op_a_mux_sel;
assign alu_op_b_mux_sel_o = decoder_ctrl_mux.alu_op_b_mux_sel;
assign op_c_mux_sel_o = decoder_ctrl_mux.op_c_mux_sel;
assign imm_a_mux_sel_o = decoder_ctrl_mux.imm_a_mux_sel;
assign imm_b_mux_sel_o = decoder_ctrl_mux.imm_b_mux_sel;
assign bch_jmp_mux_sel_o = decoder_ctrl_mux.bch_jmp_mux_sel;
assign mul_en = decoder_ctrl_mux.mul_en;
assign mul_operator_o = decoder_ctrl_mux.mul_operator;
assign mul_signed_mode_o = decoder_ctrl_mux.mul_signed_mode;
assign div_en = decoder_ctrl_mux.div_en;
assign div_operator_o = decoder_ctrl_mux.div_operator;
assign bch_jmp_mux_sel_o = decoder_i_ctrl.bch_jmp_mux_sel; // Only I decoder handles branches/jumps
assign mul_en = decoder_m_ctrl.mul_en; // Only M decoder handles mul/div
assign mul_operator_o = decoder_m_ctrl.mul_operator; // Only M decoder handles mul/div
assign mul_signed_mode_o = decoder_m_ctrl.mul_signed_mode; // Only M decoder handles mul/div
assign div_en = decoder_m_ctrl.div_en; // Only M decoder handles mul/div
assign div_operator_o = decoder_m_ctrl.div_operator; // Only M decoder handles mul/div
assign rf_re_o = decoder_ctrl_mux.rf_re;
assign rf_we = decoder_ctrl_mux.rf_we;
assign csr_en = decoder_ctrl_mux.csr_en;
assign csr_op_o = decoder_ctrl_mux.csr_op;
assign csr_en = decoder_i_ctrl.csr_en; // Only I decoder handles CSR
assign csr_op_o = decoder_i_ctrl.csr_op; // Only I decoder handles CSR
assign lsu_en = decoder_ctrl_mux.lsu_en;
assign lsu_we_o = decoder_ctrl_mux.lsu_we;
assign lsu_size_o = decoder_ctrl_mux.lsu_size;
assign lsu_sext_o = decoder_ctrl_mux.lsu_sext;
assign lsu_atop_o = decoder_ctrl_mux.lsu_atop;
assign sys_en = decoder_ctrl_mux.sys_en;
assign sys_mret_insn_o = decoder_ctrl_mux.sys_mret_insn;
assign sys_dret_insn_o = decoder_ctrl_mux.sys_dret_insn;
assign sys_ebrk_insn_o = decoder_ctrl_mux.sys_ebrk_insn;
assign sys_ecall_insn_o = decoder_ctrl_mux.sys_ecall_insn;
assign sys_wfi_insn_o = decoder_ctrl_mux.sys_wfi_insn;
assign sys_fencei_insn_o = decoder_ctrl_mux.sys_fencei_insn;
assign lsu_atop_o = decoder_a_ctrl.lsu_atop; // Only A decoder handles atomics
assign sys_en = decoder_i_ctrl.sys_en; // Only I decoder handles SYS
assign sys_mret_insn_o = decoder_i_ctrl.sys_mret_insn; // Only I decoder handles SYS
assign sys_dret_insn_o = decoder_i_ctrl.sys_dret_insn; // Only I decoder handles SYS
assign sys_ebrk_insn_o = decoder_i_ctrl.sys_ebrk_insn; // Only I decoder handles SYS
assign sys_ecall_insn_o = decoder_i_ctrl.sys_ecall_insn; // Only I decoder handles SYS
assign sys_wfi_insn_o = decoder_i_ctrl.sys_wfi_insn; // Only I decoder handles SYS
assign sys_fencei_insn_o = decoder_i_ctrl.sys_fencei_insn; // Only I decoder handles SYS

// Suppress control signals
assign alu_en_o = deassert_we_i ? 1'b0 : alu_en;
assign sys_en_o = deassert_we_i ? 1'b0 : sys_en;
assign mul_en_o = deassert_we_i ? 1'b0 : mul_en;
assign div_en_o = deassert_we_i ? 1'b0 : div_en;
assign lsu_en_o = deassert_we_i ? 1'b0 : lsu_en;

assign csr_en_o = deassert_we_i ? 1'b0 : csr_en;
assign rf_we_o = deassert_we_i ? 1'b0 : rf_we;
assign alu_en_o = deassert_we_i ? 1'b0 : alu_en;
assign sys_en_o = deassert_we_i ? 1'b0 : sys_en;
assign mul_en_o = deassert_we_i ? 1'b0 : mul_en;
assign div_en_o = deassert_we_i ? 1'b0 : div_en;
assign lsu_en_o = deassert_we_i ? 1'b0 : lsu_en;

assign csr_en_o = deassert_we_i ? 1'b0 : csr_en;
assign rf_we_o = deassert_we_i ? 1'b0 : rf_we;

// Suppress special instruction/illegal instruction bits
assign illegal_insn_o = deassert_we_i ? 1'b0 : decoder_ctrl_mux.illegal_insn;
Expand Down
51 changes: 51 additions & 0 deletions sva/cv32e40x_decoder_sva.sv
Original file line number Diff line number Diff line change
Expand Up @@ -119,4 +119,55 @@ module cv32e40x_decoder_sva
decoder_ctrl_mux.illegal_insn, if_id_pipe.instr_meta.clic_ptr}))
else `uvm_error("decoder", "Multiple functional units enabled")



// Check that branch/jump related signals can be used from I decoder directly (bypassing other decoders)
a_branch_jump_decode :
assert property (@(posedge clk) disable iff (!rst_n)
1'b1 |-> (
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert is failing formal when the instruction is an illegal compressed instruction. Assert can be made passing by changing "1'b1 |->" to "!if_id_pipe.illegal_c_insn |->".

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the RTL so that these assertions now pass.

(decoder_i_ctrl.alu_bch == decoder_ctrl_mux.alu_bch) &&
(decoder_i_ctrl.bch_jmp_mux_sel == decoder_ctrl_mux.bch_jmp_mux_sel) &&
(decoder_i_ctrl.alu_jmp == decoder_ctrl_mux.alu_jmp) &&
(decoder_i_ctrl.alu_jmpr == decoder_ctrl_mux.alu_jmpr)))
else `uvm_error("decoder", "Branch/jump related signals driven from unexpected decoder")

// Check that CSR related signals can be used from I decoder directly (bypassing other decoders)
a_csr_decode :
assert property (@(posedge clk) disable iff (!rst_n)
1'b1 |-> (
(decoder_i_ctrl.csr_en == decoder_ctrl_mux.csr_en) &&
(decoder_i_ctrl.csr_op == decoder_ctrl_mux.csr_op)))
else `uvm_error("decoder", "CSR related signals driven from unexpected decoder")

// Check that SYS related signals can be used from I decoder directly (bypassing other decoders)
a_sys_decode :
assert property (@(posedge clk) disable iff (!rst_n)
1'b1 |-> (
(decoder_i_ctrl.sys_en == decoder_ctrl_mux.sys_en) &&
(decoder_i_ctrl.sys_mret_insn == decoder_ctrl_mux.sys_mret_insn) &&
(decoder_i_ctrl.sys_dret_insn == decoder_ctrl_mux.sys_dret_insn) &&
(decoder_i_ctrl.sys_ebrk_insn == decoder_ctrl_mux.sys_ebrk_insn) &&
(decoder_i_ctrl.sys_ecall_insn == decoder_ctrl_mux.sys_ecall_insn) &&
(decoder_i_ctrl.sys_wfi_insn == decoder_ctrl_mux.sys_wfi_insn) &&
(decoder_i_ctrl.sys_fencei_insn == decoder_ctrl_mux.sys_fencei_insn)))
else `uvm_error("decoder", "SYS related signals driven from unexpected decoder")

// Check that MUL/DIV related signals can be used from M decoder directly (bypassing other decoders)
a_muldiv_decode :
assert property (@(posedge clk) disable iff (!rst_n)
1'b1 |-> (
(decoder_m_ctrl.mul_en == decoder_ctrl_mux.mul_en) &&
(decoder_m_ctrl.mul_operator == decoder_ctrl_mux.mul_operator) &&
(decoder_m_ctrl.mul_signed_mode == decoder_ctrl_mux.mul_signed_mode) &&
(decoder_m_ctrl.div_en == decoder_ctrl_mux.div_en) &&
(decoder_m_ctrl.div_operator == decoder_ctrl_mux.div_operator)))
else `uvm_error("decoder", "Mul/div related signals driven from unexpected decoder")

// Check that ATOP related signals can be used from A decoder directly (bypassing other decoders)
a_atop_decode :
assert property (@(posedge clk) disable iff (!rst_n)
1'b1 |-> (
(decoder_a_ctrl.lsu_atop == decoder_ctrl_mux.lsu_atop)))
else `uvm_error("decoder", "Atop related signals driven from unexpected decoder")

endmodule : cv32e40x_decoder_sva