diff --git a/rv32.sv b/rv32.sv index fcce4b4..e31023b 100644 --- a/rv32.sv +++ b/rv32.sv @@ -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 diff --git a/rv32_decode.sv b/rv32_decode.sv index 1cb12b2..35a860f 100644 --- a/rv32_decode.sv +++ b/rv32_decode.sv @@ -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 diff --git a/rv32_execute.sv b/rv32_execute.sv index 5e29b67..cfa9170 100644 --- a/rv32_execute.sv +++ b/rv32_execute.sv @@ -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 diff --git a/rv32_mem.sv b/rv32_mem.sv index 17f6da7..fcc9cc8 100644 --- a/rv32_mem.sv +++ b/rv32_mem.sv @@ -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) diff --git a/rv32_writeback.sv b/rv32_writeback.sv new file mode 100644 index 0000000..f62dcd1 --- /dev/null +++ b/rv32_writeback.sv @@ -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