diff --git a/rtl/decoder.v b/rtl/decoder.v index b3b1667..be5bd3e 100644 --- a/rtl/decoder.v +++ b/rtl/decoder.v @@ -6,11 +6,14 @@ module decoder (input [31:0] instruction, output reg alu_src, output reg [3:0] alu_func, output reg mem_we, + output reg [1:0] mem_func_in, + output reg [2:0] mem_func_out, output reg [1:0] pc_is_branch, output reg pc_is_jmp, alu_not); `include "op_code.vh" `include "alu_func.vh" +`include "mem_func.vh" function [3:0] get_alu_func(input [2:0] func, input arithmetic); begin @@ -74,7 +77,6 @@ endfunction // TODO - Manage ALU OP CODE and IMM Extension - always @(*) begin case (instruction[6:2]) OP : begin // OP - Add, ... @@ -87,6 +89,8 @@ endfunction alu_src = 0; alu_func = get_alu_func(instruction[14:12], instruction[30]); mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b00; pc_is_jmp = 0; alu_not = 0; @@ -102,6 +106,8 @@ endfunction alu_src = 1; alu_func = get_alu_func_imm(instruction[14:12], instruction[30]); mem_we = 0; + mem_func_in = instruction[13:12]; + mem_func_out = 3'b000; pc_is_branch = 2'b00; pc_is_jmp = 0; alu_not = 0; @@ -117,6 +123,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = instruction[14:12]; pc_is_branch = 2'b00; pc_is_jmp = 0; alu_not = 0; @@ -132,6 +140,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 1; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b00; pc_is_jmp = 0; alu_not = 0; @@ -147,6 +157,8 @@ endfunction alu_src = 0; alu_func = branch_func(instruction[14:12]); mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b00; pc_is_jmp = 1; alu_not = branch_not(instruction[14:12]); @@ -162,6 +174,8 @@ endfunction alu_src = 0; alu_func = 3'b000; mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b01; pc_is_jmp = 0; alu_not = 0; @@ -177,6 +191,8 @@ endfunction alu_src = 0; alu_func = 3'b000; mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b10; pc_is_jmp = 0; alu_not = 0; @@ -191,6 +207,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b00; pc_is_jmp = 0; alu_not = 0; @@ -205,6 +223,8 @@ endfunction alu_src = 1; alu_func = 3'b000; mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b00; pc_is_jmp = 0; alu_not = 0; @@ -219,6 +239,8 @@ endfunction alu_src = 0; alu_func = 3'b000; mem_we = 0; + mem_func_in = 2'b00; + mem_func_out = 3'b000; pc_is_branch = 2'b00; pc_is_jmp = 0; alu_not = 0; diff --git a/rtl/mem_func.vh b/rtl/mem_func.vh new file mode 100644 index 0000000..a5872cd --- /dev/null +++ b/rtl/mem_func.vh @@ -0,0 +1,9 @@ +parameter [2:0] LB = 3'b000; +parameter [2:0] LH = 3'b001; +parameter [2:0] LW = 3'b010; +parameter [2:0] LBU = 3'b011; +parameter [2:0] LHU = 3'b100; + +parameter [2:0] SB = 2'b00; +parameter [2:0] SH = 2'b01; +parameter [2:0] SW = 2'b10; diff --git a/rtl/memory.v b/rtl/memory.v index 3b5dea1..e4f6c16 100644 --- a/rtl/memory.v +++ b/rtl/memory.v @@ -1,21 +1,46 @@ -module memory (input clock, reset, - input we, - input [31:0] address, - input [31:0] data_in, - output [31:0] data_out); +module memory (input clock, reset, + input we, + input [1:0] func_in, + input [2:0] func_out, + input [31:0] address, + input [31:0] data_in, + output reg [31:0] data_out); + + `include "mem_func.vh" reg [7:0] memory [127:0]; always @(posedge clock, posedge reset) begin if (reset == 1) memory[0] <= 8'b0; - else if (we == 1) - memory[address] <= data_in[7:0]; - memory[address + 1] <= data_in[15:8]; - memory[address + 2] <= data_in[23:16]; - memory[address + 3] <= data_in[31:24]; + else if (we == 1) begin + case (func_in) + SB : begin + memory[address] <= data_in[7:0]; + end + SH : begin + memory[address] <= data_in[7:0]; + memory[address + 1] <= data_in[15:8]; + end + SW : begin + memory[address] <= data_in[7:0]; + memory[address + 1] <= data_in[15:8]; + memory[address + 2] <= data_in[23:16]; + memory[address + 3] <= data_in[31:24]; + end + endcase + end end - assign data_out = {memory[address + 3], memory[address + 2], memory[address + 1], memory[address]}; + always @(*) begin + case (func_out) + LB : data_out <= {(memory[address][7] == 1'b1 ? 24'b111111111111111111111111 : 24'b000000000000000000000000), memory[address]}; + LH : data_out <= {(memory[address][15] == 1'b1 ? 16'b1111111111111111 : 16'b0000000000000000), memory[address], memory[address]}; + LW : data_out <= {memory[address + 3], memory[address + 2], memory[address + 1], memory[address]}; + LBU : data_out <= {24'b000000000000000000000000, memory[address]}; + LHU : data_out <= {16'b0000000000000000, memory[address]}; + default : data_out <= 32'b00000000000000000000000000000000; + endcase + end endmodule diff --git a/rtl/risc_v_cpu.v b/rtl/risc_v_cpu.v index 1385a08..2c740c1 100644 --- a/rtl/risc_v_cpu.v +++ b/rtl/risc_v_cpu.v @@ -15,6 +15,8 @@ module risc_v_cpu (input clock, reset, wire [31:0] alu_in_b, alu_out; wire mem_we; + wire [1:0] mem_func_in; + wire [2:0] mem_func_out; wire [31:0] mem_out; wire pc_is_jmp; @@ -32,6 +34,8 @@ module risc_v_cpu (input clock, reset, .alu_src(alu_src), .alu_func(alu_func), .mem_we(mem_we), + .mem_func_in(mem_func_in), + .mem_func_out(mem_func_out), .pc_is_branch(pc_is_branch), .pc_is_jmp(pc_is_jmp), .alu_not(alu_not) @@ -65,7 +69,7 @@ module risc_v_cpu (input clock, reset, mux2_1 #(2) mux2_pc_sel_branch ( .in_1(pc_is_branch), - .in_2({0, (alu_not ? (~alu_out != 32'b0 ? 1 : 0) : (alu_out != 0 ? 1 : 0))}), + .in_2({1'b0, (alu_not ? (~alu_out != 32'b0 ? 1'b1 : 1'b0) : (alu_out != 0 ? 1'b1 : 1'b0))}), .sel(pc_is_jmp), .out(pc_sel_in) ); @@ -95,6 +99,8 @@ module risc_v_cpu (input clock, reset, .clock(clock), .reset(reset), .we(mem_we), + .func_in(mem_func_in), + .func_out(mem_func_out), .address(alu_out), .data_in(reg_data_out_b), .data_out(mem_out)