mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-28 16:34:14 +01:00
107 lines
3.0 KiB
Systemverilog
107 lines
3.0 KiB
Systemverilog
|
module n64_sdram (
|
||
|
if_system sys,
|
||
|
if_n64_bus bus,
|
||
|
if_dma.memory dma,
|
||
|
if_sdram.memory sdram,
|
||
|
|
||
|
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;
|
||
|
|
||
|
typedef enum bit [0:0] {
|
||
|
S_IDLE,
|
||
|
S_WAIT
|
||
|
} e_state;
|
||
|
|
||
|
typedef enum bit [1:0] {
|
||
|
T_BUS,
|
||
|
T_DMA,
|
||
|
T_SDRAM
|
||
|
} e_source_request;
|
||
|
|
||
|
e_state state;
|
||
|
e_source_request source_request;
|
||
|
|
||
|
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
|
||
|
if (bus.request || sdram.request || dma.request) begin
|
||
|
state <= S_WAIT;
|
||
|
mem_request <= 1'b1;
|
||
|
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
|
||
|
end
|
||
|
end
|
||
|
|
||
|
S_WAIT: begin
|
||
|
if (mem_ack) begin
|
||
|
state <= S_IDLE;
|
||
|
mem_request <= 1'b0;
|
||
|
end
|
||
|
end
|
||
|
endcase
|
||
|
end
|
||
|
end
|
||
|
|
||
|
always_comb begin
|
||
|
bus.ack = source_request == T_BUS && mem_ack;
|
||
|
bus.rdata = bus.ack ? mem_rdata : 16'd0;
|
||
|
|
||
|
dma.ack = source_request == T_DMA && mem_ack;
|
||
|
dma.rdata = mem_rdata;
|
||
|
|
||
|
sdram.ack = source_request == T_SDRAM && mem_ack;
|
||
|
sdram.rdata = mem_rdata;
|
||
|
end
|
||
|
|
||
|
memory_sdram memory_sdram_inst (
|
||
|
.sys(sys),
|
||
|
|
||
|
.request(mem_request),
|
||
|
.ack(mem_ack),
|
||
|
.write(mem_write),
|
||
|
.address(mem_address[25:0]),
|
||
|
.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
|