factorio-riscv/board/parts/ram.sv

55 lines
1.9 KiB
Systemverilog

module ram(
input clk,
input reg rd,
input reg wr,
input reg[1:0] size,
input reg[31:0] addr,
output reg[31:0] datar,
input reg[31:0] dataw
);
parameter SIZE = 'h1000;
reg [31:0] data[0 : SIZE - 1];
always @(posedge clk) begin
// $display("RAM: %c%c", wr ? "W" : "-", rd ? "R" : "-");
if (wr) begin
$display("RAM: [%08x](%d) <= %d", addr, size, dataw);
case (size)
0: begin
data[addr >> 2] = (data[addr >> 2] & ~('hff << (8 * addr[1:0]))) | ((dataw & 'hff) << (8 * addr[1:0]));
end
1: begin
if (addr[0] != 0) $error("MISALIGNED STORE OF SIZE %d AT %08x", size, addr);
data[addr >> 2] = (data[addr >> 2] & ~('hffff << (8 * addr[1:0]))) | ((dataw & 'hffff) << (8 * addr[1:0]));
end
2: begin
if (addr[1:0] != 0) $error("MISALIGNED STORE OF SIZE %d AT %08x", size, addr);
data[addr >> 2] = dataw;
end
default: $error("INVALID STORE SIZE %d", size);
endcase
end
if (rd) begin
case (size)
0: begin
datar = (data[addr >> 2] >> (8 * addr[1:0])) & 'hff;
end
1: begin
if (addr[0] != 0) $error("MISALIGNED LOAD OF SIZE 1 AT %08x", addr);
datar = (data[addr >> 2] >> (8 * addr[1:0])) & 'hffff;
end
2: begin
if (addr[1:0] != 0) $error("MISALIGNED LOAD OF SIZE %d AT %08x", size, addr);
datar = data[addr >> 2];
end
default: $error("INVALID LOAD SIZE %d", size);
endcase
$display("RAM: [%08x](%d) => %d", addr, size, datar);
end else datar = 0;
end
endmodule