From 018faac56029c74a897a805aade54a16a9437b5a Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Tue, 5 Dec 2017 22:00:47 +0000 Subject: [PATCH] Add memory bus and move data memory to a separate module --- ram.sv | 36 ++++++++++++++ rv32.sv | 24 +++++++++- rv32_mem.sv | 132 +++++++++++++++++++++++++--------------------------- top.sv | 35 +++++++++++++- 4 files changed, 156 insertions(+), 71 deletions(-) create mode 100644 ram.sv diff --git a/ram.sv b/ram.sv new file mode 100644 index 0000000..4114bd9 --- /dev/null +++ b/ram.sv @@ -0,0 +1,36 @@ +`ifndef RAM +`define RAM + +module ram ( + input clk, + + /* control in */ + input [3:0] write_mask_in, + + /* data in */ + input [31:0] address_in, + input [31:0] write_value_in, + + /* data out */ + output [31:0] read_value_out +); + logic [31:0] mem [255:0]; + + always_ff @(negedge clk) begin + read_value_out <= mem[address_in[31:2]]; + + if (write_mask_in[3]) + mem[address_in[31:2]][31:24] <= write_value_in[31:24]; + + if (write_mask_in[2]) + mem[address_in[31:2]][23:16] <= write_value_in[23:16]; + + if (write_mask_in[1]) + mem[address_in[31:2]][15:8] <= write_value_in[15:8]; + + if (write_mask_in[0]) + mem[address_in[31:2]][7:0] <= write_value_in[7:0]; + end +endmodule + +`endif diff --git a/rv32.sv b/rv32.sv index 42ba00d..e60b2be 100644 --- a/rv32.sv +++ b/rv32.sv @@ -9,7 +9,17 @@ module rv32 ( input clk, - output [7:0] leds + output [7:0] leds, + + /* control out (memory bus) */ + output [3:0] write_mask_out, + + /* data in (memory bus) */ + input [31:0] read_value_in, + + /* data out (memory bus) */ + output [31:0] address_out, + output [31:0] write_value_out ); always_ff @(posedge clk) begin if (mem_rd_writeback && mem_rd == 31) @@ -236,14 +246,24 @@ module rv32 ( .rs2_value_in(execute_rs2_value), .branch_pc_in(execute_branch_pc), + /* data in (from memory bus) */ + .read_value_in(read_value_in), + /* control out */ .branch_taken_out(mem_branch_taken), .rd_out(mem_rd), .rd_writeback_out(mem_rd_writeback), + /* control out (to memory bus) */ + .write_mask_out(write_mask_out), + /* data out */ .rd_value_out(mem_rd_value), - .branch_pc_out(mem_branch_pc) + .branch_pc_out(mem_branch_pc), + + /* data out (to memory bus) */ + .address_out(address_out), + .write_value_out(write_value_out) ); /* mem -> writeback control */ diff --git a/rv32_mem.sv b/rv32_mem.sv index d53dd58..a8618d1 100644 --- a/rv32_mem.sv +++ b/rv32_mem.sv @@ -28,17 +28,25 @@ module rv32_mem ( input [31:0] rs2_value_in, input [31:0] branch_pc_in, + /* data in (from memory bus) */ + input [31:0] read_value_in, + /* control out */ output branch_taken_out, output [4:0] rd_out, output rd_writeback_out, + /* control out (to memory bus) */ + output [3:0] write_mask_out, + /* data out */ output [31:0] rd_value_out, - output [31:0] branch_pc_out -); - logic [31:0] data_mem [255:0]; + output [31:0] branch_pc_out, + /* data out (to memory bus) */ + output [31:0] address_out, + output [31:0] write_value_out +); rv32_branch branch ( /* control in */ .op_in(branch_op_in), @@ -52,67 +60,55 @@ module rv32_mem ( assign branch_pc_out = branch_pc_in; - logic [31:0] read_value; - logic [31:0] write_value; - logic [3:0] write_mask; + assign address_out = result_in; always_comb begin - case (width_in) - RV32_MEM_WIDTH_WORD: begin - write_value = rs2_value_in; - write_mask = 4'b1111; - end - RV32_MEM_WIDTH_HALF: begin - case (result_in[0]) - 2'b0: begin - write_value = {rs2_value_in[15:0], 16'bx}; - write_mask = 4'b1100; - end - 2'b1: begin - write_value = {16'bx, rs2_value_in[15:0]}; - write_mask = 4'b0011; - end - endcase - end - RV32_MEM_WIDTH_BYTE: begin - case (result_in[1:0]) - 2'b00: begin - write_value = {rs2_value_in[7:0], 24'bx}; - write_mask = 4'b1000; - end - 2'b01: begin - write_value = {8'bx, rs2_value_in[7:0], 16'bx}; - write_mask = 4'b0100; - end - 2'b10: begin - write_value = {16'bx, rs2_value_in[7:0], 8'bx}; - write_mask = 4'b0010; - end - 2'b11: begin - write_value = {24'bx, rs2_value_in[7:0]}; - write_mask = 4'b0001; - end - endcase - end - default: begin - write_value = 32'bx; - write_mask = 4'bx; - end - endcase - end - - always_ff @(negedge clk) begin - read_value <= data_mem[result_in[31:2]]; - if (write_en_in) begin - if (write_mask[3]) - data_mem[result_in[31:2]][31:24] <= write_value[31:24]; - if (write_mask[2]) - data_mem[result_in[31:2]][23:16] <= write_value[23:16]; - if (write_mask[1]) - data_mem[result_in[31:2]][15:8] <= write_value[15:8]; - if (write_mask[0]) - data_mem[result_in[31:2]][7:0] <= write_value[7:0]; + case (width_in) + RV32_MEM_WIDTH_WORD: begin + write_value_out = rs2_value_in; + write_mask_out = 4'b1111; + end + RV32_MEM_WIDTH_HALF: begin + case (result_in[0]) + 2'b0: begin + write_value_out = {rs2_value_in[15:0], 16'bx}; + write_mask_out = 4'b1100; + end + 2'b1: begin + write_value_out = {16'bx, rs2_value_in[15:0]}; + write_mask_out = 4'b0011; + end + endcase + end + RV32_MEM_WIDTH_BYTE: begin + case (result_in[1:0]) + 2'b00: begin + write_value_out = {rs2_value_in[7:0], 24'bx}; + write_mask_out = 4'b1000; + end + 2'b01: begin + write_value_out = {8'bx, rs2_value_in[7:0], 16'bx}; + write_mask_out = 4'b0100; + end + 2'b10: begin + write_value_out = {16'bx, rs2_value_in[7:0], 8'bx}; + write_mask_out = 4'b0010; + end + 2'b11: begin + write_value_out = {24'bx, rs2_value_in[7:0]}; + write_mask_out = 4'b0001; + end + endcase + end + default: begin + write_value_out = 32'bx; + write_mask_out = 4'bx; + end + endcase + end else begin + write_value_out = 32'bx; + write_mask_out = 4'b0; end end @@ -124,20 +120,20 @@ module rv32_mem ( if (read_en_in) begin case (width_in) RV32_MEM_WIDTH_WORD: begin - rd_value_out <= read_value; + rd_value_out <= read_value_in; end RV32_MEM_WIDTH_HALF: begin case (result_in[0]) - 1'b0: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:16]}; - 1'b1: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:0]}; + 1'b0: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value_in[31]}}, read_value_in[31:16]}; + 1'b1: rd_value_out <= {{16{zero_extend_in ? 1'b0 : read_value_in[15]}}, read_value_in[15:0]}; endcase end RV32_MEM_WIDTH_BYTE: begin case (result_in[1:0]) - 2'b00: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[31]}}, read_value[31:24]}; - 2'b01: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[23]}}, read_value[23:16]}; - 2'b10: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[15]}}, read_value[15:8]}; - 2'b11: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value[7]}}, read_value[7:0]}; + 2'b00: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[31]}}, read_value_in[31:24]}; + 2'b01: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[23]}}, read_value_in[23:16]}; + 2'b10: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[15]}}, read_value_in[15:8]}; + 2'b11: rd_value_out <= {{24{zero_extend_in ? 1'b0 : read_value_in[7]}}, read_value_in[7:0]}; endcase end default: begin diff --git a/top.sv b/top.sv index e1d9e04..96ad89f 100644 --- a/top.sv +++ b/top.sv @@ -1,4 +1,5 @@ `include "clk_div.sv" +`include "ram.sv" `include "rv32.sv" module top ( @@ -45,6 +46,38 @@ module top ( rv32 rv32 ( .clk(clk_slow), - .leds(leds) + .leds(leds), + + /* control out */ + .write_mask_out(mem_write_mask), + + /* data in */ + .read_value_in(mem_read_value), + + /* data out */ + .address_out(mem_address), + .write_value_out(mem_write_value) + ); + + /* memory bus control */ + logic [3:0] mem_write_mask; + + /* memory bus data */ + logic [31:0] mem_address; + logic [31:0] mem_read_value; + logic [31:0] mem_write_value; + + ram ram ( + .clk(clk_slow), + + /* control in */ + .write_mask_in(mem_write_mask), + + /* data in */ + .address_in(mem_address), + .write_value_in(mem_write_value), + + /* data out */ + .read_value_out(mem_read_value) ); endmodule