SummerCart64/fw/rtl/n64/n64_sdram.sv

107 lines
3.0 KiB
Systemverilog
Raw Normal View History

2021-08-21 02:53:28 +02:00
module n64_sdram (
if_system sys,
if_n64_bus bus,
2021-08-21 04:35:40 +02:00
if_dma.memory dma,
2021-08-28 04:15:24 +02:00
if_sdram.memory sdram,
2021-08-21 02:53:28 +02:00
output sdram_cs,
output sdram_ras,
output sdram_cas,
output sdram_we,
output [1:0] sdram_ba,
output [12:0] sdram_a,
inout [15:0] sdram_dq
);
logic mem_request;
logic mem_ack;
logic mem_write;
logic [31:0] mem_address;
logic [15:0] mem_rdata;
logic [15:0] mem_wdata;
2021-08-21 23:51:54 +02:00
typedef enum bit [0:0] {
S_IDLE,
S_WAIT
} e_state;
2021-08-28 04:15:24 +02:00
typedef enum bit [1:0] {
2021-08-21 23:51:54 +02:00
T_BUS,
2021-08-28 04:15:24 +02:00
T_DMA,
T_SDRAM
} e_source_request;
2021-08-21 23:51:54 +02:00
e_state state;
2021-08-28 04:15:24 +02:00
e_source_request source_request;
2021-08-21 23:51:54 +02:00
always_ff @(posedge sys.clk) begin
if (sys.reset) begin
state <= S_IDLE;
mem_request <= 1'b0;
end else begin
case (state)
S_IDLE: begin
2021-08-28 04:15:24 +02:00
if (bus.request || sdram.request || dma.request) begin
2021-08-21 23:51:54 +02:00
state <= S_WAIT;
mem_request <= 1'b1;
2021-08-28 04:15:24 +02:00
if (bus.request) begin
mem_write <= bus.write;
mem_address <= bus.address;
mem_wdata <= bus.wdata;
source_request <= T_BUS;
end else if (sdram.request) begin
mem_write <= sdram.write;
mem_address <= sdram.address;
mem_wdata <= sdram.wdata;
source_request <= T_SDRAM;
end else if (dma.request) begin
mem_write <= dma.write;
mem_address <= dma.address;
mem_wdata <= dma.wdata;
source_request <= T_DMA;
end
2021-08-21 23:51:54 +02:00
end
end
S_WAIT: begin
if (mem_ack) begin
state <= S_IDLE;
mem_request <= 1'b0;
end
end
endcase
end
end
2021-08-21 02:53:28 +02:00
always_comb begin
2021-08-28 04:15:24 +02:00
bus.ack = source_request == T_BUS && mem_ack;
2021-08-23 21:40:37 +02:00
bus.rdata = bus.ack ? mem_rdata : 16'd0;
2021-08-21 23:51:54 +02:00
2021-08-28 04:15:24 +02:00
dma.ack = source_request == T_DMA && mem_ack;
2021-08-21 02:53:28 +02:00
dma.rdata = mem_rdata;
2021-08-28 04:15:24 +02:00
sdram.ack = source_request == T_SDRAM && mem_ack;
sdram.rdata = mem_rdata;
2021-08-21 02:53:28 +02:00
end
memory_sdram memory_sdram_inst (
.sys(sys),
.request(mem_request),
.ack(mem_ack),
.write(mem_write),
2021-08-23 00:35:50 +02:00
.address(mem_address[25:0]),
2021-08-21 02:53:28 +02:00
.rdata(mem_rdata),
.wdata(mem_wdata),
.sdram_cs(sdram_cs),
.sdram_ras(sdram_ras),
.sdram_cas(sdram_cas),
.sdram_we(sdram_we),
.sdram_ba(sdram_ba),
.sdram_a(sdram_a),
.sdram_dq(sdram_dq)
);
endmodule