diff --git a/rv32.sv b/rv32.sv index 214d6c9..fcce4b4 100644 --- a/rv32.sv +++ b/rv32.sv @@ -4,6 +4,7 @@ `include "rv32_decode.sv" `include "rv32_execute.sv" `include "rv32_fetch.sv" +`include "rv32_mem.sv" module rv32 ( input clk @@ -32,6 +33,8 @@ module rv32 ( .alu_sub_sra_out(decode_alu_sub_sra), .alu_src1_out(decode_alu_src1), .alu_src2_out(decode_alu_src2), + .mem_read_en_out(decode_mem_read_en), + .mem_write_en_out(decode_mem_write_en), /* data out */ .pc_out(decode_pc), @@ -45,6 +48,8 @@ module rv32 ( logic decode_alu_sub_sra; logic decode_alu_src1; logic decode_alu_src2; + logic decode_mem_read_en; + logic decode_mem_write_en; /* decode -> execute data */ logic [31:0] decode_pc; @@ -60,6 +65,8 @@ module rv32 ( .alu_sub_sra_in(decode_alu_sub_sra), .alu_src1_in(decode_alu_src1), .alu_src2_in(decode_alu_src2), + .mem_read_en_in(decode_mem_read_en), + .mem_write_en_in(decode_mem_write_en), /* data in */ .pc_in(decode_pc), @@ -67,12 +74,34 @@ module rv32 ( .rs2_value_in(decode_rs2_value), .imm_in(decode_imm), + /* control out */ + .mem_read_en_out(execute_mem_read_en), + .mem_write_en_out(execute_mem_write_en), + /* data out */ - .result_out(execute_result) + .result_out(execute_result), + .rs2_value_out(execute_rs2_value) ); + /* execute -> mem control */ + logic execute_mem_read_en; + logic execute_mem_write_en; + /* execute -> mem data */ logic [31:0] execute_result; + logic [31:0] execute_rs2_value; + + rv32_mem mem ( + .clk(clk), + + /* control in */ + .read_en_in(execute_mem_read_en), + .write_en_in(execute_mem_write_en), + + /* data in */ + .result_in(execute_result), + .rs2_value_in(execute_rs2_value) + ); endmodule `endif diff --git a/rv32_decode.sv b/rv32_decode.sv index b81b24e..f4abcd5 100644 --- a/rv32_decode.sv +++ b/rv32_decode.sv @@ -18,6 +18,8 @@ module rv32_decode ( output alu_sub_sra_out, output alu_src1_out, output alu_src2_out, + output mem_read_en_out, + output mem_write_en_out, /* data out */ output [31:0] pc_out, @@ -62,6 +64,8 @@ module rv32_decode ( alu_sub_sra_out <= 1'bx; alu_src1_out <= 1'bx; alu_src2_out <= 1'bx; + mem_read_en_out <= 0; + mem_write_en_out <= 0; imm_out <= 32'bx; casez ({opcode, funct3, funct7}) @@ -156,6 +160,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_read_en_out <= 1; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LH, RV32_FUNCT7_ANY}: begin @@ -165,6 +170,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_read_en_out <= 1; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LW, RV32_FUNCT7_ANY}: begin @@ -174,6 +180,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_read_en_out <= 1; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LBU, RV32_FUNCT7_ANY}: begin @@ -183,6 +190,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_read_en_out <= 1; imm_out <= imm_i; end {RV32_OPCODE_LOAD, RV32_FUNCT3_LOAD_LHU, RV32_FUNCT7_ANY}: begin @@ -192,6 +200,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_read_en_out <= 1; imm_out <= imm_i; end {RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SB, RV32_FUNCT7_ANY}: begin @@ -201,6 +210,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_write_en_out <= 1; imm_out <= imm_s; end {RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SH, RV32_FUNCT7_ANY}: begin @@ -210,6 +220,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_write_en_out <= 1; imm_out <= imm_s; end {RV32_OPCODE_STORE, RV32_FUNCT3_STORE_SW, RV32_FUNCT7_ANY}: begin @@ -219,6 +230,7 @@ module rv32_decode ( alu_sub_sra_out <= 0; alu_src1_out <= RV32_ALU_SRC1_REG; alu_src2_out <= RV32_ALU_SRC2_IMM; + mem_write_en_out <= 1; imm_out <= imm_s; end {RV32_OPCODE_OP_IMM, RV32_FUNCT3_OP_ADD_SUB, RV32_FUNCT7_ANY}: begin diff --git a/rv32_execute.sv b/rv32_execute.sv index a2cbc4c..5e29b67 100644 --- a/rv32_execute.sv +++ b/rv32_execute.sv @@ -11,6 +11,8 @@ module rv32_execute ( input alu_sub_sra_in, input alu_src1_in, input alu_src2_in, + input mem_read_en_in, + input mem_write_en_in, /* data in */ input [31:0] pc_in, @@ -18,8 +20,13 @@ module rv32_execute ( input [31:0] rs2_value_in, input [31:0] imm_in, + /* control out */ + output mem_read_en_out, + output mem_write_en_out, + /* data out */ - output [31:0] result_out + output [31:0] result_out, + output [31:0] rs2_value_out ); rv32_alu alu ( .clk(clk), @@ -39,6 +46,12 @@ module rv32_execute ( /* data out */ .result_out(result_out) ); + + always @(posedge clk) begin + mem_read_en_out <= mem_read_en_in; + mem_write_en_out <= mem_write_en_in; + rs2_value_out <= rs2_value_in; + end endmodule `endif diff --git a/rv32_mem.sv b/rv32_mem.sv new file mode 100644 index 0000000..17f6da7 --- /dev/null +++ b/rv32_mem.sv @@ -0,0 +1,32 @@ +`ifndef RV32_MEM +`define RV32_MEM + +module rv32_mem ( + input clk, + + /* control in */ + input read_en_in, + input write_en_in, + + /* data in */ + input [31:0] result_in, + input [31:0] rs2_value_in, + + /* data out */ + output [31:0] result_out, + output [31:0] read_value_out +); + logic [31:0] data_mem [255:0]; + + always @(posedge clk) begin + result_out <= result_in; + + if (read_en_in) + read_value_out <= data_mem[result_in[31:2]]; + + if (write_en_in) + data_mem[result_in[31:2]] <= rs2_value_in; + end +endmodule + +`endif