Add writeback stage

This commit is contained in:
Graham Edgecombe 2017-12-02 11:26:12 +00:00
parent 062462eeb3
commit 4c68818134
5 changed files with 150 additions and 1 deletions

65
rv32.sv
View file

@ -5,6 +5,7 @@
`include "rv32_execute.sv"
`include "rv32_fetch.sv"
`include "rv32_mem.sv"
`include "rv32_writeback.sv"
module rv32 (
input clk
@ -24,9 +25,14 @@ module rv32 (
rv32_decode decode (
.clk(clk),
/* control in */
.rd_in(writeback_rd),
.rd_writeback_in(writeback_rd_writeback),
/* data in */
.pc_in(fetch_pc),
.instr_in(fetch_instr),
.rd_value_in(writeback_rd_value),
/* control out */
.alu_op_out(decode_alu_op),
@ -35,6 +41,8 @@ module rv32 (
.alu_src2_out(decode_alu_src2),
.mem_read_en_out(decode_mem_read_en),
.mem_write_en_out(decode_mem_write_en),
.rd_out(decode_rd),
.rd_writeback_out(decode_rd_writeback),
/* data out */
.pc_out(decode_pc),
@ -50,6 +58,8 @@ module rv32 (
logic decode_alu_src2;
logic decode_mem_read_en;
logic decode_mem_write_en;
logic [4:0] decode_rd;
logic decode_rd_writeback;
/* decode -> execute data */
logic [31:0] decode_pc;
@ -67,6 +77,8 @@ module rv32 (
.alu_src2_in(decode_alu_src2),
.mem_read_en_in(decode_mem_read_en),
.mem_write_en_in(decode_mem_write_en),
.rd_in(decode_rd),
.rd_writeback_in(decode_rd_writeback),
/* data in */
.pc_in(decode_pc),
@ -77,6 +89,8 @@ module rv32 (
/* control out */
.mem_read_en_out(execute_mem_read_en),
.mem_write_en_out(execute_mem_write_en),
.rd_out(execute_rd),
.rd_writeback_out(execute_rd_writeback),
/* data out */
.result_out(execute_result),
@ -86,6 +100,8 @@ module rv32 (
/* execute -> mem control */
logic execute_mem_read_en;
logic execute_mem_write_en;
logic [4:0] execute_rd;
logic execute_rd_writeback;
/* execute -> mem data */
logic [31:0] execute_result;
@ -97,11 +113,58 @@ module rv32 (
/* control in */
.read_en_in(execute_mem_read_en),
.write_en_in(execute_mem_write_en),
.rd_in(execute_rd),
.rd_writeback_in(execute_rd_writeback),
/* data in */
.result_in(execute_result),
.rs2_value_in(execute_rs2_value)
.rs2_value_in(execute_rs2_value),
/* control out */
.read_en_out(mem_read_en),
.rd_out(mem_rd),
.rd_writeback_out(mem_rd_writeback),
/* data out */
.result_out(mem_result),
.read_value_out(mem_read_value)
);
/* mem -> writeback control */
logic mem_read_en;
logic [4:0] mem_rd;
logic mem_rd_writeback;
/* mem -> writeback data */
logic [31:0] mem_result;
logic [31:0] mem_read_value;
rv32_writeback writeback (
.clk(clk),
/* control in */
.mem_read_en_in(mem_read_en),
.rd_in(mem_rd),
.rd_writeback_in(mem_rd_writeback),
/* data in */
.result_in(mem_result),
.mem_read_value_in(mem_read_value),
/* control out */
.rd_out(writeback_rd),
.rd_writeback_out(writeback_rd_writeback),
/* data out */
.rd_value_out(writeback_rd_value)
);
/* writeback -> decode control */
logic [4:0] writeback_rd;
logic writeback_rd_writeback;
/* writeback -> decode data */
logic [31:0] writeback_rd_value;
endmodule
`endif

View file

@ -8,9 +8,14 @@
module rv32_decode (
input clk,
/* control in */
input [4:0] rd_in,
input rd_writeback_in,
/* data in */
input [31:0] pc_in,
input [31:0] instr_in,
input [31:0] rd_value_in,
/* control out */
output valid_out,
@ -20,6 +25,8 @@ module rv32_decode (
output alu_src2_out,
output mem_read_en_out,
output mem_write_en_out,
output [4:0] rd_out,
output rd_writeback_out,
/* data out */
output [31:0] pc_out,
@ -50,6 +57,11 @@ module rv32_decode (
/* control in */
.rs1_in(rs1),
.rs2_in(rs2),
.rd_in(rd_in),
.rd_writeback_in(rd_writeback_in),
/* data in */
.rd_value_in(rd_value_in),
/* data out */
.rs1_value_out(rs1_value_out),
@ -57,6 +69,7 @@ module rv32_decode (
);
always_ff @(posedge clk) begin
rd_out <= rd;
pc_out <= pc_in;
valid_out <= 0;
@ -64,6 +77,7 @@ module rv32_decode (
alu_sub_sra_out <= 1'bx;
alu_src1_out <= 1'bx;
alu_src2_out <= 1'bx;
rd_writeback_out <= 0;
mem_read_en_out <= 0;
mem_write_en_out <= 0;
imm_out <= 32'bx;
@ -74,6 +88,7 @@ module rv32_decode (
valid_out <= 1;
alu_op_out <= RV32_ALU_OP_SRC2;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_u;
end
{RV32_OPCODE_AUIPC, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin
@ -83,6 +98,7 @@ module rv32_decode (
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_PC;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_u;
end
{RV32_OPCODE_JAL, RV32_FUNCT3_ANY, RV32_FUNCT7_ANY}: begin
@ -90,6 +106,7 @@ module rv32_decode (
valid_out <= 1;
alu_op_out <= RV32_ALU_OP_SRC1P4;
alu_src1_out <= RV32_ALU_SRC1_PC;
rd_writeback_out <= 1;
imm_out <= imm_j;
end
{RV32_OPCODE_JALR, RV32_FUNCT3_ZERO, RV32_FUNCT7_ANY}: begin
@ -97,6 +114,7 @@ module rv32_decode (
valid_out <= 1;
alu_op_out <= RV32_ALU_OP_SRC1P4;
alu_src1_out <= RV32_ALU_SRC1_PC;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_BRANCH, RV32_FUNCT3_BRANCH_BEQ, RV32_FUNCT7_ANY}: begin
@ -161,6 +179,7 @@ module rv32_decode (
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
mem_read_en_out <= 1;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LH, RV32_FUNCT7_ANY}: begin
@ -171,6 +190,7 @@ module rv32_decode (
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
mem_read_en_out <= 1;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LW, RV32_FUNCT7_ANY}: begin
@ -181,6 +201,7 @@ module rv32_decode (
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
mem_read_en_out <= 1;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LBU, RV32_FUNCT7_ANY}: begin
@ -191,6 +212,7 @@ module rv32_decode (
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
mem_read_en_out <= 1;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LHU, RV32_FUNCT7_ANY}: begin
@ -201,6 +223,7 @@ module rv32_decode (
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
mem_read_en_out <= 1;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SB, RV32_FUNCT7_ANY}: begin
@ -240,6 +263,7 @@ module rv32_decode (
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLT, RV32_FUNCT7_ANY}: begin
@ -249,6 +273,7 @@ module rv32_decode (
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLTU, RV32_FUNCT7_ANY}: begin
@ -258,6 +283,7 @@ module rv32_decode (
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_XOR, RV32_FUNCT7_ANY}: begin
@ -266,6 +292,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_XOR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_OR, RV32_FUNCT7_ANY}: begin
@ -274,6 +301,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_OR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_AND, RV32_FUNCT7_ANY}: begin
@ -282,6 +310,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_AND;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= imm_i;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SLL, RV32_FUNCT7_ZERO}: begin
@ -290,6 +319,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_SLL;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= shamt;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_ZERO}: begin
@ -299,6 +329,7 @@ module rv32_decode (
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= shamt;
end
{RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_OP_SRA}: begin
@ -308,6 +339,7 @@ module rv32_decode (
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_IMM;
rd_writeback_out <= 1;
imm_out <= shamt;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_ZERO}: begin
@ -317,6 +349,7 @@ module rv32_decode (
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_OP_SUB}: begin
/* SUB */
@ -325,6 +358,7 @@ module rv32_decode (
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SLL, RV32_FUNCT7_ZERO}: begin
/* SLL */
@ -332,6 +366,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_SLL;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SLT, RV32_FUNCT7_ZERO}: begin
/* SLT */
@ -340,6 +375,7 @@ module rv32_decode (
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SLTU, RV32_FUNCT7_ZERO}: begin
/* SLTU */
@ -348,6 +384,7 @@ module rv32_decode (
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_XOR, RV32_FUNCT7_ZERO}: begin
/* XOR */
@ -355,6 +392,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_XOR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_ZERO}: begin
/* SRL */
@ -363,6 +401,7 @@ module rv32_decode (
alu_sub_sra_out <= 0;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_SRL_SRA, RV32_FUNCT7_OP_SRA}: begin
/* SRA */
@ -371,6 +410,7 @@ module rv32_decode (
alu_sub_sra_out <= 1;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_OR, RV32_FUNCT7_ZERO}: begin
/* OR */
@ -378,6 +418,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_OR;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
{RV32_OPCODE_OP, RV32_FUNCT3_OP_AND, RV32_FUNCT7_ZERO}: begin
/* AND */
@ -385,6 +426,7 @@ module rv32_decode (
alu_op_out <= RV32_ALU_OP_AND;
alu_src1_out <= RV32_ALU_SRC1_REG;
alu_src2_out <= RV32_ALU_SRC2_REG;
rd_writeback_out <= 1;
end
endcase
end

View file

@ -13,6 +13,8 @@ module rv32_execute (
input alu_src2_in,
input mem_read_en_in,
input mem_write_en_in,
input [4:0] rd_in,
input rd_writeback_in,
/* data in */
input [31:0] pc_in,
@ -23,6 +25,8 @@ module rv32_execute (
/* control out */
output mem_read_en_out,
output mem_write_en_out,
output [4:0] rd_out,
output rd_writeback_out,
/* data out */
output [31:0] result_out,
@ -50,6 +54,8 @@ module rv32_execute (
always @(posedge clk) begin
mem_read_en_out <= mem_read_en_in;
mem_write_en_out <= mem_write_en_in;
rd_out <= rd_in;
rd_writeback_out <= rd_writeback_in;
rs2_value_out <= rs2_value_in;
end
endmodule

View file

@ -7,11 +7,18 @@ module rv32_mem (
/* control in */
input read_en_in,
input write_en_in,
input [4:0] rd_in,
input rd_writeback_in,
/* data in */
input [31:0] result_in,
input [31:0] rs2_value_in,
/* control out */
output read_en_out,
output [4:0] rd_out,
output rd_writeback_out,
/* data out */
output [31:0] result_out,
output [31:0] read_value_out
@ -19,6 +26,9 @@ module rv32_mem (
logic [31:0] data_mem [255:0];
always @(posedge clk) begin
read_en_out <= read_en_in;
rd_out <= rd_in;
rd_writeback_out <= rd_writeback_in;
result_out <= result_in;
if (read_en_in)

28
rv32_writeback.sv Normal file
View file

@ -0,0 +1,28 @@
`ifndef RV32_WRITEBACK
`define RV32_WRITEBACK
module rv32_writeback (
input clk,
/* control in */
input mem_read_en_in,
input [4:0] rd_in,
input rd_writeback_in,
/* data in */
input [31:0] result_in,
input [31:0] mem_read_value_in,
/* control out */
output [4:0] rd_out,
output rd_writeback_out,
/* data out */
output [31:0] rd_value_out
);
assign rd_out = rd_in;
assign rd_writeback_out = rd_writeback_in;
assign rd_value_out = mem_read_en_in ? mem_read_value_in : result_in;
endmodule
`endif