icicle/rv32_decode.sv

394 lines
15 KiB
Systemverilog
Raw Normal View History

2017-12-01 23:30:33 +00:00
`ifndef RV32_DECODE
`define RV32_DECODE
2017-12-01 22:54:08 +00:00
`include "rv32_alu_ops.sv"
2017-11-30 22:30:49 +00:00
`include "rv32_opcodes.sv"
`include "rv32_regs.sv"
module rv32_decode (
input clk,
2017-11-30 22:30:49 +00:00
/* data in */
input [31:0] pc_in,
input [31:0] instr_in,
2017-11-30 22:30:49 +00:00
/* control out */
2017-12-01 22:37:11 +00:00
output valid_out,
2017-12-01 22:36:26 +00:00
output [3:0] alu_op_out,
output alu_sub_sra_out,
output alu_src1_out,
output alu_src2_out,
2017-12-02 10:22:48 +00:00
output mem_read_en_out,
output mem_write_en_out,
2017-11-30 22:30:49 +00:00
/* data out */
output [31:0] pc_out,
output [31:0] rs1_value_out,
output [31:0] rs2_value_out,
output [31:0] imm_out
2017-11-30 22:30:49 +00:00
);
logic [6:0] funct7 = instr_in[31:25];
logic [4:0] rs2 = instr_in[24:20];
logic [4:0] rs1 = instr_in[19:15];
logic [2:0] funct3 = instr_in[14:12];
logic [4:0] rd = instr_in[11:7];
logic [6:0] opcode = instr_in[6:0];
logic sign = instr_in[31];
logic [31:0] imm_i = {{21{sign}}, instr_in[30:25], instr_in[24:21], instr_in[20]};
logic [31:0] imm_s = {{21{sign}}, instr_in[30:25], instr_in[11:8], instr_in[7]};
logic [31:0] imm_b = {{20{sign}}, instr_in[7], instr_in[30:25], instr_in[11:8], 1'b0};
logic [31:0] imm_u = {sign, instr_in[30:20], instr_in[19:12], 12'b0};
logic [31:0] imm_j = {{12{sign}}, instr_in[19:12], instr_in[20], instr_in[30:25], instr_in[24:1], 1'b0};
2017-12-01 21:51:41 +00:00
logic [31:0] shamt = {27'b0, rs2};
2017-11-30 22:30:49 +00:00
rv32_regs regs (
.clk(clk),
2017-12-01 22:36:26 +00:00
/* control in */
2017-11-30 22:30:49 +00:00
.rs1_in(rs1),
.rs2_in(rs2),
2017-12-01 22:36:26 +00:00
/* data out */
2017-11-30 22:30:49 +00:00
.rs1_value_out(rs1_value_out),
.rs2_value_out(rs2_value_out)
);
always_ff @(posedge clk) begin
pc_out <= pc_in;
2017-12-01 22:37:11 +00:00
valid_out <= 0;
2017-12-01 22:36:26 +00:00
alu_op_out <= 4'bx;
alu_sub_sra_out <= 1'bx;
alu_src1_out <= 1'bx;
alu_src2_out <= 1'bx;
2017-12-02 10:22:48 +00:00
mem_read_en_out <= 0;
mem_write_en_out <= 0;
2017-11-30 22:30:49 +00:00
imm_out <= 32'bx;
casez ({opcode, funct3, funct7})
{RV32_OPCODE_LUI, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin
/* LUI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SRC2;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_u;
end
{RV32_OPCODE_AUIPC, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin
/* AUIPC */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_PC;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_u;
end
{RV32_OPCODE_JAL, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin
/* JAL */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:58:10 +00:00
alu_op_out <= RV32_ALU_OP_SRC1P4;
alu_src1_out <= RV32_ALU_SRC1_PC;
2017-11-30 22:30:49 +00:00
imm_out <= imm_j;
end
{RV32_OPCODE_JALR, RV32_FUNCT3_ZERO, RV32_FUNCT7_ANY}: begin
/* JALR */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:58:10 +00:00
alu_op_out <= RV32_ALU_OP_SRC1P4;
alu_src1_out <= RV32_ALU_SRC1_PC;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BEQ, RV32_FUNCT7_ANY}: begin
/* BEQ */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
imm_out <= imm_b;
end
{RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BNE, RV32_FUNCT7_ANY}: begin
/* BNE */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
imm_out <= imm_b;
end
{RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BLT, RV32_FUNCT7_ANY}: begin
/* BLT */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLT;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
imm_out <= imm_b;
end
{RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BGE, RV32_FUNCT7_ANY}: begin
/* BGE */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLT;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
imm_out <= imm_b;
end
{RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BLTU, RV32_FUNCT7_ANY}: begin
/* BLTU */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLTU;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
imm_out <= imm_b;
end
{RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BGEU, RV32_FUNCT7_ANY}: begin
/* BGEU */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLTU;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
imm_out <= imm_b;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LB, RV32_FUNCT7_ANY}: begin
/* LB */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_read_en_out <= 1;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LH, RV32_FUNCT7_ANY}: begin
/* LH */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_read_en_out <= 1;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LW, RV32_FUNCT7_ANY}: begin
/* LW */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_read_en_out <= 1;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LBU, RV32_FUNCT7_ANY}: begin
/* LBU */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_read_en_out <= 1;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LHU, RV32_FUNCT7_ANY}: begin
/* LHU */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_read_en_out <= 1;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SB, RV32_FUNCT7_ANY}: begin
/* SB */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_write_en_out <= 1;
2017-11-30 22:30:49 +00:00
imm_out <= imm_s;
end
{RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SH, RV32_FUNCT7_ANY}: begin
/* SH */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_write_en_out <= 1;
2017-12-01 22:54:08 +00:00
imm_out <= imm_s;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SW, RV32_FUNCT7_ANY}: begin
/* SW */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-02 10:22:48 +00:00
mem_write_en_out <= 1;
2017-12-01 22:54:08 +00:00
imm_out <= imm_s;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_ANY}: begin
/* ADDI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLT, RV32_FUNCT7_ANY}: begin
/* SLTI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLT;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLTU, RV32_FUNCT7_ANY}: begin
/* SLTIU */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLTU;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_XOR, RV32_FUNCT7_ANY}: begin
/* XORI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_XOR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_OR, RV32_FUNCT7_ANY}: begin
/* ORI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_OR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_AND, RV32_FUNCT7_ANY}: begin
/* ANDI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_AND;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-11-30 22:30:49 +00:00
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLL, RV32_FUNCT7_ZERO}: begin
/* SLLI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLL;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-01 21:51:41 +00:00
imm_out <= shamt;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_ZERO}: begin
/* SRLI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-01 21:51:41 +00:00
imm_out <= shamt;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_OP_SRA}: begin
/* SRAI */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
2017-12-01 21:51:41 +00:00
imm_out <= shamt;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_ZERO}: begin
/* ADD */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_OP_SUB}: begin
/* SUB */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SLL, RV32_FUNCT7_ZERO}: begin
/* SLL */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLL;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SLT, RV32_FUNCT7_ZERO}: begin
/* SLT */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLT;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SLTU, RV32_FUNCT7_ZERO}: begin
/* SLTU */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SLTU;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_XOR, RV32_FUNCT7_ZERO}: begin
/* XOR */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_XOR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_ZERO}: begin
/* SRL */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_OP_SRA}: begin
/* SRA */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_OR, RV32_FUNCT7_ZERO}: begin
/* OR */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_OR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_AND, RV32_FUNCT7_ZERO}: begin
/* AND */
2017-12-01 22:37:11 +00:00
valid_out <= 1;
2017-12-01 22:54:08 +00:00
alu_op_out <= RV32_ALU_OP_AND;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
2017-11-30 22:30:49 +00:00
end
endcase
end
endmodule
2017-12-01 23:30:33 +00:00
`endif