summaryrefslogtreecommitdiff
path: root/verilog/memory.v
blob: ec64832a9bb2d74c640013cf8f1a8825afa206c6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
`default_nettype none
`timescale 1ns/1ps

module memory
#(
	parameter DATA_WIDTH = 32, // Word access are the largest, we need to get instructions in one cycle
	parameter ADDR_WIDTH = 14, // Byte Addressable Memory
	parameter FILE_NAME  = "default.mem"
)
(
	input wire clk, we,
	input wire [3:0] be,
	/* verilator lint_off UNUSEDSIGNAL */
	input wire [ADDR_WIDTH-1:0] addr, 
	/* lint_on */
	input wire [DATA_WIDTH-1:0] din,
	output reg [DATA_WIDTH-1:0] dout
);

reg [DATA_WIDTH-1:0] ram [0:(1 << (ADDR_WIDTH-2)) - 1]; // Word addressable memory

initial $readmemh(FILE_NAME, ram);

wire [ADDR_WIDTH-3:0] word_addr = addr[ADDR_WIDTH-1:2];

always @ (posedge clk) begin
	if (we) begin
		if (be[3])
			ram[word_addr][31:24] <= din[31:24];
		if (be[2])
			ram[word_addr][23:16] <= din[23:16];
		if (be[1])
			ram[word_addr][15:8] <= din[15:8];
		if (be[0])
			ram[word_addr][7:0] <= din[7:0];
	end
	else begin
		dout <= ram[word_addr];
	end
end

endmodule