mirror of
https://github.com/Polprzewodnikowy/SummerCart64.git
synced 2024-11-25 07:06:52 +01:00
408 lines
11 KiB
Verilog
408 lines
11 KiB
Verilog
module top (
|
|
input i_clk,
|
|
|
|
output o_ftdi_clk,
|
|
output o_ftdi_si,
|
|
input i_ftdi_so,
|
|
input i_ftdi_cts,
|
|
|
|
input i_n64_nmi,
|
|
input i_n64_reset,
|
|
|
|
input i_n64_pi_alel,
|
|
input i_n64_pi_aleh,
|
|
input i_n64_pi_read,
|
|
input i_n64_pi_write,
|
|
inout [15:0] io_n64_pi_ad,
|
|
|
|
input i_n64_si_clk,
|
|
inout io_n64_si_dq,
|
|
|
|
input i_n64_cic_clk,
|
|
inout io_n64_cic_dq,
|
|
|
|
output o_sdram_clk,
|
|
output o_sdram_cs,
|
|
output o_sdram_ras,
|
|
output o_sdram_cas,
|
|
output o_sdram_we,
|
|
output [1:0] o_sdram_ba,
|
|
output [12:0] o_sdram_a,
|
|
inout [15:0] io_sdram_dq,
|
|
|
|
output o_sd_clk,
|
|
inout io_sd_cmd,
|
|
inout [3:0] io_sd_dat,
|
|
|
|
output o_flash_clk,
|
|
output o_flash_cs,
|
|
inout [3:0] io_flash_dq,
|
|
|
|
output o_sram_clk,
|
|
output o_sram_cs,
|
|
inout [3:0] io_sram_dq,
|
|
|
|
output o_rtc_scl,
|
|
inout io_rtc_sda,
|
|
|
|
output o_led,
|
|
|
|
inout [7:0] io_pmod
|
|
);
|
|
|
|
// Clock and reset signals
|
|
|
|
wire w_sys_clk;
|
|
wire w_sdram_clk;
|
|
wire w_pll_lock;
|
|
wire w_sys_reset = ~w_pll_lock;
|
|
|
|
|
|
// PLL clock generator
|
|
|
|
pll sys_pll (
|
|
.inclk0(i_clk),
|
|
.c0(w_sys_clk),
|
|
.c1(w_sdram_clk),
|
|
.locked(w_pll_lock)
|
|
);
|
|
|
|
|
|
// SDRAM clock output
|
|
|
|
gpio_ddro sdram_clk_ddro (
|
|
.outclock(w_sdram_clk),
|
|
.outclocken(1'b1),
|
|
.din({1'b0, 1'b1}),
|
|
.pad_out(o_sdram_clk)
|
|
);
|
|
|
|
|
|
// Bank ids
|
|
|
|
localparam [3:0] BANK_INVALID = 4'd0;
|
|
localparam [3:0] BANK_ROM = 4'd1;
|
|
localparam [3:0] BANK_CART = 4'd2;
|
|
localparam [3:0] BANK_EEPROM = 4'd3;
|
|
|
|
|
|
// N64 PI
|
|
|
|
wire w_n64_request;
|
|
wire w_n64_write;
|
|
wire w_n64_busy;
|
|
wire w_n64_ack;
|
|
wire [3:0] w_n64_bank;
|
|
wire [25:0] w_n64_address;
|
|
wire [31:0] w_n64_i_data;
|
|
wire [31:0] w_n64_o_data;
|
|
|
|
wire w_n64_busy_cart_control;
|
|
wire w_n64_ack_cart_control;
|
|
wire [31:0] w_n64_i_data_cart_control;
|
|
|
|
wire w_n64_busy_sdram;
|
|
wire w_n64_ack_sdram;
|
|
wire [31:0] w_n64_i_data_sdram;
|
|
|
|
wire w_n64_busy_embedded_flash;
|
|
wire w_n64_ack_embedded_flash;
|
|
wire [31:0] w_n64_i_data_embedded_flash;
|
|
|
|
wire w_n64_busy_eeprom;
|
|
wire w_n64_ack_eeprom;
|
|
wire [31:0] w_n64_i_data_eeprom;
|
|
|
|
always @(*) begin
|
|
w_n64_busy = w_n64_busy_cart_control || w_n64_busy_sdram || w_n64_busy_embedded_flash || w_n64_busy_eeprom;
|
|
w_n64_ack = w_n64_ack_cart_control || w_n64_ack_sdram || w_n64_ack_embedded_flash || w_n64_ack_eeprom;
|
|
w_n64_i_data = 32'h0000_0000;
|
|
if (w_n64_ack_cart_control) w_n64_i_data = w_n64_i_data_cart_control;
|
|
if (w_n64_ack_sdram) w_n64_i_data = w_n64_i_data_sdram;
|
|
if (w_n64_ack_embedded_flash) w_n64_i_data = w_n64_i_data_embedded_flash;
|
|
if (w_n64_ack_eeprom) w_n64_i_data = w_n64_i_data_eeprom;
|
|
end
|
|
|
|
n64_pi n64_pi_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.i_n64_reset(i_n64_reset),
|
|
.i_n64_pi_alel(i_n64_pi_alel),
|
|
.i_n64_pi_aleh(i_n64_pi_aleh),
|
|
.i_n64_pi_read(i_n64_pi_read),
|
|
.i_n64_pi_write(i_n64_pi_write),
|
|
.io_n64_pi_ad(io_n64_pi_ad),
|
|
|
|
.o_request(w_n64_request),
|
|
.o_write(w_n64_write),
|
|
.i_busy(w_n64_busy),
|
|
.i_ack(w_n64_ack),
|
|
.o_bank(w_n64_bank),
|
|
.o_address(w_n64_address),
|
|
.i_data(w_n64_i_data),
|
|
.o_data(w_n64_o_data)
|
|
);
|
|
|
|
|
|
// PC USB
|
|
|
|
wire w_pc_request;
|
|
wire w_pc_write;
|
|
wire w_pc_busy;
|
|
wire w_pc_ack;
|
|
wire [3:0] w_pc_bank;
|
|
wire [25:0] w_pc_address;
|
|
wire [31:0] w_pc_i_data;
|
|
wire [31:0] w_pc_o_data;
|
|
|
|
wire w_pc_busy_cart_control;
|
|
wire w_pc_ack_cart_control;
|
|
wire [31:0] w_pc_i_data_cart_control;
|
|
|
|
wire w_pc_busy_sdram;
|
|
wire w_pc_ack_sdram;
|
|
wire [31:0] w_pc_i_data_sdram;
|
|
|
|
wire w_pc_busy_eeprom;
|
|
wire w_pc_ack_eeprom;
|
|
wire [31:0] w_pc_i_data_eeprom;
|
|
|
|
always @(*) begin
|
|
w_pc_busy = w_pc_busy_cart_control || w_pc_busy_sdram || w_pc_busy_eeprom;
|
|
w_pc_ack = w_pc_ack_cart_control || w_pc_ack_sdram || w_pc_ack_eeprom;
|
|
w_pc_i_data = 32'h0000_0000;
|
|
if (w_pc_ack_cart_control) w_pc_i_data = w_pc_i_data_cart_control;
|
|
if (w_pc_ack_sdram) w_pc_i_data = w_pc_i_data_sdram;
|
|
if (w_pc_ack_eeprom) w_pc_i_data = w_pc_i_data_eeprom;
|
|
end
|
|
|
|
usb_pc usb_pc_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.o_ftdi_clk(o_ftdi_clk),
|
|
.o_ftdi_si(o_ftdi_si),
|
|
.i_ftdi_so(i_ftdi_so),
|
|
.i_ftdi_cts(i_ftdi_cts),
|
|
|
|
.o_request(w_pc_request),
|
|
.o_write(w_pc_write),
|
|
.i_busy(w_pc_busy),
|
|
.i_ack(w_pc_ack),
|
|
.o_bank(w_pc_bank),
|
|
.o_address(w_pc_address),
|
|
.i_data(w_pc_i_data),
|
|
.o_data(w_pc_o_data)
|
|
);
|
|
|
|
|
|
// Cart interface
|
|
|
|
wire w_cart_control_request;
|
|
wire w_cart_control_write;
|
|
wire w_cart_control_busy;
|
|
wire w_cart_control_ack;
|
|
wire [25:0] w_cart_control_address;
|
|
wire [31:0] w_cart_control_o_data;
|
|
wire [31:0] w_cart_control_i_data;
|
|
|
|
wire w_rom_switch;
|
|
wire w_eeprom_enable;
|
|
wire w_eeprom_16k_mode;
|
|
|
|
device_arbiter device_arbiter_cart_control_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.i_request_pri(w_n64_request),
|
|
.i_write_pri(w_n64_write),
|
|
.o_busy_pri(w_n64_busy_cart_control),
|
|
.o_ack_pri(w_n64_ack_cart_control),
|
|
.i_bank_pri(w_n64_bank),
|
|
.i_address_pri(w_n64_address[25:2]),
|
|
.o_data_pri(w_n64_i_data_cart_control),
|
|
.i_data_pri(w_n64_o_data),
|
|
|
|
.i_request_sec(w_pc_request),
|
|
.i_write_sec(w_pc_write),
|
|
.o_busy_sec(w_pc_busy_cart_control),
|
|
.o_ack_sec(w_pc_ack_cart_control),
|
|
.i_bank_sec(w_pc_bank),
|
|
.i_address_sec(w_pc_address[25:2]),
|
|
.o_data_sec(w_pc_i_data_cart_control),
|
|
.i_data_sec(w_pc_o_data),
|
|
|
|
.o_request(w_cart_control_request),
|
|
.o_write(w_cart_control_write),
|
|
.i_busy(w_cart_control_busy),
|
|
.i_ack(w_cart_control_ack),
|
|
.o_address(w_cart_control_address),
|
|
.i_data(w_cart_control_o_data),
|
|
.o_data(w_cart_control_i_data)
|
|
);
|
|
defparam device_arbiter_cart_control_inst.DEVICE_BANK = BANK_CART;
|
|
|
|
cart_control cart_control_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.i_n64_reset(i_n64_reset),
|
|
.i_n64_nmi(i_n64_nmi),
|
|
|
|
.i_request(w_cart_control_request),
|
|
.i_write(w_cart_control_write),
|
|
.o_busy(w_cart_control_busy),
|
|
.o_ack(w_cart_control_ack),
|
|
.i_address(w_cart_control_address),
|
|
.o_data(w_cart_control_o_data),
|
|
.i_data(w_cart_control_i_data),
|
|
|
|
.o_rom_switch(w_rom_switch),
|
|
.o_eeprom_enable(w_eeprom_enable),
|
|
.o_eeprom_16k_mode(w_eeprom_16k_mode)
|
|
);
|
|
|
|
|
|
// Embedded flash
|
|
|
|
memory_embedded_flash memory_embedded_flash_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.i_request(!w_rom_switch && w_n64_request && !w_n64_write && w_n64_bank == BANK_ROM),
|
|
.o_busy(w_n64_busy_embedded_flash),
|
|
.o_ack(w_n64_ack_embedded_flash),
|
|
.i_address(w_n64_address[25:2]),
|
|
.o_data(w_n64_i_data_embedded_flash)
|
|
);
|
|
|
|
|
|
// SDRAM
|
|
|
|
wire w_sdram_request;
|
|
wire w_sdram_write;
|
|
wire w_sdram_busy;
|
|
wire w_sdram_ack;
|
|
wire [25:0] w_sdram_address;
|
|
wire [31:0] w_sdram_o_data;
|
|
wire [31:0] w_sdram_i_data;
|
|
|
|
device_arbiter device_arbiter_sdram_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.i_request_pri(w_rom_switch && w_n64_request),
|
|
.i_write_pri(w_n64_write),
|
|
.o_busy_pri(w_n64_busy_sdram),
|
|
.o_ack_pri(w_n64_ack_sdram),
|
|
.i_bank_pri(w_n64_bank),
|
|
.i_address_pri(w_n64_address[25:1]),
|
|
.o_data_pri(w_n64_i_data_sdram),
|
|
.i_data_pri(w_n64_o_data),
|
|
|
|
.i_request_sec(w_pc_request),
|
|
.i_write_sec(w_pc_write),
|
|
.o_busy_sec(w_pc_busy_sdram),
|
|
.o_ack_sec(w_pc_ack_sdram),
|
|
.i_bank_sec(w_pc_bank),
|
|
.i_address_sec(w_pc_address[25:1]),
|
|
.o_data_sec(w_pc_i_data_sdram),
|
|
.i_data_sec(w_pc_o_data),
|
|
|
|
.o_request(w_sdram_request),
|
|
.o_write(w_sdram_write),
|
|
.i_busy(w_sdram_busy),
|
|
.i_ack(w_sdram_ack),
|
|
.o_address(w_sdram_address),
|
|
.i_data(w_sdram_o_data),
|
|
.o_data(w_sdram_i_data)
|
|
);
|
|
defparam device_arbiter_sdram_inst.DEVICE_BANK = BANK_ROM;
|
|
|
|
memory_sdram memory_sdram_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.o_sdram_cs(o_sdram_cs),
|
|
.o_sdram_ras(o_sdram_ras),
|
|
.o_sdram_cas(o_sdram_cas),
|
|
.o_sdram_we(o_sdram_we),
|
|
.o_sdram_ba(o_sdram_ba),
|
|
.o_sdram_a(o_sdram_a),
|
|
.io_sdram_dq(io_sdram_dq),
|
|
|
|
.i_request(w_sdram_request),
|
|
.i_write(w_sdram_write),
|
|
.o_busy(w_sdram_busy),
|
|
.o_ack(w_sdram_ack),
|
|
.i_address(w_sdram_address),
|
|
.o_data(w_sdram_o_data),
|
|
.i_data(w_sdram_i_data)
|
|
);
|
|
|
|
|
|
// EEPROM 4/16k
|
|
|
|
wire w_eeprom_request;
|
|
wire w_eeprom_write;
|
|
wire w_eeprom_busy;
|
|
wire w_eeprom_ack;
|
|
wire [25:0] w_eeprom_address;
|
|
wire [31:0] w_eeprom_o_data;
|
|
wire [31:0] w_eeprom_i_data;
|
|
|
|
device_arbiter device_arbiter_eeprom_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.i_request_pri(w_n64_request),
|
|
.i_write_pri(w_n64_write),
|
|
.o_busy_pri(w_n64_busy_eeprom),
|
|
.o_ack_pri(w_n64_ack_eeprom),
|
|
.i_bank_pri(w_n64_bank),
|
|
.i_address_pri(w_n64_address[25:2]),
|
|
.o_data_pri(w_n64_i_data_eeprom),
|
|
.i_data_pri(w_n64_o_data),
|
|
|
|
.i_request_sec(w_pc_request),
|
|
.i_write_sec(w_pc_write),
|
|
.o_busy_sec(w_pc_busy_eeprom),
|
|
.o_ack_sec(w_pc_ack_eeprom),
|
|
.i_bank_sec(w_pc_bank),
|
|
.i_address_sec(w_pc_address[25:2]),
|
|
.o_data_sec(w_pc_i_data_eeprom),
|
|
.i_data_sec(w_pc_o_data),
|
|
|
|
.o_request(w_eeprom_request),
|
|
.o_write(w_eeprom_write),
|
|
.i_busy(w_eeprom_busy),
|
|
.i_ack(w_eeprom_ack),
|
|
.o_address(w_eeprom_address),
|
|
.i_data(w_eeprom_o_data),
|
|
.o_data(w_eeprom_i_data)
|
|
);
|
|
defparam device_arbiter_eeprom_inst.DEVICE_BANK = BANK_EEPROM;
|
|
|
|
n64_si n64_si_inst (
|
|
.i_clk(w_sys_clk),
|
|
.i_reset(w_sys_reset),
|
|
|
|
.i_n64_reset(i_n64_reset),
|
|
.i_n64_si_clk(i_n64_si_clk),
|
|
.io_n64_si_dq(io_n64_si_dq),
|
|
|
|
.i_request(w_eeprom_request),
|
|
.i_write(w_eeprom_write),
|
|
.o_busy(w_eeprom_busy),
|
|
.o_ack(w_eeprom_ack),
|
|
.i_address(w_eeprom_address),
|
|
.i_data(w_eeprom_i_data),
|
|
.o_data(w_eeprom_o_data),
|
|
|
|
.i_eeprom_enable(w_eeprom_enable),
|
|
.i_eeprom_16k_mode(w_eeprom_16k_mode)
|
|
);
|
|
|
|
endmodule
|