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

Implemented all C0 instructions from Zc v 0.70.1. #528

Merged
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
77 changes: 75 additions & 2 deletions rtl/cv32e40x_compressed_decoder.sv
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
////////////////////////////////////////////////////////////////////////////////

module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
#(
parameter bit ZC_EXT = 0
)
(
input inst_resp_t instr_i,
input logic instr_is_ptr_i,
Expand Down Expand Up @@ -66,6 +69,24 @@ module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
if (instr[12:5] == 8'b0) illegal_instr_o = 1'b1;
end

3'b001: begin
if (ZC_EXT) begin
if (instr[12]) begin
// cm.lh -> lh rd', imm(rs1')
Copy link
Contributor

Choose a reason for hiding this comment

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

cm.lh has some codes designated for custom use. These need to set illegal_instr_o = 1'b1

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

instr_o.bus_resp.rdata = {7'b0, instr[11:10], instr[6:5], 1'b0, 2'b01, instr[9:7], 3'b001, 2'b01, instr[4:2], OPCODE_LOAD};

// uimm < 4 is designated for custom use, flagging as illegal
if ({instr[11:10], instr[6]} == 3'b000) illegal_instr_o = 1'b1;
end else begin
// cm.lb -> lb rd', imm(rs1')
instr_o.bus_resp.rdata = {8'b0, instr[10], instr[6:5], instr[11], 2'b01, instr[9:7], 3'b000, 2'b01, instr[4:2], OPCODE_LOAD};
end
end else begin
illegal_instr_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
end

3'b010: begin
// c.lw -> lw rd', imm(rs1')
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};
Expand All @@ -76,9 +97,61 @@ module cv32e40x_compressed_decoder import cv32e40x_pkg::*;
instr_o.bus_resp.rdata = {5'b0, instr[5], instr[12], 2'b01, instr[4:2], 2'b01, instr[9:7], 3'b010, instr[11:10], instr[6], 2'b00, OPCODE_STORE};
end

3'b001, // c.fld -> fld rd', imm(rs1')

3'b100: begin
if (ZC_EXT) begin
unique case (instr[12:10])
3'b000: begin
// c.lbu -> lbu rd', imm(rs1')
Copy link
Contributor

Choose a reason for hiding this comment

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

Not all cm.lbu codes are legal.

Copy link
Contributor Author

@silabs-oysteink silabs-oysteink May 3, 2022

Choose a reason for hiding this comment

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

Agreed, but for this specific line (c.lbu vs cm.lbu) there is no illegal encodings. Fixing for the actual cm.lbu once that gets implemented

instr_o.bus_resp.rdata = {10'b0, instr[5], instr[6], 2'b01, instr[9:7], 3'b100, 2'b01, instr[4:2], OPCODE_LOAD};
end
3'b001: begin
// c.lh -> lh rd', imm(rs1')
// c.lhu -> lhu rd', imm(rs1')
Copy link
Contributor

Choose a reason for hiding this comment

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

cm.lhu has some codes designated for custom use. These need to set illegal_instr_o = 1'b1

Copy link
Contributor Author

Choose a reason for hiding this comment

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

cm.lhu is not yet implemented (will be part of PR for C2 instructions. This line is for c.lhu, which does not seem to have any reserved encodings.

// instr[6] determines sign extension for lh vs lhu
instr_o.bus_resp.rdata = {10'b0, instr[5], 1'b0, 2'b01, instr[9:7], !instr[6], 2'b01, 2'b01, instr[4:2], OPCODE_LOAD};
end
3'b010: begin
// c.sb -> sb rs2', imm(rs1')
instr_o.bus_resp.rdata = {7'b0, 2'b01, instr[4:2], 2'b01, instr[9:7], 3'b000, 3'b000, instr[5], instr[6], OPCODE_STORE};
end
3'b011: begin
// c.sh -> sh rs2', imm(rs1')
instr_o.bus_resp.rdata = {7'b0, 2'b01, instr[4:2], 2'b01, instr[9:7], 3'b001, 3'b000, instr[5], 1'b0, OPCODE_STORE};
end
default: begin
illegal_instr_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
endcase
end else begin
illegal_instr_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
end

3'b101: begin
if (ZC_EXT) begin
if (instr[12]) begin
// cm.sh -> sh rs2', imm(rs1')
Copy link
Contributor

Choose a reason for hiding this comment

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

cm.sh has some codes designated for custom use. These need to set illegal_instr_o = 1'b1

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

instr_o.bus_resp.rdata = {7'b0, 2'b01, instr[4:2], 2'b01, instr[9:7], 3'b001, instr[11:10], instr[6:5], 1'b0, OPCODE_STORE};

// uimm < 4 is designated for custom use, flagging as illegal
if ({instr[11:10], instr[6]} == 3'b000) illegal_instr_o = 1'b1;
end else begin
// cm.sb -> sb rs2', imm(rs1')
Copy link
Contributor

Choose a reason for hiding this comment

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

cm.sb has some codes designated for custom use. These need to set illegal_instr_o = 1'b1

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

instr_o.bus_resp.rdata = {7'b0, 2'b01, instr[4:2], 2'b01, instr[9:7], 3'b000, 1'b0, instr[10], instr[6:5], instr[11], OPCODE_STORE};

// uimm < 4 is designated for custom use, flagging as illegal
if ({instr[10], instr[6]} == 2'b00) illegal_instr_o = 1'b1;
end
end else begin
illegal_instr_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
end

3'b011, // c.flw -> flw rd', imm(rs1')
3'b101, // c.fsd -> fsd rs2', imm(rs1')
3'b111: begin // c.fsw -> fsw rs2', imm(rs1')
illegal_instr_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};
Expand Down
3 changes: 2 additions & 1 deletion rtl/cv32e40x_core.sv
Original file line number Diff line number Diff line change
Expand Up @@ -381,7 +381,8 @@ module cv32e40x_core import cv32e40x_pkg::*;
.PMA_CFG ( PMA_CFG ),
.MTVT_ADDR_WIDTH ( MTVT_ADDR_WIDTH ),
.SMCLIC ( SMCLIC ),
.SMCLIC_ID_WIDTH ( SMCLIC_ID_WIDTH )
.SMCLIC_ID_WIDTH ( SMCLIC_ID_WIDTH ),
.ZC_EXT ( ZC_EXT )
)
if_stage_i
(
Expand Down
6 changes: 5 additions & 1 deletion rtl/cv32e40x_if_stage.sv
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
parameter pma_cfg_t PMA_CFG[PMA_NUM_REGIONS-1:0] = '{default:PMA_R_DEFAULT},
parameter int unsigned MTVT_ADDR_WIDTH = 26,
parameter bit SMCLIC = 1'b0,
parameter int SMCLIC_ID_WIDTH = 5
parameter int SMCLIC_ID_WIDTH = 5,
parameter bit ZC_EXT = 0
)
(
input logic clk,
Expand Down Expand Up @@ -294,6 +295,9 @@ module cv32e40x_if_stage import cv32e40x_pkg::*;
end

cv32e40x_compressed_decoder
#(
.ZC_EXT (ZC_EXT)
)
compressed_decoder_i
(
.instr_i ( prefetch_instr ),
Expand Down