factorio-riscv/board/parts/pmmu.sv

64 lines
1.5 KiB
Systemverilog
Raw Normal View History

2023-12-29 18:45:02 +00:00
// System physical memory management unit, addresses are dword aligned
2023-12-29 14:10:10 +00:00
module pmmu(
clk,
2023-12-30 18:04:40 +00:00
rd, wr, size,
2023-12-29 14:10:10 +00:00
addr, datar, dataw,
2023-12-29 18:45:02 +00:00
rom_rd,
2023-12-29 21:59:32 +00:00
rom_addr, rom_datar,
2023-12-30 18:04:40 +00:00
ram_rd, ram_wr, ram_size,
2023-12-29 21:59:32 +00:00
ram_addr, ram_datar, ram_dataw
2023-12-29 14:10:10 +00:00
);
// INPUT SHIT
2023-12-30 18:04:40 +00:00
input clk;
input reg rd;
input reg wr;
input reg[1:0] size;
input reg[31:0] addr;
input reg[31:0] dataw;
output reg[31:0] datar;
2023-12-29 14:10:10 +00:00
// ROM
2023-12-30 18:04:40 +00:00
output reg rom_rd;
output reg[31:0] rom_addr;
input reg[31:0] rom_datar;
2023-12-29 14:10:10 +00:00
2023-12-29 21:59:32 +00:00
// RAM
2023-12-30 18:04:40 +00:00
output reg ram_rd;
output reg ram_wr;
output reg[1:0] ram_size;
output reg[31:0] ram_addr;
output reg[31:0] ram_dataw;
input reg[31:0] ram_datar;
2023-12-29 21:59:32 +00:00
2023-12-29 14:10:10 +00:00
always @(posedge clk) begin
rom_rd = 0;
2023-12-29 21:59:32 +00:00
ram_rd = 0;
ram_wr = 0;
if ((addr == 0 || addr > 0) && addr < 'h1000) begin
rom_addr = addr >> 2;
rom_rd = rd;
2023-12-29 14:10:10 +00:00
2023-12-29 21:59:32 +00:00
#1;
2023-12-29 14:10:10 +00:00
if (rd) datar = rom_datar;
2023-12-29 21:59:32 +00:00
rom_rd = 0;
end else if ((addr == 'h100000 || addr > 'h100000) && addr < 'h101000) begin
2023-12-30 18:04:40 +00:00
ram_addr = addr;
2023-12-29 21:59:32 +00:00
ram_rd = rd;
ram_wr = wr;
2023-12-30 18:04:40 +00:00
ram_size = size;
2023-12-29 21:59:32 +00:00
if (wr) ram_dataw = dataw;
#1;
if (rd) datar = ram_datar;
ram_wr = 0;
ram_rd = 0;
2023-12-29 14:10:10 +00:00
end else begin
2023-12-29 21:59:32 +00:00
$error("INVALID MEMORY ACCESS %08x", addr);
2023-12-29 14:10:10 +00:00
end
end
endmodule