This commit is contained in:
Graham Edgecombe 2017-12-01 22:36:26 +00:00
parent e7389a3065
commit 30b793cbaf
4 changed files with 167 additions and 1 deletions

50
rv32.sv
View file

@ -1,4 +1,5 @@
`include "rv32_decode.sv"
`include "rv32_execute.sv"
`include "rv32_fetch.sv"
module rv32 (
@ -12,6 +13,7 @@ module rv32 (
.instr_out(fetch_instr)
);
/* fetch -> decode data */
logic [31:0] fetch_pc;
logic [31:0] fetch_instr;
@ -20,6 +22,52 @@ module rv32 (
/* data in */
.pc_in(fetch_pc),
.instr_in(fetch_instr)
.instr_in(fetch_instr),
/* control out */
.alu_op_out(decode_alu_op),
.alu_sub_sra_out(decode_alu_sub_sra),
.alu_src1_out(decode_alu_src1),
.alu_src2_out(decode_alu_src2),
/* data out */
.pc_out(decode_pc),
.rs1_value_out(decode_rs1_value),
.rs2_value_out(decode_rs2_value),
.imm_out(decode_imm)
);
/* decode -> execute control */
logic [3:0] decode_alu_op;
logic decode_alu_sub_sra;
logic decode_alu_src1;
logic decode_alu_src2;
/* decode -> execute data */
logic [31:0] decode_pc;
logic [31:0] decode_rs1_value;
logic [31:0] decode_rs2_value;
logic [31:0] decode_imm;
rv32_execute execute (
.clk(clk),
/* control in */
.alu_op_in(decode_alu_op),
.alu_sub_sra_in(decode_alu_sub_sra),
.alu_src1_in(decode_alu_src1),
.alu_src2_in(decode_alu_src2),
/* data in */
.pc_in(decode_pc),
.rs1_value_in(decode_rs1_value),
.rs2_value_in(decode_rs2_value),
.imm_in(decode_imm),
/* data out */
.result_out(execute_result)
);
/* execute -> mem data */
logic [31:0] execute_result;
endmodule

67
rv32_alu.sv Normal file
View file

@ -0,0 +1,67 @@
localparam RV32_ALU_OP_ADD_SUB = 4'b0000;
localparam RV32_ALU_OP_XOR = 4'b0001;
localparam RV32_ALU_OP_OR = 4'b0010;
localparam RV32_ALU_OP_AND = 4'b0011;
localparam RV32_ALU_OP_SLL = 4'b0100;
localparam RV32_ALU_OP_SRL_SRA = 4'b0101;
localparam RV32_ALU_OP_SLT = 4'b0110;
localparam RV32_ALU_OP_SLTU = 4'b0111;
localparam RV32_ALU_OP_SRC2 = 4'b1000;
localparam RV32_ALU_SRC1_REG = 1'b0;
localparam RV32_ALU_SRC1_PC = 1'b1;
localparam RV32_ALU_SRC2_REG = 1'b0;
localparam RV32_ALU_SRC2_IMM = 1'b1;
module rv32_alu (
input clk,
/* control in */
input [3:0] op_in,
input sub_sra_in,
input src1_in,
input src2_in,
/* data in */
input [31:0] pc_in,
input [31:0] rs1_value_in,
input [31:0] rs2_value_in,
input [31:0] imm_in,
/* data out */
output [31:0] result_out
);
logic [31:0] src1 = src1_in ? rs1_value_in : pc_in;
logic [31:0] src2 = src2_in ? rs2_value_in : imm_in;
logic src1_sign = src1[31];
logic src2_sign = src2[31];
logic shamt = src2[4:0];
logic [32:0] add_sub = sub_sra_in ? src1 - src2 : src1 + src2;
logic [31:0] srl_sra = $signed({sub_sra_in ? src1_sign : 1'b0, src1}) >>> shamt;
logic carry = add_sub[32];
logic sign = add_sub[31];
logic ovf = (!src1_sign && src2_sign && sign) || (src1_sign && !src2_sign && !sign);
logic lt = sign != ovf;
logic ltu = carry;
always @(posedge clk) begin
case (op_in)
RV32_ALU_OP_ADD_SUB: result_out <= add_sub[31:0];
RV32_ALU_OP_XOR: result_out <= src1 ^ src2;
RV32_ALU_OP_OR: result_out <= src1 | src2;
RV32_ALU_OP_AND: result_out <= src1 & src2;
RV32_ALU_OP_SLL: result_out <= src1 << shamt;
RV32_ALU_OP_SRL_SRA: result_out <= srl_sra;
RV32_ALU_OP_SLT: result_out <= {31'b0, lt};
RV32_ALU_OP_SLTU: result_out <= {31'b0, ltu};
RV32_ALU_OP_SRC2: result_out <= src2;
default: result_out <= 32'bx;
endcase
end
endmodule

View file

@ -10,6 +10,10 @@ module rv32_decode (
/* control out */
output valid,
output [3:0] alu_op_out,
output alu_sub_sra_out,
output alu_src1_out,
output alu_src2_out,
/* data out */
output [31:0] pc_out,
@ -36,8 +40,12 @@ module rv32_decode (
rv32_regs regs (
.clk(clk),
/* control in */
.rs1_in(rs1),
.rs2_in(rs2),
/* data out */
.rs1_value_out(rs1_value_out),
.rs2_value_out(rs2_value_out)
);
@ -46,6 +54,10 @@ module rv32_decode (
pc_out <= pc_in;
valid <= 0;
alu_op_out <= 4'bx;
alu_sub_sra_out <= 1'bx;
alu_src1_out <= 1'bx;
alu_src2_out <= 1'bx;
imm_out <= 32'bx;
casez ({opcode, funct3, funct7})

39
rv32_execute.sv Normal file
View file

@ -0,0 +1,39 @@
`include "rv32_alu.sv"
module rv32_execute (
input clk,
/* control in */
input [3:0] alu_op_in,
input alu_sub_sra_in,
input alu_src1_in,
input alu_src2_in,
/* data in */
input [31:0] pc_in,
input [31:0] rs1_value_in,
input [31:0] rs2_value_in,
input [31:0] imm_in,
/* data out */
output [31:0] result_out
);
rv32_alu alu (
.clk(clk),
/* control in */
.op_in(alu_op_in),
.sub_sra_in(alu_sub_sra_in),
.src1_in(alu_src1_in),
.src2_in(alu_src2_in),
/* data in */
.pc_in(pc_in),
.rs1_value_in(rs1_value_in),
.rs2_value_in(rs2_value_in),
.imm_in(imm_in),
/* data out */
.result_out(result_out)
);
endmodule