117 lines
3.4 KiB
Systemverilog
117 lines
3.4 KiB
Systemverilog
// Base rv32i instruction set decoder
|
|
module rvx0_decoder_i (
|
|
input wire [31:0] instruction_i,
|
|
|
|
input wire [6:0] opcode,
|
|
input wire [2:0] funct3,
|
|
|
|
input wire signed [11:0] imm_i_type,
|
|
input wire signed [11:0] imm_s_type,
|
|
input wire signed [12:0] imm_b_type,
|
|
input wire [19:0] imm_u_type,
|
|
input wire signed [20:0] imm_j_type,
|
|
|
|
output logic write_pc_o,
|
|
output logic write_mem_o,
|
|
output logic conditional_o,
|
|
|
|
output logic instruction_fault_o,
|
|
output wire [31:0] imm_o,
|
|
output wire v1src_o,
|
|
output wire [1:0] v2src_o,
|
|
output wire [1:0] vdsrc_o,
|
|
output wire [3:0] aluop_o
|
|
);
|
|
always_comb begin
|
|
write_pc_o = 0;
|
|
write_mem_o = 0;
|
|
conditional_o = 0;
|
|
instruction_fault_o = 0;
|
|
aluop_o = 0;
|
|
|
|
case (opcode)
|
|
7'b0110111: begin // lui
|
|
v1src_o = V1SRC_ZERO;
|
|
v2src_o = V2SRC_ZERO;
|
|
vdsrc_o = RDSRC_ALU;
|
|
imm_o = { imm_u_type, 12'b0 };
|
|
end
|
|
7'b0010111: begin // auipc
|
|
v1src_o = V1SRC_ZERO;
|
|
v2src_o = V2SRC_PC;
|
|
vdsrc_o = RDSRC_ALU;
|
|
imm_o = { imm_u_type, 12'b0 };
|
|
end
|
|
7'b1101111: begin // jal
|
|
v1src_o = V1SRC_ZERO;
|
|
v2src_o = V2SRC_PC;
|
|
vdsrc_o = RDSRC_PC;
|
|
write_pc_o = 1;
|
|
imm_o = 32'(signed'(imm_j_type));
|
|
end
|
|
7'b1100111: begin // jalr
|
|
v1src_o = V1SRC_RS1;
|
|
v2src_o = V2SRC_ZERO;
|
|
vdsrc_o = RDSRC_PC;
|
|
write_pc_o = 1;
|
|
imm_o = 32'(signed'(imm_i_type));
|
|
end
|
|
7'b1100011: begin // b.???
|
|
v1src_o = V1SRC_ZERO;
|
|
v2src_o = V2SRC_PC;
|
|
vdsrc_o = RDSRC_NONE;
|
|
write_pc_o = 1;
|
|
conditional_o = 1;
|
|
imm_o = 32'(signed'(imm_b_type));
|
|
end
|
|
7'b0000011: begin // load
|
|
v1src_o = V1SRC_RS1;
|
|
v2src_o = V2SRC_ZERO;
|
|
vdsrc_o = RDSRC_MEM;
|
|
imm_o = 32'(signed'(imm_i_type));
|
|
end
|
|
7'b0100011: begin // store
|
|
v1src_o = V1SRC_RS1;
|
|
v2src_o = V2SRC_ZERO;
|
|
vdsrc_o = RDSRC_NONE;
|
|
write_mem_o = 1;
|
|
imm_o = 32'(signed'(imm_s_type));
|
|
end
|
|
7'b0010011: begin // alu imm
|
|
v1src_o = V1SRC_RS1;
|
|
v2src_o = V2SRC_ZERO;
|
|
vdsrc_o = RDSRC_ALU;
|
|
case (funct3)
|
|
3'b001: begin
|
|
aluop_o = ALUOP_SLL;
|
|
imm_o = { 27'b0, instruction_i[24:20] };
|
|
end
|
|
3'b101: begin
|
|
aluop_o = { instruction_i[30], funct3 };
|
|
imm_o = { 27'b0, instruction_i[24:20] };
|
|
end
|
|
default: begin
|
|
aluop_o = { 1'b0, funct3 };
|
|
imm_o = 32'(signed'(imm_i_type));
|
|
end
|
|
endcase
|
|
end
|
|
7'b0110011: begin
|
|
v1src_o = V1SRC_RS1;
|
|
v2src_o = V2SRC_RS2;
|
|
vdsrc_o = RDSRC_ALU;
|
|
aluop_o = { instruction_i[30], funct3 };
|
|
imm_o = 0;
|
|
end
|
|
default: begin
|
|
v1src_o = V1SRC_ZERO;
|
|
v2src_o = V2SRC_ZERO;
|
|
vdsrc_o = RDSRC_NONE;
|
|
instruction_fault_o = 1;
|
|
imm_o = 0;
|
|
end
|
|
endcase
|
|
|
|
end
|
|
endmodule
|