Add ALU
This commit is contained in:
parent
e7389a3065
commit
30b793cbaf
4 changed files with 167 additions and 1 deletions
50
rv32.sv
50
rv32.sv
|
|
@ -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
67
rv32_alu.sv
Normal 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
|
||||
|
|
@ -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
39
rv32_execute.sv
Normal 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
|
||||
Loading…
Reference in a new issue