flashram working

This commit is contained in:
Polprzewodnikowy 2021-02-27 15:56:46 +01:00
parent aa74831511
commit c4c101b6d3
15 changed files with 770 additions and 186 deletions

View File

@ -19,7 +19,7 @@
#
# Quartus Prime
# Version 20.1.1 Build 720 11/11/2020 SJ Lite Edition
# Date created = 01:35:54 February 19, 2021
# Date created = 15:52:44 February 27, 2021
#
# -------------------------------------------------------------------------- #
#
@ -51,6 +51,7 @@ set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo_sd.qip
set_global_assignment -name QIP_FILE rtl/intel/fifo/fifo_usb.qip
set_global_assignment -name QIP_FILE rtl/intel/gpio/gpio_ddro.qip
set_global_assignment -name QIP_FILE rtl/intel/pll/pll.qip
set_global_assignment -name QIP_FILE rtl/intel/ram/ram_flashram_write_buffer.qip
set_global_assignment -name QIP_FILE rtl/intel/ram/ram_n64_eeprom.qip
set_global_assignment -name QSYS_FILE rtl/intel/flash/onchip_flash.qsys
set_global_assignment -name SDC_FILE constraints.sdc
@ -58,6 +59,7 @@ set_global_assignment -name SIGNALTAP_FILE output_files/signal_tap_logic_analyze
set_global_assignment -name SYSTEMVERILOG_FILE rtl/intel/gpio/gpio_ddro/altera_gpio_lite.sv -library gpio_ddro
set_global_assignment -name VERILOG_FILE rtl/cart/cart_control.v
set_global_assignment -name VERILOG_FILE rtl/cart/cart_led.v
set_global_assignment -name VERILOG_FILE rtl/flashram/flashram_controller.v
set_global_assignment -name VERILOG_FILE rtl/glue/device_arbiter.v
set_global_assignment -name VERILOG_FILE rtl/memory/memory_embedded_flash.v
set_global_assignment -name VERILOG_FILE rtl/memory/memory_sdram.v
@ -160,12 +162,6 @@ set_location_assignment PIN_114 -to o_sd_clk
set_location_assignment PIN_118 -to io_sd_cmd
set_location_assignment PIN_119 -to io_sd_dat[3]
set_location_assignment PIN_120 -to io_sd_dat[2]
set_location_assignment PIN_121 -to io_sram_dq[0]
set_location_assignment PIN_122 -to o_sram_clk
set_location_assignment PIN_123 -to io_sram_dq[3]
set_location_assignment PIN_124 -to o_sram_cs
set_location_assignment PIN_126 -to io_sram_dq[1]
set_location_assignment PIN_127 -to io_sram_dq[2]
set_location_assignment PIN_138 -to io_pmod[0]
set_location_assignment PIN_140 -to io_pmod[1]
set_location_assignment PIN_141 -to io_pmod[2]

View File

@ -17,7 +17,6 @@ module cart_control (
output reg o_rom_switch,
output reg o_ddipl_enable,
output reg o_sram_enable,
output reg o_sram_768k_mode,
output reg o_flashram_enable,
output reg o_sd_enable,
output reg o_eeprom_pi_enable,
@ -40,7 +39,7 @@ module cart_control (
input [31:0] i_debug_fifo_data,
output reg [23:0] o_ddipl_address,
output reg [23:0] o_sram_address
output reg [23:0] o_save_address
);
// Module parameters
@ -100,17 +99,16 @@ module cart_control (
o_rom_switch <= 1'b0;
o_ddipl_enable <= 1'b0;
o_sram_enable <= 1'b0;
o_sram_768k_mode <= 1'b0;
o_flashram_enable <= 1'b0;
o_sd_enable <= 1'b0;
o_eeprom_pi_enable <= 1'b0;
o_eeprom_enable <= 1'b0;
o_eeprom_16k_mode <= 1'b0;
o_n64_reset_btn <= 1'b1;
o_ddipl_address <= 24'hF0_0000;
o_sram_address <= 24'hFF_E000;
o_ddipl_address <= 24'hEF_8000;
o_save_address <= 24'hFF_8000;
o_debug_dma_bank <= 4'd1;
o_debug_dma_address <= 24'hFC_0000;
o_debug_dma_address <= 24'hCF_8000;
o_debug_dma_length <= 20'd0;
r_bootloader <= 16'h0000;
r_skip_bootloader <= 1'b0;
@ -121,7 +119,6 @@ module cart_control (
{
r_skip_bootloader,
o_flashram_enable,
o_sram_768k_mode,
o_sram_enable,
o_sd_enable,
o_eeprom_pi_enable,
@ -130,31 +127,38 @@ module cart_control (
o_ddipl_enable,
o_rom_switch,
o_sdram_writable
} <= i_data[10:0];
} <= {i_data[10:9], i_data[7:0]};
end
REG_BOOT: begin
r_bootloader <= i_data[15:0];
end
REG_GPIO: begin
o_n64_reset_btn <= ~i_data[0];
end
REG_USB_SCR: begin
{o_debug_fifo_flush, o_debug_dma_start} <= {i_data[2], i_data[0]};
end
REG_USB_DMA_ADDR: begin
{o_debug_dma_bank, o_debug_dma_address} <= {i_data[31:28], i_data[25:2]};
end
REG_USB_DMA_LEN: begin
o_debug_dma_length <= i_data[19:0];
end
REG_DDIPL_ADDR: begin
o_ddipl_address <= i_data[25:2];
end
REG_SRAM_ADDR: begin
o_sram_address <= i_data[25:2];
end
default: begin
o_save_address <= i_data[25:2];
end
default: begin end
endcase
end
@ -182,7 +186,7 @@ module cart_control (
o_data[10:0] <= {
r_skip_bootloader,
o_flashram_enable,
o_sram_768k_mode,
1'b0,
o_sram_enable,
o_sd_enable,
o_eeprom_pi_enable,
@ -193,26 +197,32 @@ module cart_control (
o_sdram_writable
};
end
REG_BOOT: begin
o_data[15:0] <= r_bootloader;
end
REG_VERSION: begin
o_data <= {"S", "6", "4", VERSION};
end
REG_GPIO: begin
o_data[2:0] <= {r_nmi_ff2, r_reset_ff2, ~o_n64_reset_btn};
end
REG_USB_SCR: begin
{o_data[13:3], o_data[1:0]} <= {i_debug_fifo_items, i_debug_ready, i_debug_dma_busy};
end
REG_DDIPL_ADDR: begin
o_data[25:0] <= {o_ddipl_address, 2'b00};
end
REG_SRAM_ADDR: begin
o_data[25:0] <= {o_sram_address, 2'b00};
end
default: begin
o_data[25:0] <= {o_save_address, 2'b00};
end
default: begin end
endcase
end else begin
o_data <= i_debug_fifo_data;

View File

@ -4,5 +4,4 @@
`define BANK_SDRAM 4'd1
`define BANK_CART 4'd2
`define BANK_EEPROM 4'd3
`define BANK_FLASHRAM 4'd4
`define BANK_SD 4'd5
`define BANK_SD 4'd4

View File

@ -0,0 +1,301 @@
`include "../constants.vh"
module flashram_controller (
input i_clk,
input i_reset,
input [23:0] i_save_address,
output o_flashram_read_mode,
input i_request,
input i_write,
output o_busy,
output reg o_ack,
input [14:0] i_address,
output reg [31:0] o_data,
input [31:0] i_data,
output reg o_mem_request,
output reg o_mem_write,
input i_mem_busy,
input i_mem_ack,
output reg [3:0] o_mem_bank,
output reg [23:0] o_mem_address,
output reg [31:0] o_mem_data,
input [31:0] i_mem_data
);
// State machine and command decoder
localparam [31:0] FLASH_TYPE_ID = 32'h1111_8001;
localparam [31:0] FLASH_MODEL_ID = 32'h00C2_001D;
localparam [7:0] CMD_STATUS_MODE = 8'hD2;
localparam [7:0] CMD_READID_MODE = 8'hE1;
localparam [7:0] CMD_READ_MODE = 8'hF0;
localparam [7:0] CMD_ERASE_SECTOR = 8'h4B;
localparam [7:0] CMD_ERASE_CHIP = 8'h3C;
localparam [7:0] CMD_WRITE_MODE = 8'hB4;
localparam [7:0] CMD_ERASE_START = 8'h78;
localparam [7:0] CMD_WRITE_START = 8'hA5;
localparam STATE_STATUS = 0;
localparam STATE_ID = 1;
localparam STATE_READ = 2;
localparam STATE_ERASE = 3;
localparam STATE_WRITE = 4;
localparam STATE_EXECUTE = 5;
localparam [1:0] EXECUTE_WRITE = 2'b00;
localparam [1:0] EXECUTE_ERASE_SECTOR = 2'b10;
localparam [1:0] EXECUTE_ERASE_CHIP = 2'b11;
reg [5:0] r_flashram_state;
reg [9:0] r_sector_offset;
reg [1:0] r_execute_mode;
reg r_execute_start;
reg r_execute_done;
assign o_flashram_read_mode = r_flashram_state[STATE_READ];
wire w_cmd_request = i_request && i_write && i_address[14] && !r_flashram_state[STATE_EXECUTE];
wire [7:0] w_cmd_op = i_data[31:24];
always @(posedge i_clk) begin
r_execute_start <= 1'b0;
if (i_reset || r_execute_done) begin
r_flashram_state <= (1'b1 << STATE_STATUS);
end else begin
if (w_cmd_request) begin
r_flashram_state <= 6'b000000;
if (w_cmd_op == CMD_STATUS_MODE) begin
r_flashram_state[STATE_STATUS] <= 1'b1;
end
if (w_cmd_op == CMD_READID_MODE) begin
r_flashram_state[STATE_ID] <= 1'b1;
end
if (w_cmd_op == CMD_READ_MODE) begin
r_flashram_state[STATE_READ] <= 1'b1;
end
if (w_cmd_op == CMD_ERASE_SECTOR) begin
r_flashram_state[STATE_ERASE] <= 1'b1;
r_sector_offset <= {i_data[9:7], 7'd0};
r_execute_mode <= EXECUTE_ERASE_SECTOR;
end
if (w_cmd_op == CMD_ERASE_CHIP) begin
r_flashram_state[STATE_ERASE] <= 1'b1;
r_sector_offset <= 10'd0;
r_execute_mode <= EXECUTE_ERASE_CHIP;
end
if (w_cmd_op == CMD_WRITE_MODE) begin
r_flashram_state[STATE_WRITE] <= 1'b1;
end
if (w_cmd_op == CMD_ERASE_START) begin
if (r_flashram_state[STATE_ERASE]) begin
r_flashram_state[STATE_EXECUTE] <= 1'b1;
r_execute_start <= 1'b1;
end
end
if (w_cmd_op == CMD_WRITE_START) begin
r_flashram_state[STATE_EXECUTE] <= 1'b1;
r_sector_offset <= i_data[9:0];
r_execute_mode <= EXECUTE_WRITE;
r_execute_start <= 1'b1;
end
end
end
end
// Status controller
reg r_erase_busy;
reg r_erase_done;
reg r_write_busy;
reg r_write_done;
wire [3:0] w_status = {r_erase_done, r_write_done, r_erase_busy, r_write_busy};
wire w_status_write_request = i_request && i_write && !i_address[14] && r_flashram_state[STATE_STATUS];
always @(posedge i_clk) begin
if (i_reset) begin
r_erase_busy <= 1'b0;
r_write_busy <= 1'b0;
r_erase_done <= 1'b0;
r_write_done <= 1'b0;
end else begin
if (w_status_write_request) begin
r_erase_done <= r_erase_done & i_data[3];
r_write_done <= r_write_done & i_data[1];
end
if (r_execute_start) begin
if (r_execute_mode == EXECUTE_WRITE) begin
r_write_busy <= 1'b1;
r_write_done <= 1'b0;
end else begin
r_erase_busy <= 1'b1;
r_erase_done <= 1'b0;
end
end
if (r_execute_done) begin
if (r_execute_mode == EXECUTE_WRITE) begin
r_write_busy <= 1'b0;
r_write_done <= 1'b1;
end else begin
r_erase_busy <= 1'b0;
r_erase_done <= 1'b1;
end
end
end
end
// Bus controller
assign o_busy = 1'b0;
wire [31:0] w_write_buffer_o_data;
wire w_flashram_controller_read_request = i_request && !i_write && !o_busy && !r_flashram_state[STATE_READ];
always @(posedge i_clk) begin
o_ack <= 1'b0;
if (w_flashram_controller_read_request) begin
o_ack <= 1'b1;
o_data <= {12'h000, w_status, 12'h000, w_status};
if (r_flashram_state[STATE_ID]) begin
o_data <= i_address[0] ? FLASH_MODEL_ID : FLASH_TYPE_ID;
end
if (r_flashram_state[STATE_WRITE]) begin
o_data <= w_write_buffer_o_data;
end
end
end
// Page write buffer
reg [4:0] r_write_buffer_address;
wire [31:0] w_write_buffer_o_mem_data;
wire w_write_buffer_request = i_request && i_write && !o_busy && !i_address[14] && r_flashram_state[STATE_WRITE];
ram_flashram_write_buffer ram_flashram_write_buffer_inst (
.clock(i_clk),
.wren_a(w_write_buffer_request),
.address_a(i_address[4:0]),
.data_a(i_data),
.q_a(w_write_buffer_o_data),
.wren_b(i_mem_ack),
.address_b(r_write_buffer_address),
.data_b(i_mem_data & w_write_buffer_o_mem_data),
.q_b(w_write_buffer_o_mem_data)
);
// Memory controller
reg [15:0] r_items_left;
wire w_execute_done = !r_execute_start && (r_items_left == 16'd0) && r_flashram_state[STATE_EXECUTE];
wire w_read_phase_done = w_execute_done && !o_mem_write && i_mem_ack;
wire w_write_phase_done = w_execute_done && o_mem_write;
wire w_mem_request_successful = o_mem_request && !i_mem_busy;
wire w_address_reset = r_execute_start || w_read_phase_done;
wire w_write_buffer_address_increment = o_mem_write ? w_mem_request_successful : i_mem_ack;
always @(posedge i_clk) begin
r_execute_done <= w_write_phase_done;
end
always @(posedge i_clk) begin
if (w_address_reset) begin
case (r_execute_mode)
EXECUTE_WRITE: r_items_left <= 16'h20;
EXECUTE_ERASE_SECTOR: r_items_left <= 16'h1000;
EXECUTE_ERASE_CHIP: r_items_left <= 16'h8000;
default: r_items_left <= 16'd0;
endcase
end
if (w_mem_request_successful) begin
r_items_left <= r_items_left - 1'd1;
end
end
always @(posedge i_clk) begin
if (i_reset) begin
o_mem_request <= 1'b0;
end else begin
if (r_items_left > 16'd0) begin
o_mem_request <= 1'b1;
end
if (w_mem_request_successful) begin
o_mem_request <= 1'b0;
end
end
end
always @(posedge i_clk) begin
if (r_execute_start) begin
if (r_execute_mode == EXECUTE_WRITE) begin
o_mem_write <= 1'b0;
end else begin
o_mem_write <= 1'b1;
end
end
if (w_read_phase_done) begin
o_mem_write <= 1'b1;
end
end
always @(posedge i_clk) begin
o_mem_bank <= `BANK_SDRAM;
end
always @(posedge i_clk) begin
if (w_address_reset) begin
o_mem_address <= i_save_address + {9'd0, r_sector_offset, 5'd0};
r_write_buffer_address <= 5'd0;
end else begin
if (w_mem_request_successful) begin
o_mem_address <= o_mem_address + 1'd1;
end
if (w_write_buffer_address_increment) begin
r_write_buffer_address <= r_write_buffer_address + 1'd1;
end
end
end
always @(*) begin
o_mem_data = 32'hFFFF_FFFF;
if (r_execute_mode == EXECUTE_WRITE) begin
o_mem_data = w_write_buffer_o_mem_data;
end
end
endmodule

View File

@ -0,0 +1,4 @@
set_global_assignment -name IP_TOOL_NAME "RAM: 2-PORT"
set_global_assignment -name IP_TOOL_VERSION "20.1"
set_global_assignment -name IP_GENERATED_DEVICE_FAMILY "{MAX 10}"
set_global_assignment -name VERILOG_FILE [file join $::quartus(qip_path) "ram_flashram_write_buffer.v"]

View File

@ -0,0 +1,243 @@
// megafunction wizard: %RAM: 2-PORT%
// GENERATION: STANDARD
// VERSION: WM1.0
// MODULE: altsyncram
// ============================================================
// File Name: ram_flashram_write_buffer.v
// Megafunction Name(s):
// altsyncram
//
// Simulation Library Files(s):
// altera_mf
// ============================================================
// ************************************************************
// THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
//
// 20.1.1 Build 720 11/11/2020 SJ Lite Edition
// ************************************************************
//Copyright (C) 2020 Intel Corporation. All rights reserved.
//Your use of Intel Corporation's design tools, logic functions
//and other software and tools, and any partner logic
//functions, and any output files from any of the foregoing
//(including device programming or simulation files), and any
//associated documentation or information are expressly subject
//to the terms and conditions of the Intel Program License
//Subscription Agreement, the Intel Quartus Prime License Agreement,
//the Intel FPGA IP License Agreement, or other applicable license
//agreement, including, without limitation, that your use is for
//the sole purpose of programming logic devices manufactured by
//Intel and sold by Intel or its authorized distributors. Please
//refer to the applicable agreement for further details, at
//https://fpgasoftware.intel.com/eula.
// synopsys translate_off
`timescale 1 ps / 1 ps
// synopsys translate_on
module ram_flashram_write_buffer (
address_a,
address_b,
clock,
data_a,
data_b,
wren_a,
wren_b,
q_a,
q_b);
input [4:0] address_a;
input [4:0] address_b;
input clock;
input [31:0] data_a;
input [31:0] data_b;
input wren_a;
input wren_b;
output [31:0] q_a;
output [31:0] q_b;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_off
`endif
tri1 clock;
tri0 wren_a;
tri0 wren_b;
`ifndef ALTERA_RESERVED_QIS
// synopsys translate_on
`endif
wire [31:0] sub_wire0;
wire [31:0] sub_wire1;
wire [31:0] q_a = sub_wire0[31:0];
wire [31:0] q_b = sub_wire1[31:0];
altsyncram altsyncram_component (
.address_a (address_a),
.address_b (address_b),
.clock0 (clock),
.data_a (data_a),
.data_b (data_b),
.wren_a (wren_a),
.wren_b (wren_b),
.q_a (sub_wire0),
.q_b (sub_wire1),
.aclr0 (1'b0),
.aclr1 (1'b0),
.addressstall_a (1'b0),
.addressstall_b (1'b0),
.byteena_a (1'b1),
.byteena_b (1'b1),
.clock1 (1'b1),
.clocken0 (1'b1),
.clocken1 (1'b1),
.clocken2 (1'b1),
.clocken3 (1'b1),
.eccstatus (),
.rden_a (1'b1),
.rden_b (1'b1));
defparam
altsyncram_component.address_reg_b = "CLOCK0",
altsyncram_component.clock_enable_input_a = "BYPASS",
altsyncram_component.clock_enable_input_b = "BYPASS",
altsyncram_component.clock_enable_output_a = "BYPASS",
altsyncram_component.clock_enable_output_b = "BYPASS",
altsyncram_component.indata_reg_b = "CLOCK0",
altsyncram_component.intended_device_family = "MAX 10",
altsyncram_component.lpm_type = "altsyncram",
altsyncram_component.numwords_a = 32,
altsyncram_component.numwords_b = 32,
altsyncram_component.operation_mode = "BIDIR_DUAL_PORT",
altsyncram_component.outdata_aclr_a = "NONE",
altsyncram_component.outdata_aclr_b = "NONE",
altsyncram_component.outdata_reg_a = "UNREGISTERED",
altsyncram_component.outdata_reg_b = "UNREGISTERED",
altsyncram_component.power_up_uninitialized = "FALSE",
altsyncram_component.read_during_write_mode_mixed_ports = "DONT_CARE",
altsyncram_component.read_during_write_mode_port_a = "NEW_DATA_WITH_NBE_READ",
altsyncram_component.read_during_write_mode_port_b = "NEW_DATA_WITH_NBE_READ",
altsyncram_component.widthad_a = 5,
altsyncram_component.widthad_b = 5,
altsyncram_component.width_a = 32,
altsyncram_component.width_b = 32,
altsyncram_component.width_byteena_a = 1,
altsyncram_component.width_byteena_b = 1,
altsyncram_component.wrcontrol_wraddress_reg_b = "CLOCK0";
endmodule
// ============================================================
// CNX file retrieval info
// ============================================================
// Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
// Retrieval info: PRIVATE: ADDRESSSTALL_B NUMERIC "0"
// Retrieval info: PRIVATE: BYTEENA_ACLR_A NUMERIC "0"
// Retrieval info: PRIVATE: BYTEENA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_ENABLE_A NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_ENABLE_B NUMERIC "0"
// Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
// Retrieval info: PRIVATE: BlankMemory NUMERIC "1"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_B NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
// Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_B NUMERIC "0"
// Retrieval info: PRIVATE: CLRdata NUMERIC "0"
// Retrieval info: PRIVATE: CLRq NUMERIC "0"
// Retrieval info: PRIVATE: CLRrdaddress NUMERIC "0"
// Retrieval info: PRIVATE: CLRrren NUMERIC "0"
// Retrieval info: PRIVATE: CLRwraddress NUMERIC "0"
// Retrieval info: PRIVATE: CLRwren NUMERIC "0"
// Retrieval info: PRIVATE: Clock NUMERIC "0"
// Retrieval info: PRIVATE: Clock_A NUMERIC "0"
// Retrieval info: PRIVATE: Clock_B NUMERIC "0"
// Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: INDATA_REG_B NUMERIC "1"
// Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
// Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
// Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "MAX 10"
// Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
// Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
// Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
// Retrieval info: PRIVATE: MEMSIZE NUMERIC "1024"
// Retrieval info: PRIVATE: MEM_IN_BITS NUMERIC "0"
// Retrieval info: PRIVATE: MIFfilename STRING ""
// Retrieval info: PRIVATE: OPERATION_MODE NUMERIC "3"
// Retrieval info: PRIVATE: OUTDATA_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: OUTDATA_REG_B NUMERIC "0"
// Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_MIXED_PORTS NUMERIC "2"
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_A NUMERIC "4"
// Retrieval info: PRIVATE: READ_DURING_WRITE_MODE_PORT_B NUMERIC "4"
// Retrieval info: PRIVATE: REGdata NUMERIC "1"
// Retrieval info: PRIVATE: REGq NUMERIC "0"
// Retrieval info: PRIVATE: REGrdaddress NUMERIC "0"
// Retrieval info: PRIVATE: REGrren NUMERIC "0"
// Retrieval info: PRIVATE: REGwraddress NUMERIC "1"
// Retrieval info: PRIVATE: REGwren NUMERIC "1"
// Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
// Retrieval info: PRIVATE: USE_DIFF_CLKEN NUMERIC "0"
// Retrieval info: PRIVATE: UseDPRAM NUMERIC "1"
// Retrieval info: PRIVATE: VarWidth NUMERIC "0"
// Retrieval info: PRIVATE: WIDTH_READ_A NUMERIC "32"
// Retrieval info: PRIVATE: WIDTH_READ_B NUMERIC "32"
// Retrieval info: PRIVATE: WIDTH_WRITE_A NUMERIC "32"
// Retrieval info: PRIVATE: WIDTH_WRITE_B NUMERIC "32"
// Retrieval info: PRIVATE: WRADDR_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: WRADDR_REG_B NUMERIC "1"
// Retrieval info: PRIVATE: WRCTRL_ACLR_B NUMERIC "0"
// Retrieval info: PRIVATE: enable NUMERIC "0"
// Retrieval info: PRIVATE: rden NUMERIC "0"
// Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
// Retrieval info: CONSTANT: ADDRESS_REG_B STRING "CLOCK0"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
// Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_B STRING "BYPASS"
// Retrieval info: CONSTANT: INDATA_REG_B STRING "CLOCK0"
// Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "MAX 10"
// Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
// Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "32"
// Retrieval info: CONSTANT: NUMWORDS_B NUMERIC "32"
// Retrieval info: CONSTANT: OPERATION_MODE STRING "BIDIR_DUAL_PORT"
// Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_ACLR_B STRING "NONE"
// Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
// Retrieval info: CONSTANT: OUTDATA_REG_B STRING "UNREGISTERED"
// Retrieval info: CONSTANT: POWER_UP_UNINITIALIZED STRING "FALSE"
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_MIXED_PORTS STRING "DONT_CARE"
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_A STRING "NEW_DATA_WITH_NBE_READ"
// Retrieval info: CONSTANT: READ_DURING_WRITE_MODE_PORT_B STRING "NEW_DATA_WITH_NBE_READ"
// Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "5"
// Retrieval info: CONSTANT: WIDTHAD_B NUMERIC "5"
// Retrieval info: CONSTANT: WIDTH_A NUMERIC "32"
// Retrieval info: CONSTANT: WIDTH_B NUMERIC "32"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
// Retrieval info: CONSTANT: WIDTH_BYTEENA_B NUMERIC "1"
// Retrieval info: CONSTANT: WRCONTROL_WRADDRESS_REG_B STRING "CLOCK0"
// Retrieval info: USED_PORT: address_a 0 0 5 0 INPUT NODEFVAL "address_a[4..0]"
// Retrieval info: USED_PORT: address_b 0 0 5 0 INPUT NODEFVAL "address_b[4..0]"
// Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
// Retrieval info: USED_PORT: data_a 0 0 32 0 INPUT NODEFVAL "data_a[31..0]"
// Retrieval info: USED_PORT: data_b 0 0 32 0 INPUT NODEFVAL "data_b[31..0]"
// Retrieval info: USED_PORT: q_a 0 0 32 0 OUTPUT NODEFVAL "q_a[31..0]"
// Retrieval info: USED_PORT: q_b 0 0 32 0 OUTPUT NODEFVAL "q_b[31..0]"
// Retrieval info: USED_PORT: wren_a 0 0 0 0 INPUT GND "wren_a"
// Retrieval info: USED_PORT: wren_b 0 0 0 0 INPUT GND "wren_b"
// Retrieval info: CONNECT: @address_a 0 0 5 0 address_a 0 0 5 0
// Retrieval info: CONNECT: @address_b 0 0 5 0 address_b 0 0 5 0
// Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
// Retrieval info: CONNECT: @data_a 0 0 32 0 data_a 0 0 32 0
// Retrieval info: CONNECT: @data_b 0 0 32 0 data_b 0 0 32 0
// Retrieval info: CONNECT: @wren_a 0 0 0 0 wren_a 0 0 0 0
// Retrieval info: CONNECT: @wren_b 0 0 0 0 wren_b 0 0 0 0
// Retrieval info: CONNECT: q_a 0 0 32 0 @q_a 0 0 32 0
// Retrieval info: CONNECT: q_b 0 0 32 0 @q_b 0 0 32 0
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.v TRUE
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.inc FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.cmp FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer.bsf FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer_inst.v FALSE
// Retrieval info: GEN_FILE: TYPE_NORMAL ram_flashram_write_buffer_bb.v FALSE
// Retrieval info: LIB_FILE: altera_mf

View File

@ -4,46 +4,44 @@ module n64_bank_decoder (
input i_clk,
input i_address_high_op,
input i_address_low_op,
input [15:0] i_n64_pi_ad,
output reg [3:0] o_bank,
output reg o_prefetch,
output reg o_ddipl_request,
output reg o_sram_request,
output reg o_ddipl_pi_request,
output reg o_sram_pi_request,
output reg o_flashram_pi_request,
input i_ddipl_enable,
input i_sram_enable,
input i_sram_768k_mode,
input i_flashram_enable,
input i_eeprom_enable,
input i_eeprom_pi_enable,
input i_sd_enable
);
reg r_address_high_lsb;
always @(posedge i_clk) begin
if (i_address_high_op) begin
o_bank <= `BANK_INVALID;
o_prefetch <= 1'b1;
o_ddipl_request <= 1'b0;
o_sram_request <= 1'b0;
o_ddipl_pi_request <= 1'b0;
o_sram_pi_request <= 1'b0;
o_flashram_pi_request <= 1'b0;
casez (i_n64_pi_ad)
16'b0000011000??????: begin // DDIPL
if (i_ddipl_enable) begin
o_bank <= `BANK_SDRAM;
o_ddipl_request <= 1'b1;
o_ddipl_pi_request <= 1'b1;
end
end
16'b000010000000000?: begin // SRAM / FlashRAM
r_address_high_lsb <= i_n64_pi_ad[0];
if (i_flashram_enable && !i_n64_pi_ad[0]) begin
o_bank <= `BANK_FLASHRAM;
if (i_flashram_enable) begin
o_bank <= `BANK_SDRAM;
o_flashram_pi_request <= 1'b1;
end else if (i_sram_enable) begin
o_bank <= `BANK_SDRAM;
o_sram_request <= 1'b1;
o_sram_pi_request <= 1'b1;
end
end
@ -57,7 +55,7 @@ module n64_bank_decoder (
end
16'b0001111000000001: begin // EEPROM
if (i_eeprom_enable) begin
if (i_eeprom_pi_enable) begin
o_bank <= `BANK_EEPROM;
end
end
@ -68,49 +66,6 @@ module n64_bank_decoder (
o_prefetch <= 1'b0;
end
end
default: begin end
endcase
end
if (i_address_low_op) begin
case (o_bank)
`BANK_SDRAM: begin
if (o_sram_request) begin
if (i_sram_768k_mode) begin
if (r_address_high_lsb && i_n64_pi_ad[1]) begin
o_bank <= `BANK_INVALID;
end
end else begin
if (i_n64_pi_ad[1]) begin
o_bank <= `BANK_INVALID;
end
end
end
end
`BANK_CART: begin
if (i_n64_pi_ad[15:14] != 2'b00) begin
o_bank <= `BANK_INVALID;
end
end
`BANK_EEPROM: begin
if (i_n64_pi_ad[15:11] != 5'b00000) begin
o_bank <= `BANK_INVALID;
end
end
`BANK_FLASHRAM: begin
if (r_address_high_lsb) begin
o_bank <= `BANK_INVALID;
end
end
`BANK_SD: begin
if (i_n64_pi_ad[15:10] != 6'b000000) begin
o_bank <= `BANK_INVALID;
end
end
default: begin end
endcase

View File

@ -20,17 +20,19 @@ module n64_pi (
input [31:0] i_data,
output reg [31:0] o_data,
output o_sram_request,
output o_sram_pi_request,
output o_flashram_pi_request,
input i_ddipl_enable,
input i_sram_enable,
input i_sram_768k_mode,
input i_flashram_enable,
input i_sd_enable,
input i_eeprom_enable,
input i_eeprom_pi_enable,
input [23:0] i_ddipl_address,
input [23:0] i_sram_address
input [23:0] i_save_address,
input i_flashram_read_mode
);
// Parameters
@ -88,7 +90,7 @@ module n64_pi (
// Bank decoder, address translator and prefetch signal
wire w_bank_prefetch;
wire w_ddipl_request;
wire w_ddipl_pi_request;
wire w_prefetch = !PREFETCH_DISABLE && w_bank_prefetch;
@ -96,19 +98,18 @@ module n64_pi (
.i_clk(i_clk),
.i_address_high_op(w_address_high_op),
.i_address_low_op(w_address_low_op),
.i_n64_pi_ad(io_n64_pi_ad),
.o_bank(o_bank),
.o_prefetch(w_bank_prefetch),
.o_ddipl_request(w_ddipl_request),
.o_sram_request(o_sram_request),
.o_ddipl_pi_request(w_ddipl_pi_request),
.o_sram_pi_request(o_sram_pi_request),
.o_flashram_pi_request(o_flashram_pi_request),
.i_ddipl_enable(i_ddipl_enable),
.i_sram_enable(i_sram_enable),
.i_sram_768k_mode(i_sram_768k_mode),
.i_flashram_enable(i_flashram_enable),
.i_eeprom_enable(i_eeprom_enable),
.i_eeprom_pi_enable(i_eeprom_pi_enable),
.i_sd_enable(i_sd_enable)
);
@ -124,6 +125,7 @@ module n64_pi (
if (r_address_valid_op) begin
r_word_counter <= 1'b0;
end
if (w_read_op || w_write_op) begin
r_word_counter <= ~r_word_counter;
end
@ -153,11 +155,13 @@ module n64_pi (
end
if (i_ack) begin
r_prefetch_read <= 1'b0;
if (w_prefetch) begin
r_pi_read_buffer <= i_data;
end else begin
r_pi_output_data <= i_data;
end
if (r_prefetch_read) begin
r_pi_output_data <= i_data;
end
@ -201,6 +205,7 @@ module n64_pi (
o_request <= 1'b0;
o_write <= 1'b0;
end
if (w_bus_request_op) begin
if (o_request) begin
r_pending_request <= 1'b1;
@ -210,6 +215,7 @@ module n64_pi (
o_write <= w_bus_write_op;
end
end
if (r_pending_request && !i_busy) begin
o_request <= 1'b1;
o_write <= r_pending_request_write;
@ -224,7 +230,7 @@ module n64_pi (
wire [9:0] w_pi_high_address = io_n64_pi_ad[9:0];
wire [15:0] w_pi_low_address = {io_n64_pi_ad[15:1], 1'b0};
wire [25:0] w_ddipl_translated_address = o_address + {i_ddipl_address, 2'b00};
wire [25:0] w_sram_translated_address = o_address + {i_sram_address, 2'b00};
wire [25:0] w_save_translated_address = o_address + {i_save_address, 2'b00};
reg r_first_transfer;
reg [14:0] r_address_low_buffer;
@ -241,13 +247,19 @@ module n64_pi (
if (r_address_valid_op) begin
r_first_transfer <= w_prefetch;
r_address_low_buffer <= o_address[15:1];
if (w_ddipl_request) begin
if (w_ddipl_pi_request) begin
o_address <= w_ddipl_translated_address;
r_address_low_buffer <= w_ddipl_translated_address[15:1];
end
if (o_sram_request) begin
o_address <= w_sram_translated_address;
r_address_low_buffer <= w_sram_translated_address[15:1];
if (o_sram_pi_request) begin
o_address <= w_save_translated_address;
r_address_low_buffer <= w_save_translated_address[15:1];
end
if (o_flashram_pi_request && i_flashram_read_mode) begin
o_address <= w_save_translated_address;
end
end

View File

@ -20,8 +20,8 @@ module sd_interface (
input i_dma_ack,
output [3:0] o_dma_bank,
output [23:0] o_dma_address,
input [31:0] i_dma_data,
output [31:0] o_dma_data
output [31:0] o_dma_data,
input [31:0] i_dma_data
);
// Clock generator

View File

@ -33,10 +33,6 @@ module top (
inout io_sd_cmd,
inout [3:0] io_sd_dat,
output o_sram_clk,
output o_sram_cs,
inout [3:0] io_sram_dq,
output o_rtc_scl,
inout io_rtc_sda,
@ -57,7 +53,6 @@ module top (
wire w_n64_reset_btn;
assign {o_sram_clk, o_sram_cs, io_sram_dq} = 6'bZZZZZZ;
assign {o_rtc_scl, io_rtc_sda} = 2'bZZ;
assign io_pmod[3] = w_n64_reset_btn ? 1'bZ : 1'b0;
assign {io_pmod[7:4], io_pmod[2:0]} = 7'bZZZZZZZ;
@ -110,42 +105,63 @@ module top (
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_sdram;
wire w_n64_ack_sdram;
wire [31:0] w_n64_i_data_sdram;
wire w_n64_busy_eeprom;
wire w_n64_ack_eeprom;
wire [31:0] w_n64_i_data_eeprom;
wire w_n64_busy_flashram;
wire w_n64_ack_flashram;
wire [31:0] w_n64_i_data_flashram;
wire w_n64_busy_sd;
wire w_n64_ack_sd;
wire [31:0] w_n64_i_data_sd;
wire w_sram_request;
wire w_sram_pi_request;
wire w_flashram_pi_request;
wire w_ddipl_enable;
wire w_sram_enable;
wire w_sram_768k_mode;
wire w_flashram_enable;
wire w_sd_enable;
wire w_eeprom_pi_enable;
wire [23:0] w_ddipl_address;
wire [23:0] w_sram_address;
wire [23:0] w_save_address;
wire w_flashram_read_mode;
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_busy_sd;
w_n64_ack = w_n64_ack_cart_control || w_n64_ack_sdram || w_n64_ack_embedded_flash || w_n64_ack_eeprom || w_n64_ack_sd;
w_n64_busy = (
w_n64_busy_cart_control ||
w_n64_busy_embedded_flash ||
w_n64_busy_sdram ||
w_n64_busy_eeprom ||
w_n64_busy_flashram ||
w_n64_busy_sd
);
w_n64_ack = (
w_n64_ack_cart_control ||
w_n64_ack_embedded_flash ||
w_n64_ack_sdram ||
w_n64_ack_eeprom ||
w_n64_ack_flashram ||
w_n64_ack_sd
);
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_sdram) w_n64_i_data = w_n64_i_data_sdram;
if (w_n64_ack_eeprom) w_n64_i_data = w_n64_i_data_eeprom;
if (w_n64_ack_flashram) w_n64_i_data = w_n64_i_data_flashram;
if (w_n64_ack_sd) w_n64_i_data = w_n64_i_data_sd;
end
@ -169,17 +185,19 @@ module top (
.i_data(w_n64_i_data),
.o_data(w_n64_o_data),
.o_sram_request(w_sram_request),
.o_sram_pi_request(w_sram_pi_request),
.o_flashram_pi_request(w_flashram_pi_request),
.i_ddipl_enable(w_ddipl_enable),
.i_sram_enable(w_sram_enable),
.i_sram_768k_mode(w_sram_768k_mode),
.i_flashram_enable(w_flashram_enable),
.i_sd_enable(w_sd_enable),
.i_eeprom_enable(w_eeprom_pi_enable),
.i_eeprom_pi_enable(w_eeprom_pi_enable),
.i_ddipl_address(w_ddipl_address),
.i_sram_address(w_sram_address)
.i_save_address(w_save_address),
.i_flashram_read_mode(w_flashram_read_mode)
);
@ -321,7 +339,6 @@ module top (
.o_rom_switch(w_rom_switch),
.o_ddipl_enable(w_ddipl_enable),
.o_sram_enable(w_sram_enable),
.o_sram_768k_mode(w_sram_768k_mode),
.o_flashram_enable(w_flashram_enable),
.o_sd_enable(w_sd_enable),
.o_eeprom_pi_enable(w_eeprom_pi_enable),
@ -330,7 +347,7 @@ module top (
.o_n64_reset_btn(w_n64_reset_btn),
.i_debug_ready(1'b1),
.i_debug_ready(1'b1), // TODO: Detect USB cable insertion
.o_debug_dma_start(w_debug_dma_start),
.i_debug_dma_busy(w_debug_dma_busy),
@ -344,29 +361,16 @@ module top (
.i_debug_fifo_data(w_debug_fifo_data),
.o_ddipl_address(w_ddipl_address),
.o_sram_address(w_sram_address)
);
// Embedded flash
wire w_embedded_flash_request_n64 = w_n64_request && !w_rom_switch && !w_n64_write && w_n64_bank == `BANK_SDRAM;
memory_embedded_flash memory_embedded_flash_inst (
.i_clk(w_sys_clk),
.i_reset(w_sys_reset),
.i_request(w_embedded_flash_request_n64),
.o_busy(w_n64_busy_embedded_flash),
.o_ack(w_n64_ack_embedded_flash),
.i_address(w_n64_address[20:2]),
.o_data(w_n64_i_data_embedded_flash)
.o_save_address(w_save_address)
);
// SD card
wire w_n64_request_sd = w_n64_request && w_n64_bank == `BANK_SD;
wire w_n64_request_sd = (
w_n64_request &&
w_n64_bank == `BANK_SD
);
wire w_sd_dma_request;
wire w_sd_dma_write;
@ -415,14 +419,83 @@ module top (
.i_dma_ack(w_sd_dma_ack),
.o_dma_bank(w_sd_dma_bank),
.o_dma_address(w_sd_dma_address),
.i_dma_data(w_sd_dma_i_data),
.o_dma_data(w_sd_dma_o_data)
.o_dma_data(w_sd_dma_o_data),
.i_dma_data(w_sd_dma_i_data)
);
// FlashRAM
wire w_flashram_request_n64 = (
w_n64_request &&
w_flashram_pi_request &&
w_n64_bank == `BANK_SDRAM
);
wire w_flashram_dma_request;
wire w_flashram_dma_write;
wire w_flashram_dma_busy;
wire w_flashram_dma_ack;
wire [3:0] w_flashram_dma_bank;
wire [23:0] w_flashram_dma_address;
wire [31:0] w_flashram_dma_i_data;
wire [31:0] w_flashram_dma_o_data;
flashram_controller flashram_controller_inst (
.i_clk(w_sys_clk),
.i_reset(w_sys_reset),
.i_save_address(w_save_address),
.o_flashram_read_mode(w_flashram_read_mode),
.i_request(w_flashram_request_n64),
.i_write(w_n64_write),
.o_busy(w_n64_busy_flashram),
.o_ack(w_n64_ack_flashram),
.i_address(w_n64_address[16:2]),
.o_data(w_n64_i_data_flashram),
.i_data(w_n64_o_data),
.o_mem_request(w_flashram_dma_request),
.o_mem_write(w_flashram_dma_write),
.i_mem_busy(w_flashram_dma_busy),
.i_mem_ack(w_flashram_dma_ack),
.o_mem_bank(w_flashram_dma_bank),
.o_mem_address(w_flashram_dma_address),
.o_mem_data(w_flashram_dma_o_data),
.i_mem_data(w_flashram_dma_i_data)
);
// Embedded flash in FPGA
wire w_embedded_flash_request_n64 = (
w_n64_request &&
!w_rom_switch &&
!w_n64_write &&
w_n64_bank == `BANK_SDRAM
);
memory_embedded_flash memory_embedded_flash_inst (
.i_clk(w_sys_clk),
.i_reset(w_sys_reset),
.i_request(w_embedded_flash_request_n64),
.o_busy(w_n64_busy_embedded_flash),
.o_ack(w_n64_ack_embedded_flash),
.i_address(w_n64_address[20:2]),
.o_data(w_n64_i_data_embedded_flash)
);
// SDRAM
wire w_sdram_request_n64 = w_n64_request && w_rom_switch && (!w_n64_write || (w_n64_write && (w_sdram_writable || w_sram_request)));
wire w_sdram_request_n64 = w_n64_request && (
(w_rom_switch && (w_sdram_writable || !w_n64_write) && !w_flashram_pi_request) ||
w_sram_pi_request ||
(w_flashram_pi_request && w_flashram_read_mode && !w_n64_write)
);
wire w_sdram_request;
wire w_sdram_write;
@ -433,21 +506,21 @@ module top (
wire [31:0] w_sdram_i_data;
device_arbiter #(
.NUM_CONTROLLERS(3),
.NUM_CONTROLLERS(4),
.ADDRESS_WIDTH(25),
.DEVICE_BANK(`BANK_SDRAM)
) device_arbiter_sdram_inst (
.i_clk(w_sys_clk),
.i_reset(w_sys_reset),
.i_request({w_sd_dma_request, w_pc_request, w_sdram_request_n64}),
.i_write({w_sd_dma_write, w_pc_write, w_n64_write}),
.o_busy({w_sd_dma_busy_sdram, w_pc_busy_sdram, w_n64_busy_sdram}),
.o_ack({w_sd_dma_ack_sdram, w_pc_ack_sdram, w_n64_ack_sdram}),
.i_bank({w_sd_dma_bank, w_pc_bank, w_n64_bank}),
.i_address({{w_sd_dma_address, 1'b0}, w_pc_address[25:1], w_n64_address[25:1]}),
.o_data({w_sd_dma_i_data_sdram, w_pc_i_data_sdram, w_n64_i_data_sdram}),
.i_data({w_sd_dma_o_data, w_pc_o_data, w_n64_o_data}),
.i_request({w_flashram_dma_request, w_sd_dma_request, w_pc_request, w_sdram_request_n64}),
.i_write({w_flashram_dma_write, w_sd_dma_write, w_pc_write, w_n64_write}),
.o_busy({w_flashram_dma_busy, w_sd_dma_busy_sdram, w_pc_busy_sdram, w_n64_busy_sdram}),
.o_ack({w_flashram_dma_ack, w_sd_dma_ack_sdram, w_pc_ack_sdram, w_n64_ack_sdram}),
.i_bank({w_flashram_dma_bank, w_sd_dma_bank, w_pc_bank, w_n64_bank}),
.i_address({{w_flashram_dma_address, 1'b0}, {w_sd_dma_address, 1'b0}, w_pc_address[25:1], w_n64_address[25:1]}),
.o_data({w_flashram_dma_i_data, w_sd_dma_i_data_sdram, w_pc_i_data_sdram, w_n64_i_data_sdram}),
.i_data({w_flashram_dma_o_data, w_sd_dma_o_data, w_pc_o_data, w_n64_o_data}),
.o_device_request(w_sdram_request),
.o_device_write(w_sdram_write),
@ -480,7 +553,7 @@ module top (
);
// EEPROM 4/16k
// N64 SI (EEPROM 4/16k and RTC)
wire w_eeprom_request;
wire w_eeprom_write;
@ -539,7 +612,11 @@ module top (
// LED
wire w_led_trigger = (w_n64_request && !w_n64_busy) || (w_pc_request && !w_pc_busy) || (w_sd_dma_request && !w_sd_dma_busy);
wire w_led_trigger = (
(w_n64_request && !w_n64_busy) ||
(w_pc_request && !w_pc_busy) ||
(w_sd_dma_request && !w_sd_dma_busy)
);
cart_led cart_led_inst (
.i_clk(w_sys_clk),

View File

@ -93,15 +93,16 @@ int main(void) {
switch (config.save_type) {
case 1: sc64_enable_eeprom(false); break;
case 2: sc64_enable_eeprom(true); break;
case 3: sc64_enable_sram(false); break;
case 4: sc64_enable_sram(true); break;
case 5: sc64_enable_flashram(); break;
case 3:
case 4: sc64_enable_sram(); break;
case 5:
case 6: sc64_enable_flashram(); break;
}
if (config.save_type == 3) {
sc64_set_sram_address(SC64_SDRAM_SIZE - (32 * 1024));
} else if (config.save_type == 4) {
sc64_set_sram_address(SC64_SDRAM_SIZE - (3 * 32 * 1024));
if (config.save_type >= 3 || config.save_type <= 5) {
sc64_set_save_address(SC64_SDRAM_SIZE - (128 * 1024));
} else if (config.save_type == 6) {
sc64_set_save_address(0x01618000);
}
if (rom_loaded && (config.save[0] != '\0') && config.save_writeback) {

View File

@ -41,13 +41,8 @@ void sc64_disable_flashram(void) {
sc64_disable_peripheral(SC64_CART_SCR_FLASHRAM_ENABLE);
}
void sc64_enable_sram(bool mode_768k) {
void sc64_enable_sram(void) {
sc64_enable_peripheral(SC64_CART_SCR_SRAM_ENABLE);
if (mode_768k) {
sc64_enable_peripheral(SC64_CART_SCR_SRAM_768K_MODE);
} else {
sc64_disable_peripheral(SC64_CART_SCR_SRAM_768K_MODE);
}
}
void sc64_disable_sram(void) {
@ -127,10 +122,10 @@ void sc64_set_ddipl_address(uint32_t address) {
platform_pi_io_write(&SC64_CART->DDIPL_ADDR, address & SC64_CART_DDIPL_ADDR_ADDRESS_MASK);
}
uint32_t sc64_get_sram_address(void) {
uint32_t sc64_get_save_address(void) {
return platform_pi_io_read(&SC64_CART->SRAM_ADDR) & SC64_CART_SRAM_ADDR_ADDRESS_MASK;
}
void sc64_set_sram_address(uint32_t address) {
void sc64_set_save_address(uint32_t address) {
platform_pi_io_write(&SC64_CART->SRAM_ADDR, address & SC64_CART_SRAM_ADDR_ADDRESS_MASK);
}

View File

@ -14,7 +14,7 @@ void sc64_enable_skip_bootloader(void);
void sc64_disable_skip_bootloader(void);
void sc64_enable_flashram(void);
void sc64_disable_flashram(void);
void sc64_enable_sram(bool mode_768k);
void sc64_enable_sram(void);
void sc64_disable_sram(void);
void sc64_enable_sd(void);
void sc64_disable_sd(void);
@ -33,8 +33,8 @@ void sc64_set_boot_mode(uint32_t boot);
uint32_t sc64_get_version(void);
uint32_t sc64_get_ddipl_address(void);
void sc64_set_ddipl_address(uint32_t address);
uint32_t sc64_get_sram_address(void);
void sc64_set_sram_address(uint32_t address);
uint32_t sc64_get_save_address(void);
void sc64_set_save_address(uint32_t address);
#endif

View File

@ -11,8 +11,7 @@
#define SC64_BANK_SDRAM (1)
#define SC64_BANK_CART (2)
#define SC64_BANK_EEPROM (3)
#define SC64_BANK_FLASHRAM (4)
#define SC64_BANK_SD (5)
#define SC64_BANK_SD (4)
// Cart Interface Registers

View File

@ -156,14 +156,10 @@ sc64_sd_fs_error_t sc64_sd_fs_load_save(const char *path) {
length = (scr & SC64_CART_SCR_EEPROM_16K_MODE) ? 2048 : 512;
current_bank = SC64_BANK_EEPROM;
current_offset = 0;
} else if (scr & SC64_CART_SCR_SRAM_ENABLE) {
length = ((scr & SC64_CART_SCR_SRAM_768K_MODE) ? 3 : 1) * (32 * 1024);
} else if (scr & (SC64_CART_SCR_SRAM_ENABLE | SC64_CART_SCR_FLASHRAM_ENABLE)) {
length = 128 * 1024;
current_bank = SC64_BANK_SDRAM;
current_offset = sc64_get_sram_address();
} else if (scr & SC64_CART_SCR_FLASHRAM_ENABLE) { // TODO: FlashRAM
length = 0;
current_bank = SC64_BANK_FLASHRAM;
current_offset = 0;
current_offset = sc64_get_save_address();
}
if ((length == 0) || (path == NULL)) {
@ -203,14 +199,10 @@ sc64_sd_fs_error_t sc64_sd_fs_store_save(const char *path) {
platform_pi_dma_read(save_buffer, &SC64_EEPROM->MEM, length);
platform_cache_invalidate(save_buffer, length);
sc64_disable_eeprom_pi();
} else if (scr & SC64_CART_SCR_SRAM_ENABLE) {
length = ((scr & SC64_CART_SCR_SRAM_768K_MODE) ? 3 : 1) * (32 * 1024);
platform_pi_dma_read(save_buffer, sc64_get_sram_address(), length);
} else if (scr & (SC64_CART_SCR_SRAM_ENABLE | SC64_CART_SCR_FLASHRAM_ENABLE)) {
length = 128 * 1024;
platform_pi_dma_read(save_buffer, sc64_get_save_address(), length);
platform_cache_invalidate(save_buffer, length);
} else if (scr & SC64_CART_SCR_FLASHRAM_ENABLE) { // TODO: FlashRAM
length = 0;
// platform_pi_dma_read(save_buffer, 0, length);
// platform_cache_invalidate(save_buffer, length);
}
if ((length == 0) || (path == NULL)) {