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