Skip to content

Commit

Permalink
Merge pull request #390 from silabs-oysteink/silabs-oysteink_merge-w3-1
Browse files Browse the repository at this point in the history
Merge from CV32E40X
  • Loading branch information
Silabs-ArjanB committed Jan 16, 2023
2 parents dac54e6 + 0da760b commit 151a465
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 75 deletions.
71 changes: 3 additions & 68 deletions rtl/cv32e40s_compressed_decoder.sv
Expand Up @@ -75,26 +75,6 @@ module cv32e40s_compressed_decoder import cv32e40s_pkg::*;
end
end

3'b001: begin
if (ZC_EXT) begin
if (instr[12]) begin
// cm.lh -> lh rd', imm(rs1')
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) begin
illegal_instr_o = 1'b1;
end
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 Down Expand Up @@ -142,34 +122,9 @@ module cv32e40s_compressed_decoder import cv32e40s_pkg::*;
end
end

3'b101: begin
if (ZC_EXT) begin
if (instr[12]) begin
// cm.sh -> sh rs2', imm(rs1')
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) begin
illegal_instr_o = 1'b1;
end
end else begin
// cm.sb -> sb rs2', imm(rs1')
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) begin
illegal_instr_o = 1'b1;
end
end
end else begin
illegal_instr_o = 1'b1;
// todo: likely change to commented line, but that is not SEC clean due to load stalls differences.
//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};
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'b001,
3'b011, // c.flw -> flw rd', imm(rs1')
3'b101,
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 Expand Up @@ -380,28 +335,7 @@ module cv32e40s_compressed_decoder import cv32e40s_pkg::*;
end
end

3'b001: begin
if (ZC_EXT) begin
if (instr[12]) begin
// cm.lhu rd', uimm(rs1') -> lhu rd', uimm(rs1')
instr_o.bus_resp.rdata = {7'b0000000, instr[11:10], instr[6:5], 1'b0, 2'b01, instr[9:7], 3'b101, 2'b01, instr[4:2], OPCODE_LOAD};

if ({instr[11:10], instr[6]} == 3'b000) begin
illegal_instr_o = 1'b1;
end
end else begin
// cm.lbu rd', uimm(rs1') -> lbu rd', uimm(rs1')
instr_o.bus_resp.rdata = {8'h00, instr[10], instr[6:5], instr[11], 2'b01, instr[9:7], 3'b100, 2'b01, instr[4:2], OPCODE_LOAD};

if ({instr[10], instr[6]} == 2'b00) begin
illegal_instr_o = 1'b1;
end
end
end else begin
instr_o.bus_resp.rdata = {4'b0, instr[3:2], instr[12], instr[6:4], 2'b00, 5'h02, 3'b010, instr[11:7], OPCODE_LOAD};
illegal_instr_o = 1'b1;
end
end
3'b010: begin
// c.lwsp -> lw rd, imm(x2)
instr_o.bus_resp.rdata = {4'b0, instr[3:2], instr[12], instr[6:4], 2'b00, 5'h02, 3'b010, instr[11:7], OPCODE_LOAD};
Expand Down Expand Up @@ -456,6 +390,7 @@ module cv32e40s_compressed_decoder import cv32e40s_pkg::*;
instr_o.bus_resp.rdata = {4'b0, instr[8:7], instr[12], instr[6:2], 5'h02, 3'b010, instr[11:9], 2'b00, OPCODE_STORE};
end

3'b001,
3'b011,
3'b101,
3'b111: begin // c.fswsp -> fsw rs2, imm(x2)
Expand Down
3 changes: 3 additions & 0 deletions rtl/cv32e40s_core.sv
Expand Up @@ -234,6 +234,7 @@ module cv32e40s_core import cv32e40s_pkg::*;

// JVT
logic [JVT_ADDR_WIDTH-1:0] jvt_addr;
logic [5:0] jvt_mode;

logic [MTVT_ADDR_WIDTH-1:0] mtvt_addr;

Expand Down Expand Up @@ -558,6 +559,7 @@ module cv32e40s_core import cv32e40s_pkg::*;
.mepc_i ( mepc ), // Exception PC (restore upon return from exception/interrupt)
.mtvec_addr_i ( mtvec_addr ), // Exception/interrupt address (MSBs only)
.mtvt_addr_i ( mtvt_addr ), // CLIC vector base
.jvt_mode_i ( jvt_mode ),

.branch_decision_ex_i( branch_decision_ex ),

Expand Down Expand Up @@ -938,6 +940,7 @@ module cv32e40s_core import cv32e40s_pkg::*;
.dcsr_o ( dcsr ),
.dpc_o ( dpc ),
.jvt_addr_o ( jvt_addr ),
.jvt_mode_o ( jvt_mode ),
.mcause_o ( mcause ),
.mcycle_o ( mcycle_o ),
.mepc_o ( mepc ),
Expand Down
2 changes: 2 additions & 0 deletions rtl/cv32e40s_cs_registers.sv
Expand Up @@ -71,6 +71,7 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;
output dcsr_t dcsr_o,
output logic [31:0] dpc_o,
output logic [JVT_ADDR_WIDTH-1:0] jvt_addr_o,
output logic [5:0] jvt_mode_o,
output mcause_t mcause_o,
output logic [63:0] mcycle_o,
output logic [31:0] mepc_o,
Expand Down Expand Up @@ -2629,6 +2630,7 @@ module cv32e40s_cs_registers import cv32e40s_pkg::*;
assign dcsr_o = dcsr_rdata;
assign dpc_o = dpc_rdata;
assign jvt_addr_o = jvt_rdata.base[31:32-JVT_ADDR_WIDTH];
assign jvt_mode_o = jvt_rdata.mode;
assign mcause_o = mcause_rdata;
assign mcycle_o = mhpmcounter_rdata[0];
assign mepc_o = mepc_rdata;
Expand Down
4 changes: 3 additions & 1 deletion rtl/cv32e40s_if_stage.sv
Expand Up @@ -56,6 +56,7 @@ module cv32e40s_if_stage import cv32e40s_pkg::*;
input logic [31:0] jump_target_id_i, // Jump target address
input logic [31:0] mepc_i, // Exception PC (restore upon return from exception/interrupt)
input logic [24:0] mtvec_addr_i, // Exception/interrupt address (MSBs)
input logic [5:0] jvt_mode_i,

input logic branch_decision_ex_i, // Current branch decision from EX

Expand Down Expand Up @@ -375,7 +376,6 @@ module cv32e40s_if_stage import cv32e40s_pkg::*;
.mepc_i ( mepc_i ),
.mtvec_addr_i ( mtvec_addr_i ),
.dpc_i ( dpc_i ),
.jvt_addr_i ( jvt_addr_i ),

.boot_addr_i ( boot_addr_i ),
.dm_halt_addr_i ( dm_halt_addr_i ),
Expand Down Expand Up @@ -582,6 +582,8 @@ module cv32e40s_if_stage import cv32e40s_pkg::*;
.clk ( clk ),
.rst_n ( rst_n ),

.jvt_mode_i ( jvt_mode_i ),

.instr_i ( prefetch_instr ),
.instr_is_clic_ptr_i ( prefetch_is_clic_ptr ),
.instr_is_mret_ptr_i ( prefetch_is_mret_ptr ),
Expand Down
1 change: 0 additions & 1 deletion rtl/cv32e40s_pc_check.sv
Expand Up @@ -60,7 +60,6 @@ module cv32e40s_pc_check import cv32e40s_pkg::*;
input logic [31:0] mepc_i,
input logic [24:0] mtvec_addr_i,
input logic [31:0] dpc_i,
input logic [JVT_ADDR_WIDTH-1:0] jvt_addr_i,

// Static core inputs
input logic [31:0] boot_addr_i, // Boot address from toplevel pins
Expand Down
13 changes: 8 additions & 5 deletions rtl/cv32e40s_sequencer.sv
Expand Up @@ -39,6 +39,7 @@ module cv32e40s_sequencer import cv32e40s_pkg::*;
input logic clk,
input logic rst_n,

input logic [5:0] jvt_mode_i,
input inst_resp_t instr_i, // Instruction from prefetch unit
input logic instr_is_clic_ptr_i, // CLIC pointer flag, instr_i does not contain an instruction
input logic instr_is_mret_ptr_i, // mret pointer flag, instr_i does not contain an instruction
Expand Down Expand Up @@ -153,8 +154,10 @@ module cv32e40s_sequencer import cv32e40s_pkg::*;
unique case (instr[12:10])
3'b000: begin
if ((priv_lvl_i == PRIV_LVL_M) || mstateen0_i[2]) begin
seq_tbljmp_o = 1'b1;
seq_instr = TBLJMP;
if (!(|jvt_mode_i)) begin
seq_tbljmp_o = 1'b1;
seq_instr = TBLJMP;
end
end
end

Expand Down Expand Up @@ -306,12 +309,12 @@ module cv32e40s_sequencer import cv32e40s_pkg::*;
instr_o.bus_resp.rdata = {12'h000, 5'd10, 3'b000, sn_to_regnum(5'(instr[9:7])), OPCODE_OPIMM};
seq_state_n = S_DMOVE;
end else if (seq_tbljmp_o) begin
if (instr[9:8] == 2'b00) begin
if (instr[9:7] == 3'b000) begin
// cm.jt -> JAL x0, index
instr_o.bus_resp.rdata = {13'b0000000000000, instr[7:2], 5'b00000, OPCODE_JAL};
instr_o.bus_resp.rdata = {15'b000000000000000, instr[6:2], 5'b00000, OPCODE_JAL};
end else begin
// cm.jalt -> JAL, x1, index
instr_o.bus_resp.rdata = {11'b00000000000, instr[9:2], 5'b00001, OPCODE_JAL};
instr_o.bus_resp.rdata = {12'b000000000000, instr[9:2], 5'b00001, OPCODE_JAL};
end
// The second half of tablejumps (pointer) will not use the FSM (the jump will kill the sequencer anyway).
// Signalling ready here will acknowledge the prefetcher.
Expand Down

0 comments on commit 151a465

Please sign in to comment.