Split decode stage into smaller modules
This increases the number of LUTs slightly (by ~20), as the immediate mux is now separate to the main control unit, but I think it's worth the cost. The imm output is also renamed to imm_value. This is consistent with rs1_value and rs2_value, and avoids a collision with the new imm output, which represents the type of immediate.
This commit is contained in:
parent
2b1e0de9de
commit
0013935bb0
8 changed files with 575 additions and 453 deletions
2
Makefile
2
Makefile
|
|
@ -16,7 +16,7 @@ DEVICE = 8k
|
|||
PACKAGE = ct256
|
||||
PCF = ice40hx8k-b-evn.pcf
|
||||
FREQ_OSC = 12
|
||||
FREQ_PLL = 36
|
||||
FREQ_PLL = 32
|
||||
TARGET = riscv64-unknown-elf
|
||||
AS = $(TARGET)-as
|
||||
ASFLAGS = -march=rv32i -mabi=ilp32
|
||||
|
|
|
|||
6
rv32.sv
6
rv32.sv
|
|
@ -70,7 +70,7 @@ module rv32 (
|
|||
logic [31:0] decode_pc;
|
||||
logic [31:0] decode_rs1_value;
|
||||
logic [31:0] decode_rs2_value;
|
||||
logic [31:0] decode_imm;
|
||||
logic [31:0] decode_imm_value;
|
||||
|
||||
/* execute -> mem control */
|
||||
logic execute_mem_read;
|
||||
|
|
@ -201,7 +201,7 @@ module rv32 (
|
|||
.pc_out(decode_pc),
|
||||
.rs1_value_out(decode_rs1_value),
|
||||
.rs2_value_out(decode_rs2_value),
|
||||
.imm_out(decode_imm)
|
||||
.imm_value_out(decode_imm_value)
|
||||
);
|
||||
|
||||
rv32_execute execute (
|
||||
|
|
@ -235,7 +235,7 @@ module rv32 (
|
|||
.pc_in(decode_pc),
|
||||
.rs1_value_in(decode_rs1_value),
|
||||
.rs2_value_in(decode_rs2_value),
|
||||
.imm_in(decode_imm),
|
||||
.imm_value_in(decode_imm_value),
|
||||
|
||||
/* data in (from writeback) */
|
||||
.writeback_rd_value_in(mem_rd_value),
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ module rv32_alu (
|
|||
input [31:0] pc_in,
|
||||
input [31:0] rs1_value_in,
|
||||
input [31:0] rs2_value_in,
|
||||
input [31:0] imm_in,
|
||||
input [31:0] imm_value_in,
|
||||
|
||||
/* data out */
|
||||
output logic [31:0] result_out
|
||||
|
|
@ -62,7 +62,7 @@ module rv32_alu (
|
|||
|
||||
case (src2_in)
|
||||
`RV32_ALU_SRC2_REG: src2 = rs2_value_in;
|
||||
`RV32_ALU_SRC2_IMM: src2 = imm_in;
|
||||
`RV32_ALU_SRC2_IMM: src2 = imm_value_in;
|
||||
`RV32_ALU_SRC2_FOUR: src2 = 4;
|
||||
default: src2 = 32'bx;
|
||||
endcase
|
||||
|
|
|
|||
|
|
@ -16,14 +16,14 @@ module rv32_branch_pc_mux (
|
|||
/* data in */
|
||||
input [31:0] pc_in,
|
||||
input [31:0] rs1_value_in,
|
||||
input [31:0] imm_in,
|
||||
input [31:0] imm_value_in,
|
||||
|
||||
/* data out */
|
||||
output logic [31:0] pc_out
|
||||
);
|
||||
logic [31:0] pc;
|
||||
|
||||
assign pc = (pc_src_in ? rs1_value_in : pc_in) + imm_in;
|
||||
assign pc = (pc_src_in ? rs1_value_in : pc_in) + imm_value_in;
|
||||
assign pc_out = {pc[31:1], 1'b0};
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
439
rv32_control.sv
Normal file
439
rv32_control.sv
Normal file
|
|
@ -0,0 +1,439 @@
|
|||
`ifndef RV32_CONTROL
|
||||
`define RV32_CONTROL
|
||||
|
||||
`include "rv32_alu.sv"
|
||||
`include "rv32_branch.sv"
|
||||
`include "rv32_imm.sv"
|
||||
`include "rv32_mem.sv"
|
||||
`include "rv32_opcodes.sv"
|
||||
|
||||
module rv32_control_unit (
|
||||
/* data in */
|
||||
input [31:0] instr_in,
|
||||
|
||||
/* control out */
|
||||
output logic valid_out,
|
||||
output logic [2:0] imm_out,
|
||||
output logic [2:0] alu_op_out,
|
||||
output logic alu_sub_sra_out,
|
||||
output logic [1:0] alu_src1_out,
|
||||
output logic [1:0] alu_src2_out,
|
||||
output logic mem_read_out,
|
||||
output logic mem_write_out,
|
||||
output logic [1:0] mem_width_out,
|
||||
output logic mem_zero_extend_out,
|
||||
output logic mem_fence_out,
|
||||
output logic [1:0] branch_op_out,
|
||||
output logic branch_pc_src_out,
|
||||
output logic rd_write_out
|
||||
);
|
||||
always_comb begin
|
||||
valid_out = 0;
|
||||
imm_out = 3'bx;
|
||||
alu_op_out = 3'bx;
|
||||
alu_sub_sra_out = 1'bx;
|
||||
alu_src1_out = 2'bx;
|
||||
alu_src2_out = 2'bx;
|
||||
mem_read_out = 0;
|
||||
mem_write_out = 0;
|
||||
mem_width_out = 2'bx;
|
||||
mem_zero_extend_out = 1'bx;
|
||||
mem_fence_out = 0;
|
||||
branch_op_out = `RV32_BRANCH_OP_NEVER;
|
||||
branch_pc_src_out = 1'bx;
|
||||
rd_write_out = 0;
|
||||
|
||||
casez (instr_in)
|
||||
`RV32_INSTR_LUI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_U;
|
||||
alu_op_out = `RV32_ALU_OP_ADD_SUB;
|
||||
alu_sub_sra_out = 0;
|
||||
alu_src1_out = `RV32_ALU_SRC1_ZERO;
|
||||
alu_src2_out = `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_AUIPC: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_U;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_JAL: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_J;
|
||||
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_FOUR;
|
||||
branch_op_out = `RV32_BRANCH_OP_ALWAYS;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_IMM;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_JALR: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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_FOUR;
|
||||
branch_op_out = `RV32_BRANCH_OP_ALWAYS;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_REG;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_BEQ: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_B;
|
||||
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;
|
||||
branch_op_out = `RV32_BRANCH_OP_ZERO;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_IMM;
|
||||
end
|
||||
`RV32_INSTR_BNE: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_B;
|
||||
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;
|
||||
branch_op_out = `RV32_BRANCH_OP_NON_ZERO;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_IMM;
|
||||
end
|
||||
`RV32_INSTR_BLT: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_B;
|
||||
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;
|
||||
branch_op_out = `RV32_BRANCH_OP_NON_ZERO;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_IMM;
|
||||
end
|
||||
`RV32_INSTR_BGE: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_B;
|
||||
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;
|
||||
branch_op_out = `RV32_BRANCH_OP_ZERO;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_IMM;
|
||||
end
|
||||
`RV32_INSTR_BLTU: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_B;
|
||||
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;
|
||||
branch_op_out = `RV32_BRANCH_OP_NON_ZERO;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_IMM;
|
||||
end
|
||||
`RV32_INSTR_BGEU: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_B;
|
||||
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;
|
||||
branch_op_out = `RV32_BRANCH_OP_ZERO;
|
||||
branch_pc_src_out = `RV32_BRANCH_PC_SRC_IMM;
|
||||
end
|
||||
`RV32_INSTR_LB: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
mem_read_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_BYTE;
|
||||
mem_zero_extend_out = 0;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_LH: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
mem_read_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_HALF;
|
||||
mem_zero_extend_out = 0;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_LW: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
mem_read_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_WORD;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_LBU: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
mem_read_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_BYTE;
|
||||
mem_zero_extend_out = 1;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_LHU: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
mem_read_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_HALF;
|
||||
mem_zero_extend_out = 1;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SB: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_S;
|
||||
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;
|
||||
mem_write_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_BYTE;
|
||||
end
|
||||
`RV32_INSTR_SH: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_S;
|
||||
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;
|
||||
mem_write_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_HALF;
|
||||
end
|
||||
`RV32_INSTR_SW: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_S;
|
||||
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;
|
||||
mem_write_out = 1;
|
||||
mem_width_out = `RV32_MEM_WIDTH_WORD;
|
||||
end
|
||||
`RV32_INSTR_ADDI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SLTI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SLTIU: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_XORI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
alu_op_out = `RV32_ALU_OP_XOR;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_ORI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
alu_op_out = `RV32_ALU_OP_OR;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_ANDI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_I;
|
||||
alu_op_out = `RV32_ALU_OP_AND;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SLLI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_SHAMT;
|
||||
alu_op_out = `RV32_ALU_OP_SLL;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SRLI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_SHAMT;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SRAI: begin
|
||||
valid_out = 1;
|
||||
imm_out = `RV32_IMM_SHAMT;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_ADD: begin
|
||||
valid_out = 1;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SUB: begin
|
||||
valid_out = 1;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SLL: begin
|
||||
valid_out = 1;
|
||||
alu_op_out = `RV32_ALU_OP_SLL;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_REG;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SLT: begin
|
||||
valid_out = 1;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SLTU: begin
|
||||
valid_out = 1;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_XOR: begin
|
||||
valid_out = 1;
|
||||
alu_op_out = `RV32_ALU_OP_XOR;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_REG;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SRL: begin
|
||||
valid_out = 1;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_SRA: begin
|
||||
valid_out = 1;
|
||||
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;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_OR: begin
|
||||
valid_out = 1;
|
||||
alu_op_out = `RV32_ALU_OP_OR;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_REG;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_AND: begin
|
||||
valid_out = 1;
|
||||
alu_op_out = `RV32_ALU_OP_AND;
|
||||
alu_src1_out = `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out = `RV32_ALU_SRC2_REG;
|
||||
rd_write_out = 1;
|
||||
end
|
||||
`RV32_INSTR_FENCE: begin
|
||||
valid_out = 1;
|
||||
end
|
||||
`RV32_INSTR_FENCE_I: begin
|
||||
valid_out = 1;
|
||||
mem_fence_out = 1;
|
||||
end
|
||||
`RV32_INSTR_ECALL: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_EBREAK: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_MRET: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_WFI: begin
|
||||
valid_out = 1;
|
||||
end
|
||||
`RV32_INSTR_CSRRW: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRS: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRC: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRWI: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRSI: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRCI: begin
|
||||
valid_out = 1;
|
||||
// TODO
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
509
rv32_decode.sv
509
rv32_decode.sv
|
|
@ -1,10 +1,7 @@
|
|||
`ifndef RV32_DECODE
|
||||
`define RV32_DECODE
|
||||
|
||||
`include "rv32_alu.sv"
|
||||
`include "rv32_branch.sv"
|
||||
`include "rv32_mem.sv"
|
||||
`include "rv32_opcodes.sv"
|
||||
`include "rv32_control.sv"
|
||||
`include "rv32_regs.sv"
|
||||
|
||||
module rv32_decode (
|
||||
|
|
@ -30,7 +27,6 @@ module rv32_decode (
|
|||
output logic [4:0] rs2_unreg_out,
|
||||
|
||||
/* control out */
|
||||
output logic valid_out,
|
||||
output logic [4:0] rs1_out,
|
||||
output logic [4:0] rs2_out,
|
||||
output logic [2:0] alu_op_out,
|
||||
|
|
@ -51,43 +47,15 @@ module rv32_decode (
|
|||
output logic [31:0] pc_out,
|
||||
output logic [31:0] rs1_value_out,
|
||||
output logic [31:0] rs2_value_out,
|
||||
output logic [31:0] imm_out
|
||||
output logic [31:0] imm_value_out
|
||||
);
|
||||
logic [6:0] funct7;
|
||||
logic [4:0] rs2;
|
||||
logic [4:0] rs1;
|
||||
logic [2:0] funct3;
|
||||
logic [4:0] rd;
|
||||
logic [6:0] opcode;
|
||||
|
||||
logic sign;
|
||||
|
||||
logic [31:0] imm_i;
|
||||
logic [31:0] imm_s;
|
||||
logic [31:0] imm_b;
|
||||
logic [31:0] imm_u;
|
||||
logic [31:0] imm_j;
|
||||
|
||||
logic [31:0] shamt;
|
||||
logic [31:0] zimm;
|
||||
|
||||
assign funct7 = instr_in[31:25];
|
||||
assign rs2 = instr_in[24:20];
|
||||
assign rs1 = instr_in[19:15];
|
||||
assign funct3 = instr_in[14:12];
|
||||
assign rd = instr_in[11:7];
|
||||
assign opcode = instr_in[6:0];
|
||||
|
||||
assign sign = instr_in[31];
|
||||
|
||||
assign imm_i = {{21{sign}}, instr_in[30:25], instr_in[24:21], instr_in[20]};
|
||||
assign imm_s = {{21{sign}}, instr_in[30:25], instr_in[11:8], instr_in[7]};
|
||||
assign imm_b = {{20{sign}}, instr_in[7], instr_in[30:25], instr_in[11:8], 1'b0};
|
||||
assign imm_u = {sign, instr_in[30:20], instr_in[19:12], 12'b0};
|
||||
assign imm_j = {{12{sign}}, instr_in[19:12], instr_in[20], instr_in[30:25], instr_in[24:21], 1'b0};
|
||||
|
||||
assign shamt = {27'bx, rs2};
|
||||
assign zimm = {27'b0, rs1};
|
||||
assign rs2 = instr_in[24:20];
|
||||
assign rs1 = instr_in[19:15];
|
||||
assign rd = instr_in[11:7];
|
||||
|
||||
assign rs1_unreg_out = rs1;
|
||||
assign rs2_unreg_out = rs2;
|
||||
|
|
@ -110,418 +78,75 @@ module rv32_decode (
|
|||
.rs2_value_out(rs2_value_out)
|
||||
);
|
||||
|
||||
logic valid;
|
||||
logic [2:0] imm;
|
||||
logic [2:0] alu_op;
|
||||
logic alu_sub_sra;
|
||||
logic [1:0] alu_src1;
|
||||
logic [1:0] alu_src2;
|
||||
logic mem_read;
|
||||
logic mem_write;
|
||||
logic [1:0] mem_width;
|
||||
logic mem_zero_extend;
|
||||
logic mem_fence;
|
||||
logic [1:0] branch_op;
|
||||
logic branch_pc_src;
|
||||
logic rd_write;
|
||||
|
||||
rv32_control_unit control_unit (
|
||||
/* data in */
|
||||
.instr_in(instr_in),
|
||||
|
||||
/* control out */
|
||||
.valid_out(valid),
|
||||
.imm_out(imm),
|
||||
.alu_op_out(alu_op),
|
||||
.alu_sub_sra_out(alu_sub_sra),
|
||||
.alu_src1_out(alu_src1),
|
||||
.alu_src2_out(alu_src2),
|
||||
.mem_read_out(mem_read),
|
||||
.mem_write_out(mem_write),
|
||||
.mem_width_out(mem_width),
|
||||
.mem_zero_extend_out(mem_zero_extend),
|
||||
.mem_fence_out(mem_fence),
|
||||
.branch_op_out(branch_op),
|
||||
.branch_pc_src_out(branch_pc_src),
|
||||
.rd_write_out(rd_write)
|
||||
);
|
||||
|
||||
logic [31:0] imm_value;
|
||||
|
||||
rv32_imm_mux imm_mux (
|
||||
/* control in */
|
||||
.imm_in(imm),
|
||||
|
||||
/* data in */
|
||||
.instr_in(instr_in),
|
||||
|
||||
/* data out */
|
||||
.imm_value_out(imm_value)
|
||||
);
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if (!stall_in) begin
|
||||
valid_out <= 0;
|
||||
rs1_out <= rs1;
|
||||
rs2_out <= rs2;
|
||||
alu_op_out <= 3'bx;
|
||||
alu_sub_sra_out <= 1'bx;
|
||||
alu_src1_out <= 2'bx;
|
||||
alu_src2_out <= 2'bx;
|
||||
mem_read_out <= 0;
|
||||
mem_write_out <= 0;
|
||||
mem_width_out <= 2'bx;
|
||||
mem_zero_extend_out <= 1'bx;
|
||||
mem_fence_out <= 0;
|
||||
branch_op_out <= `RV32_BRANCH_OP_NEVER;
|
||||
branch_pc_src_out <= 1'bx;
|
||||
alu_op_out <= alu_op;
|
||||
alu_sub_sra_out <= alu_sub_sra;
|
||||
alu_src1_out <= alu_src1;
|
||||
alu_src2_out <= alu_src2;
|
||||
mem_read_out <= mem_read;
|
||||
mem_write_out <= mem_write;
|
||||
mem_width_out <= mem_width;
|
||||
mem_zero_extend_out <= mem_zero_extend;
|
||||
mem_fence_out <= mem_fence;
|
||||
branch_op_out <= branch_op;
|
||||
branch_pc_src_out <= branch_pc_src;
|
||||
rd_out <= rd;
|
||||
rd_write_out <= 0;
|
||||
rd_write_out <= rd_write;
|
||||
|
||||
pc_out <= pc_in;
|
||||
imm_out <= 32'bx;
|
||||
|
||||
casez (instr_in)
|
||||
`RV32_INSTR_LUI: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_ADD_SUB;
|
||||
alu_sub_sra_out <= 0;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_ZERO;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_u;
|
||||
end
|
||||
`RV32_INSTR_AUIPC: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_u;
|
||||
end
|
||||
`RV32_INSTR_JAL: begin
|
||||
valid_out <= 1;
|
||||
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_FOUR;
|
||||
branch_op_out <= `RV32_BRANCH_OP_ALWAYS;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_IMM;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_j;
|
||||
end
|
||||
`RV32_INSTR_JALR: begin
|
||||
valid_out <= 1;
|
||||
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_FOUR;
|
||||
branch_op_out <= `RV32_BRANCH_OP_ALWAYS;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_REG;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_BEQ: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
branch_op_out <= `RV32_BRANCH_OP_ZERO;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_IMM;
|
||||
imm_out <= imm_b;
|
||||
end
|
||||
`RV32_INSTR_BNE: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
branch_op_out <= `RV32_BRANCH_OP_NON_ZERO;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_IMM;
|
||||
imm_out <= imm_b;
|
||||
end
|
||||
`RV32_INSTR_BLT: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
branch_op_out <= `RV32_BRANCH_OP_NON_ZERO;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_IMM;
|
||||
imm_out <= imm_b;
|
||||
end
|
||||
`RV32_INSTR_BGE: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
branch_op_out <= `RV32_BRANCH_OP_ZERO;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_IMM;
|
||||
imm_out <= imm_b;
|
||||
end
|
||||
`RV32_INSTR_BLTU: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
branch_op_out <= `RV32_BRANCH_OP_NON_ZERO;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_IMM;
|
||||
imm_out <= imm_b;
|
||||
end
|
||||
`RV32_INSTR_BGEU: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
branch_op_out <= `RV32_BRANCH_OP_ZERO;
|
||||
branch_pc_src_out <= `RV32_BRANCH_PC_SRC_IMM;
|
||||
imm_out <= imm_b;
|
||||
end
|
||||
`RV32_INSTR_LB: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_read_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_BYTE;
|
||||
mem_zero_extend_out <= 0;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_LH: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_read_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_HALF;
|
||||
mem_zero_extend_out <= 0;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_LW: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_read_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_WORD;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_LBU: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_read_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_BYTE;
|
||||
mem_zero_extend_out <= 1;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_LHU: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_read_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_HALF;
|
||||
mem_zero_extend_out <= 1;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_SB: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_write_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_BYTE;
|
||||
imm_out <= imm_s;
|
||||
end
|
||||
`RV32_INSTR_SH: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_write_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_HALF;
|
||||
imm_out <= imm_s;
|
||||
end
|
||||
`RV32_INSTR_SW: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
mem_write_out <= 1;
|
||||
mem_width_out <= `RV32_MEM_WIDTH_WORD;
|
||||
imm_out <= imm_s;
|
||||
end
|
||||
`RV32_INSTR_ADDI: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_SLTI: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_SLTIU: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_XORI: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_XOR;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_ORI: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_OR;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_ANDI: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_AND;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= imm_i;
|
||||
end
|
||||
`RV32_INSTR_SLLI: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_SLL;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_IMM;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= shamt;
|
||||
end
|
||||
`RV32_INSTR_SRLI: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= shamt;
|
||||
end
|
||||
`RV32_INSTR_SRAI: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
imm_out <= shamt;
|
||||
end
|
||||
`RV32_INSTR_ADD: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_SUB: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_SLL: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_SLL;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_REG;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_SLT: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_SLTU: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_XOR: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_XOR;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_REG;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_SRL: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_SRA: begin
|
||||
valid_out <= 1;
|
||||
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;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_OR: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_OR;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_REG;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_AND: begin
|
||||
valid_out <= 1;
|
||||
alu_op_out <= `RV32_ALU_OP_AND;
|
||||
alu_src1_out <= `RV32_ALU_SRC1_REG;
|
||||
alu_src2_out <= `RV32_ALU_SRC2_REG;
|
||||
rd_write_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_FENCE: begin
|
||||
valid_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_FENCE_I: begin
|
||||
valid_out <= 1;
|
||||
mem_fence_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_ECALL: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_EBREAK: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_MRET: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_WFI: begin
|
||||
valid_out <= 1;
|
||||
end
|
||||
`RV32_INSTR_CSRRW: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRS: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRC: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRWI: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRSI: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
`RV32_INSTR_CSRRCI: begin
|
||||
valid_out <= 1;
|
||||
// TODO
|
||||
end
|
||||
endcase
|
||||
imm_value_out <= imm_value;
|
||||
|
||||
if (flush_in) begin
|
||||
mem_read_out <= 0;
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ module rv32_execute (
|
|||
input [31:0] pc_in,
|
||||
input [31:0] rs1_value_in,
|
||||
input [31:0] rs2_value_in,
|
||||
input [31:0] imm_in,
|
||||
input [31:0] imm_value_in,
|
||||
|
||||
/* data in (from writeback) */
|
||||
input [31:0] writeback_rd_value_in,
|
||||
|
|
@ -88,7 +88,7 @@ module rv32_execute (
|
|||
.pc_in(pc_in),
|
||||
.rs1_value_in(rs1_value),
|
||||
.rs2_value_in(rs2_value),
|
||||
.imm_in(imm_in),
|
||||
.imm_value_in(imm_value_in),
|
||||
|
||||
/* data out */
|
||||
.result_out(result)
|
||||
|
|
@ -103,7 +103,7 @@ module rv32_execute (
|
|||
/* data in */
|
||||
.pc_in(pc_in),
|
||||
.rs1_value_in(rs1_value),
|
||||
.imm_in(imm_in),
|
||||
.imm_value_in(imm_value_in),
|
||||
|
||||
/* data out */
|
||||
.pc_out(branch_pc)
|
||||
|
|
|
|||
58
rv32_imm.sv
Normal file
58
rv32_imm.sv
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
`ifndef RV32_IMM
|
||||
`define RV32_IMM
|
||||
|
||||
`define RV32_IMM_I 3'b000
|
||||
`define RV32_IMM_S 3'b001
|
||||
`define RV32_IMM_B 3'b010
|
||||
`define RV32_IMM_U 3'b011
|
||||
`define RV32_IMM_J 3'b100
|
||||
`define RV32_IMM_SHAMT 3'b101
|
||||
`define RV32_IMM_ZIMM 3'b110
|
||||
|
||||
module rv32_imm_mux (
|
||||
/* control in */
|
||||
input [2:0] imm_in,
|
||||
|
||||
/* data in */
|
||||
input [31:0] instr_in,
|
||||
|
||||
/* data out */
|
||||
output logic [31:0] imm_value_out
|
||||
);
|
||||
logic sign;
|
||||
|
||||
logic [31:0] imm_i;
|
||||
logic [31:0] imm_s;
|
||||
logic [31:0] imm_b;
|
||||
logic [31:0] imm_u;
|
||||
logic [31:0] imm_j;
|
||||
|
||||
logic [31:0] shamt;
|
||||
logic [31:0] zimm;
|
||||
|
||||
assign sign = instr_in[31];
|
||||
|
||||
assign imm_i = {{21{sign}}, instr_in[30:25], instr_in[24:21], instr_in[20]};
|
||||
assign imm_s = {{21{sign}}, instr_in[30:25], instr_in[11:8], instr_in[7]};
|
||||
assign imm_b = {{20{sign}}, instr_in[7], instr_in[30:25], instr_in[11:8], 1'b0};
|
||||
assign imm_u = {sign, instr_in[30:20], instr_in[19:12], 12'b0};
|
||||
assign imm_j = {{12{sign}}, instr_in[19:12], instr_in[20], instr_in[30:25], instr_in[24:21], 1'b0};
|
||||
|
||||
assign shamt = {27'bx, instr_in[24:20]};
|
||||
assign zimm = {27'b0, instr_in[19:15]};
|
||||
|
||||
always_comb begin
|
||||
case (imm_in)
|
||||
`RV32_IMM_I: imm_value_out = imm_i;
|
||||
`RV32_IMM_S: imm_value_out = imm_s;
|
||||
`RV32_IMM_B: imm_value_out = imm_b;
|
||||
`RV32_IMM_U: imm_value_out = imm_u;
|
||||
`RV32_IMM_J: imm_value_out = imm_j;
|
||||
`RV32_IMM_SHAMT: imm_value_out = shamt;
|
||||
`RV32_IMM_ZIMM: imm_value_out = zimm;
|
||||
default: imm_value_out = 32'bx;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
Loading…
Reference in a new issue