Skip to content
Open
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
1 change: 1 addition & 0 deletions sim/iverilog/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ src_sub = \
../PulseRain_processor_core/source/RV2T_execution_unit \
../PulseRain_processor_core/source/RV2T_fetch_instruction \
../PulseRain_processor_core/source/RV2T_instruction_decode \
../PulseRain_processor_core/source/RV2T_compressed_decode \
../PulseRain_processor_core/source/RV2T_machine_timer \
../PulseRain_processor_core/source/RV2T_memory \
../PulseRain_processor_core/source/RV2T_mm_reg \
Expand Down
1 change: 1 addition & 0 deletions sim/verilator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ src_sub = \
../PulseRain_processor_core/source/RV2T_CSR \
../PulseRain_processor_core/source/RV2T_fetch_instruction \
../PulseRain_processor_core/source/RV2T_instruction_decode \
../PulseRain_processor_core/source/RV2T_compressed_decode \
../PulseRain_processor_core/source/RV2T_execution_unit \
../PulseRain_processor_core/source/RV2T_data_access \
../PulseRain_processor_core/source/RV2T_controller \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,11 @@ module PulseRain_RV2T_core (
wire fetch_enable_out;
wire [`XLEN - 1 : 0] fetch_IR_out;
wire [`PC_BITWIDTH - 1 : 0] fetch_PC_out;


wire [`XLEN - 1 : 2] uncompress_IR_out;
wire uncompress_is_compressed;
wire uncompress_illegal_instr;

wire fetch_read_mem_enable;
wire [`PC_BITWIDTH - 1 : 0] fetch_read_mem_addr;

Expand All @@ -114,7 +118,8 @@ module PulseRain_RV2T_core (

wire [`XLEN - 1 : 2] decode_IR_out ;
wire [`PC_BITWIDTH - 1 : 0] decode_PC_out ;

wire decode_is_compress;

wire [`CSR_BITS - 1 : 0] decode_csr;
wire decode_csr_enable;

Expand Down Expand Up @@ -196,6 +201,7 @@ module PulseRain_RV2T_core (

wire decode_exception_illegal_instruction;
wire csr_exception_illegal_instruction;
wire exception_illegal_instruction;

wire activate_exception;
wire [`EXCEPTION_CODE_BITS - 1 : 0] exception_code;
Expand Down Expand Up @@ -375,6 +381,16 @@ module PulseRain_RV2T_core (
.read_mem_enable (fetch_read_mem_enable),
.read_mem_addr (fetch_read_mem_addr));

//---------------------------------------------------------------------
// compressed instruction decode
//---------------------------------------------------------------------
RV2T_compressed_decode RV2T_compressed_decode_i (
.instr_i (fetch_IR_out),
.instr_o (uncompress_IR_out),
.is_compressed_o (uncompress_is_compressed),
.illegal_instr_o (uncompress_illegal_instr)
);

//---------------------------------------------------------------------
// instruction decode
//---------------------------------------------------------------------
Expand All @@ -386,8 +402,10 @@ module PulseRain_RV2T_core (
.decode_enable (decode_enable),

.enable_in (fetch_enable_out),
.IR_in (fetch_IR_out),
.IR_in (uncompress_IR_out),
.PC_in (fetch_PC_out),
.is_compressed_in (uncompress_is_compressed),
.exception_illegal_instr_in (uncompress_illegal_instr),

.rs1 (rs1),
.rs2 (rs2),
Expand Down Expand Up @@ -419,7 +437,8 @@ module PulseRain_RV2T_core (
.ctl_MRET (decode_ctl_MRET),
.ctl_WFI (decode_ctl_WFI),

.exception_illegal_instruction (decode_exception_illegal_instruction));
.exception_illegal_instruction (decode_exception_illegal_instruction),
.is_compressed_out (decode_is_compress));

//---------------------------------------------------------------------
// execution unit
Expand Down Expand Up @@ -452,11 +471,13 @@ module PulseRain_RV2T_core (
.ctl_MISC_MEM (decode_ctl_MISC_MEM),
.ctl_MRET (decode_ctl_MRET),
.ctl_MUL_DIV_FUNCT3 (decode_ctl_MUL_DIV_FUNCT3),

.ctl_exception_illegal_instruction (decode_exception_illegal_instruction),

.rs1_in (reg_file_read_rs1_data_out),
.rs2_in (reg_file_read_rs2_data_out),

.csr_in (csr_read_data_out),
.is_compressed (decode_is_compress),

.enable_out (),
.rd_addr_out (exe_rd_addr_out),
Expand All @@ -483,6 +504,7 @@ module PulseRain_RV2T_core (
.csr_addr_out (exe_csr_addr),
.ecall_active (exception_ecall),
.ebreak_active (exception_ebreak),
.exception_illegal_instruction (exception_illegal_instruction),
.mret_active (mret_active),
.mul_div_active (mul_div_active),
.mul_div_done (mul_div_done)
Expand Down Expand Up @@ -602,7 +624,7 @@ module PulseRain_RV2T_core (
.activate_exception (activate_exception),
.exception_PC (exception_PC),
.exception_addr (exception_addr),
.exception_illegal_instruction (decode_exception_illegal_instruction | csr_exception_illegal_instruction),
.exception_illegal_instruction (exception_illegal_instruction | csr_exception_illegal_instruction),
.paused (paused)

);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
`include "RV2T_common.vh"

`default_nettype none

module RV2T_compressed_decode
(
input wire [31:0] instr_i,
output reg [31:2] instr_o,
output wire is_compressed_o,
output reg illegal_instr_o
);

always @(*) begin
illegal_instr_o = 1'b0;
instr_o = 30'b0;

case (instr_i[1:0])
// C0
2'b00: begin
case (instr_i[15:13])
3'b000: begin
Copy link
Member

@PulseRainmaker PulseRainmaker Aug 28, 2019

Choose a reason for hiding this comment

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

One suggestion is to make those constants as macro definitions, which can include both bit [15:13] and bit [1 :0], and put them in common.vh, like the following:

define C_ADDI4SPN (5'b000_00) define C_LW (5'b010_00)
define C_SW (5'b110_00) define C_NOP_ADDI (5'b000_01)
define C_JAL (5'b001_01) define C_J (5'b101_01)
define C_LI (5'b010_01) define C_BEQZ (5'b110_01)
define C_BNEZ (5'b111_01) define C_ADDI16SP_LUI (5'b011_01)
define C_SLLI (5'b000_10) define C_SWSP (5'b110_10)
define C_LWSP (5'b010_10) define C_JR_JALR_MV_ADD (5'b100_10)
`define C_MISC_ALU (5'b100_01)

// c.addi4spn -> addi rd', x2, imm
instr_o = {2'b0, instr_i[10:7], instr_i[12:11], instr_i[5], instr_i[6], 2'b00, 5'h02, 3'b000, 2'b01, instr_i[4:2], `CMD_OP_IMM};
if (instr_i[12:5] == 8'b0) illegal_instr_o = 1'b1;
end

3'b001: begin
// c.fld -> fld rd', imm(rs1')
illegal_instr_o = 1'b1;
end

3'b010: begin
// c.lw -> lw rd', imm(rs1')
instr_o = {5'b0, instr_i[5], instr_i[12:10], instr_i[6], 2'b00, 2'b01, instr_i[9:7], 3'b010, 2'b01, instr_i[4:2], `CMD_LOAD};
end

3'b011: begin
// c.flw -> flw rd', imm(rs1')
illegal_instr_o = 1'b1;
end

3'b101: begin
// c.fsd -> fsd rs2', imm(rs1')
illegal_instr_o = 1'b1;
end

3'b110: begin
// c.sw -> sw rs2', imm(rs1')
instr_o = {5'b0, instr_i[5], instr_i[12], 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b010, instr_i[11:10], instr_i[6], 2'b00, `CMD_STORE};
end

3'b111: begin
// c.fsw -> fsw rs2', imm(rs1')
illegal_instr_o = 1'b1;
end
default: begin
illegal_instr_o = 1'b1;
end
endcase
end


// C1
2'b01: begin
case (instr_i[15:13])
3'b000: begin
// c.addi -> addi rd, rd, nzimm
// c.nop
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], `CMD_OP_IMM};
end

3'b001, 3'b101: begin
// 001: c.jal -> jal x1, imm
// 101: c.j -> jal x0, imm
instr_o = {instr_i[12], instr_i[8], instr_i[10:9], instr_i[6], instr_i[7], instr_i[2], instr_i[11], instr_i[5:3], {9 {instr_i[12]}}, 4'b0, ~instr_i[15], `CMD_JAL};
end

3'b010: begin
// c.li -> addi rd, x0, nzimm
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], `CMD_OP_IMM};
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
end

3'b011: begin
// c.lui -> lui rd, imm
instr_o = {{15 {instr_i[12]}}, instr_i[6:2], instr_i[11:7], `CMD_LUI};

if (instr_i[11:7] == 5'h02) begin
// c.addi16sp -> addi x2, x2, nzimm
instr_o = {{3 {instr_i[12]}}, instr_i[4:3], instr_i[5], instr_i[2], instr_i[6], 4'b0, 5'h02, 3'b000, 5'h02, `CMD_OP_IMM};
end else if (instr_i[11:7] == 5'b0) begin
illegal_instr_o = 1'b1;
end

if ({instr_i[12], instr_i[6:2]} == 6'b0) illegal_instr_o = 1'b1;
end

3'b100: begin
case (instr_i[11:10])
2'b00,
2'b01: begin
// 00: c.srli -> srli rd, rd, shamt
// 01: c.srai -> srai rd, rd, shamt
instr_o = {1'b0, instr_i[10], 5'b0, instr_i[6:2], 2'b01, instr_i[9:7], 3'b101, 2'b01, instr_i[9:7], `CMD_OP_IMM};
if (instr_i[12] == 1'b1) illegal_instr_o = 1'b1;
if (instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
end

2'b10: begin
// c.andi -> andi rd, rd, imm
instr_o = {{6 {instr_i[12]}}, instr_i[12], instr_i[6:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], `CMD_OP_IMM};
end

2'b11: begin
case ({instr_i[12], instr_i[6:5]})
3'b000: begin
// c.sub -> sub rd', rd', rs2'
instr_o = {2'b01, 5'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b000, 2'b01, instr_i[9:7], `CMD_OP};
end

3'b001: begin
// c.xor -> xor rd', rd', rs2'
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b100, 2'b01, instr_i[9:7], `CMD_OP};
end

3'b010: begin
// c.or -> or rd', rd', rs2'
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b110, 2'b01, instr_i[9:7], `CMD_OP};
end

3'b011: begin
// c.and -> and rd', rd', rs2'
instr_o = {7'b0, 2'b01, instr_i[4:2], 2'b01, instr_i[9:7], 3'b111, 2'b01, instr_i[9:7], `CMD_OP};
end

3'b100,
3'b101,
3'b110,
3'b111: begin
// 100: c.subw
// 101: c.addw
illegal_instr_o = 1'b1;
end
endcase
end
endcase
end

3'b110, 3'b111: begin
// 0: c.beqz -> beq rs1', x0, imm
// 1: c.bnez -> bne rs1', x0, imm
instr_o = {{4 {instr_i[12]}}, instr_i[6:5], instr_i[2], 5'b0, 2'b01, instr_i[9:7], 2'b00, instr_i[13], instr_i[11:10], instr_i[4:3], instr_i[12], `CMD_BRANCH};
end
endcase
end

// C2
2'b10: begin
case (instr_i[15:13])
3'b000: begin
// c.slli -> slli rd, rd, shamt
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b001, instr_i[11:7], `CMD_OP_IMM};
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
if (instr_i[12] == 1'b1 || instr_i[6:2] == 5'b0) illegal_instr_o = 1'b1;
end

3'b001: begin
// c.fldsp -> fld rd, imm(x2)
illegal_instr_o = 1'b1;
end

3'b010: begin
// c.lwsp -> lw rd, imm(x2)
instr_o = {4'b0, instr_i[3:2], instr_i[12], instr_i[6:4], 2'b00, 5'h02, 3'b010, instr_i[11:7], `CMD_LOAD};
if (instr_i[11:7] == 5'b0) illegal_instr_o = 1'b1;
end

3'b011: begin
// c.flwsp -> flw rd, imm(x2)
illegal_instr_o = 1'b1;
end

3'b100: begin
if (instr_i[12] == 1'b0) begin
// c.mv -> add rd/rs1, x0, rs2
instr_o = {7'b0, instr_i[6:2], 5'b0, 3'b0, instr_i[11:7], `CMD_OP};

if (instr_i[6:2] == 5'b0) begin
// c.jr -> jalr x0, rd/rs1, 0
instr_o = {12'b0, instr_i[11:7], 3'b0, 5'b0, `CMD_JALR};
end
end else begin
// c.add -> add rd, rd, rs2
instr_o = {7'b0, instr_i[6:2], instr_i[11:7], 3'b0, instr_i[11:7], `CMD_OP};

if (instr_i[11:7] == 5'b0) begin
// c.ebreak -> ebreak
instr_o = {30'h04_00_1C};
if (instr_i[6:2] != 5'b0)
illegal_instr_o = 1'b1;
end else if (instr_i[6:2] == 5'b0) begin
// c.jalr -> jalr x1, rs1, 0
instr_o = {12'b0, instr_i[11:7], 3'b000, 5'b00001, `CMD_JALR};
end
end
end

3'b101: begin
// c.fsdsp -> fsd rs2, imm(x2)
illegal_instr_o = 1'b1;
end

3'b110: begin
// c.swsp -> sw rs2, imm(x2)
instr_o = {4'b0, instr_i[8:7], instr_i[12], instr_i[6:2], 5'h02, 3'b010, instr_i[11:9], 2'b00, `CMD_STORE};
end

3'b111: begin
// c.fswsp -> fsw rs2, imm(x2)
illegal_instr_o = 1'b1;
end
endcase
end

default: begin
// 32 bit (or more) instruction
instr_o = instr_i[31:2];
end
endcase
end

assign is_compressed_o = (instr_i[1:0] != 2'b11);

endmodule
Loading